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 WritableSampleTrackArray *tracks)=0
 
virtual void OnCommitRecording ()=0
 
virtual void OnSoundActivationThreshold ()=0
 
- Public Member Functions inherited from Observer::Publisher< RecordingDropoutEvent >
 Publisher (ExceptionPolicy *pPolicy=nullptr, Alloc a={})
 Constructor supporting type-erased custom allocation/deletion. More...
 
 Publisher (Publisher &&)=default
 
Publisheroperator= (Publisher &&)=default
 
Subscription Subscribe (Callback callback)
 Connect a callback to the Publisher; later-connected are called earlier. More...
 
Subscription Subscribe (Object &obj, Return(Object::*callback)(Args...))
 Overload of Subscribe takes an object and pointer-to-member-function. More...
 

Static Public Member Functions

static ProjectAudioManagerGet (AudacityProject &project)
 
static const ProjectAudioManagerGet (const AudacityProject &project)
 
static WritableSampleTrackArray ChooseExistingRecordingTracks (AudacityProject &proj, bool selectedOnly, double targetRate=RATE_NOT_SELECTED)
 
static bool UseDuplex ()
 

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 WritableSampleTrackArray *tracks) override
 
void OnCommitRecording () override
 
void OnSoundActivationThreshold () override
 
void OnCheckpointFailure (ProjectFileIOMessage)
 

Static Private Member Functions

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

Private Attributes

Observer::Subscription mCheckpointFailureSubcription
 
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 }
 

Additional Inherited Members

- Public Types inherited from Observer::Publisher< RecordingDropoutEvent >
using message_type = RecordingDropoutEvent
 
using CallbackReturn = std::conditional_t< true, void, bool >
 
using Callback = std::function< CallbackReturn(const RecordingDropoutEvent &) >
 Type of functions that can be connected to the Publisher. More...
 
- Static Public Attributes inherited from Observer::Publisher< RecordingDropoutEvent >
static constexpr bool notifies_all
 
- Protected Member Functions inherited from Observer::Publisher< RecordingDropoutEvent >
CallbackReturn Publish (const RecordingDropoutEvent &message)
 Send a message to connected callbacks. More...
 

Detailed Description

Definition at line 60 of file ProjectAudioManager.h.

Constructor & Destructor Documentation

◆ ProjectAudioManager() [1/2]

ProjectAudioManager::ProjectAudioManager ( AudacityProject project)
explicit

Definition at line 65 of file ProjectAudioManager.cpp.

66 : mProject{ project }
67{
69 registerStatusWidthFunction{ StatusWidthFunction };
72}
Subscription Subscribe(Callback callback)
Connect a callback to the Publisher; later-connected are called earlier.
Definition: Observer.h:199
Observer::Subscription mCheckpointFailureSubcription
AudacityProject & mProject
static std::pair< TranslatableStrings, unsigned > StatusWidthFunction(const AudacityProject &project, StatusBarField field)
void OnCheckpointFailure(ProjectFileIOMessage)
static ProjectFileIO & Get(AudacityProject &project)

References ProjectFileIO::Get(), mCheckpointFailureSubcription, OnCheckpointFailure(), StatusWidthFunction(), and Observer::Publisher< Message, NotifyAll >::Subscribe().

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 97 of file ProjectAudioManager.h.

97{ return mAppending; }

◆ CancelRecording()

void ProjectAudioManager::CancelRecording ( )
private

Definition at line 1019 of file ProjectAudioManager.cpp.

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

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:147

References AudioIO::Get().

Here is the call graph for this function:

◆ ChooseExistingRecordingTracks()

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

Definition at line 562 of file ProjectAudioManager.cpp.

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

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

Referenced by anonymous_namespace{TimerRecordDialog.cpp}::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 100 of file ProjectAudioManager.h.

100{ return mCutting; }

◆ DoPlayStopSelect() [1/2]

void ProjectAudioManager::DoPlayStopSelect ( )

Definition at line 1266 of file ProjectAudioManager.cpp.

