Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 91b14c4c authored by Eric Laurent's avatar Eric Laurent
Browse files

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
parent 91b0d43a
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -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--;
                }
+4 −0
Original line number Diff line number Diff line
@@ -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