From 6fccbd04fc7e64dfc05096281cd64d76dfcb299d Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Wed, 5 Oct 2011 17:42:25 -0700 Subject: Fix issue 5381089: problem with A2DP music volume This problem only occurs when audio effects are present and the music volume is applied by one effect engine. When connecting or disconnecting A2DP, audio effects are moved from one mixer thread to another. When removed from the source thread, the effect is stopped but it is not restarted when added to the destination thread. This regression was introduced by commit 21b5c47e. Change-Id: I4cc578d8d760ec65b185032b6fda98c739d331bc --- services/audioflinger/AudioFlinger.cpp | 18 ++++++++++++++++-- services/audioflinger/AudioFlinger.h | 1 + 2 files changed, 17 insertions(+), 2 deletions(-) (limited to 'services/audioflinger') diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 01f5a6f..ab49f93 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -5550,7 +5550,7 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, // remove chain first. This is useful only if reconfiguring effect chain on same output thread, // so that a new chain is created with correct parameters when first effect is added. This is - // otherwise unecessary as removeEffect_l() will remove the chain when last effect is + // otherwise unnecessary as removeEffect_l() will remove the chain when last effect is // removed. srcThread->removeEffectChain_l(chain); @@ -5563,6 +5563,11 @@ status_t AudioFlinger::moveEffectChain_l(int sessionId, while (effect != 0) { srcThread->removeEffect_l(effect); dstThread->addEffect_l(effect); + // removeEffect_l() has stopped the effect if it was active so it must be restarted + if (effect->state() == EffectModule::ACTIVE || + effect->state() == EffectModule::STOPPING) { + effect->start(); + } // if the move request is not received from audio policy manager, the effect must be // re-registered with the new strategy and output if (dstChain == 0) { @@ -6350,6 +6355,12 @@ status_t AudioFlinger::EffectModule::init() return status; } +status_t AudioFlinger::EffectModule::start() +{ + Mutex::Autolock _l(mLock); + return start_l(); +} + status_t AudioFlinger::EffectModule::start_l() { if (mEffectInterface == NULL) { @@ -7214,7 +7225,10 @@ size_t AudioFlinger::EffectChain::removeEffect_l(const sp& effect) // calling stop here will remove pre-processing effect from the audio HAL. // This is safe as we hold the EffectChain mutex which guarantees that we are not in // the middle of a read from audio HAL - mEffects[i]->stop(); + if (mEffects[i]->state() == EffectModule::ACTIVE || + mEffects[i]->state() == EffectModule::STOPPING) { + mEffects[i]->stop(); + } if (type == EFFECT_FLAG_TYPE_AUXILIARY) { delete[] effect->inBuffer(); } else { diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 2e05593..ed9d81e 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -1117,6 +1117,7 @@ private: status_t setDevice(uint32_t device); status_t setVolume(uint32_t *left, uint32_t *right, bool controller); status_t setMode(uint32_t mode); + status_t start(); status_t stop(); void setSuspended(bool suspended); bool suspended(); -- cgit v1.1