From 03def8dbafe31db476c3345c8bd9b22ae738e221 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sat, 8 Sep 2018 22:24:11 -0400 Subject: [PATCH] Bug1967: scrub shouldn't be clicky... ... And this further simplifies the use of the clock. Rely on the regularity of spacing between calls to FillBuffers at commit a62cf53 --- src/AudioIO.cpp | 72 ++++++++++--------------------------- src/tracks/ui/Scrubbing.cpp | 4 +-- 2 files changed, 20 insertions(+), 56 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index c59b13c20..03972d700 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -541,49 +541,40 @@ struct AudioIO::ScrubState } void Get(sampleCount &startSample, sampleCount &endSample, - sampleCount &duration) + sampleCount inDuration, sampleCount &duration) { // Called by the thread that calls AudioIO::FillBuffers startSample = endSample = duration = -1LL; - Duration dd { *this }; - if (dd.duration <= 0) - return; Message message( mMessage.Read() ); if ( !mStarted ) { + // Make some initial silence const sampleCount s0 { llrint( mRate * std::max( message.options.minTime, std::min( message.options.maxTime, mStartTime ) ) ) }; - const sampleCount s1 ( message.options.bySpeed - ? s0.as_double() + - llrint(dd.duration.as_double() * message.end) // end is a speed - : llrint(message.end * mRate) // end is a time - ); - auto actualDuration = std::max(sampleCount{1}, dd.duration); - auto success = mData.Init(nullptr, - s0, s1, actualDuration, message.options, mRate); - if ( !success ) { - // If not, we can wait to enqueue again later - dd.Cancel(); - return; - } + mData.mS0 = mData.mS1 = s0; + mData.mGoal = -1; + mData.mDuration = duration = inDuration; + mData.mSilence = 0; mStarted = true; } else { Data newData; - auto previous = &mData; + inDuration += mAccumulatedSeekDuration; // Use the previous end as NEW start. - const auto s0 = previous->mS1; + const auto s0 = mData.mS1; const sampleCount s1 ( message.options.bySpeed ? s0.as_double() + - lrint(dd.duration.as_double() * message.end) // end is a speed + lrint(inDuration.as_double() * message.end) // end is a speed : lrint(message.end * mRate) // end is a time ); auto success = - newData.Init(previous, s0, s1, dd.duration, message.options, mRate); - if ( !success ) { - dd.Cancel(); + newData.Init(mData, s0, s1, inDuration, message.options, mRate); + if (success) + mAccumulatedSeekDuration = 0; + else { + mAccumulatedSeekDuration += inDuration; return; } mData = newData; @@ -639,10 +630,11 @@ private: , mSilence(0) {} - bool Init(Data *previous, sampleCount s0, sampleCount s1, + bool Init(Data &rPrevious, sampleCount s0, sampleCount s1, sampleCount duration, const ScrubbingOptions &options, double rate) { + auto previous = &rPrevious; auto origDuration = duration; mSilence = 0; @@ -665,7 +657,6 @@ private: adjustedSpeed = true; } else if (!adjustStart && - previous && previous->mGoal >= 0 && previous->mGoal == s1) { @@ -776,39 +767,11 @@ private: sampleCount mSilence; }; - using Clock = std::chrono::steady_clock; - - struct Duration { - Duration (ScrubState &queue_) : queue(queue_) - { - do { - clockTime = Clock::now(); - using Seconds = std::chrono::duration; - const auto elapsed = std::chrono::duration_cast( - clockTime - queue.mLastScrubTime); - duration = static_cast( queue.mRate * elapsed.count() ); - } while( duration <= 0 && (::wxMilliSleep(1), true) ); - } - ~Duration () - { - if(!cancelled) - queue.mLastScrubTime = clockTime; - } - - void Cancel() { cancelled = true; } - - ScrubState &queue; - Clock::time_point clockTime; - sampleCount duration; - bool cancelled { false }; - }; - double mStartTime; bool mStarted{ false }; std::atomic mStopped { false }; Data mData; const double mRate; - Clock::time_point mLastScrubTime { Clock::now() }; struct Message { Message() = default; Message(const Message&) = default; @@ -816,6 +779,7 @@ private: ScrubbingOptions options; }; MessageBuffer mMessage; + sampleCount mAccumulatedSeekDuration{}; }; #endif @@ -3927,7 +3891,7 @@ void AudioIO::FillBuffers() { sampleCount startSample, endSample; mScrubState->Get( - startSample, endSample, mScrubDuration); + startSample, endSample, available, mScrubDuration); if (mScrubDuration < 0) { // Can't play anything diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index a5d1033c2..b10df55da 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -364,7 +364,7 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx) AudioIOStartStreamOptions options(mProject->GetDefaultPlayOptions()); options.pScrubbingOptions = &mOptions; options.timeTrack = NULL; - mOptions.delay = (ScrubPollInterval_ms * 0.9 / 1000.0); + mOptions.delay = (ScrubPollInterval_ms / 1000.0); mOptions.isPlayingAtSpeed = false; mOptions.minSpeed = 0.0; #ifdef USE_TRANSCRIPTION_TOOLBAR @@ -470,7 +470,7 @@ bool Scrubber::StartSpeedPlay(double speed, double time0, double time1) AudioIOStartStreamOptions options(mProject->GetSpeedPlayOptions()); options.pScrubbingOptions = &mOptions; options.timeTrack = NULL; - mOptions.delay = (ScrubPollInterval_ms * 0.9 / 1000.0); + mOptions.delay = (ScrubPollInterval_ms / 1000.0); mOptions.minSpeed = speed -0.01; mOptions.maxSpeed = speed +0.01;