Loading services/audioflinger/Configuration.h +3 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ #ifdef FLOAT_EFFECT_CHAIN // define FLOAT_AUX to process aux effect buffers in float (FLOAT_EFFECT_CHAIN must be defined) #define FLOAT_AUX // define MULTICHANNEL_EFFECT_CHAIN to allow multichannel effects (FLOAT_EFFECT_CHAIN defined) #define MULTICHANNEL_EFFECT_CHAIN #endif #endif // ANDROID_AUDIOFLINGER_CONFIGURATION_H services/audioflinger/Effects.cpp +111 −28 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <system/audio_effects/effect_aec.h> #include <system/audio_effects/effect_ns.h> #include <system/audio_effects/effect_visualizer.h> #include <audio_utils/channels.h> #include <audio_utils/primitives.h> #include <media/AudioEffect.h> #include <media/audiohal/EffectHalInterface.h> Loading Loading @@ -292,7 +293,6 @@ void AudioFlinger::EffectModule::process() return; } // TODO: Implement multichannel effects; here outChannelCount == FCC_2 == 2 const uint32_t inChannelCount = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); const uint32_t outChannelCount = Loading Loading @@ -342,6 +342,7 @@ void AudioFlinger::EffectModule::process() if (isProcessImplemented()) { if (auxType) { // We overwrite the aux input buffer here and clear after processing. // aux input is always mono. #ifdef FLOAT_EFFECT_CHAIN if (mSupportsFloat) { #ifndef FLOAT_AUX Loading Loading @@ -371,6 +372,28 @@ void AudioFlinger::EffectModule::process() } } #ifdef FLOAT_EFFECT_CHAIN sp<EffectBufferHalInterface> inBuffer = mInBuffer; sp<EffectBufferHalInterface> outBuffer = mOutBuffer; if (!auxType && mInChannelCountRequested != inChannelCount) { adjust_channels( inBuffer->audioBuffer()->f32, mInChannelCountRequested, mInConversionBuffer->audioBuffer()->f32, inChannelCount, sizeof(float), sizeof(float) * mInChannelCountRequested * mConfig.inputCfg.buffer.frameCount); inBuffer = mInConversionBuffer; } if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE && mOutChannelCountRequested != outChannelCount) { adjust_selected_channels( outBuffer->audioBuffer()->f32, mOutChannelCountRequested, mOutConversionBuffer->audioBuffer()->f32, outChannelCount, sizeof(float), sizeof(float) * mOutChannelCountRequested * mConfig.outputCfg.buffer.frameCount); outBuffer = mOutConversionBuffer; } if (!mSupportsFloat) { // convert input to int16_t as effect doesn't support float. if (!auxType) { if (mInConversionBuffer.get() == nullptr) { Loading @@ -379,8 +402,9 @@ void AudioFlinger::EffectModule::process() } memcpy_to_i16_from_float( mInConversionBuffer->audioBuffer()->s16, mInBuffer->audioBuffer()->f32, inBuffer->audioBuffer()->f32, inChannelCount * mConfig.inputCfg.buffer.frameCount); inBuffer = mInConversionBuffer; } if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) { if (mOutConversionBuffer.get() == nullptr) { Loading @@ -389,21 +413,30 @@ void AudioFlinger::EffectModule::process() } memcpy_to_i16_from_float( mOutConversionBuffer->audioBuffer()->s16, mOutBuffer->audioBuffer()->f32, outBuffer->audioBuffer()->f32, outChannelCount * mConfig.outputCfg.buffer.frameCount); outBuffer = mOutConversionBuffer; } } #endif ret = mEffectInterface->process(); #ifdef FLOAT_EFFECT_CHAIN if (!mSupportsFloat) { // convert output int16_t back to float. sp<EffectBufferHalInterface> target = mOutChannelCountRequested != outChannelCount ? mOutConversionBuffer : mOutBuffer; memcpy_to_float_from_i16( mOutBuffer->audioBuffer()->f32, target->audioBuffer()->f32, mOutConversionBuffer->audioBuffer()->s16, outChannelCount * mConfig.outputCfg.buffer.frameCount); } if (mOutChannelCountRequested != outChannelCount) { adjust_selected_channels(mOutConversionBuffer->audioBuffer()->f32, outChannelCount, mOutBuffer->audioBuffer()->f32, mOutChannelCountRequested, sizeof(float), sizeof(float) * outChannelCount * mConfig.outputCfg.buffer.frameCount); } #endif } else { #ifdef FLOAT_EFFECT_CHAIN Loading Loading @@ -476,15 +509,28 @@ status_t AudioFlinger::EffectModule::configure() } // TODO: handle configuration of effects replacing track process // TODO: handle configuration of input (record) SW effects above the HAL, // similar to output EFFECT_FLAG_TYPE_INSERT/REPLACE, // in which case input channel masks should be used here. channelMask = thread->channelMask(); mConfig.inputCfg.channels = channelMask; mConfig.outputCfg.channels = channelMask; if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { if (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) { mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO; ALOGV("Overriding auxiliary effect input channels %#x as MONO", mConfig.inputCfg.channels); } #ifndef MULTICHANNEL_EFFECT_CHAIN if (mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; ALOGV("Overriding auxiliary effect input as MONO and output as STEREO"); ALOGV("Overriding auxiliary effect output channels %#x as STEREO", mConfig.outputCfg.channels); } #endif } else { mConfig.inputCfg.channels = channelMask; #ifndef MULTICHANNEL_EFFECT_CHAIN // TODO: Update this logic when multichannel effects are implemented. // For offloaded tracks consider mono output as stereo for proper effect initialization if (channelMask == AUDIO_CHANNEL_OUT_MONO) { Loading @@ -492,7 +538,12 @@ status_t AudioFlinger::EffectModule::configure() mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; ALOGV("Overriding effect input and output as STEREO"); } #endif } mInChannelCountRequested = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); mOutChannelCountRequested = audio_channel_count_from_out_mask(mConfig.outputCfg.channels); mConfig.inputCfg.format = EFFECT_BUFFER_FORMAT; mConfig.outputCfg.format = EFFECT_BUFFER_FORMAT; Loading Loading @@ -530,28 +581,58 @@ status_t AudioFlinger::EffectModule::configure() status_t cmdStatus; size = sizeof(int); status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), sizeof(mConfig), &mConfig, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } #ifdef MULTICHANNEL_EFFECT_CHAIN if (status != NO_ERROR && (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO || mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO)) { // Older effects may require exact STEREO position mask. if (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { ALOGV("Overriding effect input channels %#x as STEREO", mConfig.inputCfg.channels); mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } if (mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { ALOGV("Overriding effect output channels %#x as STEREO", mConfig.outputCfg.channels); mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } size = sizeof(int); status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG, sizeof(mConfig), &mConfig, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } } #endif #ifdef FLOAT_EFFECT_CHAIN if (status == NO_ERROR) { mSupportsFloat = true; #endif } #ifdef FLOAT_EFFECT_CHAIN else { if (status != NO_ERROR) { ALOGV("EFFECT_CMD_SET_CONFIG failed with float format, retry with int16_t."); mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; size = sizeof(int); status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), sizeof(mConfig), &mConfig, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } if (status == NO_ERROR) { mSupportsFloat = false; ALOGVV("config worked with 16 bit"); } else { Loading Loading @@ -929,11 +1010,15 @@ void AudioFlinger::EffectModule::setInBuffer(const sp<EffectBufferHalInterface>& // the original buffer) when the output buffer is identical to the input buffer, // but we don't optimize for it here. const bool auxType = (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY; if (!auxType && !mSupportsFloat && mInBuffer.get() != nullptr) { const uint32_t inChannelCount = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); const bool formatMismatch = !mSupportsFloat || mInChannelCountRequested != inChannelCount; if (!auxType && formatMismatch && mInBuffer.get() != nullptr) { // we need to translate - create hidl shared buffer and intercept const size_t inFrameCount = mConfig.inputCfg.buffer.frameCount; const int inChannels = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); const size_t size = inChannels * inFrameCount * sizeof(int16_t); // Use FCC_2 in case mInChannelCountRequested is mono and the effect is stereo. const uint32_t inChannels = std::max((uint32_t)FCC_2, mInChannelCountRequested); const size_t size = inChannels * inFrameCount * std::max(sizeof(int16_t), sizeof(float)); ALOGV("%s: setInBuffer updating for inChannels:%d inFrameCount:%zu total size:%zu", __func__, inChannels, inFrameCount, size); Loading Loading @@ -970,10 +1055,14 @@ void AudioFlinger::EffectModule::setOutBuffer(const sp<EffectBufferHalInterface> #ifdef FLOAT_EFFECT_CHAIN // Note: Any effect that does not accumulate does not need mOutConversionBuffer and // can do in-place conversion from int16_t to float. We don't optimize here. if (!mSupportsFloat && mOutBuffer.get() != nullptr) { const uint32_t outChannelCount = audio_channel_count_from_out_mask(mConfig.outputCfg.channels); const bool formatMismatch = !mSupportsFloat || mOutChannelCountRequested != outChannelCount; if (formatMismatch && mOutBuffer.get() != nullptr) { const size_t outFrameCount = mConfig.outputCfg.buffer.frameCount; const int outChannels = audio_channel_count_from_out_mask(mConfig.outputCfg.channels); const size_t size = outChannels * outFrameCount * sizeof(int16_t); // Use FCC_2 in case mOutChannelCountRequested is mono and the effect is stereo. const uint32_t outChannels = std::max((uint32_t)FCC_2, mOutChannelCountRequested); const size_t size = outChannels * outFrameCount * std::max(sizeof(int16_t), sizeof(float)); ALOGV("%s: setOutBuffer updating for outChannels:%d outFrameCount:%zu total size:%zu", __func__, outChannels, outFrameCount, size); Loading Loading @@ -1813,14 +1902,8 @@ void AudioFlinger::EffectChain::clearInputBuffer_l(const sp<ThreadBase>& thread) if (mInBuffer == NULL) { return; } // TODO: This will change in the future, depending on multichannel // and sample format changes for effects. // Currently effects processing is only available for stereo, AUDIO_FORMAT_PCM_16_BIT // (4 bytes frame size) const size_t frameSize = audio_bytes_per_sample(EFFECT_BUFFER_FORMAT) * std::min((uint32_t)FCC_2, thread->channelCount()); audio_bytes_per_sample(EFFECT_BUFFER_FORMAT) * thread->channelCount(); memset(mInBuffer->audioBuffer()->raw, 0, thread->frameCount() * frameSize); mInBuffer->commit(); Loading services/audioflinger/Effects.h +2 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,8 @@ mutable Mutex mLock; // mutex for process, commands and handl bool mSupportsFloat; // effect supports float processing sp<EffectBufferHalInterface> mInConversionBuffer; // Buffers for HAL conversion if needed. sp<EffectBufferHalInterface> mOutConversionBuffer; uint32_t mInChannelCountRequested; uint32_t mOutChannelCountRequested; #endif }; Loading services/audioflinger/Threads.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -1176,6 +1176,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( switch (mType) { case MIXER: { #ifndef MULTICHANNEL_EFFECT_CHAIN // Reject any effect on mixer multichannel sinks. // TODO: fix both format and multichannel issues with effects. if (mChannelCount != FCC_2) { Loading @@ -1183,6 +1184,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( " thread %s", desc->name, mChannelCount, mThreadName); return BAD_VALUE; } #endif audio_output_flags_t flags = mOutput->flags; if (hasFastMixer() || (flags & AUDIO_OUTPUT_FLAG_FAST)) { if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { Loading Loading @@ -1229,6 +1231,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( desc->name, mThreadName); return BAD_VALUE; case DUPLICATING: #ifndef MULTICHANNEL_EFFECT_CHAIN // Reject any effect on mixer multichannel sinks. // TODO: fix both format and multichannel issues with effects. if (mChannelCount != FCC_2) { Loading @@ -1236,6 +1239,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( " on DUPLICATING thread %s", desc->name, mChannelCount, mThreadName); return BAD_VALUE; } #endif if ((sessionId == AUDIO_SESSION_OUTPUT_STAGE) || (sessionId == AUDIO_SESSION_OUTPUT_MIX)) { ALOGW("checkEffectCompatibility_l(): global effect %s on DUPLICATING" " thread %s", desc->name, mThreadName); Loading Loading
services/audioflinger/Configuration.h +3 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ #ifdef FLOAT_EFFECT_CHAIN // define FLOAT_AUX to process aux effect buffers in float (FLOAT_EFFECT_CHAIN must be defined) #define FLOAT_AUX // define MULTICHANNEL_EFFECT_CHAIN to allow multichannel effects (FLOAT_EFFECT_CHAIN defined) #define MULTICHANNEL_EFFECT_CHAIN #endif #endif // ANDROID_AUDIOFLINGER_CONFIGURATION_H
services/audioflinger/Effects.cpp +111 −28 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ #include <system/audio_effects/effect_aec.h> #include <system/audio_effects/effect_ns.h> #include <system/audio_effects/effect_visualizer.h> #include <audio_utils/channels.h> #include <audio_utils/primitives.h> #include <media/AudioEffect.h> #include <media/audiohal/EffectHalInterface.h> Loading Loading @@ -292,7 +293,6 @@ void AudioFlinger::EffectModule::process() return; } // TODO: Implement multichannel effects; here outChannelCount == FCC_2 == 2 const uint32_t inChannelCount = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); const uint32_t outChannelCount = Loading Loading @@ -342,6 +342,7 @@ void AudioFlinger::EffectModule::process() if (isProcessImplemented()) { if (auxType) { // We overwrite the aux input buffer here and clear after processing. // aux input is always mono. #ifdef FLOAT_EFFECT_CHAIN if (mSupportsFloat) { #ifndef FLOAT_AUX Loading Loading @@ -371,6 +372,28 @@ void AudioFlinger::EffectModule::process() } } #ifdef FLOAT_EFFECT_CHAIN sp<EffectBufferHalInterface> inBuffer = mInBuffer; sp<EffectBufferHalInterface> outBuffer = mOutBuffer; if (!auxType && mInChannelCountRequested != inChannelCount) { adjust_channels( inBuffer->audioBuffer()->f32, mInChannelCountRequested, mInConversionBuffer->audioBuffer()->f32, inChannelCount, sizeof(float), sizeof(float) * mInChannelCountRequested * mConfig.inputCfg.buffer.frameCount); inBuffer = mInConversionBuffer; } if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE && mOutChannelCountRequested != outChannelCount) { adjust_selected_channels( outBuffer->audioBuffer()->f32, mOutChannelCountRequested, mOutConversionBuffer->audioBuffer()->f32, outChannelCount, sizeof(float), sizeof(float) * mOutChannelCountRequested * mConfig.outputCfg.buffer.frameCount); outBuffer = mOutConversionBuffer; } if (!mSupportsFloat) { // convert input to int16_t as effect doesn't support float. if (!auxType) { if (mInConversionBuffer.get() == nullptr) { Loading @@ -379,8 +402,9 @@ void AudioFlinger::EffectModule::process() } memcpy_to_i16_from_float( mInConversionBuffer->audioBuffer()->s16, mInBuffer->audioBuffer()->f32, inBuffer->audioBuffer()->f32, inChannelCount * mConfig.inputCfg.buffer.frameCount); inBuffer = mInConversionBuffer; } if (mConfig.outputCfg.accessMode == EFFECT_BUFFER_ACCESS_ACCUMULATE) { if (mOutConversionBuffer.get() == nullptr) { Loading @@ -389,21 +413,30 @@ void AudioFlinger::EffectModule::process() } memcpy_to_i16_from_float( mOutConversionBuffer->audioBuffer()->s16, mOutBuffer->audioBuffer()->f32, outBuffer->audioBuffer()->f32, outChannelCount * mConfig.outputCfg.buffer.frameCount); outBuffer = mOutConversionBuffer; } } #endif ret = mEffectInterface->process(); #ifdef FLOAT_EFFECT_CHAIN if (!mSupportsFloat) { // convert output int16_t back to float. sp<EffectBufferHalInterface> target = mOutChannelCountRequested != outChannelCount ? mOutConversionBuffer : mOutBuffer; memcpy_to_float_from_i16( mOutBuffer->audioBuffer()->f32, target->audioBuffer()->f32, mOutConversionBuffer->audioBuffer()->s16, outChannelCount * mConfig.outputCfg.buffer.frameCount); } if (mOutChannelCountRequested != outChannelCount) { adjust_selected_channels(mOutConversionBuffer->audioBuffer()->f32, outChannelCount, mOutBuffer->audioBuffer()->f32, mOutChannelCountRequested, sizeof(float), sizeof(float) * outChannelCount * mConfig.outputCfg.buffer.frameCount); } #endif } else { #ifdef FLOAT_EFFECT_CHAIN Loading Loading @@ -476,15 +509,28 @@ status_t AudioFlinger::EffectModule::configure() } // TODO: handle configuration of effects replacing track process // TODO: handle configuration of input (record) SW effects above the HAL, // similar to output EFFECT_FLAG_TYPE_INSERT/REPLACE, // in which case input channel masks should be used here. channelMask = thread->channelMask(); mConfig.inputCfg.channels = channelMask; mConfig.outputCfg.channels = channelMask; if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) { if (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_MONO) { mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO; ALOGV("Overriding auxiliary effect input channels %#x as MONO", mConfig.inputCfg.channels); } #ifndef MULTICHANNEL_EFFECT_CHAIN if (mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; ALOGV("Overriding auxiliary effect input as MONO and output as STEREO"); ALOGV("Overriding auxiliary effect output channels %#x as STEREO", mConfig.outputCfg.channels); } #endif } else { mConfig.inputCfg.channels = channelMask; #ifndef MULTICHANNEL_EFFECT_CHAIN // TODO: Update this logic when multichannel effects are implemented. // For offloaded tracks consider mono output as stereo for proper effect initialization if (channelMask == AUDIO_CHANNEL_OUT_MONO) { Loading @@ -492,7 +538,12 @@ status_t AudioFlinger::EffectModule::configure() mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; ALOGV("Overriding effect input and output as STEREO"); } #endif } mInChannelCountRequested = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); mOutChannelCountRequested = audio_channel_count_from_out_mask(mConfig.outputCfg.channels); mConfig.inputCfg.format = EFFECT_BUFFER_FORMAT; mConfig.outputCfg.format = EFFECT_BUFFER_FORMAT; Loading Loading @@ -530,28 +581,58 @@ status_t AudioFlinger::EffectModule::configure() status_t cmdStatus; size = sizeof(int); status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), sizeof(mConfig), &mConfig, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } #ifdef MULTICHANNEL_EFFECT_CHAIN if (status != NO_ERROR && (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO || mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO)) { // Older effects may require exact STEREO position mask. if (mConfig.inputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { ALOGV("Overriding effect input channels %#x as STEREO", mConfig.inputCfg.channels); mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } if (mConfig.outputCfg.channels != AUDIO_CHANNEL_OUT_STEREO) { ALOGV("Overriding effect output channels %#x as STEREO", mConfig.outputCfg.channels); mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO; } size = sizeof(int); status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG, sizeof(mConfig), &mConfig, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } } #endif #ifdef FLOAT_EFFECT_CHAIN if (status == NO_ERROR) { mSupportsFloat = true; #endif } #ifdef FLOAT_EFFECT_CHAIN else { if (status != NO_ERROR) { ALOGV("EFFECT_CMD_SET_CONFIG failed with float format, retry with int16_t."); mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT; mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT; size = sizeof(int); status = mEffectInterface->command(EFFECT_CMD_SET_CONFIG, sizeof(effect_config_t), sizeof(mConfig), &mConfig, &size, &cmdStatus); if (status == NO_ERROR) { status = cmdStatus; } if (status == NO_ERROR) { mSupportsFloat = false; ALOGVV("config worked with 16 bit"); } else { Loading Loading @@ -929,11 +1010,15 @@ void AudioFlinger::EffectModule::setInBuffer(const sp<EffectBufferHalInterface>& // the original buffer) when the output buffer is identical to the input buffer, // but we don't optimize for it here. const bool auxType = (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY; if (!auxType && !mSupportsFloat && mInBuffer.get() != nullptr) { const uint32_t inChannelCount = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); const bool formatMismatch = !mSupportsFloat || mInChannelCountRequested != inChannelCount; if (!auxType && formatMismatch && mInBuffer.get() != nullptr) { // we need to translate - create hidl shared buffer and intercept const size_t inFrameCount = mConfig.inputCfg.buffer.frameCount; const int inChannels = audio_channel_count_from_out_mask(mConfig.inputCfg.channels); const size_t size = inChannels * inFrameCount * sizeof(int16_t); // Use FCC_2 in case mInChannelCountRequested is mono and the effect is stereo. const uint32_t inChannels = std::max((uint32_t)FCC_2, mInChannelCountRequested); const size_t size = inChannels * inFrameCount * std::max(sizeof(int16_t), sizeof(float)); ALOGV("%s: setInBuffer updating for inChannels:%d inFrameCount:%zu total size:%zu", __func__, inChannels, inFrameCount, size); Loading Loading @@ -970,10 +1055,14 @@ void AudioFlinger::EffectModule::setOutBuffer(const sp<EffectBufferHalInterface> #ifdef FLOAT_EFFECT_CHAIN // Note: Any effect that does not accumulate does not need mOutConversionBuffer and // can do in-place conversion from int16_t to float. We don't optimize here. if (!mSupportsFloat && mOutBuffer.get() != nullptr) { const uint32_t outChannelCount = audio_channel_count_from_out_mask(mConfig.outputCfg.channels); const bool formatMismatch = !mSupportsFloat || mOutChannelCountRequested != outChannelCount; if (formatMismatch && mOutBuffer.get() != nullptr) { const size_t outFrameCount = mConfig.outputCfg.buffer.frameCount; const int outChannels = audio_channel_count_from_out_mask(mConfig.outputCfg.channels); const size_t size = outChannels * outFrameCount * sizeof(int16_t); // Use FCC_2 in case mOutChannelCountRequested is mono and the effect is stereo. const uint32_t outChannels = std::max((uint32_t)FCC_2, mOutChannelCountRequested); const size_t size = outChannels * outFrameCount * std::max(sizeof(int16_t), sizeof(float)); ALOGV("%s: setOutBuffer updating for outChannels:%d outFrameCount:%zu total size:%zu", __func__, outChannels, outFrameCount, size); Loading Loading @@ -1813,14 +1902,8 @@ void AudioFlinger::EffectChain::clearInputBuffer_l(const sp<ThreadBase>& thread) if (mInBuffer == NULL) { return; } // TODO: This will change in the future, depending on multichannel // and sample format changes for effects. // Currently effects processing is only available for stereo, AUDIO_FORMAT_PCM_16_BIT // (4 bytes frame size) const size_t frameSize = audio_bytes_per_sample(EFFECT_BUFFER_FORMAT) * std::min((uint32_t)FCC_2, thread->channelCount()); audio_bytes_per_sample(EFFECT_BUFFER_FORMAT) * thread->channelCount(); memset(mInBuffer->audioBuffer()->raw, 0, thread->frameCount() * frameSize); mInBuffer->commit(); Loading
services/audioflinger/Effects.h +2 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,8 @@ mutable Mutex mLock; // mutex for process, commands and handl bool mSupportsFloat; // effect supports float processing sp<EffectBufferHalInterface> mInConversionBuffer; // Buffers for HAL conversion if needed. sp<EffectBufferHalInterface> mOutConversionBuffer; uint32_t mInChannelCountRequested; uint32_t mOutChannelCountRequested; #endif }; Loading
services/audioflinger/Threads.cpp +4 −0 Original line number Diff line number Diff line Loading @@ -1176,6 +1176,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( switch (mType) { case MIXER: { #ifndef MULTICHANNEL_EFFECT_CHAIN // Reject any effect on mixer multichannel sinks. // TODO: fix both format and multichannel issues with effects. if (mChannelCount != FCC_2) { Loading @@ -1183,6 +1184,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( " thread %s", desc->name, mChannelCount, mThreadName); return BAD_VALUE; } #endif audio_output_flags_t flags = mOutput->flags; if (hasFastMixer() || (flags & AUDIO_OUTPUT_FLAG_FAST)) { if (sessionId == AUDIO_SESSION_OUTPUT_MIX) { Loading Loading @@ -1229,6 +1231,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( desc->name, mThreadName); return BAD_VALUE; case DUPLICATING: #ifndef MULTICHANNEL_EFFECT_CHAIN // Reject any effect on mixer multichannel sinks. // TODO: fix both format and multichannel issues with effects. if (mChannelCount != FCC_2) { Loading @@ -1236,6 +1239,7 @@ status_t AudioFlinger::PlaybackThread::checkEffectCompatibility_l( " on DUPLICATING thread %s", desc->name, mChannelCount, mThreadName); return BAD_VALUE; } #endif if ((sessionId == AUDIO_SESSION_OUTPUT_STAGE) || (sessionId == AUDIO_SESSION_OUTPUT_MIX)) { ALOGW("checkEffectCompatibility_l(): global effect %s on DUPLICATING" " thread %s", desc->name, mThreadName); Loading