1267{
1268 auto gAudioIO = AudioIO::Get();
1269 if (DoPlayStopSelect(false, false))
1270 Stop();
1271 else if (!gAudioIO->IsBusy()) {
1272 //Otherwise, start playing (assuming audio I/O isn't busy)
1273
1274 // Will automatically set mLastPlayMode
1275 PlayCurrentRegion(false);
1276 }
1277}
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 1210 of file ProjectAudioManager.cpp.

1211{
1212 auto &project = mProject;
1213 auto &scrubber = Scrubber::Get( project );
1214 auto token = ProjectAudioIO::Get( project ).GetAudioIOToken();
1215 auto &viewInfo = ViewInfo::Get( project );
1216 auto &selection = viewInfo.selectedRegion;
1217 auto gAudioIO = AudioIO::Get();
1218
1219 //If busy, stop playing, make sure everything is unpaused.
1220 if (scrubber.HasMark() ||
1221 gAudioIO->IsStreamActive(token)) {
1222 // change the selection
1223 auto time = gAudioIO->GetStreamTime();
1224 // Test WasSpeedPlaying(), not IsSpeedPlaying()
1225 // as we could be stopped now. Similarly WasKeyboardScrubbing().
1226 if (click && (scrubber.WasSpeedPlaying() || scrubber.WasKeyboardScrubbing()))
1227 {
1228 ;// don't change the selection.
1229 }
1230 else if (shift && click) {
1231 // Change the region selection, as if by shift-click at the play head
1232 auto t0 = selection.t0(), t1 = selection.t1();
1233 if (time < t0)
1234 // Grow selection
1235 t0 = time;
1236 else if (time > t1)
1237 // Grow selection
1238 t1 = time;
1239 else {
1240 // Shrink selection, changing the nearer boundary
1241 if (fabs(t0 - time) < fabs(t1 - time))
1242 t0 = time;
1243 else
1244 t1 = time;
1245 }
1246 selection.setTimes(t0, t1);
1247 }
1248 else if (click){
1249 // avoid a point at negative time.
1250 time = wxMax( time, 0 );
1251 // Set a point selection, as if by a click at the play head
1252 selection.setTimes(time, time);
1253 } else
1254 // How stop and set cursor always worked
1255 // -- change t0, collapsing to point only if t1 was greater
1256 selection.setT0(time, false);
1257
1258 ProjectHistory::Get( project ).ModifyState(false); // without bWantsAutoSave
1259 return true;
1260 }
1261 return false;
1262}
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(), ProjectAudioIO::Get(), ProjectHistory::Get(), ViewInfo::Get(), Scrubber::Get(), ProjectAudioIO::GetAudioIOToken(), and ProjectHistory::ModifyState().

Referenced by anonymous_namespace{TransportMenus.cpp}::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 761 of file ProjectAudioManager.cpp.

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

References AlwaysEnabledFlag, AudioIONotBusyFlag(), AudioIORecordChannels, CanStopAudioStreamFlag(), TransportTracks::captureTracks, WaveTrackFactory::Create(), AudioIO::Get(), TrackFocus::Get(), ProjectAudioIO::Get(), TrackList::Get(), WaveTrackFactory::Get(), MenuManager::Get(), ProjectSettings::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(), updater, wxT(), XC, and XO().

Here is the call graph for this function:

◆ Get() [1/2]

ProjectAudioManager & ProjectAudioManager::Get ( AudacityProject project)
static

Definition at line 53 of file ProjectAudioManager.cpp.

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

References sProjectAudioManagerKey.

