Audacity 3.2.0
Public Member Functions | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
ProjectAudioManager Class Referencefinal

#include <ProjectAudioManager.h>

Inheritance diagram for ProjectAudioManager:
[legend]
Collaboration diagram for ProjectAudioManager:
[legend]

Public Member Functions

 ProjectAudioManager (AudacityProject &project)
 
 ProjectAudioManager (const ProjectAudioManager &) PROHIBITED
 
ProjectAudioManageroperator= (const ProjectAudioManager &) PROHIBITED
 
 ~ProjectAudioManager () override
 
bool IsTimerRecordCancelled ()
 
void SetTimerRecordCancelled ()
 
void ResetTimerRecordCancelled ()
 
bool Paused () const
 
bool Playing () const
 
bool Recording () const
 
bool Stopping () const
 
bool Appending () const
 
bool Looping () const
 
bool Cutting () const
 
bool CanStopAudioStream () const
 
void OnRecord (bool altAppearance)
 
bool DoRecord (AudacityProject &project, const TransportTracks &transportTracks, double t0, double t1, bool altAppearance, const AudioIOStartStreamOptions &options)
 
int PlayPlayRegion (const SelectedRegion &selectedRegion, const AudioIOStartStreamOptions &options, PlayMode playMode, bool backwards=false)
 
void PlayCurrentRegion (bool newDefault=false, bool cutpreview=false)
 
void OnPause ()
 
void Stop (bool stopStream=true)
 
void StopIfPaused ()
 
bool DoPlayStopSelect (bool click, bool shift)
 
void DoPlayStopSelect ()
 
PlayMode GetLastPlayMode () const
 
- Public Member Functions inherited from ClientData::Base
virtual ~Base ()
 
- Public Member Functions inherited from AudioIOListener
 AudioIOListener ()
 
virtual ~AudioIOListener ()
 
virtual void OnAudioIORate (int rate)=0
 
virtual void OnAudioIOStartRecording ()=0
 
virtual void OnAudioIOStopRecording ()=0
 
virtual void OnAudioIONewBlocks (const WaveTrackArray *tracks)=0
 
virtual void OnCommitRecording ()=0
 
virtual void OnSoundActivationThreshold ()=0
 

Static Public Member Functions

static ProjectAudioManagerGet (AudacityProject &project)
 
static const ProjectAudioManagerGet (const AudacityProject &project)
 
static WaveTrackArray ChooseExistingRecordingTracks (AudacityProject &proj, bool selectedOnly, double targetRate=RATE_NOT_SELECTED)
 
static bool UseDuplex ()
 
static TransportTracks GetAllPlaybackTracks (TrackList &trackList, bool selectedOnly, bool nonWaveToo=false)
 

Private Member Functions

void TogglePaused ()
 
void SetPausedOff ()
 
void SetAppending (bool value)
 
void SetLooping (bool value)
 
void SetCutting (bool value)
 
void SetStopping (bool value)
 
void CancelRecording ()
 
void OnAudioIORate (int rate) override
 
void OnAudioIOStartRecording () override
 
void OnAudioIOStopRecording () override
 
void OnAudioIONewBlocks (const WaveTrackArray *tracks) override
 
void OnCommitRecording () override
 
void OnSoundActivationThreshold () override
 
void OnCheckpointFailure (wxCommandEvent &evt)
 

Static Private Member Functions

static std::pair< TranslatableStrings, unsigned > StatusWidthFunction (const AudacityProject &project, StatusBarField field)
 

Private Attributes

AudacityProjectmProject
 
PlayMode mLastPlayMode { PlayMode::normalPlay }
 
bool mTimerRecordCanceled { false }
 
std::atomic< int > mPaused { 0 }
 
bool mAppending { false }
 
bool mLooping { false }
 
bool mCutting { false }
 
bool mStopping { false }
 
int mDisplayedRate { 0 }
 

Detailed Description

Definition at line 70 of file ProjectAudioManager.h.

Constructor & Destructor Documentation

◆ ProjectAudioManager() [1/2]

ProjectAudioManager::ProjectAudioManager ( AudacityProject project)
explicit

Definition at line 67 of file ProjectAudioManager.cpp.

