Loading services/audioflinger/Effects.cpp +79 −84 Original line number Diff line number Diff line Loading @@ -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()) { Loading @@ -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; Loading @@ -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(); } } } Loading Loading @@ -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) { Loading Loading
services/audioflinger/Effects.cpp +79 −84 Original line number Diff line number Diff line Loading @@ -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()) { Loading @@ -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; Loading @@ -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(); } } } Loading Loading @@ -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) { Loading