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

Commit 28ed2f93 authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Reduce underruns in screen off, esp. with EQ

Add MonoPipe APIs to specify setpoint.
Use screen state to configure pipe setpoint.
Fix a long-standing bug where pipe sleep time was excessive,
  which interacted poorly with governor and low clock frequencies.
  Now it deducts the elapsed time since last write(),
  which was significant when there was EQ and low clock frequency.

Bug: 6618373
Change-Id: I6f3b0072c2244aeb033ef0795ad164491a164ff5
parent a4f7e0e9
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -40,12 +40,14 @@ public:
    //  keyFrameCount: to change audio output frame count, value is an int
    //  keyFrameCount: to change audio output frame count, value is an int
    //  keyInputSource: to change audio input source, value is an int in audio_source_t
    //  keyInputSource: to change audio input source, value is an int in audio_source_t
    //     (defined in media/mediarecorder.h)
    //     (defined in media/mediarecorder.h)
    //  keyScreenState: either "on" or "off"
    static const char * const keyRouting;
    static const char * const keyRouting;
    static const char * const keySamplingRate;
    static const char * const keySamplingRate;
    static const char * const keyFormat;
    static const char * const keyFormat;
    static const char * const keyChannels;
    static const char * const keyChannels;
    static const char * const keyFrameCount;
    static const char * const keyFrameCount;
    static const char * const keyInputSource;
    static const char * const keyInputSource;
    static const char * const keyScreenState;


    String8 toString();
    String8 toString();


+1 −0
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ const char * const AudioParameter::keyFormat = AUDIO_PARAMETER_STREAM_FORMAT;
const char * const AudioParameter::keyChannels = AUDIO_PARAMETER_STREAM_CHANNELS;
const char * const AudioParameter::keyChannels = AUDIO_PARAMETER_STREAM_CHANNELS;
const char * const AudioParameter::keyFrameCount = AUDIO_PARAMETER_STREAM_FRAME_COUNT;
const char * const AudioParameter::keyFrameCount = AUDIO_PARAMETER_STREAM_FRAME_COUNT;
const char * const AudioParameter::keyInputSource = AUDIO_PARAMETER_STREAM_INPUT_SOURCE;
const char * const AudioParameter::keyInputSource = AUDIO_PARAMETER_STREAM_INPUT_SOURCE;
const char * const AudioParameter::keyScreenState = AUDIO_PARAMETER_KEY_SCREEN_STATE;


AudioParameter::AudioParameter(const String8& keyValuePairs)
AudioParameter::AudioParameter(const String8& keyValuePairs)
{
{
+3 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,9 @@ LOCAL_SRC_FILES := \
#LOCAL_C_INCLUDES += path/to/libsndfile/src
#LOCAL_C_INCLUDES += path/to/libsndfile/src
#LOCAL_STATIC_LIBRARIES += libsndfile
#LOCAL_STATIC_LIBRARIES += libsndfile


# uncomment for systrace
# LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_AUDIO

LOCAL_MODULE := libnbaio
LOCAL_MODULE := libnbaio


include $(BUILD_STATIC_LIBRARY)
include $(BUILD_STATIC_LIBRARY)
+23 −0
Original line number Original line Diff line number Diff line
@@ -164,6 +164,9 @@ static const enum {
    //  up large writes into smaller ones, and the wrapper would need to deal with scheduler.
    //  up large writes into smaller ones, and the wrapper would need to deal with scheduler.
} kUseFastMixer = FastMixer_Static;
} kUseFastMixer = FastMixer_Static;


static uint32_t gScreenState; // incremented by 2 when screen state changes, bit 0 == 1 means "off"
                              // AudioFlinger::setParameters() updates, other threads read w/o lock

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


#ifdef ADD_BATTERY_DATA
#ifdef ADD_BATTERY_DATA
@@ -889,6 +892,13 @@ status_t AudioFlinger::setParameters(audio_io_handle_t ioHandle, const String8&
                mBtNrecIsOff = btNrecIsOff;
                mBtNrecIsOff = btNrecIsOff;
            }
            }
        }
        }
        String8 screenState;
        if (param.get(String8(AudioParameter::keyScreenState), screenState) == NO_ERROR) {
            bool isOff = screenState == "off";
            if (isOff != (gScreenState & 1)) {
                gScreenState = ((gScreenState & ~1) + 2) | isOff;
            }
        }
        return final_result;
        return final_result;
    }
    }


@@ -1501,6 +1511,7 @@ AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinge
        mMixerStatus(MIXER_IDLE),
        mMixerStatus(MIXER_IDLE),
        mMixerStatusIgnoringFastTracks(MIXER_IDLE),
        mMixerStatusIgnoringFastTracks(MIXER_IDLE),
        standbyDelay(AudioFlinger::mStandbyTimeInNsecs),
        standbyDelay(AudioFlinger::mStandbyTimeInNsecs),
        mScreenState(gScreenState),
        // index 0 is reserved for normal mixer's submix
        // index 0 is reserved for normal mixer's submix
        mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1)
        mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1)
{
{
@@ -2224,6 +2235,8 @@ AudioFlinger::MixerThread::MixerThread(const sp<AudioFlinger>& audioFlinger, Aud
        size_t numCounterOffers = 0;
        size_t numCounterOffers = 0;
        ssize_t index = monoPipe->negotiate(offers, 1, NULL, numCounterOffers);
        ssize_t index = monoPipe->negotiate(offers, 1, NULL, numCounterOffers);
        ALOG_ASSERT(index == 0);
        ALOG_ASSERT(index == 0);
        monoPipe->setAvgFrames((mScreenState & 1) ?
                (monoPipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
        mPipeSink = monoPipe;
        mPipeSink = monoPipe;


#ifdef TEE_SINK_FRAMES
#ifdef TEE_SINK_FRAMES
@@ -2686,6 +2699,16 @@ void AudioFlinger::PlaybackThread::threadLoop_write()
#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
        Tracer::traceBegin(ATRACE_TAG, "write");
        Tracer::traceBegin(ATRACE_TAG, "write");
#endif
#endif
        // update the setpoint when gScreenState changes
        uint32_t screenState = gScreenState;
        if (screenState != mScreenState) {
            mScreenState = screenState;
            MonoPipe *pipe = (MonoPipe *)mPipeSink.get();
            if (pipe != NULL) {
                pipe->setAvgFrames((mScreenState & 1) ?
                        (pipe->maxFrames() * 7) / 8 : mNormalFrameCount * 2);
            }
        }
        ssize_t framesWritten = mNormalSink->write(mMixBuffer, count);
        ssize_t framesWritten = mNormalSink->write(mMixBuffer, count);
#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
#if defined(ATRACE_TAG) && (ATRACE_TAG != ATRACE_TAG_NEVER)
        Tracer::traceEnd(ATRACE_TAG);
        Tracer::traceEnd(ATRACE_TAG);
+1 −0
Original line number Original line Diff line number Diff line
@@ -1119,6 +1119,7 @@ public:
        // For dumpsys
        // For dumpsys
        sp<NBAIO_Sink>          mTeeSink;
        sp<NBAIO_Sink>          mTeeSink;
        sp<NBAIO_Source>        mTeeSource;
        sp<NBAIO_Source>        mTeeSource;
        uint32_t                mScreenState;   // cached copy of gScreenState
    public:
    public:
        virtual     bool        hasFastMixer() const = 0;
        virtual     bool        hasFastMixer() const = 0;
        virtual     FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const
        virtual     FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const
Loading