Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 116a4988 authored by Andy Hung's avatar Andy Hung
Browse files

AudioEffect: Convert aux buffer format from q4.27 to float

Test: Solo Tester aux reverb
Bug: 69853407
Change-Id: I72ca2377036e5ccfd5f4631ac6cc5e86d2e40433
parent fa69ca30
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -33,6 +33,9 @@
// FIXME This is actually unity gain, which might not be max in future, expressed in U.12
#define MAX_GAIN_INT AudioMixer::UNITY_GAIN_INT

// This must match frameworks/av/services/audioflinger/Configuration.h
#define FLOAT_AUX

namespace android {

// ----------------------------------------------------------------------------
+67 −38
Original line number Diff line number Diff line
@@ -71,12 +71,20 @@ T max(const T& x, const T& y) {

// Set kUseNewMixer to true to use the new mixer engine always. Otherwise the
// original code will be used for stereo sinks, the new mixer for multichannel.
static const bool kUseNewMixer = true;
static constexpr bool kUseNewMixer = true;

// Set kUseFloat to true to allow floating input into the mixer engine.
// If kUseNewMixer is false, this is ignored or may be overridden internally
// because of downmix/upmix support.
static const bool kUseFloat = true;
static constexpr bool kUseFloat = true;

#ifdef FLOAT_AUX
using TYPE_AUX = float;
static_assert(kUseNewMixer && kUseFloat,
        "kUseNewMixer and kUseFloat must be true for FLOAT_AUX option");
#else
using TYPE_AUX = int32_t; // q4.27
#endif

// Set to default copy buffer size in frames for input processing.
static const size_t kCopyBufferFrameCount = 256;
@@ -861,16 +869,25 @@ inline void AudioMixer::track_t::adjustVolumeRamp(bool aux, bool useFloat)
            }
        }
    }
    /* TODO: aux is always integer regardless of output buffer type */

    if (aux) {
        if (((auxInc>0) && (((prevAuxLevel+auxInc)>>16) >= auxLevel)) ||
                ((auxInc<0) && (((prevAuxLevel+auxInc)>>16) <= auxLevel))) {
#ifdef FLOAT_AUX
        if (useFloat) {
            if ((mAuxInc > 0.f && mPrevAuxLevel + mAuxInc >= mAuxLevel) ||
                    (mAuxInc < 0.f && mPrevAuxLevel + mAuxInc <= mAuxLevel)) {
                auxInc = 0;
                prevAuxLevel = auxLevel << 16;
            mAuxInc = 0.;
                mAuxInc = 0.f;
                mPrevAuxLevel = mAuxLevel;
            }
        } else
#endif
        if ((auxInc > 0 && ((prevAuxLevel + auxInc) >> 16) >= auxLevel) ||
                (auxInc < 0 && ((prevAuxLevel + auxInc) >> 16) <= auxLevel)) {
            auxInc = 0;
            prevAuxLevel = auxLevel << 16;
            mAuxInc = 0.f;
            mPrevAuxLevel = mAuxLevel;
        } else {
            //ALOGV("aux ramp: %d %d %d", auxLevel << 16, prevAuxLevel, auxInc);
        }
    }
}
@@ -1694,7 +1711,7 @@ void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
 * TO: int32_t (Q4.27) or float
 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 * TA: int32_t (Q4.27)
 * TA: int32_t (Q4.27) or float
 */
template <int MIXTYPE,
        typename TO, typename TI, typename TV, typename TA, typename TAV>
