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

Commit fa69ca30 authored by Andy Hung's avatar Andy Hung
Browse files

AudioEffect: clean up format conversion in EffectModule::process()

Editing for clarity, no change in operation.

Test: Solo Tester
Bug: 69984406
Change-Id: I683fd9b83417c3d1c6d63339537d03c55625ac13
parent 14093dd0
Loading
Loading
Loading
Loading
+79 −84
Original line number Diff line number Diff line
@@ -296,6 +296,43 @@ void AudioFlinger::EffectModule::process()
    const bool auxType =
            (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY;

    // safeInputOutputSampleCount is 0 if the channel count between input and output
    // buffers do not match. This prevents automatic accumulation or copying between the
    // input and output effect buffers without an intermediary effect process.
    // TODO: consider implementing channel conversion.
    const size_t safeInputOutputSampleCount =
            inChannelCount != outChannelCount ? 0
                    : outChannelCount * std::min(
                            mConfig.inputCfg.buffer.frameCount,
                            mConfig.outputCfg.buffer.frameCount);
    const auto accumulateInputToOutput = [this, safeInputOutputSampleCount]() {
#ifdef FLOAT_EFFECT_CHAIN
        accumulate_float(
                mConfig.outputCfg.buffer.f32,
                mConfig.inputCfg.buffer.f32,
                safeInputOutputSampleCount);
#else
        accumulate_i16(
                mConfig.outputCfg.buffer.s16,
                mConfig.inputCfg.buffer.s16,
                safeInputOutputSampleCount);
#endif
    };
    const auto copyInputToOutput = [this, safeInputOutputSampleCount]() {
#ifdef FLOAT_EFFECT_CHAIN
        memcpy(
                mConfig.outputCfg.buffer.f32,
                mConfig.inputCfg.buffer.f32,
                safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.f32));

#else
        memcpy(
                mConfig.outputCfg.buffer.s16,
                mConfig.inputCfg.buffer.s16,
                safeInputOutputSampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
#endif
    };

    if (isProcessEnabled()) {
        int ret;
        if (isProcessImplemented()) {
@@ -308,97 +345,69 @@ void AudioFlinger::EffectModule::process()
                    static_assert(sizeof(float) <= sizeof(int32_t),
                            "in-place conversion requires sizeof(float) <= sizeof(int32_t)");

                    const int32_t * const p32 = mConfig.inputCfg.buffer.s32;
                    float * const pFloat = mConfig.inputCfg.buffer.f32;
                    memcpy_to_float_from_q4_27(pFloat, p32, mConfig.inputCfg.buffer.frameCount);
                } else {
                    memcpy_to_i16_from_q4_27(mConfig.inputCfg.buffer.s16,
                    memcpy_to_float_from_q4_27(
                            mConfig.inputCfg.buffer.f32,
                            mConfig.inputCfg.buffer.s32,
                            mConfig.inputCfg.buffer.frameCount);
                }
#else
                memcpy_to_i16_from_q4_27(mConfig.inputCfg.buffer.s16,
                } else
#endif
                {
                    memcpy_to_i16_from_q4_27(
                            mConfig.inputCfg.buffer.s16,
                            mConfig.inputCfg.buffer.s32,
                            mConfig.inputCfg.buffer.frameCount);
#endif
                }
            }
#ifdef FLOAT_EFFECT_CHAIN
            if (mSupportsFloat) {
                ret = mEffectInterface->process();
            } else {
                {   // convert input to int16_t as effect doesn't support float.
            if (!mSupportsFloat) { // convert input to int16_t as effect doesn't support float.
                if (!auxType) {
                    if (mInConversionBuffer.get() == nullptr) {
                        ALOGW("%s: mInConversionBuffer is null, bypassing", __func__);
                        goto data_bypass;
                    }
                        const float * const pIn = mInBuffer->audioBuffer()->f32;
                        int16_t * const pIn16 = mInConversionBuffer->audioBuffer()->s16;
                    memcpy_to_i16_from_float(
                                pIn16, pIn, inChannelCount * mConfig.inputCfg.buffer.frameCount);
                            mInConversionBuffer->audioBuffer()->s16,
                            mInBuffer->audioBuffer()->f32,
                            inChannelCount * mConfig.inputCfg.buffer.frameCount);
                }
                if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
                    if (mOutConversionBuffer.get() == nullptr) {
                        ALOGW("%s: mOutConversionBuffer is null, bypassing", __func__);
                        goto data_bypass;
                    }
                        int16_t * const pOut16 = mOutConversionBuffer->audioBuffer()->s16;
                        const float * const pOut = mOutBuffer->audioBuffer()->f32;
                    memcpy_to_i16_from_float(
                                pOut16,
                                pOut,
                            mOutConversionBuffer->audioBuffer()->s16,
                            mOutBuffer->audioBuffer()->f32,
                            outChannelCount * mConfig.outputCfg.buffer.frameCount);
                }
            }
#endif

            ret = mEffectInterface->process();

                {   // convert output back to float.
                    const int16_t * const pOut16 = mOutConversionBuffer->audioBuffer()->s16;
                    float * const pOut = mOutBuffer->audioBuffer()->f32;
#ifdef FLOAT_EFFECT_CHAIN
            if (!mSupportsFloat) { // convert output int16_t back to float.
                memcpy_to_float_from_i16(
                            pOut, pOut16, outChannelCount * mConfig.outputCfg.buffer.frameCount);
                }
                        mOutBuffer->audioBuffer()->f32,
                        mOutConversionBuffer->audioBuffer()->s16,
                        outChannelCount * mConfig.outputCfg.buffer.frameCount);
            }
#else
            ret = mEffectInterface->process();
#endif
        } else {
#ifdef FLOAT_EFFECT_CHAIN
            data_bypass:
#endif
            if (!auxType  /* aux effects do not require data bypass */
                    && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw
                    && inChannelCount == outChannelCount) {
                const size_t sampleCount = std::min(
                        mConfig.inputCfg.buffer.frameCount,
                        mConfig.outputCfg.buffer.frameCount) * outChannelCount;

#ifdef FLOAT_EFFECT_CHAIN
                const float * const in = mConfig.inputCfg.buffer.f32;
                float * const out = mConfig.outputCfg.buffer.f32;

                if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
                    accumulate_float(out, in, sampleCount);
                } else {
                    memcpy(mConfig.outputCfg.buffer.f32, mConfig.inputCfg.buffer.f32,
                            sampleCount * sizeof(*mConfig.outputCfg.buffer.f32));
                }

#else
                const int16_t * const in = mConfig.inputCfg.buffer.s16;
                int16_t * const out = mConfig.outputCfg.buffer.s16;

                    && mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
                if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) {
                    accumulate_i16(out, in, sampleCount);
                    accumulateInputToOutput();
                } else {
                    memcpy(mConfig.outputCfg.buffer.s16, mConfig.inputCfg.buffer.s16,
                            sampleCount * sizeof(*mConfig.outputCfg.buffer.s16));
                    copyInputToOutput();
                }
