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

Commit 377d9bd3 authored by Eric Laurent's avatar Eric Laurent
Browse files

AudioFlinger: fix fast capture silence

Silencing fast catpure tracks was not properly implemented.
Fix by zeroing fast capture thread HAL read buffer if the silenced
track is the only active, or by invalidating the silenced track
if other non fast tracks are active.

Bug: 157708122
Test: repro steps in the bug
Change-Id: I88b19540815bc1491b9e76c1ae6b6f85e32afa8f
Merged-In: I88b19540815bc1491b9e76c1ae6b6f85e32afa8f
(cherry picked from commit 33403f0e)
parent 7771132c
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -154,7 +154,7 @@ void FastCapture::onStateChange()
        mReadBufferState = -1;
        dumpState->mFrameCount = frameCount;
    }

    dumpState->mSilenced = current->mSilenceCapture;
}

void FastCapture::onWork()
@@ -208,6 +208,9 @@ void FastCapture::onWork()
            mReadBufferState = frameCount;
        }
        if (mReadBufferState > 0) {
            if (current->mSilenceCapture) {
                memset(mReadBuffer, 0, mReadBufferState * Format_frameSize(mFormat));
            }
            ssize_t framesWritten = mPipeSink->write(mReadBuffer, mReadBufferState);
            audio_track_cblk_t* cblk = current->mCblk;
            if (fastPatchRecordBufferProvider != 0) {
+3 −2
Original line number Diff line number Diff line
@@ -44,10 +44,11 @@ void FastCaptureDumpState::dump(int fd) const
    double periodSec = (double) mFrameCount / mSampleRate;
    dprintf(fd, "  FastCapture command=%s readSequence=%u framesRead=%u\n"
                "              readErrors=%u sampleRate=%u frameCount=%zu\n"
                "              measuredWarmup=%.3g ms, warmupCycles=%u period=%.2f ms\n",
                "              measuredWarmup=%.3g ms, warmupCycles=%u period=%.2f ms\n"
                "              silenced: %s\n",
                FastCaptureState::commandToString(mCommand), mReadSequence, mFramesRead,
                mReadErrors, mSampleRate, mFrameCount, measuredWarmupMs, mWarmupCycles,
                periodSec * 1e3);
                periodSec * 1e3, mSilenced ? "true" : "false");
}

}   // android
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ struct FastCaptureDumpState : FastThreadDumpState {
    uint32_t mReadErrors;       // total number of read() errors
    uint32_t mSampleRate;
    size_t   mFrameCount;
    bool     mSilenced = false; // capture is silenced
};

}   // android
+2 −0
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ struct FastCaptureState : FastThreadState {
    audio_format_t  mFastPatchRecordFormat = AUDIO_FORMAT_INVALID;
    AudioBufferProvider* mFastPatchRecordBufferProvider = nullptr;   // a reference to a patch
                                                                     // record in fast mode
    bool            mSilenceCapture = false;    // request to silence capture for fast track.
                                                // note: this also silences the normal mixer pipe

    // Extends FastThreadState::Command
    static const Command
+28 −3
Original line number Diff line number Diff line
@@ -6873,6 +6873,8 @@ reacquire_wakelock:
        // reference to a fast track which is about to be removed
        sp<RecordTrack> fastTrackToRemove;

        bool silenceFastCapture = false;

        { // scope for mLock
            Mutex::Autolock _l(mLock);

@@ -6957,14 +6959,33 @@ reacquire_wakelock:
                            __func__, activeTrackState, activeTrack->id(), size);
                }

                activeTracks.add(activeTrack);
                i++;

                if (activeTrack->isFastTrack()) {
                    ALOG_ASSERT(!mFastTrackAvail);
                    ALOG_ASSERT(fastTrack == 0);
                    // if the active fast track is silenced either:
                    // 1) silence the whole capture from fast capture buffer if this is
                    //    the only active track
                    // 2) invalidate this track: this will cause the client to reconnect and possibly
                    //    be invalidated again until unsilenced
                    if (activeTrack->isSilenced()) {
                        if (size > 1) {
                            activeTrack->invalidate();
                            ALOG_ASSERT(fastTrackToRemove == 0);
                            fastTrackToRemove = activeTrack;
                            removeTrack_l(activeTrack);
                            mActiveTracks.remove(activeTrack);
                            size--;
                            continue;
                        } else {
                            silenceFastCapture = true;
                        }
                    }
                    fastTrack = activeTrack;
                }

                activeTracks.add(activeTrack);
                i++;

            }

            mActiveTracks.updatePowerState(this);
@@ -7038,6 +7059,10 @@ reacquire_wakelock:
                        AUDIO_FORMAT_INVALID : fastTrack->format();
                didModify = true;
            }
            if (state->mSilenceCapture != silenceFastCapture) {
                state->mSilenceCapture = silenceFastCapture;
                didModify = true;
            }
            sq->end(didModify);
            if (didModify) {
                sq->push(block);