Referenced by AdornedRulerPanel::ScrubbingHandle::Cancel(), CanStopAudioStreamFlag(), AdornedRulerPanel::ClearPlayRegion(), CloseButtonHandle::CommitChanges(), CommandDispatch::DoAudacityCommand(), EffectUI::DoEffect(), anonymous_namespace{TransportMenus.cpp}::DoMoveToLabel(), TransportUtilities::DoStopPlaying(), anonymous_namespace{DropoutDetector.cpp}::DropoutSubscription::DropoutSubscription(), ControlToolBar::EnableDisableButtons(), Get(), Scrubber::MarkScrubStart(), ProjectManager::New(), ProjectManager::OnCloseWindow(), ControlToolBar::OnFF(), ControlToolBar::OnIdle(), AudacityApp::OnKeyDown(), ControlToolBar::OnKeyEvent(), anonymous_namespace{TransportMenus.cpp}::OnPause(), ControlToolBar::OnPause(), EffectUIHost::OnPlay(), ControlToolBar::OnPlay(), anonymous_namespace{TransportMenus.cpp}::OnPlayStopSelect(), ControlToolBar::OnRecord(), ControlToolBar::OnRewind(), anonymous_namespace{TransportMenus.cpp}::OnStop(), ControlToolBar::OnStop(), MixerBoard::OnTimer(), PlayIndicatorOverlay::OnTimer(), TrackPanel::OnTimer(), anonymous_namespace{TimerRecordDialog.cpp}::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 59 of file ProjectAudioManager.cpp.

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

References Get().

Here is the call graph for this function:

◆ GetLastPlayMode()

PlayMode ProjectAudioManager::GetLastPlayMode ( ) const
inline

Definition at line 135 of file ProjectAudioManager.h.