@@ -1738,7 +1755,7 @@ static void volumeRampMulti(uint32_t channels, TO* out, size_t frameCount,
/* MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
 * TO: int32_t (Q4.27) or float
 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 * TA: int32_t (Q4.27)
 * TA: int32_t (Q4.27) or float
 */
template <int MIXTYPE,
        typename TO, typename TI, typename TV, typename TA, typename TAV>
@@ -1778,7 +1795,7 @@ static void volumeMulti(uint32_t channels, TO* out, size_t frameCount,
 * ADJUSTVOL   (set to true if volume ramp parameters needs adjustment afterwards)
 * TO: int32_t (Q4.27) or float
 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 * TA: int32_t (Q4.27)
 * TA: int32_t (Q4.27) or float
 */
template <int MIXTYPE, bool USEFLOATVOL, bool ADJUSTVOL,
    typename TO, typename TI, typename TA>
@@ -1788,13 +1805,25 @@ void AudioMixer::volumeMix(TO *out, size_t outFrames,
    if (USEFLOATVOL) {
        if (ramp) {
            volumeRampMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
                    t->mPrevVolume, t->mVolumeInc, &t->prevAuxLevel, t->auxInc);
                    t->mPrevVolume, t->mVolumeInc,
#ifdef FLOAT_AUX
                    &t->mPrevAuxLevel, t->mAuxInc
#else
                    &t->prevAuxLevel, t->auxInc
#endif
                );
            if (ADJUSTVOL) {
                t->adjustVolumeRamp(aux != NULL, true);
            }
        } else {
            volumeMulti<MIXTYPE>(t->mMixerChannelCount, out, outFrames, in, aux,
                    t->mVolume, t->auxLevel);
                    t->mVolume,
#ifdef FLOAT_AUX
                    t->mAuxLevel
#else
                    t->auxLevel
#endif
            );
        }
    } else {
        if (ramp) {
@@ -1851,7 +1880,7 @@ void AudioMixer::process_NoResampleOneTrack(state_t* state)
        }

        const size_t outFrames = b.frameCount;
        volumeMix<MIXTYPE, is_same<TI, float>::value, false> (
        volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, false /* ADJUSTVOL */> (
                out, outFrames, in, aux, ramp, t);

        out += outFrames * channels;
@@ -1874,7 +1903,7 @@ void AudioMixer::process_NoResampleOneTrack(state_t* state)
 * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
 * TO: int32_t (Q4.27) or float
 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 * TA: int32_t (Q4.27)
 * TA: int32_t (Q4.27) or float
 */
template <int MIXTYPE, typename TO, typename TI, typename TA>
void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO* temp, TA* aux)
@@ -1890,7 +1919,7 @@ void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO*
        memset(temp, 0, outFrameCount * t->mMixerChannelCount * sizeof(TO));
        t->resampler->resample((int32_t*)temp, outFrameCount, t->bufferProvider);

        volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
        volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
                out, outFrameCount, temp, aux, ramp, t);

    } else { // constant volume gain
@@ -1905,7 +1934,7 @@ void AudioMixer::track__Resample(track_t* t, TO* out, size_t outFrameCount, TO*
 * MIXTYPE     (see AudioMixerOps.h MIXTYPE_* enumeration)
 * TO: int32_t (Q4.27) or float
 * TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 * TA: int32_t (Q4.27)
 * TA: int32_t (Q4.27) or float
 */
template <int MIXTYPE, typename TO, typename TI, typename TA>
void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
@@ -1914,7 +1943,7 @@ void AudioMixer::track__NoResample(track_t* t, TO* out, size_t frameCount,
    ALOGVV("track__NoResample\n");
    const TI *in = static_cast<const TI *>(t->in);

    volumeMix<MIXTYPE, is_same<TI, float>::value, true>(
    volumeMix<MIXTYPE, is_same<TI, float>::value /* USEFLOATVOL */, true /* ADJUSTVOL */>(
            out, frameCount, in, aux, t->needsRamp(), t);

    // MIXTYPE_MONOEXPAND reads a single input channel and expands to NCHAN output channels.
@@ -1990,11 +2019,11 @@ AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount
    case TRACKTYPE_RESAMPLE:
        switch (mixerInFormat) {
        case AUDIO_FORMAT_PCM_FLOAT:
            return (AudioMixer::hook_t)
                    track__Resample<MIXTYPE_MULTI, float /*TO*/, float /*TI*/, int32_t /*TA*/>;
            return (AudioMixer::hook_t)track__Resample<
                    MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
        case AUDIO_FORMAT_PCM_16_BIT:
            return (AudioMixer::hook_t)\
                    track__Resample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
            return (AudioMixer::hook_t)track__Resample<
                    MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
        default:
            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
            break;
@@ -2003,11 +2032,11 @@ AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount
    case TRACKTYPE_NORESAMPLEMONO:
        switch (mixerInFormat) {
        case AUDIO_FORMAT_PCM_FLOAT:
            return (AudioMixer::hook_t)
                    track__NoResample<MIXTYPE_MONOEXPAND, float, float, int32_t>;
            return (AudioMixer::hook_t)track__NoResample<
                            MIXTYPE_MONOEXPAND, float /*TO*/, float /*TI*/, TYPE_AUX>;
        case AUDIO_FORMAT_PCM_16_BIT:
            return (AudioMixer::hook_t)
                    track__NoResample<MIXTYPE_MONOEXPAND, int32_t, int16_t, int32_t>;
            return (AudioMixer::hook_t)track__NoResample<
                            MIXTYPE_MONOEXPAND, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
        default:
            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
            break;
@@ -2016,11 +2045,11 @@ AudioMixer::hook_t AudioMixer::getTrackHook(int trackType, uint32_t channelCount
    case TRACKTYPE_NORESAMPLE:
        switch (mixerInFormat) {
        case AUDIO_FORMAT_PCM_FLOAT:
            return (AudioMixer::hook_t)
                    track__NoResample<MIXTYPE_MULTI, float, float, int32_t>;
            return (AudioMixer::hook_t)track__NoResample<
                    MIXTYPE_MULTI, float /*TO*/, float /*TI*/, TYPE_AUX>;
        case AUDIO_FORMAT_PCM_16_BIT:
            return (AudioMixer::hook_t)
                    track__NoResample<MIXTYPE_MULTI, int32_t, int16_t, int32_t>;
            return (AudioMixer::hook_t)track__NoResample<
                    MIXTYPE_MULTI, int32_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
        default:
            LOG_ALWAYS_FATAL("bad mixerInFormat: %#x", mixerInFormat);
            break;
@@ -2055,11 +2084,11 @@ AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, uint32_t
    case AUDIO_FORMAT_PCM_FLOAT:
        switch (mixerOutFormat) {
        case AUDIO_FORMAT_PCM_FLOAT:
            return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
                    float /*TO*/, float /*TI*/, int32_t /*TA*/>;
            return process_NoResampleOneTrack<
                    MIXTYPE_MULTI_SAVEONLY, float /*TO*/, float /*TI*/, TYPE_AUX>;
        case AUDIO_FORMAT_PCM_16_BIT:
            return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
                    int16_t, float, int32_t>;
            return process_NoResampleOneTrack<
                    MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, float /*TI*/, TYPE_AUX>;
        default:
            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
            break;
@@ -2068,11 +2097,11 @@ AudioMixer::process_hook_t AudioMixer::getProcessHook(int processType, uint32_t
    case AUDIO_FORMAT_PCM_16_BIT:
        switch (mixerOutFormat) {
        case AUDIO_FORMAT_PCM_FLOAT:
            return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
                    float, int16_t, int32_t>;
            return process_NoResampleOneTrack<
                    MIXTYPE_MULTI_SAVEONLY, float /*TO*/, int16_t /*TI*/, TYPE_AUX>;
        case AUDIO_FORMAT_PCM_16_BIT:
            return process_NoResampleOneTrack<MIXTYPE_MULTI_SAVEONLY,
                    int16_t, int16_t, int32_t>;
            return process_NoResampleOneTrack<
                    MIXTYPE_MULTI_SAVEONLY, int16_t /*TO*/, int16_t /*TI*/, TYPE_AUX>;
        default:
            LOG_ALWAYS_FATAL("bad mixerOutFormat: %#x", mixerOutFormat);
            break;
+7 −4
Original line number Diff line number Diff line
@@ -188,13 +188,13 @@ inline void MixAccum(TO *auxaccum, TI value) {

template<>
inline void MixAccum<float, int16_t>(float *auxaccum, int16_t value) {
    static const float norm = 1. / (1 << 15);
    static constexpr float norm = 1. / (1 << 15);
    *auxaccum += norm * value;
}

template<>
inline void MixAccum<float, int32_t>(float *auxaccum, int32_t value) {
    static const float norm = 1. / (1 << 27);
    static constexpr float norm = 1. / (1 << 27);
    *auxaccum += norm * value;
}

@@ -238,6 +238,7 @@ enum {
 *   NCHAN represents number of input and output channels.
 *   TO: int32_t (Q4.27) or float
 *   TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 *   TA: int32_t (Q4.27) or float
 *   TV: int32_t (U4.28) or int16_t (U4.12) or float
 *   vol: represents a volume array.
 *
@@ -247,7 +248,8 @@ enum {
 *   Single input channel. NCHAN represents number of output channels.
 *   TO: int32_t (Q4.27) or float
 *   TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 *   TV: int32_t (U4.28) or int16_t (U4.12) or float
 *   TA: int32_t (Q4.27) or float
 *   TV/TAV: int32_t (U4.28) or int16_t (U4.12) or float
 *   Input channel count is 1.
 *   vol: represents volume array.
 *
@@ -257,7 +259,8 @@ enum {
 *   NCHAN represents number of input and output channels.
 *   TO: int16_t (Q.15) or float
 *   TI: int32_t (Q4.27) or int16_t (Q0.15) or float
 *   TV: int32_t (U4.28) or int16_t (U4.12) or float
 *   TA: int32_t (Q4.27) or float
 *   TV/TAV: int32_t (U4.28) or int16_t (U4.12) or float
 *   vol: represents a volume array.
 *
 *   MIXTYPE_MULTI_SAVEONLY does not accumulate into the out pointer.
+5 −0
Original line number Diff line number Diff line
@@ -44,4 +44,9 @@
// define FLOAT_EFFECT_CHAIN to request float effects (falls back to int16_t if unavailable)
#define FLOAT_EFFECT_CHAIN

#ifdef FLOAT_EFFECT_CHAIN
// define FLOAT_AUX to process aux effect buffers in float (FLOAT_EFFECT_CHAIN must be defined)
#define FLOAT_AUX
#endif

#endif // ANDROID_AUDIOFLINGER_CONFIGURATION_H
+15 −3
Original line number Diff line number Diff line
@@ -338,9 +338,9 @@ void AudioFlinger::EffectModule::process()
        if (isProcessImplemented()) {
            if (auxType) {
                // We overwrite the aux input buffer here and clear after processing.
                // Note that aux input buffers are format q4_27.
#ifdef FLOAT_EFFECT_CHAIN
                if (mSupportsFloat) {
#ifndef FLOAT_AUX
                    // Do in-place float conversion for auxiliary effect input buffer.
                    static_assert(sizeof(float) <= sizeof(int32_t),
                            "in-place conversion requires sizeof(float) <= sizeof(int32_t)");
@@ -349,13 +349,21 @@ void AudioFlinger::EffectModule::process()
                            mConfig.inputCfg.buffer.f32,
                            mConfig.inputCfg.buffer.s32,
                            mConfig.inputCfg.buffer.frameCount);
#endif // !FLOAT_AUX
                } else
#endif
#endif // FLOAT_EFFECT_CHAIN
                {
#ifdef FLOAT_AUX
                    memcpy_to_i16_from_float(
                            mConfig.inputCfg.buffer.s16,
                            mConfig.inputCfg.buffer.f32,
                            mConfig.inputCfg.buffer.frameCount);
#else
                    memcpy_to_i16_from_q4_27(
                            mConfig.inputCfg.buffer.s16,
                            mConfig.inputCfg.buffer.s32,
                            mConfig.inputCfg.buffer.frameCount);
#endif
                }
            }
#ifdef FLOAT_EFFECT_CHAIN
@@ -415,9 +423,13 @@ void AudioFlinger::EffectModule::process()

        // clear auxiliary effect input buffer for next accumulation
        if (auxType) {
            // input always q4_27 regardless of FLOAT_EFFECT_CHAIN.
#ifdef FLOAT_AUX
            const size_t size =
                    mConfig.inputCfg.buffer.frameCount * inChannelCount * sizeof(float);
#else
            const size_t size =
                    mConfig.inputCfg.buffer.frameCount * inChannelCount * sizeof(int32_t);
#endif
            memset(mConfig.inputCfg.buffer.raw, 0, size);
        }
    } else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&