From ba52753ff7255d9443dcc3e87a3ff56b14e6dcb2 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 27 Aug 2018 13:52:58 -0400 Subject: [PATCH 1/3] Scrub options don't need starting time --- src/AudioIO.cpp | 6 ++---- src/tracks/ui/Scrubbing.cpp | 4 +--- src/tracks/ui/Scrubbing.h | 4 ---- 3 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 2b2e41677..415088b2a 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -524,11 +524,10 @@ constexpr size_t TimeQueueGrainSize = 2000; struct AudioIO::ScrubState { - ScrubState(double t0, wxLongLong startClockMillis, + ScrubState(double t0, double rate, const ScrubbingOptions &options) : mRate(rate) - , mLastScrubTimeMillis(startClockMillis) , mStartTime( t0 ) { const double t1 = options.bySpeed ? 1.0 : t0; @@ -800,7 +799,7 @@ private: std::atomic mStopped { false }; Data mData; const double mRate; - wxLongLong mLastScrubTimeMillis; + wxLongLong mLastScrubTimeMillis{ ::wxGetLocalTimeMillis() }; struct Message { double end; ScrubbingOptions options; @@ -1958,7 +1957,6 @@ int AudioIO::StartStream(const TransportTracks &tracks, mScrubState = std::make_unique( mPlaybackSchedule.mT0, - scrubOptions.startClockTimeMillis, mRate, scrubOptions); mScrubDuration = 0; diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index dd4f43455..277eeec51 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -297,7 +297,6 @@ void Scrubber::MarkScrubStart( mScrubStartPosition = xx; ctb->UpdateStatusBar(mProject); - mOptions.startClockTimeMillis = ::wxGetLocalTimeMillis(); mCancelled = false; } @@ -424,7 +423,7 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx) } else // Wait to test again - mOptions.startClockTimeMillis = ::wxGetLocalTimeMillis(); + ; if (IsScrubbing()) { mLastScrubPosition = xx; @@ -462,7 +461,6 @@ bool Scrubber::StartSpeedPlay(double speed, double time0, double time1) AudioIOStartStreamOptions options(mProject->GetSpeedPlayOptions()); options.pScrubbingOptions = &mOptions; options.timeTrack = NULL; - mOptions.startClockTimeMillis = ::wxGetLocalTimeMillis(); mOptions.delay = (ScrubPollInterval_ms * 0.9 / 1000.0); mOptions.minSpeed = speed -0.01; mOptions.maxSpeed = speed +0.01; diff --git a/src/tracks/ui/Scrubbing.h b/src/tracks/ui/Scrubbing.h index cfb8a0960..2d1d2bef7 100644 --- a/src/tracks/ui/Scrubbing.h +++ b/src/tracks/ui/Scrubbing.h @@ -58,10 +58,6 @@ struct ScrubbingOptions { // this is the minimum amount of playback allowed at the maximum speed: double minStutterTime {}; - // Scrubbing needs the time of start of the mouse movement that began - // the scrub: - wxLongLong startClockTimeMillis { -1 }; - static double MaxAllowedScrubSpeed() { return 32.0; } // Is five octaves enough for your amusement? static double MinAllowedScrubSpeed() From e4e7a814c893ff68ed8016765b2e0639bbb34414 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 27 Aug 2018 15:04:45 -0400 Subject: [PATCH 2/3] FillBuffers won't quit too early priming the RingBuffer for scrub --- src/AudioIO.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 415088b2a..86244d3a6 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -777,7 +777,17 @@ private: }; struct Duration { - Duration (ScrubState &queue_) : queue(queue_) {} + Duration (ScrubState &queue_) : queue(queue_) + { + do { + clockTime = ::wxGetLocalTimeMillis(); + duration = static_cast( + queue.mRate * + (clockTime - queue.mLastScrubTimeMillis).ToDouble() + / 1000.0 + ); + } while( duration <= 0 && (::wxMilliSleep(1), true) ); + } ~Duration () { if(!cancelled) @@ -787,10 +797,8 @@ private: void Cancel() { cancelled = true; } ScrubState &queue; - const wxLongLong clockTime { ::wxGetLocalTimeMillis() }; - const sampleCount duration { static_cast - (queue.mRate * (clockTime - queue.mLastScrubTimeMillis).ToDouble() / 1000.0) - }; + wxLongLong clockTime; + sampleCount duration; bool cancelled { false }; }; From 9aad60d12c31ff6872731adbf78b5b41d3f7d2d5 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 27 Aug 2018 13:31:36 -0400 Subject: [PATCH 3/3] Make polling loop period slightly shorter than Audio thread loop... ... but we don't need to make it as precise, using steady_clock. Do this so that the Audio thread doesn't read the same polling message twice, halting the scrub. It's all right that it might miss one of the messages instead. --- src/AudioIO.cpp | 2 +- src/tracks/ui/Scrubbing.cpp | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 86244d3a6..251ffb614 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -1987,7 +1987,7 @@ int AudioIO::StartStream(const TransportTracks &tracks, // execute too much else if (mScrubState) { mOwningProject->GetScrubber().ContinueScrubbingPoll(); - wxMilliSleep( Scrubber::ScrubPollInterval_ms ); + wxMilliSleep( Scrubber::ScrubPollInterval_ms * 0.9 ); } else #endif diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index 277eeec51..1fe77ae11 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -51,7 +51,9 @@ enum { ScrubSpeedStepsPerOctave = 4, #endif - kOneSecondCountdown = 1000 / Scrubber::ScrubPollInterval_ms, + ScrubPollInterval_ms = 50, + + kOneSecondCountdown = 1000 / ScrubPollInterval_ms, }; static const double MinStutter = 0.2; @@ -632,7 +634,7 @@ void Scrubber::StartPolling() mpThread->Run(); #endif - mPoller->Start(ScrubPollInterval_ms); + mPoller->Start(ScrubPollInterval_ms * 0.9); } void Scrubber::StopPolling()