135{ 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 82 of file ProjectAudioManager.h.

◆ Looping()

bool ProjectAudioManager::Looping ( ) const
inline

Definition at line 99 of file ProjectAudioManager.h.

99{ return mLooping; }

◆ OnAudioIONewBlocks()

void ProjectAudioManager::OnAudioIONewBlocks ( const WritableSampleTrackArray tracks)
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1080 of file ProjectAudioManager.cpp.

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

References ProjectFileIO::Get().

Here is the call graph for this function:

◆ OnAudioIORate()

void ProjectAudioManager::OnAudioIORate ( int  rate)
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1025 of file ProjectAudioManager.cpp.

1026{
1027 auto &project = mProject;
1028
1029 mDisplayedRate = rate;
1030
1031 auto display = FormatRate( rate );
1032
1033 ProjectStatus::Get( project ).Set( display, rateStatusBarField );
1034}
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 1036 of file ProjectAudioManager.cpp.

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

◆ OnAudioIOStopRecording()

void ProjectAudioManager::OnAudioIOStopRecording ( )
overrideprivatevirtual

Implements AudioIOListener.

Definition at line 1043 of file ProjectAudioManager.cpp.

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

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

Here is the call graph for this function:

◆ OnCheckpointFailure()

void ProjectAudioManager::OnCheckpointFailure ( ProjectFileIOMessage  message)
private

Definition at line 1114 of file ProjectAudioManager.cpp.

1115{
1117 Stop();
1118}
@ CheckpointFailure
Failure happened in a worker thread.

References CheckpointFailure.

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:1145

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

Here is the call graph for this function:

◆ OnPause()

void ProjectAudioManager::OnPause ( )

Definition at line 962 of file ProjectAudioManager.cpp.

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

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

Referenced by anonymous_namespace{TransportMenus.cpp}::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 638 of file ProjectAudioManager.cpp.

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

References TrackList::Any(), AudacityMessageBox(), TransportTracks::captureTracks, PackedArray::end(), ViewInfo::Get(), TrackList::Get(), ProjectAudioIO::GetDefaultOptions(), 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 1013 of file ProjectAudioManager.cpp.

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

◆ PlayCurrentRegion()

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

Definition at line 467 of file ProjectAudioManager.cpp.

469{
470 auto &projectAudioManager = *this;
471 bool canStop = projectAudioManager.CanStopAudioStream();
472
473 if ( !canStop )
474 return;
475
477
478 {
479
480 const auto &playRegion = ViewInfo::Get( *p ).playRegion;
481
482 if (newDefault)
483 cutpreview = false;
484 auto options = ProjectAudioIO::GetDefaultOptions(*p, newDefault);
485 if (cutpreview)
486 options.envelope = nullptr;
487 auto mode =
488 cutpreview ? PlayMode::cutPreviewPlay
489 : newDefault ? PlayMode::loopedPlay
491 PlayPlayRegion(SelectedRegion(playRegion.GetStart(), playRegion.GetEnd()),
492 options,
493 mode);
494 }
495}
@ 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:220

References cutPreviewPlay, ViewInfo::Get(), ProjectAudioIO::GetDefaultOptions(), 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 289 of file ProjectAudioManager.cpp.

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

References cutPreviewPlay, AudioIO::Get(), ProjectAudioIO::Get(), ViewInfo::Get(), TrackList::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 84 of file ProjectAudioManager.h.

84{ mTimerRecordCanceled = false; }

◆ SetAppending()

void ProjectAudioManager::SetAppending ( bool  value)
inlineprivate

Definition at line 142 of file ProjectAudioManager.h.

142{ mAppending = value; }

◆ SetCutting()

void ProjectAudioManager::SetCutting ( bool  value)
inlineprivate

Definition at line 144 of file ProjectAudioManager.h.

144{ mCutting = value; }

◆ SetLooping()

void ProjectAudioManager::SetLooping ( bool  value)
inlineprivate

Definition at line 143 of file ProjectAudioManager.h.

143{ mLooping = value; }

◆ SetPausedOff()

void ProjectAudioManager::SetPausedOff ( )
private

Definition at line 1008 of file ProjectAudioManager.cpp.

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

◆ SetStopping()

void ProjectAudioManager::SetStopping ( bool  value)
inlineprivate

Definition at line 145 of file ProjectAudioManager.h.

145{ mStopping = value; }

◆ SetTimerRecordCancelled()

void ProjectAudioManager::SetTimerRecordCancelled ( )
inline

Definition at line 83 of file ProjectAudioManager.h.

83{ mTimerRecordCanceled = true; }

Referenced by anonymous_namespace{TimerRecordDialog.cpp}::OnTimerRecord().

Here is the caller graph for this function:

◆ StatusWidthFunction()

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

Definition at line 86 of file ProjectAudioManager.cpp.

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

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 497 of file ProjectAudioManager.cpp.

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

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

Referenced by AdornedRulerPanel::ScrubbingHandle::Cancel(), AdornedRulerPanel::ClearPlayRegion(), CommandDispatch::DoAudacityCommand(), EffectUI::DoEffect(), ProjectManager::OnCloseWindow(), AudacityApp::OnKeyDown(), anonymous_namespace{TransportMenus.cpp}::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 1204 of file ProjectAudioManager.cpp.

1205{
1206 if( AudioIOBase::Get()->IsPaused() )
1207 Stop();
1208}
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 94 of file ProjectAudioManager.h.

94{ return mStopping; }

◆ TogglePaused()

void ProjectAudioManager::TogglePaused ( )
private

Definition at line 1003 of file ProjectAudioManager.cpp.

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

◆ UseDuplex()

bool ProjectAudioManager::UseDuplex ( )
static

Definition at line 748 of file ProjectAudioManager.cpp.

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

References gPrefs, and wxT().

Here is the call graph for this function:

Member Data Documentation

◆ mAppending

bool ProjectAudioManager::mAppending { false }
private

Definition at line 172 of file ProjectAudioManager.h.

◆ mCheckpointFailureSubcription

Observer::Subscription ProjectAudioManager::mCheckpointFailureSubcription
private

Definition at line 160 of file ProjectAudioManager.h.

Referenced by ProjectAudioManager().

◆ mCutting

bool ProjectAudioManager::mCutting { false }
private

Definition at line 174 of file ProjectAudioManager.h.

◆ mDisplayedRate

int ProjectAudioManager::mDisplayedRate { 0 }
private

Definition at line 177 of file ProjectAudioManager.h.

◆ mLastPlayMode

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

Definition at line 163 of file ProjectAudioManager.h.

◆ mLooping

bool ProjectAudioManager::mLooping { false }
private

Definition at line 173 of file ProjectAudioManager.h.

◆ mPaused

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

Definition at line 170 of file ProjectAudioManager.h.

◆ mProject

AudacityProject& ProjectAudioManager::mProject
private

Definition at line 161 of file ProjectAudioManager.h.

◆ mStopping

bool ProjectAudioManager::mStopping { false }
private

Definition at line 175 of file ProjectAudioManager.h.

◆ mTimerRecordCanceled

bool ProjectAudioManager::mTimerRecordCanceled { false }
private

Definition at line 166 of file ProjectAudioManager.h.


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