Loading media/libaaudio/src/client/AudioStreamInternal.cpp +20 −19 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 { Loading media/libaaudio/src/client/AudioStreamInternal.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading media/libaaudio/src/client/AudioStreamInternalPlay.cpp +7 −9 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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: Loading Loading
media/libaaudio/src/client/AudioStreamInternal.cpp +20 −19 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 { Loading
media/libaaudio/src/client/AudioStreamInternal.h +3 −0 Original line number Diff line number Diff line Loading @@ -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 */ Loading
media/libaaudio/src/client/AudioStreamInternalPlay.cpp +7 −9 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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: Loading