summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2010-09-28 14:09:57 -0700
committerEric Laurent <elaurent@google.com>2010-09-28 14:23:39 -0700
commitdac69110ed1073bf0a9827a3f78698896dd05d97 (patch)
treedb990d1cf1867854ffbf39585c0ce19e436c56b9 /services
parent036fad5034d05beecae19da6da46e1ce7be78e64 (diff)
downloadframeworks_av-dac69110ed1073bf0a9827a3f78698896dd05d97.zip
frameworks_av-dac69110ed1073bf0a9827a3f78698896dd05d97.tar.gz
frameworks_av-dac69110ed1073bf0a9827a3f78698896dd05d97.tar.bz2
Fix several audio effects problems.
Fixed the following issues in LVM effect bundle wrapper: - memory leaks in EffectCreate() in case effect creation fails at various stages - Added saturation when accumulating to output buffer - Fixed problems with enabled effects count when an effect is released while enabled - Do not allocate temporary buffer for accumulation each time process() is called Fixed the following issues in effects framework (AudioFlinger) - Release effect synchronously in the library when deleted from effect chain - Do not call the effect process function if no tracks are present in the same audio session Change-Id: Ifbd80a163415cfb3c0a337c12082853ea45d9c91
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp40
1 files changed, 32 insertions, 8 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 8a732ed..97b8086 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -5332,6 +5332,15 @@ size_t AudioFlinger::EffectModule::removeHandle(const wp<EffectHandle>& handle)
}
}
+ // Release effect engine here so that it is done immediately. Otherwise it will be released
+ // by the destructor when the last strong reference on the this object is released which can
+ // happen after next process is called on this effect.
+ if (size == 0 && mEffectInterface != NULL) {
+ // release effect engine
+ EffectRelease(mEffectInterface);
+ mEffectInterface = NULL;
+ }
+
return size;
}
@@ -6145,21 +6154,36 @@ sp<AudioFlinger::EffectModule> AudioFlinger::EffectChain::getEffectFromId_l(int
// Must be called with EffectChain::mLock locked
void AudioFlinger::EffectChain::process_l()
{
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread == 0) {
+ LOGW("process_l(): cannot promote mixer thread");
+ return;
+ }
+ PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ bool isGlobalSession = (mSessionId == AudioSystem::SESSION_OUTPUT_MIX) ||
+ (mSessionId == AudioSystem::SESSION_OUTPUT_STAGE);
+ bool tracksOnSession = false;
+ if (!isGlobalSession) {
+ tracksOnSession =
+ playbackThread->hasAudioSession(mSessionId) & PlaybackThread::TRACK_SESSION;
+ }
+
size_t size = mEffects.size();
- for (size_t i = 0; i < size; i++) {
- mEffects[i]->process();
+ // do not process effect if no track is present in same audio session
+ if (isGlobalSession || tracksOnSession) {
+ for (size_t i = 0; i < size; i++) {
+ mEffects[i]->process();
+ }
}
for (size_t i = 0; i < size; i++) {
mEffects[i]->updateState();
}
// if no track is active, input buffer must be cleared here as the mixer process
// will not do it
- if (mSessionId > 0 && activeTracks() == 0) {
- sp<ThreadBase> thread = mThread.promote();
- if (thread != 0) {
- size_t numSamples = thread->frameCount() * thread->channelCount();
- memset(mInBuffer, 0, numSamples * sizeof(int16_t));
- }
+ if (tracksOnSession &&
+ activeTracks() == 0) {
+ size_t numSamples = playbackThread->frameCount() * playbackThread->channelCount();
+ memset(mInBuffer, 0, numSamples * sizeof(int16_t));
}
}