From 5627620b7885808bc251853dc683d829359695e8 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Mon, 24 Jun 2019 12:18:50 -0400 Subject: [PATCH] Remove dependency of AudioIO on Scrubbing.cpp ... ... though the demotion of the constant into AudioIO.h isn't wholly satisfactory and there is still the scrubbing queue in AudioIO --- src/AudioIO.cpp | 18 +++++------------- src/AudioIO.h | 2 ++ src/AudioIOBase.h | 6 ++++++ src/tracks/ui/Scrubbing.cpp | 23 +++++++++++++++++++++-- src/tracks/ui/Scrubbing.h | 4 +--- 5 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 859eb5e6e..de431c6d7 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -518,8 +518,6 @@ constexpr size_t TimeQueueGrainSize = 2000; #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT -#include "tracks/ui/Scrubbing.h" - #ifdef __WXGTK__ // Might #define this for a useful thing on Linux #undef REALTIME_ALSA_THREAD @@ -1704,17 +1702,11 @@ int AudioIO::StartStream(const TransportTracks &tracks, mAudioThreadShouldCallFillBuffersOnce = true; while( mAudioThreadShouldCallFillBuffersOnce ) { -#ifndef USE_SCRUB_THREAD - // Yuck, we either have to poll "by hand" when scrub polling doesn't - // work with a thread, or else yield to timer messages, but that would - // execute too much else - if (mScrubState) { - Scrubber::Get( *mOwningProject ).ContinueScrubbingPoll(); - wxMilliSleep( Scrubber::ScrubPollInterval_ms * 0.9 ); + auto interval = 50ull; + if (options.playbackStreamPrimer) { + interval = options.playbackStreamPrimer(); } - else -#endif - wxMilliSleep( 50 ); + wxMilliSleep( interval ); } if(mNumPlaybackChannels > 0 || mNumCaptureChannels > 0) { @@ -2544,7 +2536,7 @@ AudioThread::ExitCode AudioThread::Entry() { using Clock = std::chrono::steady_clock; auto loopPassStart = Clock::now(); - const auto interval = Scrubber::ScrubPollInterval_ms; + const auto interval = ScrubPollInterval_ms; // Set LoopActive outside the tests to avoid race condition gAudioIO->mAudioThreadFillBuffersLoopActive = true; diff --git a/src/AudioIO.h b/src/AudioIO.h index c5de9bd2b..215d76149 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -789,4 +789,6 @@ private: void StartStreamCleanup(bool bOnlyBuffers = false); }; +static constexpr unsigned ScrubPollInterval_ms = 50; + #endif diff --git a/src/AudioIOBase.h b/src/AudioIOBase.h index 96526696c..d72391546 100644 --- a/src/AudioIOBase.h +++ b/src/AudioIOBase.h @@ -16,6 +16,7 @@ Paul Licameli split from AudioIO.h #include #include +#include #include #include #include @@ -102,6 +103,11 @@ struct AudioIOStartStreamOptions // contents may get swapped with empty vector PRCrossfadeData *pCrossfadeData{}; + + // An unfortunate thing needed just to make scrubbing work on Linux when + // we can't use a separate polling thread. + // The return value is a number of milliseconds to sleep before calling again + std::function< unsigned long() > playbackStreamPrimer; }; ///\brief A singleton object supporting queries of the state of any active diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index e0ad1a4e6..1b28fd20f 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -56,8 +56,6 @@ enum { ScrubSpeedStepsPerOctave = 4, #endif - ScrubPollInterval_ms = 50, - kOneSecondCountdown = 1000 / ScrubPollInterval_ms, }; @@ -386,6 +384,16 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx) mSpeedPlaying = false; auto options = DefaultPlayOptions( *mProject ); + +#ifndef USE_SCRUB_THREAD + // Yuck, we either have to poll "by hand" when scrub polling doesn't + // work with a thread, or else yield to timer messages, but that would + // execute too much else + options.playbackStreamPrimer = [this](){ + ContinueScrubbingPoll(); + return ScrubPollInterval_ms; + }; +#endif options.pScrubbingOptions = &mOptions; options.envelope = nullptr; mOptions.delay = (ScrubPollInterval_ms / 1000.0); @@ -487,6 +495,17 @@ bool Scrubber::StartSpeedPlay(double speed, double time0, double time1) mDragging = false; auto options = DefaultSpeedPlayOptions( *mProject ); + +#ifndef USE_SCRUB_THREAD + // Yuck, we either have to poll "by hand" when scrub polling doesn't + // work with a thread, or else yield to timer messages, but that would + // execute too much else + options.playbackStreamPrimer = [this](){ + ContinueScrubbingPoll(); + return ScrubPollInterval_ms; + }; +#endif + options.pScrubbingOptions = &mOptions; options.envelope = nullptr; mOptions.delay = (ScrubPollInterval_ms / 1000.0); diff --git a/src/tracks/ui/Scrubbing.h b/src/tracks/ui/Scrubbing.h index f32de50e4..62e03883c 100644 --- a/src/tracks/ui/Scrubbing.h +++ b/src/tracks/ui/Scrubbing.h @@ -40,9 +40,7 @@ class Scrubber final : public wxEvtHandler , public ClientData::Base { -public: - static constexpr unsigned ScrubPollInterval_ms = 50; - +public: static Scrubber &Get( AudacityProject &project ); static const Scrubber &Get( const AudacityProject &project );