From cd3a4b8e68ba050a9d1c384f235b3d5f10ccd903 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Wed, 3 Feb 2021 13:22:15 -0500 Subject: [PATCH 1/6] We no longer need an imitation of std::optional --- libraries/lib-utility/MemoryX.h | 128 ------------------------------- src/FreqWindow.cpp | 2 +- src/LangChoice.cpp | 1 + src/LogWindow.cpp | 2 +- src/ProjectFileManager.cpp | 4 +- src/Sequence.cpp | 3 +- src/ShuttleGui.cpp | 1 + src/ShuttleGui.h | 5 +- src/commands/AudacityCommand.cpp | 1 + src/commands/CommandType.h | 4 +- src/effects/FindClipping.cpp | 2 +- src/effects/VST/VSTEffect.cpp | 2 +- src/effects/nyquist/Nyquist.cpp | 2 +- src/menus/TrackMenus.cpp | 2 +- src/prefs/TracksPrefs.cpp | 1 + src/widgets/MultiDialog.cpp | 1 + src/widgets/OverlayPanel.cpp | 4 +- 17 files changed, 24 insertions(+), 141 deletions(-) diff --git a/libraries/lib-utility/MemoryX.h b/libraries/lib-utility/MemoryX.h index f421ffd75ec2..6b5574e03fd3 100644 --- a/libraries/lib-utility/MemoryX.h +++ b/libraries/lib-utility/MemoryX.h @@ -128,134 +128,6 @@ class ArraysOf : public ArrayOf> } }; -/** - \class Optional - \brief Like a smart pointer, allows for object to not exist (nullptr) - \brief emulating some of std::optional of C++17 - - template class Optional - Can be used for monomorphic objects that are stack-allocable, but only conditionally constructed. - You might also use it as a member. - Initialize with emplace(), then use like a smart pointer, - with *, ->, reset(), or in if() - */ - -template -class Optional { -public: - - using value_type = X; - - // Construct as NULL - Optional() {} - - // Supply the copy and move, so you might use this as a class member too - Optional(const Optional &that) - { - if (that) - emplace(*that); - } - - Optional& operator= (const Optional &that) - { - if (this != &that) { - if (that) - emplace(*that); - else - reset(); - } - return *this; - } - - Optional(Optional &&that) - { - if (that) - emplace(::std::move(*that)); - } - - Optional& operator= (Optional &&that) - { - if (this != &that) { - if (that) - emplace(::std::move(*that)); - else - reset(); - } - return *this; - } - - /// Make an object in the buffer, passing constructor arguments, - /// but destroying any previous object first - /// Note that if constructor throws, we remain in a consistent - /// NULL state -- giving exception safety but only weakly - /// (previous value was lost if present) - template - X& emplace(Args&&... args) - { - // Lose any old value - reset(); - // emplace NEW value - pp = safenew(address()) X(std::forward(args)...); - return **this; - } - - // Destroy any object that was built in it - ~Optional() - { - reset(); - } - - // Pointer-like operators - - /// Dereference, with the usual bad consequences if NULL - X &operator* () const - { - return *pp; - } - - X *operator-> () const - { - return pp; - } - - void reset() - { - if (pp) - pp->~X(), pp = nullptr; - } - - // So you can say if(ptr) - explicit operator bool() const - { - return pp != nullptr; - } - - bool has_value() const - { - return pp != nullptr; - } - -private: - X* address() - { - return reinterpret_cast(&storage); - } - - // Data -#if 0 - typename ::std::aligned_storage< - sizeof(X) - // , alignof(X) // Not here yet in all compilers - >::type storage{}; -#else - union { - double d; - char storage[sizeof(X)]; - }; -#endif - X* pp{ nullptr }; -}; - /** A deleter for pointers obtained with malloc */ diff --git a/src/FreqWindow.cpp b/src/FreqWindow.cpp index 71d6e62cb810..1c4bb249b5c1 100644 --- a/src/FreqWindow.cpp +++ b/src/FreqWindow.cpp @@ -1026,7 +1026,7 @@ void FrequencyPlotDialog::Recalc() // controls while the plot was being recalculated. This doesn't appear to be necessary // so just use the top level window instead. { - Optional blocker; + std::optional blocker; if (IsShown()) blocker.emplace(this); wxYieldIfNeeded(); diff --git a/src/LangChoice.cpp b/src/LangChoice.cpp index f313147a38e5..23d0af112e36 100644 --- a/src/LangChoice.cpp +++ b/src/LangChoice.cpp @@ -17,6 +17,7 @@ of languages for Audacity. #include "LangChoice.h" +#include "MemoryX.h" #include #include diff --git a/src/LogWindow.cpp b/src/LogWindow.cpp index c38a742ee5d3..60ee53c3b5f9 100644 --- a/src/LogWindow.cpp +++ b/src/LogWindow.cpp @@ -49,7 +49,7 @@ struct LogWindowUpdater : public PrefsListener void UpdatePrefs() override; }; // Unique PrefsListener can't be statically constructed before the application -// object initializes, so use Optional +// object initializes, so use optional std::optional pUpdater; void OnCloseWindow(wxCloseEvent & e); diff --git a/src/ProjectFileManager.cpp b/src/ProjectFileManager.cpp index 9af1a7a04773..ac4b7a751696 100644 --- a/src/ProjectFileManager.cpp +++ b/src/ProjectFileManager.cpp @@ -56,6 +56,8 @@ Paul Licameli split from AudacityProject.cpp #include "HelpText.h" +#include + static const AudacityProject::AttachedObjects::RegisteredFactory sFileManagerKey{ []( AudacityProject &parent ){ auto result = std::make_shared< ProjectFileManager >( parent ); @@ -322,7 +324,7 @@ bool ProjectFileManager::DoSave(const FilePath & fileName, const bool fromSaveAs // End of confirmations // Always save a backup of the original project file - Optional pBackupProject; + std::optional pBackupProject; if (fromSaveAs && wxFileExists(fileName)) { pBackupProject.emplace(projectFileIO, fileName); diff --git a/src/Sequence.cpp b/src/Sequence.cpp index b518a79a557b..395fe1ebc3c4 100644 --- a/src/Sequence.cpp +++ b/src/Sequence.cpp @@ -32,6 +32,7 @@ #include "Sequence.h" #include +#include #include #include @@ -1804,7 +1805,7 @@ void Sequence::ConsistencyCheck { // Construction of the exception at the appropriate line of the function // gives a little more discrimination - Optional ex; + std::optional ex; unsigned int numBlocks = mBlock.size(); diff --git a/src/ShuttleGui.cpp b/src/ShuttleGui.cpp index 15380498c212..3c22dacdad91 100644 --- a/src/ShuttleGui.cpp +++ b/src/ShuttleGui.cpp @@ -98,6 +98,7 @@ for registering for changes. +#include "MemoryX.h" #include "Prefs.h" #include "ShuttlePrefs.h" #include "Theme.h" diff --git a/src/ShuttleGui.h b/src/ShuttleGui.h index 2ffc4af1ff57..c30db5e5a3b1 100644 --- a/src/ShuttleGui.h +++ b/src/ShuttleGui.h @@ -19,13 +19,14 @@ #include #include // to inherit -#include "MemoryX.h" #include // for wxLIST_FORMAT_LEFT #include "Prefs.h" #include "WrappedType.h" #include "ComponentInterfaceSymbol.h" +#include + class ChoiceSetting; class wxArrayStringEx; @@ -572,7 +573,7 @@ class AUDACITY_DLL_API ShuttleGuiBase /* not final */ std::vector mRadioSymbols; wxString mRadioSettingName; /// The setting controlled by a group. - Optional mRadioValue; /// The wrapped value associated with the active radio button. + std::optional mRadioValue; /// The wrapped value associated with the active radio button. int mRadioCount; /// The index of this radio item. -1 for none. wxString mRadioValueString; /// Unwrapped string value. wxRadioButton * DoAddRadioButton( diff --git a/src/commands/AudacityCommand.cpp b/src/commands/AudacityCommand.cpp index 2f3f558db8cb..c229cde3b2f4 100644 --- a/src/commands/AudacityCommand.cpp +++ b/src/commands/AudacityCommand.cpp @@ -21,6 +21,7 @@ ShuttleGui. #include "AudacityCommand.h" +#include "MemoryX.h" #include "CommandContext.h" diff --git a/src/commands/CommandType.h b/src/commands/CommandType.h index f44feebd430e..f36d667e2c23 100644 --- a/src/commands/CommandType.h +++ b/src/commands/CommandType.h @@ -39,11 +39,13 @@ class CommandOutputTargets; class CommandSignature; class wxString; +#include + class AUDACITY_DLL_API OldStyleCommandType : public AudacityCommand { private: ComponentInterfaceSymbol mSymbol; - Optional mSignature; + std::optional mSignature; public: OldStyleCommandType(); diff --git a/src/effects/FindClipping.cpp b/src/effects/FindClipping.cpp index e653cf0fb3c0..c110fd0343c8 100644 --- a/src/effects/FindClipping.cpp +++ b/src/effects/FindClipping.cpp @@ -111,7 +111,7 @@ bool EffectFindClipping::SetAutomationParameters(CommandParameters & parms) bool EffectFindClipping::Process() { std::shared_ptr addedTrack; - Optional modifiedTrack; + std::optional modifiedTrack; const wxString name{ _("Clipping") }; auto clt = *inputTracks()->Any< const LabelTrack >().find_if( diff --git a/src/effects/VST/VSTEffect.cpp b/src/effects/VST/VSTEffect.cpp index 3f8ce5c76bda..46113ef1243f 100644 --- a/src/effects/VST/VSTEffect.cpp +++ b/src/effects/VST/VSTEffect.cpp @@ -525,7 +525,7 @@ unsigned VSTEffectsModule::DiscoverPluginsAtPath( wxString effectIDs = wxT("0;"); wxStringTokenizer effectTzr(effectIDs, wxT(";")); - Optional progress{}; + std::optional progress{}; size_t idCnt = 0; size_t idNdx = 0; diff --git a/src/effects/nyquist/Nyquist.cpp b/src/effects/nyquist/Nyquist.cpp index 11085d4033a9..9ae52613bf76 100644 --- a/src/effects/nyquist/Nyquist.cpp +++ b/src/effects/nyquist/Nyquist.cpp @@ -826,7 +826,7 @@ bool NyquistEffect::Process() XO("Nyquist Error") ); } - Optional> pRange; + std::optional> pRange; if (!bOnePassTool) pRange.emplace(mOutputTracks->Selected< WaveTrack >() + &Track::IsLeader); diff --git a/src/menus/TrackMenus.cpp b/src/menus/TrackMenus.cpp index c547f3f28364..549404158f88 100644 --- a/src/menus/TrackMenus.cpp +++ b/src/menus/TrackMenus.cpp @@ -366,7 +366,7 @@ class ASAProgress final : public SAProgress { long mTotalCells; // how many matrix cells? long mCellCount; // how many cells so far? long mPrevCellCount; // cell_count last reported with Update() - Optional mProgress; + std::optional mProgress; #ifdef COLLECT_TIMING_DATA FILE *mTimeFile; wxDateTime mStartTime; diff --git a/src/prefs/TracksPrefs.cpp b/src/prefs/TracksPrefs.cpp index 597a0ae27e0b..3aad71abe4ac 100644 --- a/src/prefs/TracksPrefs.cpp +++ b/src/prefs/TracksPrefs.cpp @@ -19,6 +19,7 @@ #include "TracksPrefs.h" +#include "MemoryX.h" //#include //#include diff --git a/src/widgets/MultiDialog.cpp b/src/widgets/MultiDialog.cpp index 4d99ec8723d5..eb10c94ce597 100644 --- a/src/widgets/MultiDialog.cpp +++ b/src/widgets/MultiDialog.cpp @@ -18,6 +18,7 @@ #include "MultiDialog.h" +#include "MemoryX.h" #include "../ShuttleGui.h" diff --git a/src/widgets/OverlayPanel.cpp b/src/widgets/OverlayPanel.cpp index 73c7a76c5c0e..afea7dbaa695 100644 --- a/src/widgets/OverlayPanel.cpp +++ b/src/widgets/OverlayPanel.cpp @@ -10,8 +10,8 @@ #include "OverlayPanel.h" #include "Overlay.h" -#include "MemoryX.h" #include +#include #include OverlayPanel::OverlayPanel(wxWindow * parent, wxWindowID id, @@ -99,7 +99,7 @@ void OverlayPanel::DrawOverlays(bool repaint_all, wxDC *pDC) } while (!done); } - Optional myDC; + std::optional myDC; auto &dc = pDC ? *pDC : (myDC.emplace(this), *myDC); // Erase From 9e9d82aa238afda736ba40349fd474de45aec947 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sun, 10 May 2020 12:06:33 -0400 Subject: [PATCH 2/6] Simplify with _t and _v names from newer versions of std:: --- libraries/lib-files/wxFileNameWrapper.h | 2 +- libraries/lib-math/SampleCount.cpp | 2 +- .../lib-registries/AttachedVirtualFunction.h | 2 +- libraries/lib-registries/ClientData.h | 8 +-- libraries/lib-string-utils/ToChars.cpp | 4 +- libraries/lib-strings/Identifier.h | 4 +- libraries/lib-track/Track.h | 56 ++++++++----------- src/ShuttleGui.h | 14 ++--- 8 files changed, 41 insertions(+), 51 deletions(-) diff --git a/libraries/lib-files/wxFileNameWrapper.h b/libraries/lib-files/wxFileNameWrapper.h index 078532c3d58a..7683efc010f1 100644 --- a/libraries/lib-files/wxFileNameWrapper.h +++ b/libraries/lib-files/wxFileNameWrapper.h @@ -38,7 +38,7 @@ class wxFileNameWrapper : public wxFileName // Awful hack number 1 makes gcc 5 choke enum : size_t { Size = sizeof(*this) }; // Do it bitwise. - // std::aligned_storage::type buffer; + // std::aligned_storage_t buffer; char buffer[Size]; memcpy(&buffer, this, Size); memcpy(this, &that, Size); diff --git a/libraries/lib-math/SampleCount.cpp b/libraries/lib-math/SampleCount.cpp index 98677a188c86..31230f0dd476 100644 --- a/libraries/lib-math/SampleCount.cpp +++ b/libraries/lib-math/SampleCount.cpp @@ -16,7 +16,7 @@ size_t sampleCount::as_size_t() const { wxASSERT(value >= 0); - wxASSERT(static_cast::type>(value) <= std::numeric_limits::max()); + wxASSERT(static_cast>(value) <= std::numeric_limits::max()); return value; } diff --git a/libraries/lib-registries/AttachedVirtualFunction.h b/libraries/lib-registries/AttachedVirtualFunction.h index 9374ecb01d25..c7685f3b041e 100644 --- a/libraries/lib-registries/AttachedVirtualFunction.h +++ b/libraries/lib-registries/AttachedVirtualFunction.h @@ -189,7 +189,7 @@ class AttachedVirtualFunction // Check that inheritance is correct static_assert( - std::is_base_of< typename Overridden::Object, Object >::value, + std::is_base_of_v< typename Overridden::Object, Object >, "overridden class must be a base of the overriding class" ); diff --git a/libraries/lib-registries/ClientData.h b/libraries/lib-registries/ClientData.h index 1cdb4b00bc86..9b274ceb0c18 100644 --- a/libraries/lib-registries/ClientData.h +++ b/libraries/lib-registries/ClientData.h @@ -315,8 +315,8 @@ class Site //! @copydoc Get /*! const overload returns const references only. */ template< typename Subclass = const ClientData > - auto Get( const RegisteredFactory &key ) const -> typename - std::enable_if< std::is_const< Subclass >::value, Subclass & >::type + auto Get( const RegisteredFactory &key ) const -> + std::enable_if_t< std::is_const< Subclass >::value, Subclass & > { auto data = GetData(); return DoGet< Subclass >( data, key ); @@ -339,8 +339,8 @@ class Site //! @copydoc Find /*! const overload returns pointers to const only. */ template< typename Subclass = const ClientData > - auto Find( const RegisteredFactory &key ) const -> typename - std::enable_if< std::is_const< Subclass >::value, Subclass * >::type + auto Find( const RegisteredFactory &key ) const -> + std::enable_if_t< std::is_const< Subclass >::value, Subclass * > { auto data = GetData(); return DoFind< Subclass >( data, key ); diff --git a/libraries/lib-string-utils/ToChars.cpp b/libraries/lib-string-utils/ToChars.cpp index e60251262d5a..6818d8997d53 100644 --- a/libraries/lib-string-utils/ToChars.cpp +++ b/libraries/lib-string-utils/ToChars.cpp @@ -336,8 +336,8 @@ template boundaries compute_boundaries(FloatType value) constexpr std::uint64_t kHiddenBit = std::uint64_t { 1 } << (kPrecision - 1); // = 2^(p-1) - using bits_type = typename std::conditional< - kPrecision == 24, std::uint32_t, std::uint64_t>::type; + using bits_type = std::conditional_t< + kPrecision == 24, std::uint32_t, std::uint64_t>; const std::uint64_t bits = reinterpret_bits(value); const std::uint64_t E = bits >> (kPrecision - 1); diff --git a/libraries/lib-strings/Identifier.h b/libraries/lib-strings/Identifier.h index 30f2de251ad4..22a85a3a3bf9 100644 --- a/libraries/lib-strings/Identifier.h +++ b/libraries/lib-strings/Identifier.h @@ -157,7 +157,7 @@ template< typename Tag1, typename Tag2, bool b1, bool b2 > inline bool operator == ( const TaggedIdentifier< Tag1, b1 > &x, const TaggedIdentifier< Tag2, b2 > &y ) { - static_assert( std::is_same< Tag1, Tag2 >::value && b1 == b2, + static_assert( std::is_same_v< Tag1, Tag2 > && b1 == b2, "TaggedIdentifiers with different tags or sensitivity are not comparable" ); // This test should be eliminated at compile time: if ( b1 ) @@ -175,7 +175,7 @@ template< typename Tag1, typename Tag2, bool b1, bool b2 > inline bool operator < ( const TaggedIdentifier< Tag1, b1 > &x, const TaggedIdentifier< Tag2, b2 > &y ) { - static_assert( std::is_same< Tag1, Tag2 >::value && b1 == b2, + static_assert( std::is_same_v< Tag1, Tag2 > && b1 == b2, "TaggedIdentifiers with different tags or sensitivity are not comparable" ); // This test should be eliminated at compile time: if ( b1 ) diff --git a/libraries/lib-track/Track.h b/libraries/lib-track/Track.h index 2b882fb5698e..38b3e11e2d5d 100644 --- a/libraries/lib-track/Track.h +++ b/libraries/lib-track/Track.h @@ -281,10 +281,10 @@ class TRACK_API Track /* not final */ } template - inline auto SharedPointer() const -> typename - std::enable_if< - std::is_const::value, std::shared_ptr - >::type + inline auto SharedPointer() const -> + std::enable_if_t< + std::is_const_v, std::shared_ptr + > { // shared_from_this is injected into class scope by base class // std::enable_shared_from_this @@ -643,7 +643,7 @@ class TRACK_API Track /* not final */ //! Whether upcast of ArgumentType* to first BaseClass* works static constexpr bool Compatible = - std::is_base_of::value; + std::is_base_of_v; //! undefined function used in decltype only to compute a type, using other overloads template< typename Function, typename ...Functions > static auto test() @@ -928,8 +928,7 @@ template This overload for const pointers can cast only to other const pointer types. */ template inline std::enable_if_t< - std::is_pointer_v && - std::is_const_v< std::remove_pointer_t< T > >, + std::is_pointer_v && std::is_const_v< std::remove_pointer_t< T > >, T > track_cast(const Track *track) @@ -959,15 +958,8 @@ template < { public: //! Type of predicate taking pointer to const TrackType - /*! @todo C++14: simplify away ::type */ using FunctionType = std::function< bool( - typename std::add_pointer< - typename std::add_const< - typename std::remove_pointer< - TrackType - >::type - >::type - >::type + std::add_pointer_t< std::add_const_t< std::remove_pointer_t > > ) >; //! Constructor, usually not called directly except by methods of TrackList @@ -999,12 +991,12 @@ template < satisfies the type constraint, or to the end */ template < typename TrackType2 > auto Filter() const - -> typename std::enable_if< - std::is_base_of< TrackType, TrackType2 >::value && - (!std::is_const::value || - std::is_const::value), + -> std::enable_if_t< + std::is_base_of_v< TrackType, TrackType2 > && + (!std::is_const_v || + std::is_const_v), TrackIter< TrackType2 > - >::type + > { return { this->mBegin, this->mIter, this->mEnd, this->mPred }; } @@ -1373,9 +1365,9 @@ class TRACK_API TrackList final /*! const overload will only produce iterators over const TrackType */ template < typename TrackType = const Track > auto Find(const Track *pTrack) const - -> typename std::enable_if< std::is_const::value, + -> std::enable_if_t< std::is_const_v, TrackIter< TrackType > - >::type + > { if (!pTrack || pTrack->GetOwner().get() != this) return EndIterator(); @@ -1406,9 +1398,9 @@ class TRACK_API TrackList final template < typename TrackType = const Track > auto Any() const - -> typename std::enable_if< std::is_const::value, + -> std::enable_if_t< std::is_const_v, TrackIterRange< TrackType > - >::type + > { return Tracks< TrackType >(); } @@ -1423,9 +1415,9 @@ class TRACK_API TrackList final template < typename TrackType = const Track > auto Selected() const - -> typename std::enable_if< std::is_const::value, + -> std::enable_if_t< std::is_const_v, TrackIterRange< TrackType > - >::type + > { return Tracks< TrackType >( &Track::IsSelected ); } @@ -1440,9 +1432,9 @@ class TRACK_API TrackList final template < typename TrackType = const Track > auto Leaders() const - -> typename std::enable_if< std::is_const::value, + -> std::enable_if_t< std::is_const_v, TrackIterRange< TrackType > - >::type + > { return Tracks< TrackType >( &Track::IsLeader ); } @@ -1457,9 +1449,9 @@ class TRACK_API TrackList final template < typename TrackType = const Track > auto SelectedLeaders() const - -> typename std::enable_if< std::is_const::value, + -> std::enable_if_t< std::is_const_v, TrackIterRange< TrackType > - >::type + > { return Tracks< TrackType >( &Track::IsSelectedLeader ); } @@ -1601,9 +1593,9 @@ class TRACK_API TrackList final typename TrackIterRange< TrackType >::iterator::FunctionType > auto Tracks( const Pred &pred = {} ) const - -> typename std::enable_if< std::is_const::value, + -> std::enable_if_t< std::is_const_v, TrackIterRange< TrackType > - >::type + > { auto b = const_cast(this)->getBegin(); auto e = const_cast(this)->getEnd(); diff --git a/src/ShuttleGui.h b/src/ShuttleGui.h index c30db5e5a3b1..75df6d0971b9 100644 --- a/src/ShuttleGui.h +++ b/src/ShuttleGui.h @@ -176,10 +176,9 @@ struct Item { wxEventTypeTag eventType, void (Handler::*func)(Argument&) ) && - -> typename std::enable_if< - std::is_base_of::value, - Item&& - >::type + -> std::enable_if_t< + std::is_base_of_v, + Item&& > { mRootConnections.push_back({ eventType, @@ -701,10 +700,9 @@ class AUDACITY_DLL_API ShuttleGui /* not final */ : public ShuttleGuiBase wxEventTypeTag eventType, void (Handler::*func)(Argument&) ) - -> typename std::enable_if< - std::is_base_of::value, - ShuttleGui& - >::type + -> std::enable_if_t< + std::is_base_of_v, + ShuttleGui& > { std::move( mItem ).ConnectRoot( eventType, func ); return *this; From b7f380b18c7a06584de372a828adcd9c10e005ac Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 17 Dec 2021 12:03:58 -0500 Subject: [PATCH 3/6] Use std::this_thread::sleep_for --- libraries/lib-audio-devices/AudioIOBase.h | 4 +-- src/AudacityApp.cpp | 3 ++- src/AudioIO.cpp | 30 +++++++++++++++-------- src/CrashReport.cpp | 3 ++- src/DBConnection.cpp | 3 ++- src/ProjectFileIO.cpp | 6 +++-- src/TimerRecordDialog.cpp | 10 +++++--- src/TransportUtilities.cpp | 10 +++++--- src/commands/ScreenshotCommand.cpp | 29 +++++++++++++--------- src/effects/Effect.cpp | 7 ++++-- src/effects/ladspa/LadspaEffect.cpp | 4 ++- src/export/ExportCL.cpp | 5 +++- src/menus/TransportMenus.cpp | 4 ++- src/prefs/PrefsDialog.cpp | 8 ++++-- src/toolbars/DeviceToolBar.cpp | 8 ++++-- src/tracks/ui/Scrubbing.cpp | 4 ++- 16 files changed, 92 insertions(+), 46 deletions(-) diff --git a/libraries/lib-audio-devices/AudioIOBase.h b/libraries/lib-audio-devices/AudioIOBase.h index 291d0539be5c..5de86cd61088 100644 --- a/libraries/lib-audio-devices/AudioIOBase.h +++ b/libraries/lib-audio-devices/AudioIOBase.h @@ -11,10 +11,8 @@ Paul Licameli split from AudioIO.h #ifndef __AUDACITY_AUDIO_IO_BASE__ #define __AUDACITY_AUDIO_IO_BASE__ - - - #include +#include #include #include #include diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index beef426adee7..b5fe7368741b 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -1905,7 +1905,8 @@ bool AudacityApp::CreateSingleInstanceChecker(const wxString &dir) return false; } - wxMilliSleep(10); + using namespace std::chrono; + std::this_thread::sleep_for(10ms); } // There is another copy of Audacity running. Force quit. diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 9a10da80dbf2..658d9f4f882e 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -631,7 +631,8 @@ bool AudioIO::StartPortAudioStream(const AudioIOStartStreamOptions &options, break; } wxLogDebug("Attempt %u to open capture stream failed with: %d", 1 + tries, mLastPaError); - wxMilliSleep(1000); + using namespace std::chrono; + std::this_thread::sleep_for(1s); } @@ -775,8 +776,10 @@ int AudioIO::StartStream(const TransportTracks &tracks, if (mPortStreamV19) { StopStream(); - while(mPortStreamV19) - wxMilliSleep( 50 ); + while(mPortStreamV19) { + using namespace std::chrono; + std::this_thread::sleep_for(50ms); + } } #ifdef __WXGTK__ @@ -975,7 +978,8 @@ int AudioIO::StartStream(const TransportTracks &tracks, if (options.playbackStreamPrimer) { interval = options.playbackStreamPrimer(); } - wxMilliSleep( interval ); + using namespace std::chrono; + std::this_thread::sleep_for(milliseconds{interval}); } if(mNumPlaybackChannels > 0 || mNumCaptureChannels > 0) { @@ -1353,8 +1357,10 @@ void AudioIO::StopStream() // If we can gracefully fade out in 200ms, with the faded-out play buffers making it through // the sound card, then do so. If we can't, don't wait around. Just stop quickly and accept // there will be a click. - if( mbMicroFades && (latency < 150 )) - wxMilliSleep( latency + 50); + if( mbMicroFades && (latency < 150 )) { + using namespace std::chrono; + std::this_thread::sleep_for(milliseconds{latency + 50}); + } } wxMutexLocker locker(mSuspendAudioThread); @@ -1403,7 +1409,8 @@ void AudioIO::StopStream() mUpdateMeters = false; while(mUpdatingMeters) { ::wxSafeYield(); - wxMilliSleep( 50 ); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); } // Turn off HW playthrough if PortMixer is being used @@ -1450,7 +1457,8 @@ void AudioIO::StopStream() //FIXME: Seems like this block of the UI thread isn't bounded, //but we cannot allow event handlers to see incompletely terminated //AudioIO state with wxYield (or similar functions) - wxMilliSleep( 50 ); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); } // @@ -3041,7 +3049,8 @@ int AudioIoCallback::CallbackDoSeek() mAudioThreadTrackBufferExchangeLoopRunning = false; while( mAudioThreadTrackBufferExchangeLoopActive ) { - wxMilliSleep( 50 ); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); } // Calculate the NEW time position, in the PortAudio callback @@ -3072,7 +3081,8 @@ int AudioIoCallback::CallbackDoSeek() mAudioThreadShouldCallTrackBufferExchangeOnce = true; while( mAudioThreadShouldCallTrackBufferExchangeOnce ) { - wxMilliSleep( 50 ); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); } // Reenable the audio thread diff --git a/src/CrashReport.cpp b/src/CrashReport.cpp index 2df9c0628000..714a19a60d39 100644 --- a/src/CrashReport.cpp +++ b/src/CrashReport.cpp @@ -87,7 +87,8 @@ void Generate(wxDebugReport::Context ctx) // Wait for information to be gathered while (!done) { - wxMilliSleep(50); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); pd->Pulse(); } thread.join(); diff --git a/src/DBConnection.cpp b/src/DBConnection.cpp index 6da225da883f..12c5a6bd4735 100644 --- a/src/DBConnection.cpp +++ b/src/DBConnection.cpp @@ -266,7 +266,8 @@ bool DBConnection::Close() // Wait for the checkpoints to end while (mCheckpointPending || mCheckpointActive) { - wxMilliSleep(50); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); pd->Pulse(); } } diff --git a/src/ProjectFileIO.cpp b/src/ProjectFileIO.cpp index baa8400a788c..69bd49bda095 100644 --- a/src/ProjectFileIO.cpp +++ b/src/ProjectFileIO.cpp @@ -1361,7 +1361,8 @@ bool ProjectFileIO::RenameOrWarn(const FilePath &src, const FilePath &dst) // Wait for the checkpoints to end while (!done) { - wxMilliSleep(50); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); pd->Pulse(); } thread.join(); @@ -2302,7 +2303,8 @@ bool ProjectFileIO::SaveProject( // Wait for the checkpoints to end while (!done) { - wxMilliSleep(50); + using namespace std::chrono; + std::this_thread::sleep_for(50ms); pd->Pulse(); } thread.join(); diff --git a/src/TimerRecordDialog.cpp b/src/TimerRecordDialog.cpp index 2cef922e6999..2c2d02966bde 100644 --- a/src/TimerRecordDialog.cpp +++ b/src/TimerRecordDialog.cpp @@ -23,6 +23,7 @@ #include "FileNames.h" +#include #include // for wxUSE_* macros #include @@ -537,7 +538,8 @@ int TimerRecordDialog::RunWaitDialog() // Loop for progress display during recording. while (bIsRecording && (updateResult == ProgressResult::Success)) { updateResult = progress.UpdateProgress(); - wxMilliSleep(kTimerInterval); + using namespace std::chrono; + std::this_thread::sleep_for(milliseconds{kTimerInterval}); bIsRecording = (wxDateTime::UNow() <= m_DateTime_End); // Call UNow() again for extra accuracy... } } @@ -1036,7 +1038,8 @@ ProgressResult TimerRecordDialog::WaitForStart() while (updateResult == ProgressResult::Success && !bIsRecording) { updateResult = progress.UpdateProgress(); - wxMilliSleep(kTimerInterval); + using namespace std::chrono; + std::this_thread::sleep_for(milliseconds{kTimerInterval}); bIsRecording = (m_DateTime_Start <= wxDateTime::UNow()); } return updateResult; @@ -1086,7 +1089,8 @@ ProgressResult TimerRecordDialog::PreActionDelay(int iActionIndex, TimerRecordCo while (iUpdateResult == ProgressResult::Success && !bIsTime) { iUpdateResult = dlgAction.UpdateProgress(); - wxMilliSleep(kTimerInterval); + using namespace std::chrono; + std::this_thread::sleep_for(milliseconds{kTimerInterval}); bIsTime = (dtActionTime <= wxDateTime::UNow()); } return iUpdateResult; diff --git a/src/TransportUtilities.cpp b/src/TransportUtilities.cpp index ceeabc95e940..165b49d4c77d 100644 --- a/src/TransportUtilities.cpp +++ b/src/TransportUtilities.cpp @@ -11,6 +11,7 @@ #include "TransportUtilities.h" +#include #include "AudioIO.h" #include "commands/CommandContext.h" #include "Project.h" @@ -52,7 +53,8 @@ void TransportUtilities::PlayCurrentRegionAndWait( break; } - wxMilliSleep(100); + using namespace std::chrono; + std::this_thread::sleep_for(100ms); wxYieldIfNeeded(); } @@ -93,7 +95,8 @@ void TransportUtilities::PlayPlayRegionAndWait( break; } - wxMilliSleep(100); + using namespace std::chrono; + std::this_thread::sleep_for(100ms); wxYieldIfNeeded(); } @@ -132,7 +135,8 @@ void TransportUtilities::RecordAndWait( break; } - wxMilliSleep(100); + using namespace std::chrono; + std::this_thread::sleep_for(100ms); wxYieldIfNeeded(); } diff --git a/src/commands/ScreenshotCommand.cpp b/src/commands/ScreenshotCommand.cpp index 7f05017661a6..360ddf31f087 100644 --- a/src/commands/ScreenshotCommand.cpp +++ b/src/commands/ScreenshotCommand.cpp @@ -21,6 +21,7 @@ small calculations of rectangles. #include "ScreenshotCommand.h" #include +#include #include "LoadCommands.h" #include "Project.h" @@ -198,14 +199,13 @@ wxRect ScreenshotCommand::GetBackgroundRect() static void Yield() { + using namespace std::chrono; int cnt; - for (cnt = 10; cnt && !wxTheApp->Yield(true); cnt--) { - wxMilliSleep(10); - } - wxMilliSleep(200); - for (cnt = 10; cnt && !wxTheApp->Yield(true); cnt--) { - wxMilliSleep(10); - } + for (cnt = 10; cnt && !wxTheApp->Yield(true); cnt--) + std::this_thread::sleep_for(10ms); + std::this_thread::sleep_for(200ms); + for (cnt = 10; cnt && !wxTheApp->Yield(true); cnt--) + std::this_thread::sleep_for(10ms); } bool ScreenshotCommand::Capture( @@ -355,6 +355,7 @@ void ScreenshotCommand::CaptureWindowOnIdle( const CommandContext & context, wxWindow * pWin ) { + using namespace std::chrono; wxDialog * pDlg = dynamic_cast(pWin); if( !pDlg ){ wxLogDebug("Event from bogus dlg" ); @@ -374,7 +375,7 @@ void ScreenshotCommand::CaptureWindowOnIdle( wxLogDebug("Taking screenshot of window %s (%i,%i,%i,%i)", Name, Pos.x, Pos.y, Siz.x, Siz.y ); // This delay is needed, as dialogs take a moment or two to fade in. - wxMilliSleep( 400 ); + std::this_thread::sleep_for(400ms); // JKC: The border of 7 pixels was determined from a trial capture and then measuring // in the GIMP. I'm unsure where the border comes from. Capture( context, Name, pDlg, wxRect((int)Pos.x+7, (int)Pos.y, (int)Siz.x-14, (int)Siz.y-7) ); @@ -386,7 +387,9 @@ void ScreenshotCommand::CaptureWindowOnIdle( void ScreenshotCommand::CapturePreferences( const CommandContext & context, - AudacityProject * pProject, const wxString &FileName ){ + AudacityProject * pProject, const wxString &FileName ) +{ + using namespace std::chrono; (void)&FileName;//compiler food. (void)&context; CommandManager &commandManager = CommandManager::Get( *pProject ); @@ -416,7 +419,7 @@ void ScreenshotCommand::CapturePreferences( } // This sleep is not needed, but gives user a chance to see the // dialogs as they whizz by. - wxMilliSleep( 200 ); + std::this_thread::sleep_for(200ms); } } @@ -552,7 +555,9 @@ void ScreenshotCommand::CaptureScriptables( void ScreenshotCommand::CaptureCommands( - const CommandContext & context, const wxArrayStringEx & Commands ){ + const CommandContext & context, const wxArrayStringEx & Commands ) +{ + using namespace std::chrono; AudacityProject * pProject = &context.project; CommandManager &manager = CommandManager::Get( *pProject ); wxString Str; @@ -576,7 +581,7 @@ void ScreenshotCommand::CaptureCommands( } // This particular sleep is not needed, but gives user a chance to see the // dialogs as they whizz by. - wxMilliSleep( 200 ); + std::this_thread::sleep_for(200ms); } } diff --git a/src/effects/Effect.cpp b/src/effects/Effect.cpp index e8178644c1bb..36754a619371 100644 --- a/src/effects/Effect.cpp +++ b/src/effects/Effect.cpp @@ -20,6 +20,7 @@ #include "TimeWarper.h" #include +#include #include #include @@ -2209,7 +2210,8 @@ void Effect::Preview(bool dryOnly) (GetName(), XO("Previewing"), pdlgHideCancelButton); while (gAudioIO->IsStreamActive(token) && previewing == ProgressResult::Success) { - ::wxMilliSleep(100); + using namespace std::chrono; + std::this_thread::sleep_for(100ms); previewing = progress.Update(gAudioIO->GetStreamTime() - mT0, t1 - mT0); } } @@ -2217,7 +2219,8 @@ void Effect::Preview(bool dryOnly) gAudioIO->StopStream(); while (gAudioIO->IsBusy()) { - ::wxMilliSleep(100); + using namespace std::chrono; + std::this_thread::sleep_for(100ms); } } else { diff --git a/src/effects/ladspa/LadspaEffect.cpp b/src/effects/ladspa/LadspaEffect.cpp index f2123c660f30..9d772bfd0eaf 100644 --- a/src/effects/ladspa/LadspaEffect.cpp +++ b/src/effects/ladspa/LadspaEffect.cpp @@ -27,6 +27,7 @@ effects from this one class. #include "SampleCount.h" #include +#include #if !defined(__WXMSW__) #include @@ -309,7 +310,8 @@ unsigned LadspaEffectsModule::DiscoverPluginsAtPath( // dependent multi-threading bug in the Amplio2 library itself, in case the unload of the .dll // comes too soon after the load. I saw the bug in Release builds but not Debug. // A sleep of even 1 ms was enough to fix the problem for me, but let's be even more generous. - ::wxMilliSleep(10); + using namespace std::chrono; + std::this_thread::sleep_for(10ms); lib.Unload(); } #else diff --git a/src/export/ExportCL.cpp b/src/export/ExportCL.cpp index d9e38d5d5513..d50cc5926da6 100644 --- a/src/export/ExportCL.cpp +++ b/src/export/ExportCL.cpp @@ -13,6 +13,8 @@ #include "ProjectRate.h" +#include + #include #include #include @@ -570,7 +572,8 @@ ProgressResult ExportCL::Export(AudacityProject *project, // Wait for process to terminate while (process.IsActive()) { - wxMilliSleep(10); + using namespace std::chrono; + std::this_thread::sleep_for(10ms); wxTheApp->Yield(); } diff --git a/src/menus/TransportMenus.cpp b/src/menus/TransportMenus.cpp index c0806e64dde8..01fbb3ef5f2a 100644 --- a/src/menus/TransportMenus.cpp +++ b/src/menus/TransportMenus.cpp @@ -37,6 +37,7 @@ #include "BasicUI.h" #include "../widgets/ProgressDialog.h" +#include #include #include @@ -65,7 +66,8 @@ bool MakeReadyToPlay(AudacityProject &project) toolbar.SetStop(); //Pushes stop down toolbar.OnStop(evt); - ::wxMilliSleep(100); + using namespace std::chrono; + std::this_thread::sleep_for(100ms); } // If it didn't stop playing quickly, or if some other diff --git a/src/prefs/PrefsDialog.cpp b/src/prefs/PrefsDialog.cpp index 28c214089846..8a0ab1c61df9 100644 --- a/src/prefs/PrefsDialog.cpp +++ b/src/prefs/PrefsDialog.cpp @@ -17,6 +17,8 @@ #include "PrefsDialog.h" +#include + #include #include // for wxUSE_* macros #include @@ -753,8 +755,10 @@ void PrefsDialog::OnOK(wxCommandEvent & WXUNUSED(event)) if (gAudioIO->IsMonitoring()) { gAudioIO->StopStream(); - while (gAudioIO->IsBusy()) - wxMilliSleep(100); + while (gAudioIO->IsBusy()) { + using namespace std::chrono; + std::this_thread::sleep_for(100ms); + } } gAudioIO->HandleDeviceChange(); } diff --git a/src/toolbars/DeviceToolBar.cpp b/src/toolbars/DeviceToolBar.cpp index 195354b19495..b46eb020c120 100644 --- a/src/toolbars/DeviceToolBar.cpp +++ b/src/toolbars/DeviceToolBar.cpp @@ -18,6 +18,8 @@ #include "DeviceToolBar.h" #include "ToolManager.h" +#include + // For compilers that support precompilation, includes "wx/wx.h". #include @@ -675,8 +677,10 @@ void DeviceToolBar::OnChoice(wxCommandEvent &event) if (gAudioIO->IsMonitoring()) { gAudioIO->StopStream(); - while (gAudioIO->IsBusy()) - wxMilliSleep(100); + while (gAudioIO->IsBusy()) { + using namespace std::chrono; + std::this_thread::sleep_for(100ms); + } } gAudioIO->HandleDeviceChange(); } diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index 657669915b22..201c43a12db4 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -12,6 +12,7 @@ Paul Licameli split from TrackPanel.cpp #include "Scrubbing.h" #include +#include #include "../../AudioIO.h" #include "../../CommonCommandFlags.h" @@ -152,7 +153,8 @@ auto Scrubber::ScrubPollerThread::Entry() -> ExitCode { while( !TestDestroy() ) { - wxThread::Sleep(ScrubPollInterval_ms); + using namespace std::chrono; + std::this_thread::sleep_for(milliseconds{ScrubPollInterval_ms}); mScrubber.ContinueScrubbingPoll(); } return 0; From ae5dd35a24b06bcdfe0473dddb609432694e62c4 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 17 Dec 2021 12:42:21 -0500 Subject: [PATCH 4/6] More uses of std::chrono::duration... say what you mean with types --- libraries/lib-audio-devices/AudioIOBase.h | 4 ++-- src/AudioIO.cpp | 14 +++++++------- src/AudioIO.h | 2 +- src/PlaybackSchedule.cpp | 6 ++++-- src/PlaybackSchedule.h | 8 +++++--- src/ScrubState.cpp | 7 ++++--- src/ScrubState.h | 6 +++--- src/TimerRecordDialog.cpp | 8 ++++---- src/TrackPanel.cpp | 4 ++-- src/TrackPanel.h | 8 ++------ src/tracks/ui/PlayIndicatorOverlay.cpp | 2 +- src/tracks/ui/Scrubbing.cpp | 17 ++++++++--------- 12 files changed, 43 insertions(+), 43 deletions(-) diff --git a/libraries/lib-audio-devices/AudioIOBase.h b/libraries/lib-audio-devices/AudioIOBase.h index 5de86cd61088..4409e3efa293 100644 --- a/libraries/lib-audio-devices/AudioIOBase.h +++ b/libraries/lib-audio-devices/AudioIOBase.h @@ -65,8 +65,8 @@ struct AudioIOStartStreamOptions // 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; + // The return value is duration to sleep before calling again + std::function< std::chrono::milliseconds() > playbackStreamPrimer; using PolicyFactory = std::function< std::unique_ptr(const AudioIOStartStreamOptions&) >; diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 658d9f4f882e..fd2bdb5e5448 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -974,12 +974,12 @@ int AudioIO::StartStream(const TransportTracks &tracks, mAudioThreadShouldCallTrackBufferExchangeOnce = true; while( mAudioThreadShouldCallTrackBufferExchangeOnce ) { - auto interval = 50ull; + using namespace std::chrono; + auto interval = 50ms; if (options.playbackStreamPrimer) { interval = options.playbackStreamPrimer(); } - using namespace std::chrono; - std::this_thread::sleep_for(milliseconds{interval}); + std::this_thread::sleep_for(interval); } if(mNumPlaybackChannels > 0 || mNumCaptureChannels > 0) { @@ -1130,7 +1130,7 @@ bool AudioIO::AllocateBuffers( // usually, make fillings fewer and longer for less CPU usage. // What Audio thread produces for playback is then consumed by the PortAudio // thread, in many smaller pieces. - double playbackTime = lrint(times.batchSize * mRate) / mRate; + double playbackTime = lrint(times.batchSize.count() * mRate) / mRate; wxASSERT( playbackTime >= 0 ); mPlaybackSamplesToCopy = playbackTime * mRate; @@ -1153,7 +1153,7 @@ bool AudioIO::AllocateBuffers( // Allocate output buffers. For every output track we allocate // a ring buffer of ten seconds auto playbackBufferSize = - (size_t)lrint(mRate * mPlaybackRingBufferSecs); + (size_t)lrint(mRate * mPlaybackRingBufferSecs.count()); // Always make at least one playback buffer mPlaybackBuffers.reinit( @@ -1164,7 +1164,7 @@ bool AudioIO::AllocateBuffers( const auto &warpOptions = policy.MixerWarpOptions(mPlaybackSchedule); - mPlaybackQueueMinimum = lrint( mRate * times.latency ); + mPlaybackQueueMinimum = lrint( mRate * times.latency.count() ); mPlaybackQueueMinimum = std::min( mPlaybackQueueMinimum, playbackBufferSize ); @@ -1267,7 +1267,7 @@ bool AudioIO::AllocateBuffers( // In the extraordinarily rare case that we can't even afford 100 // samples, just give up. auto playbackBufferSize = - (size_t)lrint(mRate * mPlaybackRingBufferSecs); + (size_t)lrint(mRate * mPlaybackRingBufferSecs.count()); if(playbackBufferSize < 100 || mPlaybackSamplesToCopy < 100) { AudacityMessageBox( XO("Out of memory!") ); diff --git a/src/AudioIO.h b/src/AudioIO.h index f5969c03a7f8..66ae9ab09406 100644 --- a/src/AudioIO.h +++ b/src/AudioIO.h @@ -263,7 +263,7 @@ class AUDACITY_DLL_API AudioIoCallback /* not final */ bool mbMicroFades; double mSeek; - double mPlaybackRingBufferSecs; + PlaybackPolicy::Duration mPlaybackRingBufferSecs; double mCaptureRingBufferSecs; /// Preferred batch size for replenishing the playback RingBuffer diff --git a/src/PlaybackSchedule.cpp b/src/PlaybackSchedule.cpp index 0865d8795ba7..3f58d3e18f92 100644 --- a/src/PlaybackSchedule.cpp +++ b/src/PlaybackSchedule.cpp @@ -37,7 +37,8 @@ Mixer::WarpOptions PlaybackPolicy::MixerWarpOptions(PlaybackSchedule &schedule) PlaybackPolicy::BufferTimes PlaybackPolicy::SuggestedBufferTimes(PlaybackSchedule &) { - return { 4.0, 4.0, 10.0 }; + using namespace std::chrono; + return { 4.0s, 4.0s, 10.0s }; } bool PlaybackPolicy::AllowSeek(PlaybackSchedule &) @@ -191,7 +192,8 @@ NewDefaultPlaybackPolicy::SuggestedBufferTimes(PlaybackSchedule &) { // Shorter times than in the default policy so that responses to changes of // loop region or speed slider don't lag too much - return { 0.05, 0.05, 0.25 }; + using namespace std::chrono; + return { 0.05s, 0.05s, 0.25s }; } bool NewDefaultPlaybackPolicy::RevertToOldDefault(const PlaybackSchedule &schedule) const diff --git a/src/PlaybackSchedule.h b/src/PlaybackSchedule.h index 5363aaff8d7a..73bbf9a55dcc 100644 --- a/src/PlaybackSchedule.h +++ b/src/PlaybackSchedule.h @@ -175,6 +175,8 @@ struct PlaybackSlice { */ class PlaybackPolicy { public: + using Duration = std::chrono::duration; + //! @section Called by the main thread virtual ~PlaybackPolicy() = 0; @@ -190,9 +192,9 @@ class PlaybackPolicy { //! Times are in seconds struct BufferTimes { - double batchSize; //!< Try to put at least this much into the ring buffer in each pass - double latency; //!< Try not to let ring buffer contents fall below this - double ringBufferDelay; //!< Length of ring buffer in seconds + Duration batchSize; //!< Try to put at least this much into the ring buffer in each pass + Duration latency; //!< Try not to let ring buffer contents fall below this + Duration ringBufferDelay; //!< Length of ring buffer }; //! Provide hints for construction of playback RingBuffer objects virtual BufferTimes SuggestedBufferTimes(PlaybackSchedule &schedule); diff --git a/src/ScrubState.cpp b/src/ScrubState.cpp index 72c2e9399a7c..2082b9fc4ae3 100644 --- a/src/ScrubState.cpp +++ b/src/ScrubState.cpp @@ -219,7 +219,7 @@ struct ScrubQueue : NonInterferingBase // When playback follows a fast mouse movement by "stuttering" // at maximum playback, don't make stutters too short to be useful. if (options.adjustStart && - duration < llrint( options.minStutterTime * rate ) ) + duration < llrint( options.minStutterTime.count() * rate ) ) return false; sampleCount minSample { llrint(options.minTime * rate) }; @@ -324,6 +324,7 @@ Mixer::WarpOptions ScrubbingPlaybackPolicy::MixerWarpOptions(PlaybackSchedule &) PlaybackPolicy::BufferTimes ScrubbingPlaybackPolicy::SuggestedBufferTimes(PlaybackSchedule &) { + using namespace std::chrono; return { // For useful scrubbing, we can't run too far ahead without checking // mouse input, so make fillings more and shorter. @@ -338,7 +339,7 @@ ScrubbingPlaybackPolicy::SuggestedBufferTimes(PlaybackSchedule &) 2 * mOptions.minStutterTime, // Same as for default policy - 10.0 + 10.0s }; } @@ -357,7 +358,7 @@ bool ScrubbingPlaybackPolicy::Done( std::chrono::milliseconds ScrubbingPlaybackPolicy::SleepInterval( PlaybackSchedule & ) { - return std::chrono::milliseconds{ ScrubPollInterval_ms }; + return ScrubPollInterval_ms; } PlaybackSlice ScrubbingPlaybackPolicy::GetPlaybackSlice( diff --git a/src/ScrubState.h b/src/ScrubState.h index 300ee5e4e1ee..52f131eb7d4d 100644 --- a/src/ScrubState.h +++ b/src/ScrubState.h @@ -27,7 +27,7 @@ struct ScrubbingOptions { bool bySpeed {}; bool isKeyboardScrubbing{}; - double delay {}; + PlaybackPolicy::Duration delay {}; // Initial and limiting values for the speed of a scrub interval: double initSpeed { 1.0 }; @@ -37,7 +37,7 @@ struct ScrubbingOptions { // When maximum speed scrubbing skips to follow the mouse, // this is the minimum amount of playback allowed at the maximum speed: - double minStutterTime {}; + PlaybackPolicy::Duration minStutterTime {}; static double MaxAllowedScrubSpeed() { return 32.0; } // Is five octaves enough for your amusement? @@ -106,6 +106,6 @@ struct ScrubState static double GetLastScrubTime(); }; -static constexpr unsigned ScrubPollInterval_ms = 50; +static constexpr auto ScrubPollInterval_ms = std::chrono::milliseconds{50}; #endif diff --git a/src/TimerRecordDialog.cpp b/src/TimerRecordDialog.cpp index 2c2d02966bde..a83c73395228 100644 --- a/src/TimerRecordDialog.cpp +++ b/src/TimerRecordDialog.cpp @@ -86,7 +86,7 @@ enum { const int kSlowTimerInterval = 1000; // ms // This timer interval is used in some busy-wait loops and is much shorter. -const int kTimerInterval = 50; // ms +constexpr auto kTimerInterval = std::chrono::milliseconds{50}; static double wxDateTime_to_AudacityTime(wxDateTime& dateTime) { @@ -539,7 +539,7 @@ int TimerRecordDialog::RunWaitDialog() while (bIsRecording && (updateResult == ProgressResult::Success)) { updateResult = progress.UpdateProgress(); using namespace std::chrono; - std::this_thread::sleep_for(milliseconds{kTimerInterval}); + std::this_thread::sleep_for(kTimerInterval); bIsRecording = (wxDateTime::UNow() <= m_DateTime_End); // Call UNow() again for extra accuracy... } } @@ -1039,7 +1039,7 @@ ProgressResult TimerRecordDialog::WaitForStart() { updateResult = progress.UpdateProgress(); using namespace std::chrono; - std::this_thread::sleep_for(milliseconds{kTimerInterval}); + std::this_thread::sleep_for(kTimerInterval); bIsRecording = (m_DateTime_Start <= wxDateTime::UNow()); } return updateResult; @@ -1090,7 +1090,7 @@ ProgressResult TimerRecordDialog::PreActionDelay(int iActionIndex, TimerRecordCo { iUpdateResult = dlgAction.UpdateProgress(); using namespace std::chrono; - std::this_thread::sleep_for(milliseconds{kTimerInterval}); + std::this_thread::sleep_for(kTimerInterval); bIsTime = (dtActionTime <= wxDateTime::UNow()); } return iUpdateResult; diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index a133a0210595..847ee579f4ae 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -381,7 +381,7 @@ void TrackPanel::OnIdle(wxIdleEvent& event) // The window must be ready when the timer fires (#1401) if (IsShownOnScreen()) { - mTimer.Start(kTimerInterval, FALSE); + mTimer.Start(kTimerInterval.count(), FALSE); // Timer is started, we don't need the event anymore GetProjectFrame( *GetProject() ).Unbind(wxEVT_IDLE, @@ -727,7 +727,7 @@ void TrackPanel::OnMouseEvent(wxMouseEvent & event) // When this timer fires, we call TrackPanel::OnTimer and // possibly update the screen for offscreen scrolling. mTimer.Stop(); - mTimer.Start(kTimerInterval, FALSE); + mTimer.Start(kTimerInterval.count(), FALSE); } diff --git a/src/TrackPanel.h b/src/TrackPanel.h index c685510ea4fc..bab741879734 100644 --- a/src/TrackPanel.h +++ b/src/TrackPanel.h @@ -11,9 +11,7 @@ #ifndef __AUDACITY_TRACK_PANEL__ #define __AUDACITY_TRACK_PANEL__ - - - +#include #include #include // for wxUSE_* macros @@ -53,9 +51,7 @@ struct TrackPanelDrawingContext; enum class UndoPush : unsigned char; -enum { - kTimerInterval = 50, // milliseconds -}; +static constexpr auto kTimerInterval = std::chrono::milliseconds{50}; const int DragThreshold = 3;// Anything over 3 pixels is a drag, else a click. diff --git a/src/tracks/ui/PlayIndicatorOverlay.cpp b/src/tracks/ui/PlayIndicatorOverlay.cpp index 6d471324ac5d..9e236fb42200 100644 --- a/src/tracks/ui/PlayIndicatorOverlay.cpp +++ b/src/tracks/ui/PlayIndicatorOverlay.cpp @@ -190,7 +190,7 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) // Use a small tolerance to avoid flicker of play head pinned all the way // left or right - const auto tolerance = pinned ? 1.5 * kTimerInterval / 1000.0 : 0; + const auto tolerance = pinned ? 1.5 * kTimerInterval.count() / 1000.0 : 0; bool onScreen = playPos >= 0.0 && between_incexc(viewInfo.h - tolerance, playPos, diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index 201c43a12db4..5efcac903232 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -52,10 +52,10 @@ enum { ScrubSpeedStepsPerOctave = 4, #endif - kOneSecondCountdown = 1000 / ScrubPollInterval_ms, + kOneSecondCountdown = 1000 / ScrubPollInterval_ms.count(), }; -static const double MinStutter = 0.2; +static constexpr PlaybackPolicy::Duration MinStutter{0.2}; // static const double MaxDragSpeed = 1.0; namespace { @@ -153,8 +153,7 @@ auto Scrubber::ScrubPollerThread::Entry() -> ExitCode { while( !TestDestroy() ) { - using namespace std::chrono; - std::this_thread::sleep_for(milliseconds{ScrubPollInterval_ms}); + std::this_thread::sleep_for(ScrubPollInterval_ms); mScrubber.ContinueScrubbingPoll(); } return 0; @@ -423,7 +422,7 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx) #endif options.playNonWaveTracks = false; options.envelope = nullptr; - mOptions.delay = (ScrubPollInterval_ms / 1000.0); + mOptions.delay = ScrubPollInterval_ms; mOptions.isKeyboardScrubbing = false; mOptions.initSpeed = 0; mOptions.minSpeed = 0.0; @@ -449,9 +448,9 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx) std::max(0.0, TrackList::Get( *mProject ).GetEndTime()); mOptions.minStutterTime = #ifdef DRAG_SCRUB - mDragging ? 0.0 : + mDragging ? PlaybackPolicy::Duration{} : #endif - std::max(0.0, MinStutter); + std::max(PlaybackPolicy::Duration{}, MinStutter); const bool backwards = time1 < time0; #ifdef EXPERIMENTAL_SCRUBBING_SCROLL_WHEEL @@ -528,7 +527,7 @@ bool Scrubber::StartKeyboardScrubbing(double time0, bool backwards) // delay and minStutterTime are used in AudioIO::AllocateBuffers() for setting the // values of mPlaybackQueueMinimum and mPlaybackSamplesToCopy respectively. - mOptions.delay = (ScrubPollInterval_ms / 1000.0); + mOptions.delay = ScrubPollInterval_ms; mOptions.minStutterTime = mOptions.delay; mOptions.initSpeed = GetKeyboardScrubbingSpeed(); @@ -730,7 +729,7 @@ void Scrubber::StartPolling() mpThread->Run(); #endif - mPoller->Start(ScrubPollInterval_ms * 0.9); + mPoller->Start(ScrubPollInterval_ms.count() * 0.9); } void Scrubber::StopPolling() From 0b9e8d8761362f11058eba404af3f192c4fe4bd9 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 31 Dec 2021 12:52:32 -0500 Subject: [PATCH 5/6] More use of std::chrono::duration eliminates one use of count() --- libraries/lib-audio-devices/DeviceManager.cpp | 4 ++-- libraries/lib-audio-devices/DeviceManager.h | 2 +- src/AudioIO.cpp | 7 +++++-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/lib-audio-devices/DeviceManager.cpp b/libraries/lib-audio-devices/DeviceManager.cpp index df55c323605f..5f680c40f23c 100644 --- a/libraries/lib-audio-devices/DeviceManager.cpp +++ b/libraries/lib-audio-devices/DeviceManager.cpp @@ -305,10 +305,10 @@ void DeviceManager::Rescan() } -float DeviceManager::GetTimeSinceRescan() { +std::chrono::duration DeviceManager::GetTimeSinceRescan() { auto now = std::chrono::steady_clock::now(); auto dur = std::chrono::duration_cast>(now - mRescanTime); - return dur.count(); + return dur; } diff --git a/libraries/lib-audio-devices/DeviceManager.h b/libraries/lib-audio-devices/DeviceManager.h index 45dbc15041c4..f3278c25ad53 100644 --- a/libraries/lib-audio-devices/DeviceManager.h +++ b/libraries/lib-audio-devices/DeviceManager.h @@ -62,7 +62,7 @@ class AUDIO_DEVICES_API DeviceManager final void Rescan(); // Time since devices scanned in seconds. - float GetTimeSinceRescan(); + std::chrono::duration GetTimeSinceRescan(); DeviceSourceMap* GetDefaultOutputDevice(int hostIndex); DeviceSourceMap* GetDefaultInputDevice(int hostIndex); diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index fd2bdb5e5448..3a53c537950a 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -616,8 +616,11 @@ bool AudioIO::StartPortAudioStream(const AudioIOStartStreamOptions &options, // On my test machine, no more than 3 attempts are required. unsigned int maxTries = 1; #ifdef __WXGTK__ - if (DeviceManager::Instance()->GetTimeSinceRescan() < 10) - maxTries = 5; + { + using namespace std::chrono; + if (DeviceManager::Instance()->GetTimeSinceRescan() < 10s) + maxTries = 5; + } #endif for (unsigned int tries = 0; tries < maxTries; tries++) { From c814e58b301432b0a4295d84cf5e614064d9ec0f Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Fri, 31 Dec 2021 13:05:08 -0500 Subject: [PATCH 6/6] Don't make assumptions about types of timer interval constants ... ... where they must mix with un-typed numbers, including calls to wxTimer methods. Change the name of one so it doesn't mention the period. Do not use duration_cast, but use other conversions that check for non-lossiness at compile time. --- src/ScrubState.cpp | 2 +- src/ScrubState.h | 2 +- src/TrackPanel.cpp | 4 ++-- src/tracks/ui/PlayIndicatorOverlay.cpp | 4 +++- src/tracks/ui/Scrubbing.cpp | 18 ++++++++++-------- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/ScrubState.cpp b/src/ScrubState.cpp index 2082b9fc4ae3..e2be7b0a2c61 100644 --- a/src/ScrubState.cpp +++ b/src/ScrubState.cpp @@ -358,7 +358,7 @@ bool ScrubbingPlaybackPolicy::Done( std::chrono::milliseconds ScrubbingPlaybackPolicy::SleepInterval( PlaybackSchedule & ) { - return ScrubPollInterval_ms; + return ScrubPollInterval; } PlaybackSlice ScrubbingPlaybackPolicy::GetPlaybackSlice( diff --git a/src/ScrubState.h b/src/ScrubState.h index 52f131eb7d4d..7d391ddef82d 100644 --- a/src/ScrubState.h +++ b/src/ScrubState.h @@ -106,6 +106,6 @@ struct ScrubState static double GetLastScrubTime(); }; -static constexpr auto ScrubPollInterval_ms = std::chrono::milliseconds{50}; +static constexpr auto ScrubPollInterval = std::chrono::milliseconds{50}; #endif diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index 847ee579f4ae..a5272ad5539f 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -381,7 +381,7 @@ void TrackPanel::OnIdle(wxIdleEvent& event) // The window must be ready when the timer fires (#1401) if (IsShownOnScreen()) { - mTimer.Start(kTimerInterval.count(), FALSE); + mTimer.Start(std::chrono::milliseconds{kTimerInterval}.count(), FALSE); // Timer is started, we don't need the event anymore GetProjectFrame( *GetProject() ).Unbind(wxEVT_IDLE, @@ -727,7 +727,7 @@ void TrackPanel::OnMouseEvent(wxMouseEvent & event) // When this timer fires, we call TrackPanel::OnTimer and // possibly update the screen for offscreen scrolling. mTimer.Stop(); - mTimer.Start(kTimerInterval.count(), FALSE); + mTimer.Start(std::chrono::milliseconds{kTimerInterval}.count(), FALSE); } diff --git a/src/tracks/ui/PlayIndicatorOverlay.cpp b/src/tracks/ui/PlayIndicatorOverlay.cpp index 9e236fb42200..8a34caa7208f 100644 --- a/src/tracks/ui/PlayIndicatorOverlay.cpp +++ b/src/tracks/ui/PlayIndicatorOverlay.cpp @@ -190,7 +190,9 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) // Use a small tolerance to avoid flicker of play head pinned all the way // left or right - const auto tolerance = pinned ? 1.5 * kTimerInterval.count() / 1000.0 : 0; + const auto tolerance = pinned + ? 1.5 * std::chrono::duration{kTimerInterval}.count() + : 0; bool onScreen = playPos >= 0.0 && between_incexc(viewInfo.h - tolerance, playPos, diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index 5efcac903232..6ef5980bf0d4 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -52,7 +52,8 @@ enum { ScrubSpeedStepsPerOctave = 4, #endif - kOneSecondCountdown = 1000 / ScrubPollInterval_ms.count(), + kOneSecondCountdown = + 1000 / std::chrono::milliseconds{ScrubPollInterval}.count(), }; static constexpr PlaybackPolicy::Duration MinStutter{0.2}; @@ -153,7 +154,7 @@ auto Scrubber::ScrubPollerThread::Entry() -> ExitCode { while( !TestDestroy() ) { - std::this_thread::sleep_for(ScrubPollInterval_ms); + std::this_thread::sleep_for(ScrubPollInterval); mScrubber.ContinueScrubbingPoll(); } return 0; @@ -417,12 +418,12 @@ bool Scrubber::MaybeStartScrubbing(wxCoord xx) // execute too much else options.playbackStreamPrimer = [this](){ ContinueScrubbingPoll(); - return ScrubPollInterval_ms; + return ScrubPollInterval; }; #endif options.playNonWaveTracks = false; options.envelope = nullptr; - mOptions.delay = ScrubPollInterval_ms; + mOptions.delay = ScrubPollInterval; mOptions.isKeyboardScrubbing = false; mOptions.initSpeed = 0; mOptions.minSpeed = 0.0; @@ -518,7 +519,7 @@ bool Scrubber::StartKeyboardScrubbing(double time0, bool backwards) // execute too much else options.playbackStreamPrimer = [this]() { ContinueScrubbingPoll(); - return ScrubPollInterval_ms; + return ScrubPollInterval; }; #endif @@ -527,7 +528,7 @@ bool Scrubber::StartKeyboardScrubbing(double time0, bool backwards) // delay and minStutterTime are used in AudioIO::AllocateBuffers() for setting the // values of mPlaybackQueueMinimum and mPlaybackSamplesToCopy respectively. - mOptions.delay = ScrubPollInterval_ms; + mOptions.delay = ScrubPollInterval; mOptions.minStutterTime = mOptions.delay; mOptions.initSpeed = GetKeyboardScrubbingSpeed(); @@ -728,8 +729,9 @@ void Scrubber::StartPolling() mpThread->Create(4096); mpThread->Run(); #endif - - mPoller->Start(ScrubPollInterval_ms.count() * 0.9); + + mPoller->Start( 0.9 * + std::chrono::duration{ScrubPollInterval}.count()); } void Scrubber::StopPolling()