From 1f4202c8788236f04e57f67b01be2324e9f213b1 Mon Sep 17 00:00:00 2001 From: Paul Licameli Date: Sun, 2 Jun 2019 13:30:56 -0400 Subject: [PATCH] New attached structure ProjectAudioIO handles tokens and meters --- src/AdornedRulerPanel.cpp | 4 +- src/AudacityApp.cpp | 2 +- src/AudioIO.cpp | 5 +- src/LyricsWindow.cpp | 2 +- src/Menus.cpp | 3 +- src/MixerBoard.cpp | 2 +- src/Project.cpp | 65 ++++++++++++++----- src/Project.h | 43 ++++++++---- src/TrackPanel.cpp | 12 ++-- src/menus/LabelMenus.cpp | 2 +- src/menus/SelectMenus.cpp | 16 ++--- src/menus/TrackMenus.cpp | 2 +- src/menus/TransportMenus.cpp | 13 ++-- src/toolbars/ControlToolBar.cpp | 13 ++-- src/toolbars/MeterToolBar.cpp | 26 ++++---- src/tracks/labeltrack/ui/LabelTextHandle.cpp | 2 +- .../notetrack/ui/StretchHandle.cpp | 8 +-- .../wavetrack/ui/CutlineHandle.cpp | 4 +- .../wavetrack/ui/SampleHandle.cpp | 8 +-- .../wavetrack/ui/WaveTrackControls.cpp | 8 +-- src/tracks/ui/EnvelopeHandle.cpp | 8 +-- src/tracks/ui/PlayIndicatorOverlay.cpp | 2 +- src/tracks/ui/Scrubbing.cpp | 7 +- src/tracks/ui/SelectHandle.cpp | 2 +- src/tracks/ui/TimeShiftHandle.cpp | 8 +-- src/tracks/ui/TrackButtonHandles.cpp | 4 +- src/tracks/ui/TrackSelectHandle.cpp | 7 +- 27 files changed, 169 insertions(+), 109 deletions(-) diff --git a/src/AdornedRulerPanel.cpp b/src/AdornedRulerPanel.cpp index a1bf9c7e2..daaa8d34f 100644 --- a/src/AdornedRulerPanel.cpp +++ b/src/AdornedRulerPanel.cpp @@ -200,7 +200,7 @@ void AdornedRulerPanel::QuickPlayRulerOverlay::Update() auto ruler = GetRuler(); // Hide during transport, or if mouse is not in the ruler, unless scrubbing - if ((!ruler->LastCell() || project->IsAudioActive()) + if ((!ruler->LastCell() || ProjectAudioIO::Get( *project ).IsAudioActive()) && (!scrubber.IsScrubbing() || scrubber.IsSpeedPlaying())) mNewQPIndicatorPos = -1; else { @@ -568,7 +568,7 @@ public: HitTest( const AudacityProject *pProject, wxCoord xx ) { if( ControlToolBar::IsTransportingPinned() && - pProject->IsAudioActive() ) + ProjectAudioIO::Get( *pProject ).IsAudioActive() ) { const auto targetX = GetPlayHeadX( pProject ); if ( abs( xx - targetX ) <= SELECT_TOLERANCE_PIXEL ) diff --git a/src/AudacityApp.cpp b/src/AudacityApp.cpp index 3344ddb27..c10fc575e 100644 --- a/src/AudacityApp.cpp +++ b/src/AudacityApp.cpp @@ -1602,7 +1602,7 @@ void AudacityApp::OnKeyDown(wxKeyEvent &event) if(event.GetKeyCode() == WXK_ESCAPE) { // Stop play, including scrub, but not record auto project = ::GetActiveProject(); - auto token = project->GetAudioIOToken(); + auto token = ProjectAudioIO::Get( *project ).GetAudioIOToken(); auto &scrubber = Scrubber::Get( *project ); auto scrubbing = scrubber.HasMark(); if (scrubbing) diff --git a/src/AudioIO.cpp b/src/AudioIO.cpp index 5adf26872..69c61d9b2 100644 --- a/src/AudioIO.cpp +++ b/src/AudioIO.cpp @@ -1559,7 +1559,7 @@ bool AudioIO::StartPortAudioStream(double sampleRate, playbackParameters.suggestedLatency = isWASAPI ? 0.0 : latencyDuration/1000.0; } - mOutputMeter = mOwningProject->GetPlaybackMeter(); + mOutputMeter = ProjectAudioIO::Get( *mOwningProject ).GetPlaybackMeter(); } if( numCaptureChannels > 0) @@ -1589,7 +1589,8 @@ bool AudioIO::StartPortAudioStream(double sampleRate, else captureParameters.suggestedLatency = latencyDuration/1000.0; - SetCaptureMeter( mOwningProject, mOwningProject->GetCaptureMeter() ); + SetCaptureMeter( mOwningProject, + ProjectAudioIO::Get( *mOwningProject ).GetCaptureMeter() ); } SetMeters(); diff --git a/src/LyricsWindow.cpp b/src/LyricsWindow.cpp index 070e49a09..43159058f 100644 --- a/src/LyricsWindow.cpp +++ b/src/LyricsWindow.cpp @@ -152,7 +152,7 @@ void LyricsWindow::OnStyle_Highlight(wxCommandEvent & WXUNUSED(event)) void LyricsWindow::OnTimer(wxCommandEvent &event) { - if (mProject->IsAudioActive()) + if (ProjectAudioIO::Get( *mProject ).IsAudioActive()) { GetLyricsPanel()->Update(gAudioIO->GetStreamTime()); } diff --git a/src/Menus.cpp b/src/Menus.cpp index a305fdd75..7a77db1e4 100644 --- a/src/Menus.cpp +++ b/src/Menus.cpp @@ -423,7 +423,8 @@ CommandFlag MenuManager::GetUpdateFlags } // These flags are cheap to calculate. - if (!gAudioIO->IsAudioTokenActive(project.GetAudioIOToken())) + if (!gAudioIO->IsAudioTokenActive(ProjectAudioIO::Get( project ) + .GetAudioIOToken())) flags |= AudioIONotBusyFlag; else flags |= AudioIOBusyFlag; diff --git a/src/MixerBoard.cpp b/src/MixerBoard.cpp index 979da57a0..ae49c63a2 100644 --- a/src/MixerBoard.cpp +++ b/src/MixerBoard.cpp @@ -1340,7 +1340,7 @@ void MixerBoard::OnTimer(wxCommandEvent &event) // Vaughan, 2010-01-30: // Since all we're doing here is updating the meters, I moved it to // audacityAudioCallback where it calls gAudioIO->mOutputMeter->UpdateDisplay(). - if (mProject->IsAudioActive()) + if (ProjectAudioIO::Get( *mProject ).IsAudioActive()) { UpdateMeters( gAudioIO->GetStreamTime(), diff --git a/src/Project.cpp b/src/Project.cpp index 58bd28f73..51244bd8a 100644 --- a/src/Project.cpp +++ b/src/Project.cpp @@ -1418,17 +1418,17 @@ void AudacityProject::OnThemeChange(wxCommandEvent& evt) AdornedRulerPanel::Get( project ).ReCreateButtons(); } -int AudacityProject::GetAudioIOToken() const +int ProjectAudioIO::GetAudioIOToken() const { return mAudioIOToken; } -void AudacityProject::SetAudioIOToken(int token) +void ProjectAudioIO::SetAudioIOToken(int token) { mAudioIOToken = token; } -bool AudacityProject::IsAudioActive() const +bool ProjectAudioIO::IsAudioActive() const { return GetAudioIOToken() > 0 && gAudioIO->IsStreamActive(GetAudioIOToken()); @@ -1780,7 +1780,7 @@ bool AudacityProject::MayScrollBeyondZero() const return true; if (scrubber.HasMark() || - IsAudioActive()) { + ProjectAudioIO::Get( project ).IsAudioActive()) { if (mPlaybackScroller) { auto mode = mPlaybackScroller->GetMode(); if (mode == PlaybackScroller::Mode::Pinned || @@ -2400,6 +2400,7 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event) auto &project = *this; auto &projectFileIO = project; const auto &settings = ProjectSettings::Get( project ); + auto &projectAudioIO = ProjectAudioIO::Get( project ); auto &tracks = TrackList::Get( project ); auto &window = project; @@ -2427,15 +2428,15 @@ void AudacityProject::OnCloseWindow(wxCloseEvent & event) // recording NEW state. // This code is derived from similar code in // AudacityProject::~AudacityProject() and TrackPanel::OnTimer(). - if (GetAudioIOToken()>0 && - gAudioIO->IsStreamActive(GetAudioIOToken())) { + if (projectAudioIO.GetAudioIOToken()>0 && + gAudioIO->IsStreamActive(projectAudioIO.GetAudioIOToken())) { // We were playing or recording audio, but we've stopped the stream. wxCommandEvent dummyEvent; ControlToolBar::Get( project ).OnStop(dummyEvent); FixScrollbars(); - SetAudioIOToken(0); + projectAudioIO.SetAudioIOToken(0); RedrawProject(); } else if (gAudioIO->IsMonitoring()) { @@ -4768,32 +4769,34 @@ void AudacityProject::SkipEnd(bool shift) } -MeterPanel *AudacityProject::GetPlaybackMeter() +MeterPanel *ProjectAudioIO::GetPlaybackMeter() { return mPlaybackMeter; } -void AudacityProject::SetPlaybackMeter(MeterPanel *playback) +void ProjectAudioIO::SetPlaybackMeter(MeterPanel *playback) { + auto &project = mProject; mPlaybackMeter = playback; if (gAudioIO) { - gAudioIO->SetPlaybackMeter(this, mPlaybackMeter); + gAudioIO->SetPlaybackMeter( &project , mPlaybackMeter ); } } -MeterPanel *AudacityProject::GetCaptureMeter() +MeterPanel *ProjectAudioIO::GetCaptureMeter() { return mCaptureMeter; } -void AudacityProject::SetCaptureMeter(MeterPanel *capture) +void ProjectAudioIO::SetCaptureMeter(MeterPanel *capture) { + auto &project = mProject; mCaptureMeter = capture; if (gAudioIO) { - gAudioIO->SetCaptureMeter(this, mCaptureMeter); + gAudioIO->SetCaptureMeter( &project, mCaptureMeter ); } } @@ -4808,6 +4811,7 @@ void AudacityProject::RestartTimer() void AudacityProject::OnTimer(wxTimerEvent& WXUNUSED(event)) { auto &project = *this; + auto &projectAudioIO = ProjectAudioIO::Get( project ); auto &window = project; auto &dirManager = DirManager::Get( project ); auto mixerToolBar = &MixerToolBar::Get( project ); @@ -4815,7 +4819,7 @@ void AudacityProject::OnTimer(wxTimerEvent& WXUNUSED(event)) // gAudioIO->GetNumCaptureChannels() should only be positive // when we are recording. - if (GetAudioIOToken() > 0 && gAudioIO->GetNumCaptureChannels() > 0) { + if (projectAudioIO.GetAudioIOToken() > 0 && gAudioIO->GetNumCaptureChannels() > 0) { wxLongLong freeSpace = dirManager.GetFreeDiskSpace(); if (freeSpace >= 0) { wxString sMessage; @@ -5063,11 +5067,12 @@ void AudacityProject::OnAudioIOStartRecording() void AudacityProject::OnAudioIOStopRecording() { auto &project = *this; + auto &projectAudioIO = ProjectAudioIO::Get( project ); auto &dirManager = DirManager::Get( project ); auto &window = ProjectWindow::Get( project ); // Only push state if we were capturing and not monitoring - if (GetAudioIOToken() > 0) + if (projectAudioIO.GetAudioIOToken() > 0) { auto &tracks = TrackList::Get( project ); auto &intervals = gAudioIO->LostCaptureIntervals(); @@ -5296,7 +5301,7 @@ void AudacityProject::PlaybackScroller::OnTimer(wxCommandEvent &event) this->ProcessEvent( event ); }); - if(!mProject->IsAudioActive()) + if(!ProjectAudioIO::Get( *mProject ).IsAudioActive()) return; else if (mMode == Mode::Refresh) { // PRL: see comments in Scrubbing.cpp for why this is sometimes needed. @@ -5346,7 +5351,8 @@ void AudacityProject::ZoomInByFactor( double ZoomFactor ) // LLL: Handling positioning differently when audio is // actively playing. Don't do this if paused. - if ((gAudioIO->IsStreamActive(GetAudioIOToken()) != 0) && + if (gAudioIO->IsStreamActive( + ProjectAudioIO::Get( project ).GetAudioIOToken()) && !gAudioIO->IsPaused()){ ZoomBy(ZoomFactor); trackPanel.ScrollIntoView(gAudioIO->GetStreamTime()); @@ -5450,3 +5456,28 @@ void AudacityProject::CloseLock() mLastSavedTracks.reset(); } } + +static const AudacityProject::AttachedObjects::RegisteredFactory sAudioIOKey{ + []( AudacityProject &parent ){ + return std::make_shared< ProjectAudioIO >( parent ); + } +}; + +ProjectAudioIO &ProjectAudioIO::Get( AudacityProject &project ) +{ + return project.AttachedObjects::Get< ProjectAudioIO >( sAudioIOKey ); +} + +const ProjectAudioIO &ProjectAudioIO::Get( const AudacityProject &project ) +{ + return Get( const_cast(project) ); +} + +ProjectAudioIO::ProjectAudioIO( AudacityProject &project ) +: mProject{ project } +{ +} + +ProjectAudioIO::~ProjectAudioIO() +{ +} diff --git a/src/Project.h b/src/Project.h index ee06debd3..036d79643 100644 --- a/src/Project.h +++ b/src/Project.h @@ -199,9 +199,6 @@ class AUDACITY_DLL_API AudacityProject final : public wxFrame, void SetPlayRegionLocked(bool value) { mLockPlayRegion = value; } wxString GetProjectName() const; - int GetAudioIOToken() const; - bool IsAudioActive() const; - void SetAudioIOToken(int token); bool IsActive() override; @@ -371,11 +368,6 @@ public: bool TP_ScrollUpDown(int delta) override; void TP_HandleResize() override; - MeterPanel *GetPlaybackMeter(); - void SetPlaybackMeter(MeterPanel *playback); - MeterPanel *GetCaptureMeter(); - void SetCaptureMeter(MeterPanel *capture); - const wxString &GetStatus() const { return mLastMainStatusMessage; } void SetStatus(const wxString &msg); @@ -484,10 +476,6 @@ private: bool mShownOnce{ false }; - // Project owned meters - MeterPanel *mPlaybackMeter{}; - MeterPanel *mCaptureMeter{}; - public: bool mbBusyImporting{ false }; // used to fix bug 584 int mBatchMode{ 0 };// 0 means not, >0 means in batch mode. @@ -500,8 +488,6 @@ private: void ResetTimerRecordCancelled(){mTimerRecordCanceled=false;} private: - int mAudioIOToken{ -1 }; - bool mIsDeleting{ false }; public: @@ -599,6 +585,35 @@ inline const wxFrame *FindProjectFrame( const AudacityProject *project ) { return project ? &GetProjectFrame( *project ) : nullptr; } +class ProjectAudioIO final + : public ClientData::Base +{ +public: + static ProjectAudioIO &Get( AudacityProject &project ); + static const ProjectAudioIO &Get( const AudacityProject &project ); + + explicit ProjectAudioIO( AudacityProject &project ); + ~ProjectAudioIO(); + + int GetAudioIOToken() const; + bool IsAudioActive() const; + void SetAudioIOToken(int token); + + MeterPanel *GetPlaybackMeter(); + void SetPlaybackMeter(MeterPanel *playback); + MeterPanel *GetCaptureMeter(); + void SetCaptureMeter(MeterPanel *capture); + +private: + AudacityProject &mProject; + + // Project owned meters + MeterPanel *mPlaybackMeter{}; + MeterPanel *mCaptureMeter{}; + + int mAudioIOToken{ -1 }; +}; + AudioIOStartStreamOptions DefaultPlayOptions( AudacityProject &project ); AudioIOStartStreamOptions DefaultSpeedPlayOptions( AudacityProject &project ); diff --git a/src/TrackPanel.cpp b/src/TrackPanel.cpp index e6ce05215..cd43fbb63 100644 --- a/src/TrackPanel.cpp +++ b/src/TrackPanel.cpp @@ -467,8 +467,10 @@ void TrackPanel::OnTimer(wxTimerEvent& ) AudacityProject *const p = GetProject(); auto &window = ProjectWindow::Get( *p ); + auto &projectAudioIO = ProjectAudioIO::Get( *p ); + // Check whether we were playing or recording, but the stream has stopped. - if (p->GetAudioIOToken()>0 && !IsAudioActive()) + if (projectAudioIO.GetAudioIOToken()>0 && !IsAudioActive()) { //the stream may have been started up after this one finished (by some other project) //in that case reset the buttons don't stop the stream @@ -478,11 +480,11 @@ void TrackPanel::OnTimer(wxTimerEvent& ) // Next, check to see if we were playing or recording // audio, but now Audio I/O is completely finished. - if (p->GetAudioIOToken()>0 && - !gAudioIO->IsAudioTokenActive(p->GetAudioIOToken())) + if (projectAudioIO.GetAudioIOToken()>0 && + !gAudioIO->IsAudioTokenActive(projectAudioIO.GetAudioIOToken())) { window.FixScrollbars(); - p->SetAudioIOToken(0); + projectAudioIO.SetAudioIOToken(0); window.RedrawProject(); mRedrawAfterStop = false; @@ -718,7 +720,7 @@ void TrackPanel::HandlePageDownKey() bool TrackPanel::IsAudioActive() { AudacityProject *p = GetProject(); - return p->IsAudioActive(); + return ProjectAudioIO::Get( *p ).IsAudioActive(); } void TrackPanel::UpdateStatusMessage( const wxString &st ) diff --git a/src/menus/LabelMenus.cpp b/src/menus/LabelMenus.cpp index 89802a341..c1d643018 100644 --- a/src/menus/LabelMenus.cpp +++ b/src/menus/LabelMenus.cpp @@ -267,7 +267,7 @@ void OnAddLabel(const CommandContext &context) void OnAddLabelPlaying(const CommandContext &context) { auto &project = context.project; - auto token = project.GetAudioIOToken(); + auto token = ProjectAudioIO::Get( project ).GetAudioIOToken(); if (token > 0 && gAudioIO->IsStreamActive(token)) { diff --git a/src/menus/SelectMenus.cpp b/src/menus/SelectMenus.cpp index 24131b949..adb75c757 100644 --- a/src/menus/SelectMenus.cpp +++ b/src/menus/SelectMenus.cpp @@ -173,7 +173,7 @@ bool OnlyHandleKeyUp( const CommandContext &context ) auto evt = context.pEvt; bool bKeyUp = (evt) && evt->GetEventType() == wxEVT_KEY_UP; - if( project.IsAudioActive() ) + if( ProjectAudioIO::Get( project ).IsAudioActive() ) return bKeyUp; if( !bKeyUp ) return false; @@ -377,7 +377,7 @@ void SeekLeftOrRight // zoom and does not vary if the key is held // Else: jump depends on the zoom and gets bigger if the key is held - if( project.IsAudioActive() ) + if( ProjectAudioIO::Get( project ).IsAudioActive() ) { if( operation == CURSOR_MOVE ) SeekWhenAudioActive( info.mSeekShort * direction, @@ -410,7 +410,7 @@ void DoCursorMove( AudacityProject &project, double seekStep, wxLongLong &lastSelectionAdjustment) { - if (project.IsAudioActive()) { + if (ProjectAudioIO::Get( project ).IsAudioActive()) { SeekWhenAudioActive(seekStep, lastSelectionAdjustment); } else @@ -445,7 +445,7 @@ void DoBoundaryMove(AudacityProject &project, int step, SeekInfo &info) // contracting. it is no longer needed. bool bMoveT0 = (step < 0 );// ^ boundaryContract ; - if( project.IsAudioActive() ) + if( ProjectAudioIO::Get( project ).IsAudioActive() ) { double indicator = gAudioIO->GetStreamTime(); if( bMoveT0 ) @@ -616,7 +616,7 @@ void OnSelectSyncLockSel(const CommandContext &context) void OnSetLeftSelection(const CommandContext &context) { auto &project = context.project; - auto token = project.GetAudioIOToken(); + auto token = ProjectAudioIO::Get( project ).GetAudioIOToken(); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; const auto &settings = ProjectSettings::Get( project ); auto &trackPanel = TrackPanel::Get( project ); @@ -656,7 +656,7 @@ void OnSetLeftSelection(const CommandContext &context) void OnSetRightSelection(const CommandContext &context) { auto &project = context.project; - auto token = project.GetAudioIOToken(); + auto token = ProjectAudioIO::Get( project ).GetAudioIOToken(); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; const auto &settings = ProjectSettings::Get( project ); auto &trackPanel = TrackPanel::Get( project ); @@ -846,7 +846,7 @@ void OnSelectCursorStoredCursor(const CommandContext &context) auto &project = context.project; auto &trackPanel = TrackPanel::Get( project ); auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto isAudioActive = project.IsAudioActive(); + auto isAudioActive = ProjectAudioIO::Get( project ).IsAudioActive(); if (mCursorPositionHasBeenStored) { double cursorPositionCurrent = isAudioActive @@ -865,7 +865,7 @@ void OnCursorPositionStore(const CommandContext &context) { auto &project = context.project; auto &selectedRegion = ViewInfo::Get( project ).selectedRegion; - auto isAudioActive = project.IsAudioActive(); + auto isAudioActive = ProjectAudioIO::Get( project ).IsAudioActive(); mCursorPositionStored = isAudioActive ? gAudioIO->GetStreamTime() : selectedRegion.t0(); diff --git a/src/menus/TrackMenus.cpp b/src/menus/TrackMenus.cpp index 788a19f4a..866b0084f 100644 --- a/src/menus/TrackMenus.cpp +++ b/src/menus/TrackMenus.cpp @@ -1404,7 +1404,7 @@ void OnTrackClose(const CommandContext &context) if (!t) return; - auto isAudioActive = project.IsAudioActive(); + auto isAudioActive = ProjectAudioIO::Get( project ).IsAudioActive(); if (isAudioActive) { diff --git a/src/menus/TransportMenus.cpp b/src/menus/TransportMenus.cpp index e228a865a..f35b7efd0 100644 --- a/src/menus/TransportMenus.cpp +++ b/src/menus/TransportMenus.cpp @@ -42,7 +42,9 @@ bool MakeReadyToPlay(AudacityProject &project, wxCommandEvent evt; // If this project is playing, stop playing - if (gAudioIO->IsStreamActive(project.GetAudioIOToken())) { + if (gAudioIO->IsStreamActive( + ProjectAudioIO::Get( project ).GetAudioIOToken() + )) { toolbar.SetPlay(false); //Pops toolbar.SetStop(true); //Pushes stop down toolbar.OnStop(evt); @@ -82,7 +84,7 @@ void DoPlayStop(const CommandContext &context) auto &project = context.project; auto &toolbar = ControlToolBar::Get( project ); auto &window = ProjectWindow::Get( project ); - auto token = project.GetAudioIOToken(); + auto token = ProjectAudioIO::Get( project ).GetAudioIOToken(); //If this project is playing, stop playing, make sure everything is unpaused. if (gAudioIO->IsStreamActive(token)) { @@ -98,7 +100,8 @@ void DoPlayStop(const CommandContext &context) auto start = AllProjects{}.begin(), finish = AllProjects{}.end(), iter = std::find_if( start, finish, []( const AllProjects::value_type &ptr ){ - return gAudioIO->IsStreamActive(ptr->GetAudioIOToken()); } ); + return gAudioIO->IsStreamActive( + ProjectAudioIO::Get( *ptr ).GetAudioIOToken()); } ); //stop playing the other project if(iter != finish) { @@ -166,7 +169,7 @@ void DoMoveToLabel(AudacityProject &project, bool next) if (i >= 0) { const LabelStruct* label = lt->GetLabel(i); - if (project.IsAudioActive()) { + if (ProjectAudioIO::Get( project ).IsAudioActive()) { DoPlayStop(project); // stop selectedRegion = label->selectedRegion; window.RedrawProject(); @@ -208,7 +211,7 @@ bool DoPlayStopSelect { auto &toolbar = ControlToolBar::Get( project ); auto &scrubber = Scrubber::Get( project ); - auto token = project.GetAudioIOToken(); + auto token = ProjectAudioIO::Get( project ).GetAudioIOToken(); auto &viewInfo = ViewInfo::Get( project ); auto &selection = viewInfo.selectedRegion; diff --git a/src/toolbars/ControlToolBar.cpp b/src/toolbars/ControlToolBar.cpp index ac90586db..ea1540928 100644 --- a/src/toolbars/ControlToolBar.cpp +++ b/src/toolbars/ControlToolBar.cpp @@ -722,7 +722,7 @@ int ControlToolBar::PlayPlayRegion(const SelectedRegion &selectedRegion, } if (token != 0) { success = true; - p->SetAudioIOToken(token); + ProjectAudioIO::Get( *p ).SetAudioIOToken(token); mBusyProject = p; #if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR) //AC: If init_seek was set, now's the time to make it happen. @@ -794,7 +794,9 @@ void ControlToolBar::OnKeyEvent(wxKeyEvent & event) // Does not appear to be needed on Linux. Perhaps on some other platform? // If so, "!CanStopAudioStream()" should probably apply. if (event.GetKeyCode() == WXK_SPACE) { - if (gAudioIO->IsStreamActive(GetActiveProject()->GetAudioIOToken())) { + if (gAudioIO->IsStreamActive( + ProjectAudioIO::Get( *GetActiveProject() ).GetAudioIOToken() + )) { SetPlay(false); SetStop(true); StopPlaying(); @@ -887,12 +889,13 @@ void ControlToolBar::StopPlaying(bool stopStream /* = true*/) // So that we continue monitoring after playing or recording. // also clean the MeterQueues if( project ) { - MeterPanel *meter = project->GetPlaybackMeter(); + auto &projectAudioIO = ProjectAudioIO::Get( *project ); + MeterPanel *meter = projectAudioIO.GetPlaybackMeter(); if( meter ) { meter->Clear(); } - meter = project->GetCaptureMeter(); + meter = projectAudioIO.GetCaptureMeter(); if( meter ) { meter->Clear(); } @@ -1266,7 +1269,7 @@ bool ControlToolBar::DoRecord(AudacityProject &project, success = (token != 0); if (success) { - p->SetAudioIOToken(token); + ProjectAudioIO::Get( *p ).SetAudioIOToken(token); mBusyProject = p; StartScrollingIfPreferred(); diff --git a/src/toolbars/MeterToolBar.cpp b/src/toolbars/MeterToolBar.cpp index a1e656462..7d85fdab0 100644 --- a/src/toolbars/MeterToolBar.cpp +++ b/src/toolbars/MeterToolBar.cpp @@ -89,27 +89,28 @@ void MeterToolBar::ReCreateButtons() { MeterPanel::State playState{ false }, recordState{ false }; - if (mPlayMeter && mProject->GetPlaybackMeter() == mPlayMeter) + auto &projectAudioIO = ProjectAudioIO::Get( *mProject ); + if (mPlayMeter && projectAudioIO.GetPlaybackMeter() == mPlayMeter) { playState = mPlayMeter->SaveState(); - mProject->SetPlaybackMeter( NULL ); + projectAudioIO.SetPlaybackMeter( nullptr ); } - if (mRecordMeter && mProject->GetCaptureMeter() == mRecordMeter) + if (mRecordMeter && projectAudioIO.GetCaptureMeter() == mRecordMeter) { recordState = mRecordMeter->SaveState(); - mProject->SetCaptureMeter( NULL ); + projectAudioIO.SetCaptureMeter( nullptr ); } ToolBar::ReCreateButtons(); mPlayMeter->RestoreState(playState); if( playState.mSaved ){ - mProject->SetPlaybackMeter( mPlayMeter ); + projectAudioIO.SetPlaybackMeter( mPlayMeter ); } mRecordMeter->RestoreState(recordState); if( recordState.mSaved ){ - mProject->SetCaptureMeter( mRecordMeter ); + projectAudioIO.SetCaptureMeter( mRecordMeter ); } } @@ -229,21 +230,22 @@ void MeterToolBar::OnSize( wxSizeEvent & event) //WXUNUSED(event) ) bool MeterToolBar::Expose( bool show ) { + auto &projectAudioIO = ProjectAudioIO::Get( *mProject ); if( show ) { if( mPlayMeter ) { - mProject->SetPlaybackMeter( mPlayMeter ); + projectAudioIO.SetPlaybackMeter( mPlayMeter ); } if( mRecordMeter ) { - mProject->SetCaptureMeter( mRecordMeter ); + projectAudioIO.SetCaptureMeter( mRecordMeter ); } } else { - if( mPlayMeter && mProject->GetPlaybackMeter() == mPlayMeter ) { - mProject->SetPlaybackMeter( NULL ); + if( mPlayMeter && projectAudioIO.GetPlaybackMeter() == mPlayMeter ) { + projectAudioIO.SetPlaybackMeter( nullptr ); } - if( mRecordMeter && mProject->GetCaptureMeter() == mRecordMeter ) { - mProject->SetCaptureMeter( NULL ); + if( mRecordMeter && projectAudioIO.GetCaptureMeter() == mRecordMeter ) { + projectAudioIO.SetCaptureMeter( nullptr ); } } diff --git a/src/tracks/labeltrack/ui/LabelTextHandle.cpp b/src/tracks/labeltrack/ui/LabelTextHandle.cpp index a37c0a603..1b6c443e9 100644 --- a/src/tracks/labeltrack/ui/LabelTextHandle.cpp +++ b/src/tracks/labeltrack/ui/LabelTextHandle.cpp @@ -107,7 +107,7 @@ UIHandle::Result LabelTextHandle::Click } // PRL: bug1659 -- make selection change undo correctly - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (!unsafe) pProject->ModifyState(false); diff --git a/src/tracks/playabletrack/notetrack/ui/StretchHandle.cpp b/src/tracks/playabletrack/notetrack/ui/StretchHandle.cpp index d4ca4025a..190d17c02 100644 --- a/src/tracks/playabletrack/notetrack/ui/StretchHandle.cpp +++ b/src/tracks/playabletrack/notetrack/ui/StretchHandle.cpp @@ -155,7 +155,7 @@ UIHandle::Result StretchHandle::Click (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if ( unsafe ) return Cancelled; @@ -184,7 +184,7 @@ UIHandle::Result StretchHandle::Drag (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) { this->Cancel(pProject); return RefreshAll | Cancelled; @@ -207,7 +207,7 @@ UIHandle::Result StretchHandle::Drag HitTestPreview StretchHandle::Preview (const TrackPanelMouseState &, const AudacityProject *pProject) { - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); return HitPreview( mStretchState.mMode, unsafe ); } @@ -217,7 +217,7 @@ UIHandle::Result StretchHandle::Release { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) { this->Cancel(pProject); return RefreshAll | Cancelled; diff --git a/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp b/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp index ccb20f9ba..ef27e9598 100644 --- a/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/CutlineHandle.cpp @@ -121,7 +121,7 @@ UIHandle::Result CutlineHandle::Click (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if ( unsafe ) return Cancelled; @@ -208,7 +208,7 @@ UIHandle::Result CutlineHandle::Drag HitTestPreview CutlineHandle::Preview (const TrackPanelMouseState &, const AudacityProject *pProject) { - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); auto bCutline = (mLocation.typ == WaveTrackLocation::locationCutLine); return HitPreview( bCutline, unsafe ); } diff --git a/src/tracks/playabletrack/wavetrack/ui/SampleHandle.cpp b/src/tracks/playabletrack/wavetrack/ui/SampleHandle.cpp index 68d3b9d5d..7ba026b5a 100644 --- a/src/tracks/playabletrack/wavetrack/ui/SampleHandle.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/SampleHandle.cpp @@ -205,7 +205,7 @@ UIHandle::Result SampleHandle::Click (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if ( unsafe ) return Cancelled; @@ -337,7 +337,7 @@ UIHandle::Result SampleHandle::Drag const wxMouseEvent &event = evt.event; const auto &viewInfo = ViewInfo::Get( *pProject ); - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) { this->Cancel(pProject); return RefreshCell | Cancelled; @@ -416,7 +416,7 @@ UIHandle::Result SampleHandle::Drag HitTestPreview SampleHandle::Preview (const TrackPanelMouseState &st, const AudacityProject *pProject) { - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); return HitPreview(st.state, pProject, unsafe); } @@ -424,7 +424,7 @@ UIHandle::Result SampleHandle::Release (const TrackPanelMouseEvent &, AudacityProject *pProject, wxWindow *) { - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) return this->Cancel(pProject); diff --git a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp index 9143d8387..8ff0f4452 100644 --- a/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp +++ b/src/tracks/playabletrack/wavetrack/ui/WaveTrackControls.cpp @@ -176,7 +176,7 @@ void WaveColorMenuTable::InitMenu(Menu *pMenu, void *pUserData) SetMenuChecks(*pMenu, [=](int id){ return id == WaveColorId; }); AudacityProject *const project = ::GetActiveProject(); - bool unsafe = project->IsAudioActive(); + bool unsafe = ProjectAudioIO::Get( *project ).IsAudioActive(); for (int i = OnInstrument1ID; i <= OnInstrument4ID; i++) { pMenu->Enable(i, !unsafe); } @@ -269,7 +269,7 @@ void FormatMenuTable::InitMenu(Menu *pMenu, void *pUserData) SetMenuChecks(*pMenu, [=](int id){ return id == formatId; }); AudacityProject *const project = ::GetActiveProject(); - bool unsafe = project->IsAudioActive(); + bool unsafe = ProjectAudioIO::Get( *project ).IsAudioActive(); for (int i = On16BitID; i <= OnFloatID; i++) { pMenu->Enable(i, !unsafe); } @@ -387,7 +387,7 @@ void RateMenuTable::InitMenu(Menu *pMenu, void *pUserData) SetMenuChecks(*pMenu, [=](int id){ return id == rateId; }); AudacityProject *const project = ::GetActiveProject(); - bool unsafe = project->IsAudioActive(); + bool unsafe = ProjectAudioIO::Get( *project ).IsAudioActive(); for (int i = OnRate8ID; i <= OnRateOtherID; i++) { pMenu->Enable(i, !unsafe); } @@ -606,7 +606,7 @@ void WaveTrackMenuTable::InitMenu(Menu *pMenu, void *pUserData) AudacityProject *const project = ::GetActiveProject(); auto &tracks = TrackList::Get( *project ); bool unsafe = EffectManager::Get().RealtimeIsActive() && - project->IsAudioActive(); + ProjectAudioIO::Get( *project ).IsAudioActive(); auto nChannels = TrackList::Channels(pTrack).size(); const bool isMono = ( nChannels == 1 ); diff --git a/src/tracks/ui/EnvelopeHandle.cpp b/src/tracks/ui/EnvelopeHandle.cpp index 921b26a37..53d65947e 100644 --- a/src/tracks/ui/EnvelopeHandle.cpp +++ b/src/tracks/ui/EnvelopeHandle.cpp @@ -169,7 +169,7 @@ UIHandle::Result EnvelopeHandle::Click (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if ( unsafe ) return Cancelled; @@ -241,7 +241,7 @@ UIHandle::Result EnvelopeHandle::Drag using namespace RefreshCode; const wxMouseEvent &event = evt.event; const auto &viewInfo = ViewInfo::Get( *pProject ); - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) { this->Cancel(pProject); return RefreshCell | Cancelled; @@ -254,7 +254,7 @@ UIHandle::Result EnvelopeHandle::Drag HitTestPreview EnvelopeHandle::Preview (const TrackPanelMouseState &, const AudacityProject *pProject) { - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); static auto disabledCursor = ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16); static auto envelopeCursor = @@ -280,7 +280,7 @@ UIHandle::Result EnvelopeHandle::Release { const wxMouseEvent &event = evt.event; const auto &viewInfo = ViewInfo::Get( *pProject ); - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) return this->Cancel(pProject); diff --git a/src/tracks/ui/PlayIndicatorOverlay.cpp b/src/tracks/ui/PlayIndicatorOverlay.cpp index ff48ba8b3..a3c2ac53e 100644 --- a/src/tracks/ui/PlayIndicatorOverlay.cpp +++ b/src/tracks/ui/PlayIndicatorOverlay.cpp @@ -148,7 +148,7 @@ void PlayIndicatorOverlay::OnTimer(wxCommandEvent &event) int width; trackPanel.GetTracksUsableArea(&width, nullptr); - if (!mProject->IsAudioActive()) { + if (!ProjectAudioIO::Get( *mProject ).IsAudioActive()) { mNewIndicatorX = -1; mNewIsCapturing = false; const auto &scrubber = Scrubber::Get( *mProject ); diff --git a/src/tracks/ui/Scrubbing.cpp b/src/tracks/ui/Scrubbing.cpp index feb8e9e28..cb6c54051 100644 --- a/src/tracks/ui/Scrubbing.cpp +++ b/src/tracks/ui/Scrubbing.cpp @@ -311,7 +311,7 @@ void Scrubber::MarkScrubStart( // Usually the timer handler of TrackPanel does this, but we do this now, // so that same timer does not StopPlaying() again after this function and destroy // scrubber state - mProject->SetAudioIOToken(0); + ProjectAudioIO::Get( *mProject ).SetAudioIOToken(0); mSeeking = seek; CheckMenuItems(); @@ -721,8 +721,9 @@ bool Scrubber::IsScrubbing() const { if (mScrubToken <= 0) return false; - else if (mScrubToken == mProject->GetAudioIOToken() && - mProject->IsAudioActive()) + auto projectAudioIO = ProjectAudioIO::Get( *mProject ); + if (mScrubToken == projectAudioIO.GetAudioIOToken() && + projectAudioIO.IsAudioActive()) return true; else { const_cast(*this).mScrubToken = -1; diff --git a/src/tracks/ui/SelectHandle.cpp b/src/tracks/ui/SelectHandle.cpp index 37b642ac5..83eff3f5e 100644 --- a/src/tracks/ui/SelectHandle.cpp +++ b/src/tracks/ui/SelectHandle.cpp @@ -544,7 +544,7 @@ UIHandle::Result SelectHandle::Click // We should reach this, only in default of other hits on glyphs or // text boxes. bool bShift = event.ShiftDown(); - bool unsafe = pProject->IsAudioActive(); + bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); SelectActions::DoListSelection( *pProject, pTrack, bShift, true, !unsafe); return true; diff --git a/src/tracks/ui/TimeShiftHandle.cpp b/src/tracks/ui/TimeShiftHandle.cpp index b6021d2ae..f9cfd4d5b 100644 --- a/src/tracks/ui/TimeShiftHandle.cpp +++ b/src/tracks/ui/TimeShiftHandle.cpp @@ -354,7 +354,7 @@ UIHandle::Result TimeShiftHandle::Click (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if ( unsafe ) return Cancelled; @@ -672,7 +672,7 @@ UIHandle::Result TimeShiftHandle::Drag (const TrackPanelMouseEvent &evt, AudacityProject *pProject) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) { this->Cancel(pProject); return RefreshAll | Cancelled; @@ -777,7 +777,7 @@ HitTestPreview TimeShiftHandle::Preview { // After all that, it still may be unsafe to drag. // Even if so, make an informative cursor change from default to "banned." - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); return HitPreview(pProject, unsafe); } @@ -786,7 +786,7 @@ UIHandle::Result TimeShiftHandle::Release wxWindow *) { using namespace RefreshCode; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) return this->Cancel(pProject); diff --git a/src/tracks/ui/TrackButtonHandles.cpp b/src/tracks/ui/TrackButtonHandles.cpp index d83451db5..1511a3495 100644 --- a/src/tracks/ui/TrackButtonHandles.cpp +++ b/src/tracks/ui/TrackButtonHandles.cpp @@ -90,7 +90,7 @@ UIHandle::Result SelectButtonHandle::CommitChanges auto pTrack = mpTrack.lock(); if (pTrack) { - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); SelectActions::DoListSelection(*pProject, pTrack.get(), event.ShiftDown(), event.ControlDown(), !unsafe); // return RefreshAll ; @@ -147,7 +147,7 @@ UIHandle::Result CloseButtonHandle::CommitChanges if (pTrack) { TransportActions::StopIfPaused( *pProject ); - if (!pProject->IsAudioActive()) { + if (!ProjectAudioIO::Get( *pProject ).IsAudioActive()) { // This pushes an undo item: TrackActions::DoRemoveTrack(*pProject, pTrack.get()); // Redraw all tracks when any one of them closes diff --git a/src/tracks/ui/TrackSelectHandle.cpp b/src/tracks/ui/TrackSelectHandle.cpp index 2d760bb45..04d57f447 100644 --- a/src/tracks/ui/TrackSelectHandle.cpp +++ b/src/tracks/ui/TrackSelectHandle.cpp @@ -84,7 +84,7 @@ UIHandle::Result TrackSelectHandle::Click const auto pTrack = mpTrack; if (!pTrack) return Cancelled; - const bool unsafe = pProject->IsAudioActive(); + const bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); // DM: If they weren't clicking on a particular part of a track label, // deselect other tracks and select this one. @@ -116,7 +116,7 @@ UIHandle::Result TrackSelectHandle::Drag auto &tracks = TrackList::Get( *pProject ); // probably harmless during play? However, we do disallow the click, so check this too. - bool unsafe = pProject->IsAudioActive(); + bool unsafe = ProjectAudioIO::Get( *pProject ).IsAudioActive(); if (unsafe) return result; @@ -150,7 +150,8 @@ HitTestPreview TrackSelectHandle::Preview ::MakeCursor(wxCURSOR_NO_ENTRY, DisabledCursorXpm, 16, 16); static wxCursor rearrangeCursor{ wxCURSOR_HAND }; - const bool unsafe = GetActiveProject()->IsAudioActive(); + const bool unsafe = + ProjectAudioIO::Get( *GetActiveProject() ).IsAudioActive(); return { message, (unsafe