#endif
            }
            ret = -ENODATA;
        }

        // force transition to IDLE state when engine is ready
        if (mState == STOPPED && ret == -ENODATA) {
            mDisableWaitCnt = 1;
@@ -417,21 +426,8 @@ void AudioFlinger::EffectModule::process()
        // If an insert effect is idle and input buffer is different from output buffer,
        // accumulate input onto output
        sp<EffectChain> chain = mChain.promote();
        if (chain != 0
                && chain->activeTrackCnt() != 0
                && inChannelCount == outChannelCount) {
            const size_t sampleCount = std::min(
                    mConfig.inputCfg.buffer.frameCount,
                    mConfig.outputCfg.buffer.frameCount) * outChannelCount;
#ifdef FLOAT_EFFECT_CHAIN
            const float * const in = mConfig.inputCfg.buffer.f32;
            float * const out = mConfig.outputCfg.buffer.f32;
            accumulate_float(out, in, sampleCount);
#else
            const int16_t * const in = mConfig.inputCfg.buffer.s16;
            int16_t * const out = mConfig.outputCfg.buffer.s16;
            accumulate_i16(out, in, sampleCount);
#endif
        if (chain.get() != nullptr && chain->activeTrackCnt() != 0) {
            accumulateInputToOutput();
        }
    }
}
@@ -927,7 +923,6 @@ void AudioFlinger::EffectModule::setInBuffer(const sp<EffectBufferHalInterface>&
            (void)EffectBufferHalInterface::allocate(size, &mInConversionBuffer);
        }
        if (mInConversionBuffer.get() != nullptr) {
            // FIXME: confirm buffer has enough size.
            mInConversionBuffer->setFrameCount(inFrameCount);
            mEffectInterface->setInBuffer(mInConversionBuffer);
        } else if (size > 0) {