diff options
author | Eric Laurent <elaurent@google.com> | 2011-05-13 10:24:24 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-13 10:24:24 -0700 |
commit | 6708b9a3fb654f5623ba5a696288fdba310a5e1a (patch) | |
tree | 46bf064d0c57fa017823e9825aff06700a3f4a4f | |
parent | 86e152e70a1aab83cba2c75c76d7c0e2d00b61dc (diff) | |
parent | b469b9490b3cd9e0f0466d9b9ab228f6c793b82e (diff) | |
download | frameworks_av-6708b9a3fb654f5623ba5a696288fdba310a5e1a.zip frameworks_av-6708b9a3fb654f5623ba5a696288fdba310a5e1a.tar.gz frameworks_av-6708b9a3fb654f5623ba5a696288fdba310a5e1a.tar.bz2 |
Merge "Fix audio effect framework issues"
-rw-r--r-- | services/audioflinger/AudioFlinger.cpp | 69 | ||||
-rw-r--r-- | services/audioflinger/AudioFlinger.h | 14 |
2 files changed, 55 insertions, 28 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 10beee96..a6ba1a0 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1257,6 +1257,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTra LOGV("createTrack_l() setting main buffer %p", chain->inBuffer()); track->setMainBuffer(chain->inBuffer()); chain->setStrategy(AudioSystem::getStrategyForStream((audio_stream_type_t)track->type())); + chain->incTrackCnt(); } } lStatus = NO_ERROR; @@ -1340,7 +1341,7 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp<Track>& track) sp<EffectChain> chain = getEffectChain_l(track->sessionId()); if (chain != 0) { LOGV("addTrack_l() starting track on chain %p for session %d", chain.get(), track->sessionId()); - chain->startTrack(); + chain->incActiveTrackCnt(); } } @@ -1358,8 +1359,17 @@ void AudioFlinger::PlaybackThread::destroyTrack_l(const sp<Track>& track) { track->mState = TrackBase::TERMINATED; if (mActiveTracks.indexOf(track) < 0) { - mTracks.remove(track); - deleteTrackName_l(track->name()); + removeTrack_l(track); + } +} + +void AudioFlinger::PlaybackThread::removeTrack_l(const sp<Track>& track) +{ + mTracks.remove(track); + deleteTrackName_l(track->name()); + sp<EffectChain> chain = getEffectChain_l(track->sessionId()); + if (chain != 0) { + chain->decTrackCnt(); } } @@ -1865,12 +1875,11 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track chain = getEffectChain_l(track->sessionId()); if (chain != 0) { LOGV("stopping track on chain %p for session Id: %d", chain.get(), track->sessionId()); - chain->stopTrack(); + chain->decActiveTrackCnt(); } } if (track->isTerminated()) { - mTracks.remove(track); - deleteTrackName_l(track->mName); + removeTrack_l(track); } } } @@ -1956,7 +1965,7 @@ bool AudioFlinger::MixerThread::checkForNewParameters_l() if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) { // when changing the audio output device, call addBatteryData to notify // the change - if (mDevice != value) { + if ((int)mDevice != value) { uint32_t params = 0; // check whether speaker is on if (value & AUDIO_DEVICE_OUT_SPEAKER) { @@ -2348,11 +2357,10 @@ bool AudioFlinger::DirectOutputThread::threadLoop() if (!effectChains.isEmpty()) { LOGV("stopping track on chain %p for session Id: %d", effectChains[0].get(), trackToRemove->sessionId()); - effectChains[0]->stopTrack(); + effectChains[0]->decActiveTrackCnt(); } if (trackToRemove->isTerminated()) { - mTracks.remove(trackToRemove); - deleteTrackName_l(trackToRemove->mName); + removeTrack_l(trackToRemove); } } @@ -5150,6 +5158,7 @@ status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& c if (session == track->sessionId()) { LOGV("addEffectChain_l() track->setMainBuffer track %p buffer %p", track.get(), buffer); track->setMainBuffer(buffer); + chain->incTrackCnt(); } } @@ -5159,7 +5168,7 @@ status_t AudioFlinger::PlaybackThread::addEffectChain_l(const sp<EffectChain>& c if (track == 0) continue; if (session == track->sessionId()) { LOGV("addEffectChain_l() activating track %p on session %d", track.get(), session); - chain->startTrack(); + chain->incActiveTrackCnt(); } } } @@ -5195,11 +5204,23 @@ size_t AudioFlinger::PlaybackThread::removeEffectChain_l(const sp<EffectChain>& for (size_t i = 0; i < mEffectChains.size(); i++) { if (chain == mEffectChains[i]) { mEffectChains.removeAt(i); + // detach all active tracks from the chain + for (size_t i = 0 ; i < mActiveTracks.size() ; ++i) { + sp<Track> track = mActiveTracks[i].promote(); + if (track == 0) continue; + if (session == track->sessionId()) { + LOGV("removeEffectChain_l(): stopping track on chain %p for session Id: %d", + chain.get(), session); + chain->decActiveTrackCnt(); + } + } + // detach all tracks with same session ID from this chain for (size_t i = 0; i < mTracks.size(); ++i) { sp<Track> track = mTracks[i]; if (session == track->sessionId()) { track->setMainBuffer(mMixBuffer); + chain->decTrackCnt(); } } break; @@ -5481,7 +5502,7 @@ void AudioFlinger::EffectModule::process() // If an insert effect is idle and input buffer is different from output buffer, // accumulate input onto output sp<EffectChain> chain = mChain.promote(); - if (chain != 0 && chain->activeTracks() != 0) { + if (chain != 0 && chain->activeTrackCnt() != 0) { size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2; //always stereo here int16_t *in = mConfig.inputCfg.buffer.s16; int16_t *out = mConfig.outputCfg.buffer.s16; @@ -6157,9 +6178,9 @@ void AudioFlinger::EffectHandle::dump(char* buffer, size_t size) AudioFlinger::EffectChain::EffectChain(const wp<ThreadBase>& wThread, int sessionId) - : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mOwnInBuffer(false), - mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX), - mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX) + : mThread(wThread), mSessionId(sessionId), mActiveTrackCnt(0), mTrackCnt(0), + mOwnInBuffer(false), mVolumeCtrlIdx(-1), mLeftVolume(UINT_MAX), mRightVolume(UINT_MAX), + mNewLeftVolume(UINT_MAX), mNewRightVolume(UINT_MAX) { mStrategy = AudioSystem::getStrategyForStream(AUDIO_STREAM_MUSIC); } @@ -6216,8 +6237,15 @@ void AudioFlinger::EffectChain::process_l() (mSessionId == AUDIO_SESSION_OUTPUT_STAGE); bool tracksOnSession = false; if (!isGlobalSession) { - tracksOnSession = - playbackThread->hasAudioSession(mSessionId) & PlaybackThread::TRACK_SESSION; + 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 = playbackThread->frameCount() * playbackThread->channelCount(); + memset(mInBuffer, 0, numSamples * sizeof(int16_t)); } size_t size = mEffects.size(); @@ -6230,13 +6258,6 @@ void AudioFlinger::EffectChain::process_l() 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 (tracksOnSession && - activeTracks() == 0) { - size_t numSamples = playbackThread->frameCount() * playbackThread->channelCount(); - memset(mInBuffer, 0, numSamples * sizeof(int16_t)); - } } // addEffect_l() must be called with PlaybackThread::mLock held diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index 43be6fe..39314ad 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -684,6 +684,7 @@ private: status_t addTrack_l(const sp<Track>& track); void destroyTrack_l(const sp<Track>& track); + void removeTrack_l(const sp<Track>& track); void readOutputParameters(); @@ -1134,9 +1135,13 @@ private: return mOutBuffer; } - void startTrack() {mActiveTrackCnt++;} - void stopTrack() {mActiveTrackCnt--;} - int activeTracks() { return mActiveTrackCnt;} + void incTrackCnt() { android_atomic_inc(&mTrackCnt); } + void decTrackCnt() { android_atomic_dec(&mTrackCnt); } + int32_t trackCnt() { return mTrackCnt;} + + void incActiveTrackCnt() { android_atomic_inc(&mActiveTrackCnt); } + void decActiveTrackCnt() { android_atomic_dec(&mActiveTrackCnt); } + int32_t activeTrackCnt() { return mActiveTrackCnt;} uint32_t strategy() { return mStrategy; } void setStrategy(uint32_t strategy) @@ -1155,7 +1160,8 @@ private: int mSessionId; // audio session ID int16_t *mInBuffer; // chain input buffer int16_t *mOutBuffer; // chain output buffer - int mActiveTrackCnt; // number of active tracks connected + volatile int32_t mActiveTrackCnt; // number of active tracks connected + volatile int32_t mTrackCnt; // number of tracks connected 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 |