summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2011-11-11 15:42:52 -0800
committerEric Laurent <elaurent@google.com>2011-11-11 16:33:24 -0800
commit544fe9b6e9325701df4ab8c1d29774fc13c4cf6c (patch)
treeaa93b41c247d3c896de2a653e029d1fd00c1a0f3 /services
parent1dc0ab1d2e2c5f40193556ad1239e304563f3083 (diff)
downloadframeworks_av-544fe9b6e9325701df4ab8c1d29774fc13c4cf6c.zip
frameworks_av-544fe9b6e9325701df4ab8c1d29774fc13c4cf6c.tar.gz
frameworks_av-544fe9b6e9325701df4ab8c1d29774fc13c4cf6c.tar.bz2
audioflinger: fix noise when skipping to next song
When audio effects are enabled, a noise can be heard at the beginning of the new song when skipping to next song in music app. This is because some effects (especially virtualizer) have a tail. This tail was not played when previous song was stopped because effects were not processed when no tracks were present on a given session. This is to reduce CPU load when effects are enabled but no audio is playing. The tail was then rendered when the new song was started. Added a delay before stopping effect process after all tracks have been removed from a session. Issue 5584880. Change-Id: I815e0f7441f9302e8dfe413dc269a94e4cc6fd95
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp39
-rw-r--r--services/audioflinger/AudioFlinger.h9
2 files changed, 35 insertions, 13 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index ff262f1..780c0d2 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -7028,11 +7028,17 @@ void AudioFlinger::EffectHandle::dump(char* buffer, size_t size)
AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& wThread,
int sessionId)
- : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0),
+ : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), mTailBufferCount(0),
mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX),
mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX)
{
mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC);
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread == 0) {
+ return;
+ }
+ mMaxTailBuffers = ((kProcessTailDurationMs * thread->sampleRate()) / 1000) /
+ thread->frameCount();
}
AudioFlinger::EffectChain::~EffectChain()
@@ -7100,22 +7106,31 @@ void AudioFlinger::EffectChain::process_l()
}
bool isGlobalSession = (mSessionId == AUDIO_SESSION_OUTPUT_MIX) ||
(mSessionId == AUDIO_SESSION_OUTPUT_STAGE);
- bool tracksOnSession = false;
+ // always process effects unless no more tracks are on the session and the effect tail
+ // has been rendered
+ bool doProcess = true;
if (!isGlobalSession) {
- tracksOnSession = (trackCnt() != 0);
- }
+ bool tracksOnSession = (trackCnt() != 0);
- // if no track is active, input buffer must be cleared here as the mixer process
- // will not do it
- if (tracksOnSession &&
- activeTrackCnt() == 0) {
- size_t numSamples = thread->frameCount() * thread->channelCount();
- memset(mInBuffer, 0, numSamples * sizeof(int16_t));
+ if (!tracksOnSession && mTailBufferCount == 0) {
+ doProcess = false;
+ }
+
+ if (activeTrackCnt() == 0) {
+ // 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));
+ if (mTailBufferCount > 0) {
+ mTailBufferCount--;
+ }
+ }
+ }
}
size_t size = mEffects.size();
- // do not process effect if no track is present in same audio session
- if (isGlobalSession || tracksOnSession) {
+ if (doProcess) {
for (size_t i = 0; i < size; i++) {
mEffects[i]->process();
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 4b794ef..897bc78 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -1247,6 +1247,10 @@ private:
// corresponding to a suspend all request.
static const int kKeyForSuspendAll = 0;
+ // minimum duration during which we force calling effect process when last track on
+ // a session is stopped or removed to allow effect tail to be rendered
+ static const int kProcessTailDurationMs = 1000;
+
void process_l();
void lock() {
@@ -1287,7 +1291,8 @@ private:
void decTrackCnt() { android_atomic_dec(&mTrackCnt); }
int32_t trackCnt() { return mTrackCnt;}
- void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); }
+ void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt);
+ mTailBufferCount = mMaxTailBuffers; }
void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); }
int32_t activeTrackCnt() { return mActiveTrackCnt;}
@@ -1338,6 +1343,8 @@ private:
int16_t *mOutBuffer; // chain output buffer
volatile int32_t mActiveTrackCnt; // number of active tracks connected
volatile int32_t mTrackCnt; // number of tracks connected
+ int32_t mTailBufferCount; // current effect tail buffer count
+ int32_t mMaxTailBuffers; // maximum effect tail buffers
bool mOwnInBuffer; // true if the chain owns its input buffer
int mVolumeCtrlIdx; // index of insert effect having control over volume
uint32_t mLeftVolume; // previous volume on left channel