68 : mProject{ project }
69{
71 registerStatusWidthFunction{ StatusWidthFunction };
72 project.Bind( EVT_CHECKPOINT_FAILURE,
74}
AudacityProject & mProject
static std::pair< TranslatableStrings, unsigned > StatusWidthFunction(const AudacityProject &project, StatusBarField field)
void OnCheckpointFailure(wxCommandEvent &evt)

References OnCheckpointFailure(), and StatusWidthFunction().

Here is the call graph for this function:

◆ ProjectAudioManager() [2/2]

ProjectAudioManager::ProjectAudioManager ( const ProjectAudioManager )

◆ ~ProjectAudioManager()

ProjectAudioManager::~ProjectAudioManager ( )
overridedefault

Member Function Documentation

◆ Appending()

bool ProjectAudioManager::Appending ( ) const
inline

Definition at line 111 of file ProjectAudioManager.h.

111{ return mAppending; }

◆ CancelRecording()

void ProjectAudioManager::CancelRecording ( )
private

Definition at line 1020 of file ProjectAudioManager.cpp.

1021{
1022 const auto project = &mProject;
1023 TrackList::Get( *project ).ClearPendingTracks();
1024}
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:486
void ClearPendingTracks(ListOfTracks *pAdded=nullptr)
Definition: Track.cpp:1103

References TrackList::ClearPendingTracks(), and TrackList::Get().

Here is the call graph for this function:

◆ CanStopAudioStream()

bool ProjectAudioManager::CanStopAudioStream ( ) const

Definition at line 1141 of file ProjectAudioManager.cpp.

1142{
1143 auto gAudioIO = AudioIO::Get();
1144 return (!gAudioIO->IsStreamActive() ||
1145 gAudioIO->IsMonitoring() ||
1146 gAudioIO->GetOwningProject().get() == &mProject );
1147}
static AudioIO * Get()
Definition: AudioIO.cpp:133

References AudioIO::Get().

Here is the call graph for this function:

◆ ChooseExistingRecordingTracks()

WaveTrackArray ProjectAudioManager::ChooseExistingRecordingTracks ( AudacityProject proj,
bool  selectedOnly,
double  targetRate = RATE_NOT_SELECTED 
)
static

Definition at line 563 of file ProjectAudioManager.cpp.

565{
566 auto p = &proj;
567 size_t recordingChannels = std::max(0, AudioIORecordChannels.Read());
568 bool strictRules = (recordingChannels <= 2);
569
570 // Iterate over all wave tracks, or over selected wave tracks only.
571 // If target rate was specified, ignore all tracks with other rates.
572 //
573 // In the usual cases of one or two recording channels, seek a first-fit
574 // unbroken sub-sequence for which the total number of channels matches the
575 // required number exactly. Never drop inputs or fill only some channels
576 // of a track.
577 //
578 // In case of more than two recording channels, choose tracks only among the
579 // selected. Simply take the earliest wave tracks, until the number of
580 // channels is enough. If there are fewer channels than inputs, but at least
581 // one channel, then some of the input channels will be dropped.
582 //
583 // Resulting tracks may be non-consecutive within the list of all tracks
584 // (there may be non-wave tracks between, or non-selected tracks when
585 // considering selected tracks only.)
586
587 if (!strictRules && !selectedOnly)
588 return {};
589
590 auto &trackList = TrackList::Get( *p );
591 std::vector<unsigned> channelCounts;
592 WaveTrackArray candidates;
593 const auto range = trackList.Leaders<WaveTrack>();
594 for ( auto candidate : selectedOnly ? range + &Track::IsSelected : range ) {
595 if (targetRate != RATE_NOT_SELECTED && candidate->GetRate() != targetRate)
596 continue;
597
598 // count channels in this track
599 const auto channels = TrackList::Channels( candidate );
600 unsigned nChannels = channels.size();
601
602 if (strictRules && nChannels > recordingChannels) {
603 // The recording would under-fill this track's channels
604 // Can't use any partial accumulated results
605 // either. Keep looking.
606 candidates.clear();
607 channelCounts.clear();
608 continue;
609 }
610 else {
611 // Might use this but may have to discard some of the accumulated
612 while(strictRules &&
613 nChannels + candidates.size() > recordingChannels) {
614 auto nOldChannels = channelCounts[0];
615 wxASSERT(nOldChannels > 0);
616 channelCounts.erase(channelCounts.begin());
617 candidates.erase(candidates.begin(),
618 candidates.begin() + nOldChannels);
619 }
620 channelCounts.push_back(nChannels);
621 for ( auto channel : channels ) {
622 candidates.push_back(channel->SharedPointer<WaveTrack>());
623 if(candidates.size() == recordingChannels)
624 // Done!
625 return candidates;
626 }
627 }
628 }
629
630 if (!strictRules && !candidates.empty())
631 // good enough
632 return candidates;
633
634 // If the loop didn't exit early, we could not find enough channels
635 return {};
636}
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:49
IntSetting AudioIORecordChannels
constexpr int RATE_NOT_SELECTED
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:200
bool IsSelected() const
Definition: Track.cpp:402
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1541
A Track that contains audio waveform data.
Definition: WaveTrack.h:57

References AudioIORecordChannels, TrackList::Channels(), TrackList::Get(), Track::IsSelected(), RATE_NOT_SELECTED, and Setting< T >::Read().

Referenced by TransportActions::Handler::OnTimerRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Cutting()

bool ProjectAudioManager::Cutting ( ) const
inline

Definition at line 114 of file ProjectAudioManager.h.

114{ return mCutting; }

◆ DoPlayStopSelect() [1/2]

void ProjectAudioManager::DoPlayStopSelect ( )

Definition at line 1294 of file ProjectAudioManager.cpp.

1295{
1296 auto gAudioIO = AudioIO::Get();
1297 if (DoPlayStopSelect(false, false))
1298 Stop();
1299 else if (!gAudioIO->IsBusy()) {
1300 //Otherwise, start playing (assuming audio I/O isn't busy)
1301
1302 // Will automatically set mLastPlayMode
1303 PlayCurrentRegion(false);
1304 }
1305}
void Stop(bool stopStream=true)
void PlayCurrentRegion(bool newDefault=false, bool cutpreview=false)

References AudioIO::Get().

Here is the call graph for this function:

◆ DoPlayStopSelect() [2/2]

bool ProjectAudioManager::DoPlayStopSelect ( bool  click,
bool  shift 
)

Definition at line 1238 of file ProjectAudioManager.cpp.

1239{
1240 auto &project = mProject;
1241 auto &scrubber = Scrubber::Get( project );
1242 auto token = ProjectAudioIO::Get( project ).GetAudioIOToken();
1243 auto &viewInfo = ViewInfo::Get( project );
1244 auto &selection = viewInfo.selectedRegion;
1245 auto gAudioIO = AudioIO::Get();
1246
1247 //If busy, stop playing, make sure everything is unpaused.
1248 if (scrubber.HasMark() ||
1249 gAudioIO->IsStreamActive(token)) {
1250 // change the selection
1251 auto time = gAudioIO->GetStreamTime();
1252 // Test WasSpeedPlaying(), not IsSpeedPlaying()
1253 // as we could be stopped now. Similarly WasKeyboardScrubbing().
1254 if (click && (scrubber.WasSpeedPlaying() || scrubber.WasKeyboardScrubbing()))
1255 {
1256 ;// don't change the selection.
1257 }
1258 else if (shift && click) {
1259 // Change the region selection, as if by shift-click at the play head
1260 auto t0 = selection.t0(), t1 = selection.t1();
1261 if (time < t0)
1262 // Grow selection
1263 t0 = time;
1264 else if (time > t1)
1265 // Grow selection
1266 t1 = time;
1267 else {
1268 // Shrink selection, changing the nearer boundary
1269 if (fabs(t0 - time) < fabs(t1 - time))
1270 t0 = time;
1271 else
1272 t1 = time;
1273 }
1274 selection.setTimes(t0, t1);
1275 }
1276 else if (click){
1277 // avoid a point at negative time.
1278 time = wxMax( time, 0 );
1279 // Set a point selection, as if by a click at the play head
1280 selection.setTimes(time, time);
1281 } else
1282 // How stop and set cursor always worked
1283 // -- change t0, collapsing to point only if t1 was greater
1284 selection.setT0(time, false);
1285
1286 ProjectHistory::Get( project ).ModifyState(false); // without bWantsAutoSave
1287 return true;
1288 }
1289 return false;
1290}
int GetAudioIOToken() const
static ProjectAudioIO & Get(AudacityProject &project)
void ModifyState(bool bWantsAutoSave)
static ProjectHistory & Get(AudacityProject &project)
static Scrubber & Get(AudacityProject &project)
Definition: Scrubbing.cpp:187
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235

References AudioIO::Get(), ProjectHistory::Get(), ViewInfo::Get(), ProjectAudioIO::Get(), Scrubber::Get(), ProjectAudioIO::GetAudioIOToken(), and ProjectHistory::ModifyState().

Referenced by TransportActions::Handler::OnPlayStopSelect().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ DoRecord()

bool ProjectAudioManager::DoRecord ( AudacityProject project,
const TransportTracks transportTracks,
double  t0,
double  t1,
bool  altAppearance,
const AudioIOStartStreamOptions options 
)

Definition at line 762 of file ProjectAudioManager.cpp.

767{
768 auto &projectAudioManager = *this;
769
770 CommandFlag flags = AlwaysEnabledFlag; // 0 means recalc flags.
771
772 // NB: The call may have the side effect of changing flags.
773 bool allowed = MenuManager::Get(project).TryToMakeActionAllowed(
774 flags,
776
777 if (!allowed)
778 return false;
779 // ...end of code from CommandHandler.
780
781 auto gAudioIO = AudioIO::Get();
782 if (gAudioIO->IsBusy())
783 return false;
784
785 projectAudioManager.SetAppending( !altAppearance );
786
787 bool success = false;
788
789 auto transportTracks = tracks;
790
791 // Will replace any given capture tracks with temporaries
792 transportTracks.captureTracks.clear();
793
794 const auto p = &project;
795
796 bool appendRecord = !tracks.captureTracks.empty();
797
798 auto makeNewClipName = [&](WaveTrack* track) {
799 for (auto i = 1;; ++i)
800 {
801 //i18n-hint a numerical suffix added to distinguish otherwise like-named clips when new record started
802 auto name = XC("%s #%d", "clip name template").Format(track->GetName(), i).Translation();
803 if (track->FindClipByName(name) == nullptr)
804 return name;
805 }
806 };
807
808 {
809 if (appendRecord) {
810 // Append recording:
811 // Pad selected/all wave tracks to make them all the same length
812 for (const auto &wt : tracks.captureTracks)
813 {
814 auto endTime = wt->GetEndTime();
815
816 // If the track was chosen for recording and playback both,
817 // remember the original in preroll tracks, before making the
818 // pending replacement.
819 bool prerollTrack = make_iterator_range(transportTracks.playbackTracks).contains(wt);
820 if (prerollTrack)
821 transportTracks.prerollTracks.push_back(wt);
822
823 // A function that copies all the non-sample data between
824 // wave tracks; in case the track recorded to changes scale
825 // type (for instance), during the recording.
826 auto updater = [](Track &d, const Track &s){
827 auto &dst = static_cast<WaveTrack&>(d);
828 auto &src = static_cast<const WaveTrack&>(s);
829 dst.Reinit(src);
830 };
831
832 // Get a copy of the track to be appended, to be pushed into
833 // undo history only later.
834 auto pending = std::static_pointer_cast<WaveTrack>(
836 updater, wt.get() ) );
837
838 // End of current track is before or at recording start time.
839 // Less than or equal, not just less than, to ensure a clip boundary.
840 // when append recording.
841 if (endTime <= t0) {
842 pending->CreateClip(t0, makeNewClipName(pending.get()));
843 }
844 transportTracks.captureTracks.push_back(pending);
845 }
847 }
848
849 if( transportTracks.captureTracks.empty() )
850 { // recording to NEW track(s).
851 bool recordingNameCustom, useTrackNumber, useDateStamp, useTimeStamp;
852 wxString defaultTrackName, defaultRecordingTrackName;
853
854 // Count the tracks.
855 auto &trackList = TrackList::Get( *p );
856 auto numTracks = trackList.Leaders< const WaveTrack >().size();
857
858 auto recordingChannels = std::max(1, AudioIORecordChannels.Read());
859
860 gPrefs->Read(wxT("/GUI/TrackNames/RecordingNameCustom"), &recordingNameCustom, false);
861 gPrefs->Read(wxT("/GUI/TrackNames/TrackNumber"), &useTrackNumber, false);
862 gPrefs->Read(wxT("/GUI/TrackNames/DateStamp"), &useDateStamp, false);
863 gPrefs->Read(wxT("/GUI/TrackNames/TimeStamp"), &useTimeStamp, false);
864 defaultTrackName = trackList.MakeUniqueTrackName(WaveTrack::GetDefaultAudioTrackNamePreference());
865 gPrefs->Read(wxT("/GUI/TrackNames/RecodingTrackName"), &defaultRecordingTrackName, defaultTrackName);
866
867 wxString baseTrackName = recordingNameCustom? defaultRecordingTrackName : defaultTrackName;
868
869 Track *first {};
870 for (int c = 0; c < recordingChannels; c++) {
871 auto newTrack = WaveTrackFactory::Get( *p ).Create();
872 if (!first)
873 first = newTrack.get();
874
875 // Quantize bounds to the rate of the new track.
876 if (c == 0) {
877 if (t0 < DBL_MAX)
878 t0 = newTrack->LongSamplesToTime(newTrack->TimeToLongSamples(t0));
879 if (t1 < DBL_MAX)
880 t1 = newTrack->LongSamplesToTime(newTrack->TimeToLongSamples(t1));
881 }
882
883 newTrack->SetOffset(t0);
884 wxString nameSuffix = wxString(wxT(""));
885
886 if (useTrackNumber) {
887 nameSuffix += wxString::Format(wxT("%d"), 1 + (int) numTracks + c);
888 }
889
890 if (useDateStamp) {
891 if (!nameSuffix.empty()) {
892 nameSuffix += wxT("_");
893 }
894 nameSuffix += wxDateTime::Now().FormatISODate();
895 }
896
897 if (useTimeStamp) {
898 if (!nameSuffix.empty()) {
899 nameSuffix += wxT("_");
900 }
901 nameSuffix += wxDateTime::Now().FormatISOTime();
902 }
903
904 // ISO standard would be nice, but ":" is unsafe for file name.
905 nameSuffix.Replace(wxT(":"), wxT("-"));
906
907 if (baseTrackName.empty()) {
908 newTrack->SetName(nameSuffix);
909 }
910 else if (nameSuffix.empty()) {
911 newTrack->SetName(baseTrackName);
912 }
913 else {
914 newTrack->SetName(baseTrackName + wxT("_") + nameSuffix);
915 }
916 //create a new clip with a proper name before recording is started
917 newTrack->CreateClip(t0, makeNewClipName(newTrack.get()));
918
919 TrackList::Get( *p ).RegisterPendingNewTrack( newTrack );
920
921 if ((recordingChannels > 2) &&
923 TrackView::Get( *newTrack ).SetMinimized(true);
924 }
925
926 transportTracks.captureTracks.push_back(newTrack);
927 }
928 TrackList::Get( *p ).MakeMultiChannelTrack(*first, recordingChannels, true);
929 // Bug 1548. First of new tracks needs the focus.
930 TrackFocus::Get(*p).Set(first);
931 if (TrackList::Get(*p).back())
932 TrackList::Get(*p).back()->EnsureVisible();
933 }
934
935 //Automated Input Level Adjustment Initialization
936 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
937 gAudioIO->AILAInitialize();
938 #endif
939
940 int token = gAudioIO->StartStream(transportTracks, t0, t1, t1, options);
941
942 success = (token != 0);
943
944 if (success) {
946 }
947 else {
949
950 // Show error message if stream could not be opened
951 auto msg = XO("Error opening recording device.\nError code: %s")
952 .Format( gAudioIO->LastPaErrorString() );
953 using namespace BasicUI;
955 XO("Error"), msg, wxT("Error_opening_sound_device"),
956 ErrorDialogOptions{ ErrorDialogType::ModalErrorReport } );
957 }
958 }
959
960 return success;
961}
wxT("CloseDown"))
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
std::bitset< NCommandFlags > CommandFlag
Definition: CommandFlag.h:31
const ReservedCommandFlag & AudioIONotBusyFlag()
const TranslatableString name
Definition: Distortion.cpp:82
#define XO(s)
Definition: Internat.h:31
#define XC(s, c)
Definition: Internat.h:37
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:431
FileConfig * gPrefs
Definition: Prefs.cpp:71
const ReservedCommandFlag & CanStopAudioStreamFlag()
std::unique_ptr< const BasicUI::WindowPlacement > ProjectFramePlacement(AudacityProject *project)
Make a WindowPlacement object suitable for project (which may be null)
bool TryToMakeActionAllowed(CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:720
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:71
void SetAudioIOToken(int token)
static ProjectSettings & Get(AudacityProject &project)
bool GetTracksFitVerticallyZoomed() const
Track * Get()
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:225
void RegisterPendingNewTrack(const std::shared_ptr< Track > &pTrack)
Definition: Track.cpp:1079
bool MakeMultiChannelTrack(Track &first, int nChannels, bool aligned)
Converts channels to a multichannel track.
Definition: Track.cpp:762
std::shared_ptr< Track > RegisterPendingChangedTrack(Updater updater, Track *src)
Definition: Track.cpp:1058
void UpdatePendingTracks()
Definition: Track.cpp:1085
void SetMinimized(bool minimized)
Definition: TrackView.cpp:93
static TrackView & Get(Track &)
Definition: TrackView.cpp:69
std::shared_ptr< WaveTrack > Create()
Creates an unnamed empty WaveTrack with default sample format and default rate.
Definition: WaveTrack.cpp:118
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2810
void Reinit(const WaveTrack &orig)
Definition: WaveTrack.cpp:196
static wxString GetDefaultAudioTrackNamePreference()
Definition: WaveTrack.cpp:100
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
Definition: BasicUI.h:254
Options for variations of error dialogs; the default is for modal dialogs.
Definition: BasicUI.h:49
WaveTrackConstArray prerollTracks
Definition: AudioIO.h:84
WaveTrackArray captureTracks
Definition: AudioIO.h:80
WaveTrackArray playbackTracks
Definition: AudioIO.h:79

References AlwaysEnabledFlag, AudioIONotBusyFlag(), AudioIORecordChannels, CanStopAudioStreamFlag(), TransportTracks::captureTracks, WaveTrackFactory::Create(), AudioIO::Get(), TrackFocus::Get(), TrackList::Get(), MenuManager::Get(), ProjectAudioIO::Get(), ProjectSettings::Get(), WaveTrackFactory::Get(), TrackView::Get(), WaveTrack::GetDefaultAudioTrackNamePreference(), ProjectSettings::GetTracksFitVerticallyZoomed(), gPrefs, make_iterator_range(), TrackList::MakeMultiChannelTrack(), name, ProjectFramePlacement(), Setting< T >::Read(), TrackList::RegisterPendingChangedTrack(), TrackList::RegisterPendingNewTrack(), WaveTrack::Reinit(), ProjectAudioIO::SetAudioIOToken(), TrackView::SetMinimized(), BasicUI::ShowErrorDialog(), size, MenuManager::TryToMakeActionAllowed(), TrackList::UpdatePendingTracks(), wxT(), XC, and XO.

Here is the call graph for this function:

◆ Get() [1/2]

ProjectAudioManager & ProjectAudioManager::Get ( AudacityProject project)
static

Definition at line 55 of file ProjectAudioManager.cpp.

56{
57 return project.AttachedObjects::Get< ProjectAudioManager >(
59}
static AudacityProject::AttachedObjects::RegisteredFactory sProjectAudioManagerKey

References sProjectAudioManagerKey.

Referenced by AdornedRulerPanel::ScrubbingHandle::Cancel(), CanStopAudioStreamFlag(), AdornedRulerPanel::ClearPlayRegion(), CloseButtonHandle::CommitChanges(), DefaultPlayOptions(), MacroCommands::DoAudacityCommand(), EffectUI::DoEffect(), anonymous_namespace{TransportMenus.cpp}::DoMoveToLabel(), TransportUtilities::DoStartPlaying(), TransportUtilities::DoStopPlaying(), ControlToolBar::EnableDisableButtons(), Get(), Scrubber::MarkScrubStart(), ProjectManager::New(), ProjectManager::OnCloseWindow(), ControlToolBar::OnFF(), ControlToolBar::OnIdle(), AudacityApp::OnKeyDown(), ControlToolBar::OnKeyEvent(), TransportActions::Handler::OnPause(), ControlToolBar::OnPause(), EffectUIHost::OnPlay(), ControlToolBar::OnPlay(), TransportActions::Handler::OnPlayStopSelect(), ControlToolBar::OnRecord(), ControlToolBar::OnRewind(), TransportActions::Handler::OnStop(), ControlToolBar::OnStop(), MixerBoard::OnTimer(), PlayIndicatorOverlay::OnTimer(), TrackPanel::OnTimer(), TransportActions::Handler::OnTimerRecord(), TranscriptionToolBar::PlayAtSpeed(), TransportUtilities::PlayCurrentRegionAndWait(), ControlToolBar::PlayDefault(), TransportUtilities::PlayPlayRegionAndWait(), TransportUtilities::RecordAndWait(), TimerRecordDialog::RunWaitDialog(), AdornedRulerPanel::StartQPPlay(), ControlToolBar::StateForStatusBar(), StatusWidthFunction(), and EffectUIHost::StopPlayback().

Here is the caller graph for this function:

◆ Get() [2/2]

const ProjectAudioManager & ProjectAudioManager::Get ( const AudacityProject project)
static

Definition at line 61 of file ProjectAudioManager.cpp.

63{
64 return Get( const_cast< AudacityProject & >( project ) );
65}
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:89
static ProjectAudioManager & Get(AudacityProject &project)

References Get().

Here is the call graph for this function:

◆ GetAllPlaybackTracks()

TransportTracks ProjectAudioManager::GetAllPlaybackTracks ( TrackList trackList,
bool  selectedOnly,
bool  nonWaveToo = false 
)
static
Parameters
nonWaveTooif true, collect all PlayableTracks

Definition at line 1205 of file ProjectAudioManager.cpp.

1207{
1208 TransportTracks result;
1209 {
1210 auto range = trackList.Any< WaveTrack >()
1211 + (selectedOnly ? &Track::IsSelected : &Track::Any );
1212 for (auto pTrack: range)
1213 result.playbackTracks.push_back(
1214 pTrack->SharedPointer< WaveTrack >() );
1215 }
1216#ifdef EXPERIMENTAL_MIDI_OUT
1217 if (nonWaveToo) {
1218 auto range = trackList.Any< const PlayableTrack >() +
1219 (selectedOnly ? &Track::IsSelected : &Track::Any );
1220 for (auto pTrack: range)
1221 if (!track_cast<const WaveTrack *>(pTrack))
1222 result.otherPlayableTracks.push_back(
1223 pTrack->SharedPointer< const PlayableTrack >() );
1224 }
1225#else
1226 WXUNUSED(useMidi);
1227#endif
1228 return result;
1229}
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:916
bool Any() const
Definition: Track.cpp:399
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1437
PlayableTrackConstArray otherPlayableTracks
Definition: AudioIO.h:81

References TrackList::Any(), Track::Any(), Track::IsSelected(), TransportTracks::otherPlayableTracks, and TransportTracks::playbackTracks.

Referenced by EffectBase::Preview().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetLastPlayMode()

PlayMode ProjectAudioManager::GetLastPlayMode ( ) const
inline

Definition at line 149 of file ProjectAudioManager.h.

149{ return mLastPlayMode; }

Referenced by MixerBoard::OnTimer(), and PlayIndicatorOverlay::OnTimer().

Here is the caller graph for this function:

◆ IsTimerRecordCancelled()

bool ProjectAudioManager::IsTimerRecordCancelled ( )
inline

Definition at line 96 of file ProjectAudioManager.h.

◆ Looping()

bool ProjectAudioManager::Looping ( ) const
inline

Definition at line 113 of file ProjectAudioManager.h.

113{ return mLooping; }

◆ OnAudioIONewBlocks()

void ProjectAudioManager::OnAudioIONewBlocks ( const WaveTrackArray tracks)
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1081 of file ProjectAudioManager.cpp.

1082{
1083 auto &project = mProject;
1084 auto &projectFileIO = ProjectFileIO::Get( project );
1085
1086 wxTheApp->CallAfter( [&]{ projectFileIO.AutoSave(true); });
1087}
static ProjectFileIO & Get(AudacityProject &project)

References ProjectFileIO::Get().

Here is the call graph for this function:

◆ OnAudioIORate()

void ProjectAudioManager::OnAudioIORate ( int  rate)
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1026 of file ProjectAudioManager.cpp.

1027{
1028 auto &project = mProject;
1029
1030 mDisplayedRate = rate;
1031
1032 auto display = FormatRate( rate );
1033
1034 ProjectStatus::Get( project ).Set( display, rateStatusBarField );
1035}
static TranslatableString FormatRate(int rate)
@ rateStatusBarField
Definition: ProjectStatus.h:27
static ProjectStatus & Get(AudacityProject &project)
void Set(const TranslatableString &msg, StatusBarField field=mainStatusBarField)

References FormatRate(), ProjectStatus::Get(), rateStatusBarField, and ProjectStatus::Set().

Here is the call graph for this function:

◆ OnAudioIOStartRecording()

void ProjectAudioManager::OnAudioIOStartRecording ( )
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1037 of file ProjectAudioManager.cpp.

1038{
1039 // Auto-save was done here before, but it is unnecessary, provided there
1040 // are sufficient autosaves when pushing or modifying undo states.
1041}

◆ OnAudioIOStopRecording()

void ProjectAudioManager::OnAudioIOStopRecording ( )
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1044 of file ProjectAudioManager.cpp.

1045{
1046 auto &project = mProject;
1047 auto &projectAudioIO = ProjectAudioIO::Get( project );
1048 auto &projectFileIO = ProjectFileIO::Get( project );
1049
1050 // Only push state if we were capturing and not monitoring
1051 if (projectAudioIO.GetAudioIOToken() > 0)
1052 {
1053 auto &history = ProjectHistory::Get( project );
1054
1055 if (IsTimerRecordCancelled()) {
1056 // discard recording
1057 history.RollbackState();
1058 // Reset timer record
1060 }
1061 else {
1062 // Add to history
1063 // We want this to have No-fail-guarantee if we get here from exception
1064 // handling of recording, and that means we rely on the last autosave
1065 // successfully committed to the database, not risking a failure
1066 history.PushState(XO("Recorded Audio"), XO("Record"),
1068
1069 // Now, we may add a label track to give information about
1070 // dropouts. We allow failure of this.
1071 auto gAudioIO = AudioIO::Get();
1072 auto &intervals = gAudioIO->LostCaptureIntervals();
1073 if (intervals.size()) {
1074 RecordingDropoutEvent evt{ intervals };
1075 mProject.ProcessEvent(evt);
1076 }
1077 }
1078 }
1079}
Notification, posted on the project, after recording has stopped, when dropouts have been detected.

References AudioIO::Get(), ProjectHistory::Get(), ProjectAudioIO::Get(), ProjectFileIO::Get(), NOAUTOSAVE, and XO.

Here is the call graph for this function:

◆ OnCheckpointFailure()

void ProjectAudioManager::OnCheckpointFailure ( wxCommandEvent &  evt)
private

Definition at line 1114 of file ProjectAudioManager.cpp.

1115{
1116 evt.Skip();
1117 Stop();
1118}

Referenced by ProjectAudioManager().

Here is the caller graph for this function:

◆ OnCommitRecording()

void ProjectAudioManager::OnCommitRecording ( )
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1089 of file ProjectAudioManager.cpp.

1090{
1091 const auto project = &mProject;
1092 TrackList::Get( *project ).ApplyPendingTracks();
1093}
bool ApplyPendingTracks()
Definition: Track.cpp:1144

References TrackList::ApplyPendingTracks(), and TrackList::Get().

Here is the call graph for this function:

◆ OnPause()

void ProjectAudioManager::OnPause ( )

Definition at line 963 of file ProjectAudioManager.cpp.

964{
965 auto &projectAudioManager = *this;
966 bool canStop = projectAudioManager.CanStopAudioStream();
967
968 if ( !canStop ) {
969 return;
970 }
971
972 bool paused = !projectAudioManager.Paused();
973 TogglePaused();
974
975 auto gAudioIO = AudioIO::Get();
976
977#ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
978
979 auto project = &mProject;
980 auto &scrubber = Scrubber::Get( *project );
981
982 // Bug 1494 - Pausing a seek or scrub should just STOP as
983 // it is confusing to be in a paused scrub state.
984 bool bStopInstead = paused &&
986 !scrubber.IsSpeedPlaying() &&
987 !scrubber.IsKeyboardScrubbing();
988
989 if (bStopInstead) {
990 Stop();
991 return;
992 }
993
995 scrubber.Pause(paused);
996 else
997#endif
998 {
999 gAudioIO->SetPaused(paused);
1000 }
1001}
static bool IsScrubbing()
Definition: ScrubState.cpp:482

References AudioIO::Get(), Scrubber::Get(), and ScrubState::IsScrubbing().

Referenced by TransportActions::Handler::OnPause(), and ControlToolBar::OnPause().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnRecord()

void ProjectAudioManager::OnRecord ( bool  altAppearance)
Exception safety guarantee:
Strong – For state of current project's tracks

Definition at line 639 of file ProjectAudioManager.cpp.

640{
641 bool bPreferNewTrack;
642 gPrefs->Read("/GUI/PreferNewTrackRecord", &bPreferNewTrack, false);
643 const bool appendRecord = (altAppearance == bPreferNewTrack);
644
645 // Code from CommandHandler start...
647
648 if (p) {
649 const auto &selectedRegion = ViewInfo::Get( *p ).selectedRegion;
650 double t0 = selectedRegion.t0();
651 double t1 = selectedRegion.t1();
652 // When no time selection, recording duration is 'unlimited'.
653 if (t1 == t0)
654 t1 = DBL_MAX;
655
656 auto options = DefaultPlayOptions(*p);
657 WaveTrackArray existingTracks;
658
659 // Checking the selected tracks: counting them and
660 // making sure they all have the same rate
661 const auto selectedTracks{ GetPropertiesOfSelected(*p) };
662 const int rateOfSelected{ selectedTracks.rateOfSelected };
663 const int numberOfSelected{ selectedTracks.numberOfSelected };
664 const bool allSameRate{ selectedTracks.allSameRate };
665
666 if (!allSameRate) {
667 AudacityMessageBox(XO("The tracks selected "
668 "for recording must all have the same sampling rate"),
669 XO("Mismatched Sampling Rates"),
670 wxICON_ERROR | wxCENTRE);
671
672 return;
673 }
674
675 if (appendRecord) {
676 const auto trackRange = TrackList::Get( *p ).Any< const WaveTrack >();
677
678 // Try to find wave tracks to record into. (If any are selected,
679 // try to choose only from them; else if wave tracks exist, may record into any.)
680 existingTracks = ChooseExistingRecordingTracks(*p, true, rateOfSelected);
681 if (!existingTracks.empty()) {
682 t0 = std::max(t0,
683 (trackRange + &Track::IsSelected).max(&Track::GetEndTime));
684 }
685 else {
686 if (numberOfSelected > 0 && rateOfSelected != options.rate) {
688 "Too few tracks are selected for recording at this sample rate.\n"
689 "(Audacity requires two channels at the same sample rate for\n"
690 "each stereo track)"),
691 XO("Too Few Compatible Tracks Selected"),
692 wxICON_ERROR | wxCENTRE);
693
694 return;
695 }
696
697 existingTracks = ChooseExistingRecordingTracks(*p, false, options.rate);
698 if (!existingTracks.empty())
699 {
700 auto endTime = std::max_element(
701 existingTracks.begin(),
702 existingTracks.end(),
703 [](const auto& a, const auto& b) {
704 return a->GetEndTime() < b->GetEndTime();
705 }
706 )->get()->GetEndTime();
707
708 //If there is a suitable track, then adjust t0 so
709 //that recording not starts before the end of that track
710 t0 = std::max(t0, endTime);
711 }
712 // If suitable tracks still not found, will record into NEW ones,
713 // starting with t0
714 }
715
716 // Whether we decided on NEW tracks or not:
717 if (t1 <= selectedRegion.t0() && selectedRegion.t1() > selectedRegion.t0()) {
718 t1 = selectedRegion.t1(); // record within the selection
719 }
720 else {
721 t1 = DBL_MAX; // record for a long, long time
722 }
723 }
724
725 TransportTracks transportTracks;
726 if (UseDuplex()) {
727 // Remove recording tracks from the list of tracks for duplex ("overdub")
728 // playback.
729 /* TODO: set up stereo tracks if that is how the user has set up
730 * their preferences, and choose sample format based on prefs */
731 transportTracks = GetAllPlaybackTracks(TrackList::Get( *p ), false, true);
732 for (const auto &wt : existingTracks) {
733 auto end = transportTracks.playbackTracks.end();
734 auto it = std::find(transportTracks.playbackTracks.begin(), end, wt);
735 if (it != end)
736 transportTracks.playbackTracks.erase(it);
737 }
738 }
739
740 transportTracks.captureTracks = existingTracks;
741
742 if (rateOfSelected != RATE_NOT_SELECTED)
743 options.rate = rateOfSelected;
744
745 DoRecord(*p, transportTracks, t0, t1, altAppearance, options);
746 }
747}
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
AudioIOStartStreamOptions DefaultPlayOptions(AudacityProject &project, bool newDefault)
PropertiesOfSelected GetPropertiesOfSelected(const AudacityProject &proj)
double t0() const
Definition: ViewInfo.h:34
static WaveTrackArray ChooseExistingRecordingTracks(AudacityProject &proj, bool selectedOnly, double targetRate=RATE_NOT_SELECTED)
static TransportTracks GetAllPlaybackTracks(TrackList &trackList, bool selectedOnly, bool nonWaveToo=false)
bool DoRecord(AudacityProject &project, const TransportTracks &transportTracks, double t0, double t1, bool altAppearance, const AudioIOStartStreamOptions &options)
virtual double GetEndTime() const =0
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:216
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159

References TrackList::Any(), AudacityMessageBox(), TransportTracks::captureTracks, DefaultPlayOptions(), PackedArray::end(), ViewInfo::Get(), TrackList::Get(), Track::GetEndTime(), GetPropertiesOfSelected(), gPrefs, Track::IsSelected(), TransportTracks::playbackTracks, RATE_NOT_SELECTED, PropertiesOfSelected::rateOfSelected, ViewInfo::selectedRegion, NotifyingSelectedRegion::t0(), and XO.

Referenced by ControlToolBar::OnRecord(), and TimerRecordDialog::RunWaitDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ OnSoundActivationThreshold()

void ProjectAudioManager::OnSoundActivationThreshold ( )
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1095 of file ProjectAudioManager.cpp.

1096{
1097 auto& project = mProject;
1098 auto gAudioIO = AudioIO::Get();
1099 if (gAudioIO && &project == gAudioIO->GetOwningProject().get())
1100 {
1101 bool canStop = CanStopAudioStream();
1102
1103 gAudioIO->SetPaused(!gAudioIO->IsPaused());
1104
1105 if (canStop)
1106 {
1107 // Instead of calling ::OnPause here, we can simply do the only thing it does (i.e. toggling the pause state),
1108 // because scrubbing can not happen while recording
1109 TogglePaused();
1110 }
1111 }
1112}

References AudioIO::Get().

Here is the call graph for this function:

◆ operator=()

ProjectAudioManager & ProjectAudioManager::operator= ( const ProjectAudioManager )

◆ Paused()

bool ProjectAudioManager::Paused ( ) const

Definition at line 1014 of file ProjectAudioManager.cpp.

1015{
1016 return mPaused.load(std::memory_order_relaxed) == 1;
1017}
std::atomic< int > mPaused

◆ PlayCurrentRegion()

void ProjectAudioManager::PlayCurrentRegion ( bool  newDefault = false,
bool  cutpreview = false 
)
Parameters
newDefaultSee DefaultPlayOptions

Definition at line 469 of file ProjectAudioManager.cpp.

471{
472 auto &projectAudioManager = *this;
473 bool canStop = projectAudioManager.CanStopAudioStream();
474
475 if ( !canStop )
476 return;
477
479
480 {
481
482 const auto &playRegion = ViewInfo::Get( *p ).playRegion;
483
484 if (newDefault)
485 cutpreview = false;
486 auto options = DefaultPlayOptions( *p, newDefault );
487 if (cutpreview)
488 options.envelope = nullptr;
489 auto mode =
490 cutpreview ? PlayMode::cutPreviewPlay
491 : newDefault ? PlayMode::loopedPlay
493 PlayPlayRegion(SelectedRegion(playRegion.GetStart(), playRegion.GetEnd()),
494 options,
495 mode);
496 }
497}
@ cutPreviewPlay
int PlayPlayRegion(const SelectedRegion &selectedRegion, const AudioIOStartStreamOptions &options, PlayMode playMode, bool backwards=false)
Defines a selected portion of a project.
PlayRegion playRegion
Definition: ViewInfo.h:217

References cutPreviewPlay, DefaultPlayOptions(), ViewInfo::Get(), loopedPlay, normalPlay, and ViewInfo::playRegion.

Referenced by ControlToolBar::PlayDefault().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Playing()

bool ProjectAudioManager::Playing ( ) const

Definition at line 1120 of file ProjectAudioManager.cpp.

1121{
1122 auto gAudioIO = AudioIO::Get();
1123 return
1124 gAudioIO->IsBusy() &&
1126 // ... and not merely monitoring
1127 !gAudioIO->IsMonitoring() &&
1128 // ... and not punch-and-roll recording
1129 gAudioIO->GetNumCaptureChannels() == 0;
1130}

References AudioIO::Get().

Here is the call graph for this function:

◆ PlayPlayRegion()

int ProjectAudioManager::PlayPlayRegion ( const SelectedRegion selectedRegion,
const AudioIOStartStreamOptions options,
PlayMode  playMode,
bool  backwards = false 
)

Definition at line 291 of file ProjectAudioManager.cpp.

295{
296 auto &projectAudioManager = *this;
297 bool canStop = projectAudioManager.CanStopAudioStream();
298
299 if ( !canStop )
300 return -1;
301
302 auto &pStartTime = options.pStartTime;
303
304 bool nonWaveToo = options.playNonWaveTracks;
305
306 // Uncomment this for laughs!
307 // backwards = true;
308
309 double t0 = selectedRegion.t0();
310 double t1 = selectedRegion.t1();
311 // SelectedRegion guarantees t0 <= t1, so we need another boolean argument
312 // to indicate backwards play.
313 const bool newDefault = (mode == PlayMode::loopedPlay);
314
315 if (backwards)
316 std::swap(t0, t1);
317
318 projectAudioManager.SetLooping( mode == PlayMode::loopedPlay );
319 projectAudioManager.SetCutting( mode == PlayMode::cutPreviewPlay );
320
321 bool success = false;
322
323 auto gAudioIO = AudioIO::Get();
324 if (gAudioIO->IsBusy())
325 return -1;
326
327 const bool cutpreview = mode == PlayMode::cutPreviewPlay;
328 if (cutpreview && t0==t1)
329 return -1; /* msmeyer: makes no sense */
330
332
333 auto &tracks = TrackList::Get( *p );
334
335 mLastPlayMode = mode;
336
337 bool hasaudio;
338 if (nonWaveToo)
339 hasaudio = ! tracks.Any<PlayableTrack>().empty();
340 else
341 hasaudio = ! tracks.Any<WaveTrack>().empty();
342
343 double latestEnd = tracks.GetEndTime();
344
345 if (!hasaudio)
346 return -1; // No need to continue without audio tracks
347
348#if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR)
349 double initSeek = 0.0;
350#endif
351 double loopOffset = 0.0;
352
353 if (t1 == t0) {
354 if (newDefault) {
355 const auto &selectedRegion = ViewInfo::Get( *p ).selectedRegion;
356 // play selection if there is one, otherwise
357 // set start of play region to project start,
358 // and loop the project from current play position.
359
360 if ((t0 > selectedRegion.t0()) && (t0 < selectedRegion.t1())) {
361 t0 = selectedRegion.t0();
362 t1 = selectedRegion.t1();
363 }
364 else {
365 // loop the entire project
366 // Bug2347, loop playback from cursor position instead of project start
367 loopOffset = t0 - tracks.GetStartTime();
368 if (!pStartTime)
369 // TODO move this reassignment elsewhere so we don't need an
370 // ugly mutable member
371 pStartTime.emplace(loopOffset);
372 t0 = tracks.GetStartTime();
373 t1 = tracks.GetEndTime();
374 }
375 } else {
376 // move t0 to valid range
377 if (t0 < 0) {
378 t0 = tracks.GetStartTime();
379 }
380 else if (t0 > tracks.GetEndTime()) {
381 t0 = tracks.GetEndTime();
382 }
383#if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR)
384 else {
385 initSeek = t0; //AC: initSeek is where playback will 'start'
386 if (!pStartTime)
387 pStartTime.emplace(initSeek);
388 t0 = tracks.GetStartTime();
389 }
390#endif
391 }
392 t1 = tracks.GetEndTime();
393 }
394 else {
395 // maybe t1 < t0, with backwards scrubbing for instance
396 if (backwards)
397 std::swap(t0, t1);
398
399 t0 = std::max(0.0, std::min(t0, latestEnd));
400 t1 = std::max(0.0, std::min(t1, latestEnd));
401
402 if (backwards)
403 std::swap(t0, t1);
404 }
405
406 int token = -1;
407
408 if (t1 != t0) {
409 if (cutpreview) {
410 const double tless = std::min(t0, t1);
411 const double tgreater = std::max(t0, t1);
412 double beforeLen, afterLen;
413 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
414 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
415 double tcp0 = tless-beforeLen;
416 const double diff = tgreater - tless;
417 double tcp1 = tgreater+afterLen;
418 if (backwards)
419 std::swap(tcp0, tcp1);
420 AudioIOStartStreamOptions myOptions = options;
421 myOptions.policyFactory =
422 [tless, diff](auto&) -> std::unique_ptr<PlaybackPolicy> {
423 return std::make_unique<CutPreviewPlaybackPolicy>(tless, diff);
424 };
425 token = gAudioIO->StartStream(
426 GetAllPlaybackTracks(TrackList::Get(*p), false, nonWaveToo),
427 tcp0, tcp1, tcp1, myOptions);
428 }
429 else {
430 double mixerLimit = t1;
431 if (newDefault) {
432 mixerLimit = latestEnd;
433 if (pStartTime && *pStartTime >= t1)
434 t1 = latestEnd;
435 }
436 token = gAudioIO->StartStream(
437 GetAllPlaybackTracks( tracks, false, nonWaveToo ),
438 t0, t1, mixerLimit, options);
439 }
440 if (token != 0) {
441 success = true;
443 }
444 else {
445 // Bug1627 (part of it):
446 // infinite error spew when trying to start scrub:
447 // Problem was that the error dialog yields to events,
448 // causing recursion to this function in the scrub timer
449 // handler! Easy fix, just delay the user alert instead.
450 auto &window = GetProjectFrame( mProject );
451 window.CallAfter( [&]{
452 using namespace BasicUI;
453 // Show error message if stream could not be opened
455 XO("Error"),
456 XO("Error opening sound device.\nTry changing the audio host, playback device and the project sample rate."),
457 wxT("Error_opening_sound_device"),
458 ErrorDialogOptions{ ErrorDialogType::ModalErrorReport } );
459 });
460 }
461 }
462
463 if (!success)
464 return -1;
465
466 return token;
467}
int min(int a, int b)
AUDACITY_DLL_API wxFrame & GetProjectFrame(AudacityProject &project)
Get the top-level window associated with the project (as a wxFrame only, when you do not need to use ...
double t1() const
double t0() const
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:753
struct holding stream options, including a pointer to the time warp info and AudioIOListener and whet...
Definition: AudioIOBase.h:44
PolicyFactory policyFactory
Definition: AudioIOBase.h:74
std::optional< double > pStartTime
Definition: AudioIOBase.h:59

References cutPreviewPlay, AudioIO::Get(), ViewInfo::Get(), TrackList::Get(), ProjectAudioIO::Get(), GetProjectFrame(), gPrefs, loopedPlay, min(), AudioIOStartStreamOptions::playNonWaveTracks, AudioIOStartStreamOptions::policyFactory, ProjectFramePlacement(), AudioIOStartStreamOptions::pStartTime, ViewInfo::selectedRegion, ProjectAudioIO::SetAudioIOToken(), BasicUI::ShowErrorDialog(), anonymous_namespace{NoteTrack.cpp}::swap(), SelectedRegion::t0(), SelectedRegion::t1(), wxT(), and XO.

Here is the call graph for this function:

◆ Recording()

bool ProjectAudioManager::Recording ( ) const

Definition at line 1132 of file ProjectAudioManager.cpp.

1133{
1134 auto gAudioIO = AudioIO::Get();
1135 return
1136 gAudioIO->IsBusy() &&
1138 gAudioIO->GetNumCaptureChannels() > 0;
1139}

References AudioIO::Get().

Here is the call graph for this function:

◆ ResetTimerRecordCancelled()

void ProjectAudioManager::ResetTimerRecordCancelled ( )
inline

Definition at line 98 of file ProjectAudioManager.h.

98{ mTimerRecordCanceled = false; }

◆ SetAppending()

void ProjectAudioManager::SetAppending ( bool  value)
inlineprivate

Definition at line 156 of file ProjectAudioManager.h.

156{ mAppending = value; }

◆ SetCutting()

void ProjectAudioManager::SetCutting ( bool  value)
inlineprivate

Definition at line 158 of file ProjectAudioManager.h.

158{ mCutting = value; }

◆ SetLooping()

void ProjectAudioManager::SetLooping ( bool  value)
inlineprivate

Definition at line 157 of file ProjectAudioManager.h.

157{ mLooping = value; }

◆ SetPausedOff()

void ProjectAudioManager::SetPausedOff ( )
private

Definition at line 1009 of file ProjectAudioManager.cpp.

1010{
1011 mPaused.store(0, std::memory_order::memory_order_relaxed);
1012}

◆ SetStopping()

void ProjectAudioManager::SetStopping ( bool  value)
inlineprivate

Definition at line 159 of file ProjectAudioManager.h.

159{ mStopping = value; }

◆ SetTimerRecordCancelled()

void ProjectAudioManager::SetTimerRecordCancelled ( )
inline

Definition at line 97 of file ProjectAudioManager.h.

97{ mTimerRecordCanceled = true; }

Referenced by TransportActions::Handler::OnTimerRecord().

Here is the caller graph for this function:

◆ StatusWidthFunction()

auto ProjectAudioManager::StatusWidthFunction ( const AudacityProject project,
StatusBarField  field 
)
staticprivate

Definition at line 88 of file ProjectAudioManager.cpp.

91{
92 if ( field == rateStatusBarField ) {
93 auto &audioManager = ProjectAudioManager::Get( project );
94 int rate = audioManager.mDisplayedRate;
95 return {
96 { { FormatRate( rate ) } },
97 50
98 };
99 }
100 return {};
101}
#define field(n, t)
Definition: ImportAUP.cpp:167

References field, FormatRate(), Get(), and rateStatusBarField.

Referenced by ProjectAudioManager().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Stop()

void ProjectAudioManager::Stop ( bool  stopStream = true)

Definition at line 499 of file ProjectAudioManager.cpp.

500{
501 AudacityProject *project = &mProject;
502 auto &projectAudioManager = *this;
503 bool canStop = projectAudioManager.CanStopAudioStream();
504
505 if ( !canStop )
506 return;
507
508 if(project) {
509 // Let scrubbing code do some appearance change
510 auto &scrubber = Scrubber::Get( *project );
511 scrubber.StopScrubbing();
512 }
513
514 auto gAudioIO = AudioIO::Get();
515
516 auto cleanup = finally( [&]{
517 projectAudioManager.SetStopping( false );
518 } );
519
520 if (stopStream && gAudioIO->IsBusy()) {
521 // flag that we are stopping
522 projectAudioManager.SetStopping( true );
523 // Allow UI to update for that
524 while( wxTheApp->ProcessIdle() )
525 ;
526 }
527
528 if(stopStream)
529 gAudioIO->StopStream();
530
531 projectAudioManager.SetLooping( false );
532 projectAudioManager.SetCutting( false );
533
534 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
535 gAudioIO->AILADisable();
536 #endif
537
538 projectAudioManager.SetPausedOff();
539 //Make sure you tell gAudioIO to unpause
540 gAudioIO->SetPaused( false );
541
542 // So that we continue monitoring after playing or recording.
543 // also clean the MeterQueues
544 if( project ) {
545 auto &projectAudioIO = ProjectAudioIO::Get( *project );
546 auto meter = projectAudioIO.GetPlaybackMeter();
547 if( meter ) {
548 meter->Clear();
549 }
550
551 meter = projectAudioIO.GetCaptureMeter();
552 if( meter ) {
553 meter->Clear();
554 }
555 }
556
557 const auto toolbar = ToolManager::Get( *project ).GetToolBar(ScrubbingBarID);
558 if (toolbar)
559 toolbar->EnableDisableButtons();
560}
@ ScrubbingBarID
Definition: ToolBar.h:79
virtual void EnableDisableButtons()=0
static ToolManager & Get(AudacityProject &project)
ToolBar * GetToolBar(int type) const

References ToolBar::EnableDisableButtons(), AudioIO::Get(), ProjectAudioIO::Get(), ToolManager::Get(), Scrubber::Get(), ToolManager::GetToolBar(), and ScrubbingBarID.

Referenced by AdornedRulerPanel::ScrubbingHandle::Cancel(), AdornedRulerPanel::ClearPlayRegion(), MacroCommands::DoAudacityCommand(), EffectUI::DoEffect(), ProjectManager::OnCloseWindow(), AudacityApp::OnKeyDown(), TransportActions::Handler::OnStop(), and TimerRecordDialog::RunWaitDialog().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StopIfPaused()

void ProjectAudioManager::StopIfPaused ( )

Definition at line 1232 of file ProjectAudioManager.cpp.

1233{
1234 if( AudioIOBase::Get()->IsPaused() )
1235 Stop();
1236}
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:91

References AudioIOBase::Get().

Referenced by CloseButtonHandle::CommitChanges(), ControlToolBar::OnFF(), and ControlToolBar::OnRewind().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Stopping()

bool ProjectAudioManager::Stopping ( ) const
inline

Definition at line 108 of file ProjectAudioManager.h.

108{ return mStopping; }

◆ TogglePaused()

void ProjectAudioManager::TogglePaused ( )
private

Definition at line 1004 of file ProjectAudioManager.cpp.

1005{
1006 mPaused.fetch_xor(1, std::memory_order::memory_order_relaxed);
1007}

◆ UseDuplex()

bool ProjectAudioManager::UseDuplex ( )
static

Definition at line 749 of file ProjectAudioManager.cpp.

750{
751 bool duplex;
752 gPrefs->Read(wxT("/AudioIO/Duplex"), &duplex,
753#ifdef EXPERIMENTAL_DA
754 false
755#else
756 true
757#endif
758 );
759 return duplex;
760}

References gPrefs, and wxT().

Here is the call graph for this function:

Member Data Documentation

◆ mAppending

bool ProjectAudioManager::mAppending { false }
private

Definition at line 185 of file ProjectAudioManager.h.

◆ mCutting

bool ProjectAudioManager::mCutting { false }
private

Definition at line 187 of file ProjectAudioManager.h.

◆ mDisplayedRate

int ProjectAudioManager::mDisplayedRate { 0 }
private

Definition at line 190 of file ProjectAudioManager.h.

◆ mLastPlayMode

PlayMode ProjectAudioManager::mLastPlayMode { PlayMode::normalPlay }
private

Definition at line 176 of file ProjectAudioManager.h.

◆ mLooping

bool ProjectAudioManager::mLooping { false }
private

Definition at line 186 of file ProjectAudioManager.h.

◆ mPaused

std::atomic<int> ProjectAudioManager::mPaused { 0 }
private

Definition at line 183 of file ProjectAudioManager.h.

◆ mProject

AudacityProject& ProjectAudioManager::mProject
private

Definition at line 174 of file ProjectAudioManager.h.

◆ mStopping

bool ProjectAudioManager::mStopping { false }
private

Definition at line 188 of file ProjectAudioManager.h.

◆ mTimerRecordCanceled

bool ProjectAudioManager::mTimerRecordCanceled { false }
private

Definition at line 179 of file ProjectAudioManager.h.


The documentation for this class was generated from the following files: