From f997cabca292d70d078ae828e21c28e6df62995f Mon Sep 17 00:00:00 2001 From: Eric Laurent Date: Mon, 19 Jul 2010 06:24:46 -0700 Subject: Fixed problems in audio effect volume control. Fixed the following problems in audio effect volume control in AudioFlinger: - Make sure that the volumes returned by EffectChain::setVolume_l() are correct even is no change is detected since last call - Do not use isEnabled() to validate volume control but mState >= ACTIVE instead as the volume control must be also active in STOPPING and STOPPED states. Change-Id: Id62da3164fad500ee8a5efd6cd78c77e8fdcb541 --- media/libeffects/visualizer/EffectVisualizer.cpp | 6 ++--- services/audioflinger/AudioFlinger.cpp | 31 ++++++++++++++++-------- services/audioflinger/AudioFlinger.h | 3 +++ 3 files changed, 27 insertions(+), 13 deletions(-) diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp index bcda06e..ec13557 100644 --- a/media/libeffects/visualizer/EffectVisualizer.cpp +++ b/media/libeffects/visualizer/EffectVisualizer.cpp @@ -230,9 +230,6 @@ extern "C" int Visualizer_process( if (pContext == NULL) { return -EINVAL; } - if (pContext->mState != VISUALIZER_STATE_ACTIVE) { - return -ENODATA; - } if (inBuffer == NULL || inBuffer->raw == NULL || outBuffer == NULL || outBuffer->raw == NULL || @@ -269,6 +266,9 @@ extern "C" int Visualizer_process( memcpy(outBuffer->raw, inBuffer->raw, outBuffer->frameCount * 2 * sizeof(int16_t)); } } + if (pContext->mState != VISUALIZER_STATE_ACTIVE) { + return -ENODATA; + } return 0; } // end Visualizer_process diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 7e528af..b38a5c8 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -2948,7 +2948,8 @@ bool AudioFlinger::PlaybackThread::Track::isReady() const { status_t AudioFlinger::PlaybackThread::Track::start() { status_t status = NO_ERROR; - LOGV("start(%d), calling thread %d", mName, IPCThreadState::self()->getCallingPid()); + LOGV("start(%d), calling thread %d session %d", + mName, IPCThreadState::self()->getCallingPid(), mSessionId); sp thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); @@ -5366,9 +5367,9 @@ status_t AudioFlinger::EffectModule::setVolume(uint32_t *left, uint32_t *right, // Send volume indication if EFFECT_FLAG_VOLUME_IND is set and read back altered volume // if controller flag is set (Note that controller == TRUE => EFFECT_FLAG_VOLUME_CTRL set) - if (isEnabled() && - (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL || - (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND) { + if ((mState >= ACTIVE) && + ((mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL || + (mDescriptor.flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_IND)) { status_t cmdStatus; uint32_t volume[2]; uint32_t *pVolume = NULL; @@ -5749,7 +5750,8 @@ void AudioFlinger::EffectHandle::dump(char* buffer, size_t size) AudioFlinger::EffectChain::EffectChain(const wp& wThread, int sessionId) : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mOwnInBuffer(false), - mVolumeCtrlIdx(-1), mLeftVolume(0), mRightVolume(0) + mVolumeCtrlIdx(-1), mLeftVolume(0), mRightVolume(0), + mNewLeftVolume(0), mNewRightVolume(0) { } @@ -5980,25 +5982,34 @@ bool AudioFlinger::EffectChain::setVolume_l(uint32_t *left, uint32_t *right) // first update volume controller for (size_t i = size; i > 0; i--) { - if (mEffects[i - 1]->isEnabled() && + if ((mEffects[i - 1]->state() >= EffectModule::ACTIVE) && (mEffects[i - 1]->desc().flags & EFFECT_FLAG_VOLUME_MASK) == EFFECT_FLAG_VOLUME_CTRL) { ctrlIdx = i - 1; + hasControl = true; break; } } if (ctrlIdx == mVolumeCtrlIdx && *left == mLeftVolume && *right == mRightVolume) { - return false; + if (hasControl) { + *left = mNewLeftVolume; + *right = mNewRightVolume; + } + return hasControl; } + if (mVolumeCtrlIdx != -1) { + hasControl = true; + } mVolumeCtrlIdx = ctrlIdx; - mLeftVolume = *left; - mRightVolume = *right; + mLeftVolume = newLeft; + mRightVolume = newRight; // second get volume update from volume controller if (ctrlIdx >= 0) { mEffects[ctrlIdx]->setVolume(&newLeft, &newRight, true); - hasControl = true; + mNewLeftVolume = newLeft; + mNewRightVolume = newRight; } // then indicate volume to all other effects in chain. // Pass altered volume to effects before volume controller diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 4507a48..99816f9 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -1110,6 +1110,9 @@ private: int mVolumeCtrlIdx; // index of insert effect having control over volume uint32_t mLeftVolume; // previous volume on left channel uint32_t mRightVolume; // previous volume on right channel + uint32_t mNewLeftVolume; // new volume on left channel + uint32_t mNewRightVolume; // new volume on right channel + }; friend class RecordThread; -- cgit v1.1