From 111d2c8673fd3b99251022911757a7094e378439 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 20 Aug 2018 11:20:46 -0400 Subject: [PATCH] Can specify a minimum to maintain in the playback RingBuffer... ... this may be more than the batch size used in ongoing playback. It is expected that this larger batch size is used only once when priming the queue before starting play. But then FillBuffers() may attempt to refill up to the minimum in case demand is outpacing supply. Thus the new number defines a "yellow zone" for the queue. --- src/AudioIO.cpp | 20 +++++++++++++++++--- src/AudioIO.h | 5 +++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 8845a7e1a..8561e3b79 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -2293,6 +2293,10 @@ bool AudioIO::AllocateBuffers( #endif Mixer::WarpOptions(mPlaybackSchedule.mTimeTrack); + mPlaybackQueueMinimum = mPlaybackSamplesToCopy; + mPlaybackQueueMinimum = + std::min( mPlaybackQueueMinimum, playbackBufferSize ); + for (unsigned int i = 0; i < mPlaybackTracks.size(); i++) { // Bug 1763 - We must fade in from zero to avoid a click on starting. @@ -2325,7 +2329,8 @@ bool AudioIO::AllocateBuffers( mPlaybackSchedule.mT0, endTime, 1, - mPlaybackSamplesToCopy, false, + std::max( mPlaybackSamplesToCopy, mPlaybackQueueMinimum ), + false, mRate, floatSample, false); mPlaybackMixers[i]->ApplyTrackGains(false); } @@ -3924,14 +3929,23 @@ void AudioIO::FillBuffers() // The exception is if we're at the end of the selected // region - then we should just fill the buffer. // + // May produce a larger amount when initially priming the buffer, or + // perhaps again later in play to avoid unerfilling the queue and falling + // behind the real-time demand on the consumer side in the callback. + auto nReady = GetCommonlyReadyPlayback(); + auto nNeeded = + mPlaybackQueueMinimum - std::min(mPlaybackQueueMinimum, nReady); + + // wxASSERT( nNeeded <= nAvailable ); + auto realTimeRemaining = mPlaybackSchedule.RealTimeRemaining(); if (nAvailable >= mPlaybackSamplesToCopy || (mPlaybackSchedule.PlayingStraight() && nAvailable / mRate >= realTimeRemaining)) { // Limit maximum buffer size (increases performance) - auto available = - std::min( nAvailable, mPlaybackSamplesToCopy ); + auto available = std::min( nAvailable, + std::max( nNeeded, mPlaybackSamplesToCopy ) ); // msmeyer: When playing a very short selection in looped // mode, the selection must be copied to the buffer multiple diff --git a/src/AudioIO.h b/src/AudioIO.h index a077fd279..c0e684354 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -720,7 +720,12 @@ private: double mSeek; double mPlaybackRingBufferSecs; double mCaptureRingBufferSecs; + + /// Preferred batch size for replenishing the playback RingBuffer size_t mPlaybackSamplesToCopy; + /// Occupancy of the queue we try to maintain, with bigger batches if needed + size_t mPlaybackQueueMinimum; + double mMinCaptureSecsToCopy; /// True if audio playback is paused bool mPaused;