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

Commit c1646388 authored by Andy Hung's avatar Andy Hung
Browse files

AudioFlinger: Properly account for underruns

When the mixer status was MIXER_ENABLED twice in a row
zeroes were forced to the audio sink.

Test: aaudio test write_sine_callback -pl -n1 -r44100 -s20
      and then use rapid volume changes.
Bug: 131767115
Change-Id: I24b41084138210c63e8c551ae4a5f3adddb9e607
parent ef7eaaf8
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -3277,6 +3277,7 @@ bool AudioFlinger::PlaybackThread::threadLoop()

        Vector< sp<EffectChain> > effectChains;
        audio_session_t activeHapticSessionId = AUDIO_SESSION_NONE;
        std::vector<sp<Track>> activeTracks;

        // If the device is AUDIO_DEVICE_OUT_BUS, check for downstream latency.
        //
@@ -3563,6 +3564,12 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                }
            }

            // Acquire a local copy of active tracks with lock (release w/o lock).
            //
            // Control methods on the track acquire the ThreadBase lock (e.g. start()
            // stop(), pause(), etc.), but the threadLoop is entitled to call audio
            // data / buffer methods on tracks from activeTracks without the ThreadBase lock.
            activeTracks.insert(activeTracks.end(), mActiveTracks.begin(), mActiveTracks.end());
        } // mLock scope ends

        if (mBytesRemaining == 0) {
@@ -3577,6 +3584,13 @@ bool AudioFlinger::PlaybackThread::threadLoop()
                threadLoop_sleepTime();
                if (mSleepTimeUs == 0) {
                    mCurrentWriteLength = mSinkBufferSize;

                    // Tally underrun frames as we are inserting 0s here.
                    for (const auto& track : activeTracks) {
                        if (track->mFillingUpStatus == Track::FS_ACTIVE) {
                            track->mAudioTrackServerProxy->tallyUnderrunFrames(mNormalFrameCount);
                        }
                    }
                }
            }
            // Either threadLoop_mix() or threadLoop_sleepTime() should have set