summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/audioflinger/AudioFlinger.cpp61
-rw-r--r--services/audioflinger/AudioFlinger.h4
2 files changed, 65 insertions, 0 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index b78c6d1..abe0293 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1106,6 +1106,20 @@ void AudioFlinger::removeClient_l(pid_t pid)
mClients.removeItem(pid);
}
+// getEffectThread_l() must be called with AudioFlinger::mLock held
+sp<AudioFlinger::PlaybackThread> AudioFlinger::getEffectThread_l(int sessionId, int EffectId)
+{
+ sp<PlaybackThread> thread;
+
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ if (mPlaybackThreads.valueAt(i)->getEffect(sessionId, EffectId) != 0) {
+ ALOG_ASSERT(thread == 0);
+ thread = mPlaybackThreads.valueAt(i);
+ }
+ }
+
+ return thread;
+}
// ----------------------------------------------------------------------------
@@ -4677,6 +4691,47 @@ status_t AudioFlinger::PlaybackThread::Track::attachAuxEffect(int EffectId)
sp<ThreadBase> thread = mThread.promote();
if (thread != 0) {
PlaybackThread *playbackThread = (PlaybackThread *)thread.get();
+ sp<AudioFlinger> af = mClient->audioFlinger();
+
+ Mutex::Autolock _l(af->mLock);
+
+ sp<PlaybackThread> srcThread = af->getEffectThread_l(AUDIO_SESSION_OUTPUT_MIX, EffectId);
+ if (srcThread == 0) {
+ return INVALID_OPERATION;
+ }
+
+ if (EffectId != 0 && playbackThread != srcThread.get()) {
+ Mutex::Autolock _dl(playbackThread->mLock);
+ Mutex::Autolock _sl(srcThread->mLock);
+ sp<EffectChain> chain = srcThread->getEffectChain_l(AUDIO_SESSION_OUTPUT_MIX);
+ if (chain == 0) {
+ return INVALID_OPERATION;
+ }
+
+ sp<EffectModule> effect = chain->getEffectFromId_l(EffectId);
+ if (effect == 0) {
+ return INVALID_OPERATION;
+ }
+ srcThread->removeEffect_l(effect);
+ playbackThread->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();
+ }
+
+ sp<EffectChain> dstChain = effect->chain().promote();
+ if (dstChain == 0) {
+ srcThread->addEffect_l(effect);
+ return INVALID_OPERATION;
+ }
+ AudioSystem::unregisterEffect(effect->id());
+ AudioSystem::registerEffect(&effect->desc(),
+ srcThread->id(),
+ dstChain->strategy(),
+ AUDIO_SESSION_OUTPUT_MIX,
+ effect->id());
+ }
status = playbackThread->attachAuxEffect(this, EffectId);
}
return status;
@@ -7645,6 +7700,12 @@ Exit:
return handle;
}
+sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect(int sessionId, int effectId)
+{
+ Mutex::Autolock _l(mLock);
+ return getEffect_l(sessionId, effectId);
+}
+
sp<AudioFlinger::EffectModule> AudioFlinger::ThreadBase::getEffect_l(int sessionId, int effectId)
{
sp<EffectChain> chain = getEffectChain_l(sessionId);
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 384306c..cfd718f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -253,6 +253,7 @@ public:
int listenerSession,
sync_event_callback_t callBack,
void *cookie);
+
private:
audio_mode_t getMode() const { return mMode; }
@@ -543,6 +544,7 @@ private:
// set audio mode to all effect chains
void setMode(audio_mode_t mode);
// get effect module with corresponding ID on specified audio session
+ sp<AudioFlinger::EffectModule> getEffect(int sessionId, int effectId);
sp<AudioFlinger::EffectModule> getEffect_l(int sessionId, int effectId);
// add and effect module. Also creates the effect chain is none exists for
// the effects audio session
@@ -1287,6 +1289,8 @@ private:
PlaybackThread *primaryPlaybackThread_l() const;
uint32_t primaryOutputDevice_l() const;
+ sp<PlaybackThread> getEffectThread_l(int sessionId, int EffectId);
+
// server side of the client's IAudioTrack
class TrackHandle : public android::BnAudioTrack {
public: