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

Commit 05350c4d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "aaudio: write if there is room"

parents c93f9c26 8d4f0062
Loading
Loading
Loading
Loading
+20 −19
Original line number Diff line number Diff line
@@ -653,7 +653,7 @@ aaudio_result_t AudioStreamInternal::processData(void *buffer, int32_t numFrames
        // Should we block?
        if (timeoutNanoseconds == 0) {
            break; // don't block
        } else if (framesLeft > 0) {
        } else if (wakeTimeNanos != 0) {
            if (!mAudioEndpoint.isFreeRunning()) {
                // If there is software on the other end of the FIFO then it may get delayed.
                // So wake up just a little after we expect it to be ready.
@@ -712,37 +712,38 @@ void AudioStreamInternal::processTimestamp(uint64_t position, int64_t time) {

aaudio_result_t AudioStreamInternal::setBufferSize(int32_t requestedFrames) {
    int32_t adjustedFrames = requestedFrames;
    int32_t actualFrames = 0;
    int32_t maximumSize = getBufferCapacity();
    const int32_t maximumSize = getBufferCapacity() - mFramesPerBurst;
    // The buffer size can be set to zero.
    // This means that the callback may be called when the internal buffer becomes empty.
    // This will be fine on some devices in ideal circumstances and will result in the
    // lowest possible latency.
    // If there are glitches then they should be detected as XRuns and the size can be increased.
    static const int32_t minimumSize = 0;

    // Clip to minimum size so that rounding up will work better.
    if (adjustedFrames < 1) {
        adjustedFrames = 1;
    }
    adjustedFrames = std::max(minimumSize, adjustedFrames);

    if (adjustedFrames > maximumSize) {
        // Clip to maximum size.
    // Prevent arithmetic overflow by clipping before we round.
    if (adjustedFrames >= maximumSize) {
        adjustedFrames = maximumSize;
    } else {
        // Round to the next highest burst size.
        int32_t numBursts = (adjustedFrames + mFramesPerBurst - 1) / mFramesPerBurst;
        adjustedFrames = numBursts * mFramesPerBurst;
        // Rounding may have gone above maximum.
        if (adjustedFrames > maximumSize) {
            adjustedFrames = maximumSize;
        }
    }

    aaudio_result_t result = mAudioEndpoint.setBufferSizeInFrames(adjustedFrames, &actualFrames);
    if (result < 0) {
        return result;
    } else {
        return (aaudio_result_t) actualFrames;
    }
    // Clip against the actual size from the endpoint.
    int32_t actualFrames = 0;
    mAudioEndpoint.setBufferSizeInFrames(maximumSize, &actualFrames);
    // actualFrames should be <= maximumSize
    adjustedFrames = std::min(actualFrames, adjustedFrames);

    mBufferSizeInFrames = adjustedFrames;
    return (aaudio_result_t) adjustedFrames;
}

int32_t AudioStreamInternal::getBufferSize() const {
    return mAudioEndpoint.getBufferSizeInFrames();
    return mBufferSizeInFrames;
}

int32_t AudioStreamInternal::getBufferCapacity() const {
+3 −0
Original line number Diff line number Diff line
@@ -204,6 +204,9 @@ private:
    // Sometimes the hardware is operating with a different channel count from the app.
    // Then we require conversion in AAudio.
    int32_t                  mDeviceChannelCount = 0;

    int32_t                  mBufferSizeInFrames = 0; // local threshold to control latency

};

} /* namespace aaudio */
+7 −9
Original line number Diff line number Diff line
@@ -167,8 +167,10 @@ aaudio_result_t AudioStreamInternalPlay::processDataNow(void *buffer, int32_t nu
        ATRACE_INT("aaWrote", framesWritten);
    }

    // Sleep if there is too much data in the buffer.
    // Calculate an ideal time to wake up.
    if (wakeTimePtr != nullptr && framesWritten >= 0) {
    if (wakeTimePtr != nullptr
            && (mAudioEndpoint.getFullFramesAvailable() >= getBufferSize())) {
        // By default wake up a few milliseconds from now.  // TODO review
        int64_t wakeTime = currentNanoTime + (1 * AAUDIO_NANOS_PER_MILLISECOND);
        aaudio_stream_state_t state = getState();
@@ -184,14 +186,10 @@ aaudio_result_t AudioStreamInternalPlay::processDataNow(void *buffer, int32_t nu
                break;
            case AAUDIO_STREAM_STATE_STARTED:
            {
                // When do we expect the next read burst to occur?

                // Calculate frame position based off of the writeCounter because
                // the readCounter might have just advanced in the background,
                // causing us to sleep until a later burst.
                int64_t nextPosition = mAudioEndpoint.getDataWriteCounter() + mFramesPerBurst
                        - mAudioEndpoint.getBufferSizeInFrames();
                wakeTime = mClockModel.convertPositionToTime(nextPosition);
                // Sleep until the readCounter catches up and we only have
                // the getBufferSize() frames of data sitting in the buffer.
                int64_t nextReadPosition = mAudioEndpoint.getDataWriteCounter() - getBufferSize();
                wakeTime = mClockModel.convertPositionToTime(nextReadPosition);
            }
                break;
            default: