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

Commit 071ccd5a authored by Eric Laurent's avatar Eric Laurent
Browse files

audioflinger: fix clicks on 48kHz audio.

The calculation done in prepareTracks_l() for the minimum amount
off frames needed to mix one output buffer had 2 issues:
- the additional sample needed for interpolation was not included
- the fact that the resampler does not acknowledge the frames consumed
immediately after each mixing round but only once all frames requested have been used
was not taken into account.
Thus the number of frames available in track buffer could be considered sufficient although
it was not and the resampler would abort producing a short silence perceived as a click.

Issue 5727099.

Change-Id: I7419847a7474c7d9f9170bedd0a636132262142c
parent 69aac3e6
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -2111,7 +2111,15 @@ uint32_t AudioFlinger::MixerThread::prepareTracks_l(const SortedVector< wp<Track
            if (t->sampleRate() == (int)mSampleRate) {
                minFrames = mFrameCount;
            } else {
                minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1;
                // +1 for rounding and +1 for additional sample needed for interpolation
                minFrames = (mFrameCount * t->sampleRate()) / mSampleRate + 1 + 1;
                // add frames already consumed but not yet released by the resampler
                // because cblk->framesReady() will  include these frames
                minFrames += mAudioMixer->getUnreleasedFrames(track->name());
                // the minimum track buffer size is normally twice the number of frames necessary
                // to fill one buffer and the resampler should not leave more than one buffer worth
                // of unreleased frames after each pass, but just in case...
                LOG_ASSERT(minFrames <= cblk->frameCount);
            }
        }
        if ((cblk->framesReady() >= minFrames) && track->isReady() &&
+17 −0
Original line number Diff line number Diff line
@@ -331,6 +331,23 @@ void AudioMixer::track_t::adjustVolumeRamp(bool aux)
    }
}

size_t AudioMixer::track_t::getUnreleasedFrames()
{
    if (resampler != NULL) {
        return resampler->getUnreleasedFrames();
    }
    return 0;
}

size_t AudioMixer::getUnreleasedFrames(int name)
{
    name -= TRACK0;
    if (uint32_t(name) < MAX_NUM_TRACKS) {
        track_t& track(mState.tracks[name]);
        return track.getUnreleasedFrames();
    }
    return 0;
}

status_t AudioMixer::setBufferProvider(AudioBufferProvider* buffer)
{
+3 −0
Original line number Diff line number Diff line
@@ -91,6 +91,8 @@ public:

    static void ditherAndClamp(int32_t* out, int32_t const *sums, size_t c);

    size_t      getUnreleasedFrames(int name);

private:

    enum {
@@ -167,6 +169,7 @@ private:
        bool        doesResample() const;
        void        resetResampler();
        void        adjustVolumeRamp(bool aux);
        size_t      getUnreleasedFrames();
    };

    // pad to 32-bytes to fill cache line
+1 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ public:
            AudioBufferProvider* provider) = 0;

    virtual void reset();
    virtual size_t getUnreleasedFrames() { return mInputIndex; }

protected:
    // number of bits for phase fraction - 30 bits allows nearly 2x downsampling