summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2012-05-30 12:30:29 -0700
committerEric Laurent <elaurent@google.com>2012-05-30 12:38:27 -0700
commit91b14c4c144d0cc957a427cffc02ba10d0615677 (patch)
treedd7c1027319b6783cdc493bf4d37afb2537a2879 /services
parent91b0d43a27b3a1cebd75270f953f3fb9fa4f2047 (diff)
audioflinger: fix effect problem during underrun
When an audio track underruns, the input buffer of the corresponding effect chain (if any) must be cleared, otherwise audio from previous mixer run will be fed again to the effect process function. Bug 6551652. Change-Id: I5cd02196745f756c85af82d6937e9dc54369b37f
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp35
-rw-r--r--services/audioflinger/AudioFlinger.h4
2 files changed, 37 insertions, 2 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 57d70891..eea3cd22 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -3147,6 +3147,13 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
mixerStatus = MIXER_TRACKS_READY;
}
} else {
+ // clear effect chain input buffer if an active track underruns to avoid sending
+ // previous audio buffer again to effects
+ chain = getEffectChain_l(track->sessionId());
+ if (chain != 0) {
+ chain->clearInputBuffer();
+ }
+
//ALOGV("track %d u=%08x, s=%08x [NOT READY] on thread %p", name, cblk->user, cblk->server, this);
if ((track->sharedBuffer() != 0) || track->isTerminated() ||
track->isStopped() || track->isPaused()) {
@@ -3661,6 +3668,12 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep
mActiveTrack = t;
mixerStatus = MIXER_TRACKS_READY;
} else {
+ // clear effect chain input buffer if an active track underruns to avoid sending
+ // previous audio buffer again to effects
+ if (!mEffectChains.isEmpty()) {
+ mEffectChains[0]->clearInputBuffer();
+ }
+
//ALOGV("track %d u=%08x, s=%08x [NOT READY]", track->name(), cblk->user, cblk->server);
if (track->isTerminated() || track->isStopped() || track->isPaused()) {
// We have consumed all the buffers of this track.
@@ -8978,6 +8991,25 @@ sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromType_l(
return 0;
}
+void AudioFlinger::EffectChain::clearInputBuffer()
+{
+ Mutex::Autolock _l(mLock);
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread == 0) {
+ ALOGW("clearInputBuffer(): cannot promote mixer thread");
+ return;
+ }
+ clearInputBuffer_l(thread);
+}
+
+// Must be called with EffectChain::mLock locked
+void AudioFlinger::EffectChain::clearInputBuffer_l(sp<ThreadBase> thread)
+{
+ size_t numSamples = thread->frameCount() * thread->channelCount();
+ memset(mInBuffer, 0, numSamples * sizeof(int16_t));
+
+}
+
// Must be called with EffectChain::mLock locked
void AudioFlinger::EffectChain::process_l()
{
@@ -9002,8 +9034,7 @@ void AudioFlinger::EffectChain::process_l()
// if no track is active and the effect tail has not been rendered,
// the input buffer must be cleared here as the mixer process will not do it
if (tracksOnSession || mTailBufferCount > 0) {
- size_t numSamples = thread->frameCount() * thread->channelCount();
- memset(mInBuffer, 0, numSamples * sizeof(int16_t));
+ clearInputBuffer_l(thread);
if (mTailBufferCount > 0) {
mTailBufferCount--;
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 51cbae73..19390b1a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -1717,6 +1717,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
void checkSuspendOnEffectEnabled(const sp<EffectModule>& effect,
bool enabled);
+ void clearInputBuffer();
+
status_t dump(int fd, const Vector<String16>& args);
protected:
@@ -1744,6 +1746,8 @@ mutable Mutex mLock; // mutex for process, commands and handl
// types or implementations from the suspend/restore mechanism.
bool isEffectEligibleForSuspend(const effect_descriptor_t& desc);
+ void clearInputBuffer_l(sp<ThreadBase> thread);
+
wp<ThreadBase> mThread; // parent mixer thread
Mutex mLock; // mutex protecting effect list
Vector< sp<EffectModule> > mEffects; // list of effect modules