Audacity  3.0.3
ProjectAudioManager.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 ProjectAudioManager.cpp
6 
7 Paul Licameli split from ProjectManager.cpp
8 
9 **********************************************************************/
10 
11 
12 #include "ProjectAudioManager.h"
13 
14 #include <wx/app.h>
15 #include <wx/frame.h>
16 #include <wx/statusbr.h>
17 
18 #include "AudioIO.h"
19 #include "BasicUI.h"
20 #include "CommonCommandFlags.h"
21 #include "LabelTrack.h"
22 #include "Menus.h"
23 #include "Meter.h"
24 #include "Project.h"
25 #include "ProjectAudioIO.h"
26 #include "ProjectFileIO.h"
27 #include "ProjectHistory.h"
28 #include "ProjectRate.h"
29 #include "ProjectSettings.h"
30 #include "ProjectStatus.h"
31 #include "ProjectWindows.h"
32 #include "TimeTrack.h"
33 #include "TrackPanelAx.h"
34 #include "UndoManager.h"
35 #include "ViewInfo.h"
36 #include "WaveTrack.h"
37 #include "toolbars/ToolManager.h"
38 #include "prefs/TracksPrefs.h"
39 #include "tracks/ui/Scrubbing.h"
40 #include "tracks/ui/TrackView.h"
41 #include "widgets/MeterPanelBase.h"
42 #include "widgets/Warning.h"
44 
45 
48  []( AudacityProject &project ) {
49  return std::make_shared< ProjectAudioManager >( project );
50  }
51 };
52 
54 {
55  return project.AttachedObjects::Get< ProjectAudioManager >(
57 }
58 
60  const AudacityProject &project )
61 {
62  return Get( const_cast< AudacityProject & >( project ) );
63 }
64 
66  : mProject{ project }
67 {
69  registerStatusWidthFunction{ StatusWidthFunction };
70  project.Bind( EVT_CHECKPOINT_FAILURE,
72 }
73 
75 
76 static TranslatableString FormatRate( int rate )
77 {
78  if (rate > 0) {
79  return XO("Actual Rate: %d").Format( rate );
80  }
81  else
82  // clear the status field
83  return {};
84 }
85 
87  const AudacityProject &project, StatusBarField field )
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 }
100 
103  const AudioIOStartStreamOptions &options,
104  PlayMode mode,
105  bool backwards, /* = false */
106  bool playWhiteSpace /* = false */)
107 {
108  auto &projectAudioManager = *this;
109  bool canStop = projectAudioManager.CanStopAudioStream();
110 
111  if ( !canStop )
112  return -1;
113 
114  bool nonWaveToo = options.playNonWaveTracks;
115 
116  // Uncomment this for laughs!
117  // backwards = true;
118 
119  double t0 = selectedRegion.t0();
120  double t1 = selectedRegion.t1();
121  // SelectedRegion guarantees t0 <= t1, so we need another boolean argument
122  // to indicate backwards play.
123  const bool looped = options.playLooped;
124 
125  if (backwards)
126  std::swap(t0, t1);
127 
128  projectAudioManager.SetLooping( mode == PlayMode::loopedPlay );
129  projectAudioManager.SetCutting( mode == PlayMode::cutPreviewPlay );
130 
131  bool success = false;
132 
133  auto gAudioIO = AudioIO::Get();
134  if (gAudioIO->IsBusy())
135  return -1;
136 
137  const bool cutpreview = mode == PlayMode::cutPreviewPlay;
138  if (cutpreview && t0==t1)
139  return -1; /* msmeyer: makes no sense */
140 
142 
143  auto &tracks = TrackList::Get( *p );
144 
145  mLastPlayMode = mode;
146 
147  bool hasaudio;
148  if (nonWaveToo)
149  hasaudio = ! tracks.Any<PlayableTrack>().empty();
150  else
151  hasaudio = ! tracks.Any<WaveTrack>().empty();
152 
153  double latestEnd = (playWhiteSpace)? t1 : tracks.GetEndTime();
154 
155  if (!hasaudio)
156  return -1; // No need to continue without audio tracks
157 
158 #if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR)
159  double init_seek = 0.0;
160 #endif
161 
162  double loop_offset = 0.0;
163 
164  if (t1 == t0) {
165  if (looped) {
166  const auto &selectedRegion = ViewInfo::Get( *p ).selectedRegion;
167  // play selection if there is one, otherwise
168  // set start of play region to project start,
169  // and loop the project from current play position.
170 
171  if ((t0 > selectedRegion.t0()) && (t0 < selectedRegion.t1())) {
172  t0 = selectedRegion.t0();
173  t1 = selectedRegion.t1();
174  }
175  else {
176  // loop the entire project
177  // Bug2347, loop playback from cursor position instead of project start
178  loop_offset = t0 - tracks.GetStartTime();
179  t0 = tracks.GetStartTime();
180  t1 = tracks.GetEndTime();
181  }
182  } else {
183  // move t0 to valid range
184  if (t0 < 0) {
185  t0 = tracks.GetStartTime();
186  }
187  else if (t0 > tracks.GetEndTime()) {
188  t0 = tracks.GetEndTime();
189  }
190 #if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR)
191  else {
192  init_seek = t0; //AC: init_seek is where playback will 'start'
193  t0 = tracks.GetStartTime();
194  }
195 #endif
196  }
197  t1 = tracks.GetEndTime();
198  }
199  else {
200  // maybe t1 < t0, with backwards scrubbing for instance
201  if (backwards)
202  std::swap(t0, t1);
203 
204  t0 = std::max(0.0, std::min(t0, latestEnd));
205  t1 = std::max(0.0, std::min(t1, latestEnd));
206 
207  if (backwards)
208  std::swap(t0, t1);
209  }
210 
211  int token = -1;
212 
213  if (t1 != t0) {
214  if (cutpreview) {
215  const double tless = std::min(t0, t1);
216  const double tgreater = std::max(t0, t1);
217  double beforeLen, afterLen;
218  gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
219  gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
220  double tcp0 = tless-beforeLen;
221  double diff = tgreater - tless;
222  double tcp1 = (tgreater+afterLen) - diff;
223  SetupCutPreviewTracks(tcp0, tless, tgreater, tcp1);
224  if (backwards)
225  std::swap(tcp0, tcp1);
226  if (mCutPreviewTracks)
227  {
228  AudioIOStartStreamOptions myOptions = options;
229  myOptions.cutPreviewGapStart = t0;
230  myOptions.cutPreviewGapLen = t1 - t0;
231  token = gAudioIO->StartStream(
232  GetAllPlaybackTracks(*mCutPreviewTracks, false, nonWaveToo),
233  tcp0, tcp1, myOptions);
234  }
235  else
236  // Cannot create cut preview tracks, clean up and exit
237  return -1;
238  }
239  else {
240  token = gAudioIO->StartStream(
241  GetAllPlaybackTracks( tracks, false, nonWaveToo ),
242  t0, t1, options);
243  }
244  if (token != 0) {
245  success = true;
247  if (loop_offset != 0.0) {
248  // Bug 2347
249  gAudioIO->SeekStream(loop_offset);
250  }
251 #if defined(EXPERIMENTAL_SEEK_BEHIND_CURSOR )
252  //AC: If init_seek was set, now's the time to make it happen.
253  gAudioIO->SeekStream(init_seek);
254 #endif
255  }
256  else {
257  // Bug1627 (part of it):
258  // infinite error spew when trying to start scrub:
259  // Problem was that the error dialog yields to events,
260  // causing recursion to this function in the scrub timer
261  // handler! Easy fix, just delay the user alert instead.
262  auto &window = GetProjectFrame( mProject );
263  window.CallAfter( [&]{
264  using namespace BasicUI;
265  // Show error message if stream could not be opened
267  XO("Error"),
268  XO("Error opening sound device.\nTry changing the audio host, playback device and the project sample rate."),
269  wxT("Error_opening_sound_device"),
270  ErrorDialogOptions{ ErrorDialogType::ModalErrorReport } );
271  });
272  }
273  }
274 
275  if (!success)
276  return -1;
277 
278  return token;
279 }
280 
281 void ProjectAudioManager::PlayCurrentRegion(bool looped /* = false */,
282  bool cutpreview /* = false */)
283 {
284  auto &projectAudioManager = *this;
285  bool canStop = projectAudioManager.CanStopAudioStream();
286 
287  if ( !canStop )
288  return;
289 
291 
292  {
293 
294  const auto &playRegion = ViewInfo::Get( *p ).playRegion;
295 
296  auto options = DefaultPlayOptions( *p );
297  options.playLooped = looped;
298  if (cutpreview)
299  options.envelope = nullptr;
300  auto mode =
301  cutpreview ? PlayMode::cutPreviewPlay
302  : options.playLooped ? PlayMode::loopedPlay
304  PlayPlayRegion(SelectedRegion(playRegion.GetStart(), playRegion.GetEnd()),
305  options,
306  mode);
307  }
308 }
309 
310 void ProjectAudioManager::Stop(bool stopStream /* = true*/)
311 {
312  AudacityProject *project = &mProject;
313  auto &projectAudioManager = *this;
314  bool canStop = projectAudioManager.CanStopAudioStream();
315 
316  if ( !canStop )
317  return;
318 
319  if(project) {
320  // Let scrubbing code do some appearance change
321  auto &scrubber = Scrubber::Get( *project );
322  scrubber.StopScrubbing();
323  }
324 
325  auto gAudioIO = AudioIO::Get();
326 
327  auto cleanup = finally( [&]{
328  projectAudioManager.SetStopping( false );
329  } );
330 
331  if (stopStream && gAudioIO->IsBusy()) {
332  // flag that we are stopping
333  projectAudioManager.SetStopping( true );
334  // Allow UI to update for that
335  while( wxTheApp->ProcessIdle() )
336  ;
337  }
338 
339  if(stopStream)
340  gAudioIO->StopStream();
341 
342  projectAudioManager.SetLooping( false );
343  projectAudioManager.SetCutting( false );
344 
345  #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
346  gAudioIO->AILADisable();
347  #endif
348 
349  projectAudioManager.SetPaused( false );
350  //Make sure you tell gAudioIO to unpause
351  gAudioIO->SetPaused( false );
352 
354 
355  // So that we continue monitoring after playing or recording.
356  // also clean the MeterQueues
357  if( project ) {
358  auto &projectAudioIO = ProjectAudioIO::Get( *project );
359  auto meter = projectAudioIO.GetPlaybackMeter();
360  if( meter ) {
361  meter->Clear();
362  }
363 
364  meter = projectAudioIO.GetCaptureMeter();
365  if( meter ) {
366  meter->Clear();
367  }
368  }
369 
370  const auto toolbar = ToolManager::Get( *project ).GetToolBar(ScrubbingBarID);
371  if (toolbar)
372  toolbar->EnableDisableButtons();
373 }
374 
376 {
377  auto &projectAudioManager = *this;
378  bool canStop = projectAudioManager.CanStopAudioStream();
379 
380  if ( !canStop ) {
381  auto gAudioIO = AudioIO::Get();
382  gAudioIO->SetPaused(!gAudioIO->IsPaused());
383  }
384  else {
385  OnPause();
386  }
387 }
388 
390  AudacityProject &proj, bool selectedOnly, double targetRate)
391 {
392  auto p = &proj;
393  size_t recordingChannels = std::max(0, AudioIORecordChannels.Read());
394  bool strictRules = (recordingChannels <= 2);
395 
396  // Iterate over all wave tracks, or over selected wave tracks only.
397  // If target rate was specified, ignore all tracks with other rates.
398  //
399  // In the usual cases of one or two recording channels, seek a first-fit
400  // unbroken sub-sequence for which the total number of channels matches the
401  // required number exactly. Never drop inputs or fill only some channels
402  // of a track.
403  //
404  // In case of more than two recording channels, choose tracks only among the
405  // selected. Simply take the earliest wave tracks, until the number of
406  // channels is enough. If there are fewer channels than inputs, but at least
407  // one channel, then some of the input channels will be dropped.
408  //
409  // Resulting tracks may be non-consecutive within the list of all tracks
410  // (there may be non-wave tracks between, or non-selected tracks when
411  // considering selected tracks only.)
412 
413  if (!strictRules && !selectedOnly)
414  return {};
415 
416  auto &trackList = TrackList::Get( *p );
417  std::vector<unsigned> channelCounts;
418  WaveTrackArray candidates;
419  const auto range = trackList.Leaders<WaveTrack>();
420  for ( auto candidate : selectedOnly ? range + &Track::IsSelected : range ) {
421  if (targetRate != RATE_NOT_SELECTED && candidate->GetRate() != targetRate)
422  continue;
423 
424  // count channels in this track
425  const auto channels = TrackList::Channels( candidate );
426  unsigned nChannels = channels.size();
427 
428  if (strictRules && nChannels > recordingChannels) {
429  // The recording would under-fill this track's channels
430  // Can't use any partial accumulated results
431  // either. Keep looking.
432  candidates.clear();
433  channelCounts.clear();
434  continue;
435  }
436  else {
437  // Might use this but may have to discard some of the accumulated
438  while(strictRules &&
439  nChannels + candidates.size() > recordingChannels) {
440  auto nOldChannels = channelCounts[0];
441  wxASSERT(nOldChannels > 0);
442  channelCounts.erase(channelCounts.begin());
443  candidates.erase(candidates.begin(),
444  candidates.begin() + nOldChannels);
445  }
446  channelCounts.push_back(nChannels);
447  for ( auto channel : channels ) {
448  candidates.push_back(channel->SharedPointer<WaveTrack>());
449  if(candidates.size() == recordingChannels)
450  // Done!
451  return candidates;
452  }
453  }
454  }
455 
456  if (!strictRules && !candidates.empty())
457  // good enough
458  return candidates;
459 
460  // If the loop didn't exit early, we could not find enough channels
461  return {};
462 }
463 
465 void ProjectAudioManager::OnRecord(bool altAppearance)
466 {
467  bool bPreferNewTrack;
468  gPrefs->Read("/GUI/PreferNewTrackRecord", &bPreferNewTrack, false);
469  const bool appendRecord = (altAppearance == bPreferNewTrack);
470 
471  // Code from CommandHandler start...
473 
474  if (p) {
475  const auto &selectedRegion = ViewInfo::Get( *p ).selectedRegion;
476  double t0 = selectedRegion.t0();
477  double t1 = selectedRegion.t1();
478  // When no time selection, recording duration is 'unlimited'.
479  if (t1 == t0)
480  t1 = DBL_MAX;
481 
482  auto options = DefaultPlayOptions(*p);
483  WaveTrackArray existingTracks;
484 
485  // Checking the selected tracks: counting them and
486  // making sure they all have the same rate
487  const auto selectedTracks{ GetPropertiesOfSelected(*p) };
488  const int rateOfSelected{ selectedTracks.rateOfSelected };
489  const int numberOfSelected{ selectedTracks.numberOfSelected };
490  const bool allSameRate{ selectedTracks.allSameRate };
491 
492  if (!allSameRate) {
493  AudacityMessageBox(XO("The tracks selected "
494  "for recording must all have the same sampling rate"),
495  XO("Mismatched Sampling Rates"),
496  wxICON_ERROR | wxCENTRE);
497 
498  return;
499  }
500 
501  if (appendRecord) {
502  const auto trackRange = TrackList::Get( *p ).Any< const WaveTrack >();
503 
504  // Try to find wave tracks to record into. (If any are selected,
505  // try to choose only from them; else if wave tracks exist, may record into any.)
506  existingTracks = ChooseExistingRecordingTracks(*p, true, rateOfSelected);
507  if (!existingTracks.empty()) {
508  t0 = std::max(t0,
509  (trackRange + &Track::IsSelected).max(&Track::GetEndTime));
510  }
511  else {
512  if (numberOfSelected > 0 && rateOfSelected != options.rate) {
514  "Too few tracks are selected for recording at this sample rate.\n"
515  "(Audacity requires two channels at the same sample rate for\n"
516  "each stereo track)"),
517  XO("Too Few Compatible Tracks Selected"),
518  wxICON_ERROR | wxCENTRE);
519 
520  return;
521  }
522 
523  existingTracks = ChooseExistingRecordingTracks(*p, false, options.rate);
524  if(!existingTracks.empty())
525  t0 = std::max( t0, trackRange.max( &Track::GetEndTime ) );
526  // If suitable tracks still not found, will record into NEW ones,
527  // starting with t0
528  }
529 
530  // Whether we decided on NEW tracks or not:
531  if (t1 <= selectedRegion.t0() && selectedRegion.t1() > selectedRegion.t0()) {
532  t1 = selectedRegion.t1(); // record within the selection
533  }
534  else {
535  t1 = DBL_MAX; // record for a long, long time
536  }
537  }
538 
539  TransportTracks transportTracks;
540  if (UseDuplex()) {
541  // Remove recording tracks from the list of tracks for duplex ("overdub")
542  // playback.
543  /* TODO: set up stereo tracks if that is how the user has set up
544  * their preferences, and choose sample format based on prefs */
545  transportTracks = GetAllPlaybackTracks(TrackList::Get( *p ), false, true);
546  for (const auto &wt : existingTracks) {
547  auto end = transportTracks.playbackTracks.end();
548  auto it = std::find(transportTracks.playbackTracks.begin(), end, wt);
549  if (it != end)
550  transportTracks.playbackTracks.erase(it);
551  }
552  }
553 
554  transportTracks.captureTracks = existingTracks;
555 
556  if (rateOfSelected != RATE_NOT_SELECTED)
557  options.rate = rateOfSelected;
558 
559  DoRecord(*p, transportTracks, t0, t1, altAppearance, options);
560  }
561 }
562 
564 {
565  bool duplex;
566  gPrefs->Read(wxT("/AudioIO/Duplex"), &duplex,
567 #ifdef EXPERIMENTAL_DA
568  false
569 #else
570  true
571 #endif
572  );
573  return duplex;
574 }
575 
577  const TransportTracks &tracks,
578  double t0, double t1,
579  bool altAppearance,
580  const AudioIOStartStreamOptions &options)
581 {
582  auto &projectAudioManager = *this;
583 
584  CommandFlag flags = AlwaysEnabledFlag; // 0 means recalc flags.
585 
586  // NB: The call may have the side effect of changing flags.
587  bool allowed = MenuManager::Get(project).TryToMakeActionAllowed(
588  flags,
590 
591  if (!allowed)
592  return false;
593  // ...end of code from CommandHandler.
594 
595  auto gAudioIO = AudioIO::Get();
596  if (gAudioIO->IsBusy())
597  return false;
598 
599  projectAudioManager.SetAppending( !altAppearance );
600 
601  bool success = false;
602 
603  auto transportTracks = tracks;
604 
605  // Will replace any given capture tracks with temporaries
606  transportTracks.captureTracks.clear();
607 
608  const auto p = &project;
609 
610  bool appendRecord = !tracks.captureTracks.empty();
611 
612  {
613  if (appendRecord) {
614  // Append recording:
615  // Pad selected/all wave tracks to make them all the same length
616  for (const auto &wt : tracks.captureTracks)
617  {
618  auto endTime = wt->GetEndTime();
619 
620  // If the track was chosen for recording and playback both,
621  // remember the original in preroll tracks, before making the
622  // pending replacement.
623  bool prerollTrack = make_iterator_range(transportTracks.playbackTracks).contains(wt);
624  if (prerollTrack)
625  transportTracks.prerollTracks.push_back(wt);
626 
627  // A function that copies all the non-sample data between
628  // wave tracks; in case the track recorded to changes scale
629  // type (for instance), during the recording.
630  auto updater = [](Track &d, const Track &s){
631  auto &dst = static_cast<WaveTrack&>(d);
632  auto &src = static_cast<const WaveTrack&>(s);
633  dst.Reinit(src);
634  };
635 
636  // Get a copy of the track to be appended, to be pushed into
637  // undo history only later.
638  auto pending = std::static_pointer_cast<WaveTrack>(
640  updater, wt.get() ) );
641 
642  // End of current track is before or at recording start time.
643  // Less than or equal, not just less than, to ensure a clip boundary.
644  // when append recording.
645  if (endTime <= t0) {
646  auto newName = [&]() {
647  for (auto i = 1;; ++i)
648  {
649  //i18n-hint a numerical suffix added to distinguish otherwise like-named clips when new record started
650  auto name = XC("%s #%d", "clip name template").Format(pending->GetName(), i).Translation();
651  if (pending->FindClipByName(name) == nullptr)
652  return name;
653  }
654  }();
655  pending->CreateClip(t0, newName);
656  }
657  transportTracks.captureTracks.push_back(pending);
658  }
660  }
661 
662  if( transportTracks.captureTracks.empty() )
663  { // recording to NEW track(s).
664  bool recordingNameCustom, useTrackNumber, useDateStamp, useTimeStamp;
665  wxString defaultTrackName, defaultRecordingTrackName;
666 
667  // Count the tracks.
668  auto &trackList = TrackList::Get( *p );
669  auto numTracks = trackList.Leaders< const WaveTrack >().size();
670 
671  auto recordingChannels = std::max(1, AudioIORecordChannels.Read());
672 
673  gPrefs->Read(wxT("/GUI/TrackNames/RecordingNameCustom"), &recordingNameCustom, false);
674  gPrefs->Read(wxT("/GUI/TrackNames/TrackNumber"), &useTrackNumber, false);
675  gPrefs->Read(wxT("/GUI/TrackNames/DateStamp"), &useDateStamp, false);
676  gPrefs->Read(wxT("/GUI/TrackNames/TimeStamp"), &useTimeStamp, false);
678  gPrefs->Read(wxT("/GUI/TrackNames/RecodingTrackName"), &defaultRecordingTrackName, defaultTrackName);
679 
680  wxString baseTrackName = recordingNameCustom? defaultRecordingTrackName : defaultTrackName;
681 
682  Track *first {};
683  for (int c = 0; c < recordingChannels; c++) {
684  auto newTrack = WaveTrackFactory::Get( *p ).NewWaveTrack();
685  if (!first)
686  first = newTrack.get();
687 
688  // Quantize bounds to the rate of the new track.
689  if (c == 0) {
690  if (t0 < DBL_MAX)
691  t0 = newTrack->LongSamplesToTime(newTrack->TimeToLongSamples(t0));
692  if (t1 < DBL_MAX)
693  t1 = newTrack->LongSamplesToTime(newTrack->TimeToLongSamples(t1));
694  }
695 
696  newTrack->SetOffset(t0);
697  wxString nameSuffix = wxString(wxT(""));
698 
699  if (useTrackNumber) {
700  nameSuffix += wxString::Format(wxT("%d"), 1 + (int) numTracks + c);
701  }
702 
703  if (useDateStamp) {
704  if (!nameSuffix.empty()) {
705  nameSuffix += wxT("_");
706  }
707  nameSuffix += wxDateTime::Now().FormatISODate();
708  }
709 
710  if (useTimeStamp) {
711  if (!nameSuffix.empty()) {
712  nameSuffix += wxT("_");
713  }
714  nameSuffix += wxDateTime::Now().FormatISOTime();
715  }
716 
717  // ISO standard would be nice, but ":" is unsafe for file name.
718  nameSuffix.Replace(wxT(":"), wxT("-"));
719 
720  if (baseTrackName.empty()) {
721  newTrack->SetName(nameSuffix);
722  }
723  else if (nameSuffix.empty()) {
724  newTrack->SetName(baseTrackName);
725  }
726  else {
727  newTrack->SetName(baseTrackName + wxT("_") + nameSuffix);
728  }
729 
730  TrackList::Get( *p ).RegisterPendingNewTrack( newTrack );
731 
732  if ((recordingChannels > 2) &&
734  TrackView::Get( *newTrack ).SetMinimized(true);
735  }
736 
737  transportTracks.captureTracks.push_back(newTrack);
738  }
739  TrackList::Get( *p ).MakeMultiChannelTrack(*first, recordingChannels, true);
740  // Bug 1548. First of new tracks needs the focus.
741  TrackFocus::Get(*p).Set(first);
742  if (TrackList::Get(*p).back())
743  TrackList::Get(*p).back()->EnsureVisible();
744  }
745 
746  //Automated Input Level Adjustment Initialization
747  #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
748  gAudioIO->AILAInitialize();
749  #endif
750 
751  int token = gAudioIO->StartStream(transportTracks, t0, t1, options);
752 
753  success = (token != 0);
754 
755  if (success) {
757  }
758  else {
759  CancelRecording();
760 
761  // Show error message if stream could not be opened
762  auto msg = XO("Error opening recording device.\nError code: %s")
763  .Format( gAudioIO->LastPaErrorString() );
764  using namespace BasicUI;
766  XO("Error"), msg, wxT("Error_opening_sound_device"),
767  ErrorDialogOptions{ ErrorDialogType::ModalErrorReport } );
768  }
769  }
770 
771  return success;
772 }
773 
775 {
776  auto &projectAudioManager = *this;
777  bool canStop = projectAudioManager.CanStopAudioStream();
778 
779  if ( !canStop ) {
780  return;
781  }
782 
783  bool paused = !projectAudioManager.Paused();
784  projectAudioManager.SetPaused( paused );
785 
786  auto gAudioIO = AudioIO::Get();
787 
788 #ifdef EXPERIMENTAL_SCRUBBING_SUPPORT
789 
790  auto project = &mProject;
791  auto &scrubber = Scrubber::Get( *project );
792 
793  // Bug 1494 - Pausing a seek or scrub should just STOP as
794  // it is confusing to be in a paused scrub state.
795  bool bStopInstead = paused &&
796  gAudioIO->IsScrubbing() &&
797  !scrubber.IsSpeedPlaying() &&
798  !scrubber.IsKeyboardScrubbing();
799 
800  if (bStopInstead) {
801  Stop();
802  return;
803  }
804 
805  if (gAudioIO->IsScrubbing())
806  scrubber.Pause(paused);
807  else
808 #endif
809  {
810  gAudioIO->SetPaused(paused);
811  }
812 }
813 
815 void ProjectAudioManager::SetupCutPreviewTracks(double WXUNUSED(playStart), double cutStart,
816  double cutEnd, double WXUNUSED(playEnd))
817 
818 {
821  {
822  auto trackRange = TrackList::Get( *p ).Selected< const PlayableTrack >();
823  if( !trackRange.empty() ) {
824  auto cutPreviewTracks = TrackList::Create( nullptr );
825  for (const auto track1 : trackRange) {
826  // Duplicate and change tracks
827  // Clear has a very small chance of throwing
828 
829  auto newTrack = track1->Duplicate();
830  newTrack->Clear(cutStart, cutEnd);
831  cutPreviewTracks->Add( newTrack );
832  }
833  // use No-throw-guarantee:
834  mCutPreviewTracks = cutPreviewTracks;
835  }
836  }
837 }
838 
840 {
841  if (mCutPreviewTracks)
842  mCutPreviewTracks->Clear();
843  mCutPreviewTracks.reset();
844 }
845 
847 {
848  const auto project = &mProject;
849  TrackList::Get( *project ).ClearPendingTracks();
850 }
851 
853 {
854  auto &project = mProject;
855 
856  mDisplayedRate = rate;
857 
858  auto display = FormatRate( rate );
859 
860  ProjectStatus::Get( project ).Set( display, rateStatusBarField );
861 }
862 
864 {
865  // Auto-save was done here before, but it is unnecessary, provided there
866  // are sufficient autosaves when pushing or modifying undo states.
867 }
868 
869 // This is called after recording has stopped and all tracks have flushed.
871 {
872  auto &project = mProject;
873  auto &projectAudioIO = ProjectAudioIO::Get( project );
874  auto &projectFileIO = ProjectFileIO::Get( project );
875  auto &window = GetProjectFrame( project );
876 
877  // Only push state if we were capturing and not monitoring
878  if (projectAudioIO.GetAudioIOToken() > 0)
879  {
880  auto &history = ProjectHistory::Get( project );
881 
882  if (IsTimerRecordCancelled()) {
883  // discard recording
884  history.RollbackState();
885  // Reset timer record
887  }
888  else {
889  // Add to history
890  // We want this to have No-fail-guarantee if we get here from exception
891  // handling of recording, and that means we rely on the last autosave
892  // successfully committed to the database, not risking a failure
893  history.PushState(XO("Recorded Audio"), XO("Record"),
895 
896  // Now, we may add a label track to give information about
897  // dropouts. We allow failure of this.
898  auto &tracks = TrackList::Get( project );
899  auto gAudioIO = AudioIO::Get();
900  auto &intervals = gAudioIO->LostCaptureIntervals();
901  if (intervals.size()) {
902  // Make a track with labels for recording errors
903  auto uTrack = std::make_shared<LabelTrack>();
904  auto pTrack = uTrack.get();
905  tracks.Add( uTrack );
906  /* i18n-hint: A name given to a track, appearing as its menu button.
907  The translation should be short or else it will not display well.
908  At most, about 11 Latin characters.
909  Dropout is a loss of a short sequence of audio sample data from the
910  recording */
911  pTrack->SetName(_("Dropouts"));
912  long counter = 1;
913  for (auto &interval : intervals)
914  pTrack->AddLabel(
915  SelectedRegion{ interval.first,
916  interval.first + interval.second },
917  wxString::Format(wxT("%ld"), counter++));
918 
919  history.ModifyState( true ); // this might fail and throw
920 
921  // CallAfter so that we avoid any problems of yielding
922  // to the event loop while still inside the timer callback,
923  // entering StopStream() recursively
924  wxTheApp->CallAfter( [&] {
925  ShowWarningDialog(&window, wxT("DropoutDetected"), XO("\
926 Recorded audio was lost at the labeled locations. Possible causes:\n\
927 \n\
928 Other applications are competing with Audacity for processor time\n\
929 \n\
930 You are saving directly to a slow external storage device\n\
931 "
932  ),
933  false,
934  XXO("Turn off dropout detection"));
935  });
936  }
937  }
938  }
939 }
940 
942 {
943  auto &project = mProject;
944  auto &projectFileIO = ProjectFileIO::Get( project );
945  projectFileIO.AutoSave(true);
946 }
947 
949 {
950  const auto project = &mProject;
951  TrackList::Get( *project ).ApplyPendingTracks();
952 }
953 
955 {
956  auto &project = mProject;
957  auto gAudioIO = AudioIO::Get();
958  if ( gAudioIO && &project == gAudioIO->GetOwningProject() ) {
959  wxTheApp->CallAfter( [this]{ Pause(); } );
960  }
961 }
962 
964 {
965  evt.Skip();
966  Stop();
967 }
968 
970 {
971  auto gAudioIO = AudioIO::Get();
972  return
973  gAudioIO->IsBusy() &&
974  CanStopAudioStream() &&
975  // ... and not merely monitoring
976  !gAudioIO->IsMonitoring() &&
977  // ... and not punch-and-roll recording
978  gAudioIO->GetNumCaptureChannels() == 0;
979 }
980 
982 {
983  auto gAudioIO = AudioIO::Get();
984  return
985  gAudioIO->IsBusy() &&
986  CanStopAudioStream() &&
987  gAudioIO->GetNumCaptureChannels() > 0;
988 }
989 
991 {
992  auto gAudioIO = AudioIO::Get();
993  return (!gAudioIO->IsStreamActive() ||
994  gAudioIO->IsMonitoring() ||
995  gAudioIO->GetOwningProject() == &mProject );
996 }
997 
998 const ReservedCommandFlag&
1000  [](const AudacityProject &project){
1001  auto &projectAudioManager = ProjectAudioManager::Get( project );
1002  bool canStop = projectAudioManager.CanStopAudioStream();
1003  return canStop;
1004  }
1005  }; return flag; }
1006 
1009 {
1010  auto &projectAudioIO = ProjectAudioIO::Get( project );
1011  AudioIOStartStreamOptions options { &project,
1012  ProjectRate::Get( project ).GetRate() };
1013  options.captureMeter = projectAudioIO.GetCaptureMeter();
1014  options.playbackMeter = projectAudioIO.GetPlaybackMeter();
1015  auto timeTrack = *TrackList::Get( project ).Any<TimeTrack>().begin();
1016  options.envelope = timeTrack ? timeTrack->GetEnvelope() : nullptr;
1017  options.listener = ProjectAudioManager::Get( project ).shared_from_this();
1018  return options;
1019 }
1020 
1023 {
1024  auto result = DefaultPlayOptions( project );
1025  auto gAudioIO = AudioIO::Get();
1026  auto PlayAtSpeedRate = gAudioIO->GetBestRate(
1027  false, //not capturing
1028  true, //is playing
1029  ProjectRate::Get( project ).GetRate() //suggested rate
1030  );
1031  result.rate = PlayAtSpeedRate;
1032  return result;
1033 }
1034 
1036  TrackList &trackList, bool selectedOnly, bool nonWaveToo)
1037 {
1038  TransportTracks result;
1039  {
1040  auto range = trackList.Any< WaveTrack >()
1041  + (selectedOnly ? &Track::IsSelected : &Track::Any );
1042  for (auto pTrack: range)
1043  result.playbackTracks.push_back(
1044  pTrack->SharedPointer< WaveTrack >() );
1045  }
1046 #ifdef EXPERIMENTAL_MIDI_OUT
1047  if (nonWaveToo) {
1048  auto range = trackList.Any< const PlayableTrack >() +
1049  (selectedOnly ? &Track::IsSelected : &Track::Any );
1050  for (auto pTrack: range)
1051  if (!track_cast<const WaveTrack *>(pTrack))
1052  result.otherPlayableTracks.push_back(
1053  pTrack->SharedPointer< const PlayableTrack >() );
1054  }
1055 #else
1056  WXUNUSED(useMidi);
1057 #endif
1058  return result;
1059 }
1060 
1061 // Stop playing or recording, if paused.
1063 {
1064  if( AudioIOBase::Get()->IsPaused() )
1065  Stop();
1066 }
1067 
1068 bool ProjectAudioManager::DoPlayStopSelect( bool click, bool shift )
1069 {
1070  auto &project = mProject;
1071  auto &scrubber = Scrubber::Get( project );
1072  auto token = ProjectAudioIO::Get( project ).GetAudioIOToken();
1073  auto &viewInfo = ViewInfo::Get( project );
1074  auto &selection = viewInfo.selectedRegion;
1075  auto gAudioIO = AudioIO::Get();
1076 
1077  //If busy, stop playing, make sure everything is unpaused.
1078  if (scrubber.HasMark() ||
1079  gAudioIO->IsStreamActive(token)) {
1080  // change the selection
1081  auto time = gAudioIO->GetStreamTime();
1082  // Test WasSpeedPlaying(), not IsSpeedPlaying()
1083  // as we could be stopped now. Similarly WasKeyboardScrubbing().
1084  if (click && (scrubber.WasSpeedPlaying() || scrubber.WasKeyboardScrubbing()))
1085  {
1086  ;// don't change the selection.
1087  }
1088  else if (shift && click) {
1089  // Change the region selection, as if by shift-click at the play head
1090  auto t0 = selection.t0(), t1 = selection.t1();
1091  if (time < t0)
1092  // Grow selection
1093  t0 = time;
1094  else if (time > t1)
1095  // Grow selection
1096  t1 = time;
1097  else {
1098  // Shrink selection, changing the nearer boundary
1099  if (fabs(t0 - time) < fabs(t1 - time))
1100  t0 = time;
1101  else
1102  t1 = time;
1103  }
1104  selection.setTimes(t0, t1);
1105  }
1106  else if (click){
1107  // avoid a point at negative time.
1108  time = wxMax( time, 0 );
1109  // Set a point selection, as if by a click at the play head
1110  selection.setTimes(time, time);
1111  } else
1112  // How stop and set cursor always worked
1113  // -- change t0, collapsing to point only if t1 was greater
1114  selection.setT0(time, false);
1115 
1116  ProjectHistory::Get( project ).ModifyState(false); // without bWantsAutoSave
1117  return true;
1118  }
1119  return false;
1120 }
1121 
1122 // The code for "OnPlayStopSelect" is simply the code of "OnPlayStop" and
1123 // "OnStopSelect" merged.
1125 {
1126  auto gAudioIO = AudioIO::Get();
1127  if (DoPlayStopSelect(false, false))
1128  Stop();
1129  else if (!gAudioIO->IsBusy()) {
1130  //Otherwise, start playing (assuming audio I/O isn't busy)
1131 
1132  // Will automatically set mLastPlayMode
1133  PlayCurrentRegion(false);
1134  }
1135 }
1136 
1137 #include "CommonCommandFlags.h"
1138 
1140  []{ return PausedFlag(); },
1141  []{ return AudioIONotBusyFlag(); },
1142  []( const AudacityProject &project ){
1143  return MenuManager::Get( project ).mStopIfWasPaused; },
1144  []( AudacityProject &project, CommandFlag ){
1145  if ( MenuManager::Get( project ).mStopIfWasPaused )
1147  }
1148 }};
1149 
1150 // GetSelectedProperties collects information about
1151 // currently selected audio tracks
1154 {
1155  double rateOfSelection{ RATE_NOT_SELECTED };
1156 
1157  PropertiesOfSelected result;
1158  result.allSameRate = true;
1159 
1160  const auto selectedTracks{
1161  TrackList::Get(proj).Selected< const WaveTrack >() };
1162 
1163  for (const auto & track : selectedTracks)
1164  {
1165  if (rateOfSelection != RATE_NOT_SELECTED &&
1166  track->GetRate() != rateOfSelection)
1167  result.allSameRate = false;
1168  else if (rateOfSelection == RATE_NOT_SELECTED)
1169  rateOfSelection = track->GetRate();
1170  }
1171 
1172  result.numberOfSelected = selectedTracks.size();
1173  result.rateOfSelected = rateOfSelection;
1174 
1175  return result;
1176 }
size
size_t size
Definition: ffmpeg-2.3.6-single-header.h:412
PropertiesOfSelected::allSameRate
bool allSameRate
Definition: ProjectAudioManager.h:176
WaveTrack.h
WaveTrackArray
std::vector< std::shared_ptr< WaveTrack > > WaveTrackArray
Definition: AudioIO.h:48
PlayMode::cutPreviewPlay
@ cutPreviewPlay
ProjectHistory::ModifyState
void ModifyState(bool bWantsAutoSave)
Definition: ProjectHistory.cpp:124
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:161
field
#define field(n, t)
Definition: ImportAUP.cpp:167
TransportTracks::playbackTracks
WaveTrackArray playbackTracks
Definition: AudioIO.h:65
ProjectAudioIO::GetAudioIOToken
int GetAudioIOToken() const
Definition: ProjectAudioIO.cpp:41
CanStopAudioStreamFlag
const ReservedCommandFlag & CanStopAudioStreamFlag()
Definition: ProjectAudioManager.cpp:999
ProjectFramePlacement
std::unique_ptr< const BasicUI::WindowPlacement > ProjectFramePlacement(AudacityProject *project)
Make a WindowPlacement object suitable for project (which may be null)
Definition: ProjectWindows.cpp:101
WaveTrackFactory::Get
static WaveTrackFactory & Get(AudacityProject &project)
Definition: WaveTrack.cpp:2901
ProjectStatus.h
ToolManager.h
Scrubber::Get
static Scrubber & Get(AudacityProject &project)
Definition: Scrubbing.cpp:200
PropertiesOfSelected::numberOfSelected
int numberOfSelected
Definition: ProjectAudioManager.h:178
WaveTrack
A Track that contains audio waveform data.
Definition: WaveTrack.h:69
make_iterator_range
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:551
ProjectFileIO.h
ProjectAudioManager::Get
static ProjectAudioManager & Get(AudacityProject &project)
Definition: ProjectAudioManager.cpp:53
ProjectAudioManager::OnRecord
void OnRecord(bool altAppearance)
Definition: ProjectAudioManager.cpp:465
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
Definition: AudacityMessageBox.cpp:17
PlayMode
PlayMode
Definition: ProjectAudioManager.h:31
TrackView::Get
static TrackView & Get(Track &)
Definition: TrackView.cpp:63
TrackView::SetMinimized
void SetMinimized(bool minimized)
Definition: TrackView.cpp:77
flag
static std::once_flag flag
Definition: WaveformView.cpp:1124
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:70
TrackView.h
Track::GetEndTime
virtual double GetEndTime() const =0
SelectedRegion::t1
double t1() const
Definition: SelectedRegion.h:92
ProjectAudioManager::GetAllPlaybackTracks
static TransportTracks GetAllPlaybackTracks(TrackList &trackList, bool selectedOnly, bool nonWaveToo=false)
Definition: ProjectAudioManager.cpp:1035
BasicUI::ShowErrorDialog
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:233
TransportTracks::captureTracks
WaveTrackArray captureTracks
Definition: AudioIO.h:66
ProjectAudioManager::DoPlayStopSelect
void DoPlayStopSelect()
Definition: ProjectAudioManager.cpp:1124
ProjectAudioManager::PlayCurrentRegion
void PlayCurrentRegion(bool looped=false, bool cutpreview=false)
Definition: ProjectAudioManager.cpp:281
ProjectAudioManager::Pause
void Pause()
Definition: ProjectAudioManager.cpp:375
Project.h
DefaultPlayOptions
AudioIOStartStreamOptions DefaultPlayOptions(AudacityProject &project)
Definition: ProjectAudioManager.cpp:1008
ViewInfo::playRegion
PlayRegion playRegion
Definition: ViewInfo.h:197
ProjectRate::Get
static ProjectRate & Get(AudacityProject &project)
Definition: ProjectRate.cpp:42
ShowWarningDialog
int ShowWarningDialog(wxWindow *parent, const wxString &internalDialogName, const TranslatableString &message, bool showCancelButton, const TranslatableString &footer)
Definition: Warning.cpp:92
AudioIONotBusyFlag
const ReservedCommandFlag & AudioIONotBusyFlag()
Definition: CommonCommandFlags.cpp:127
sProjectAudioManagerKey
static AudacityProject::AttachedObjects::RegisteredFactory sProjectAudioManagerKey
Definition: ProjectAudioManager.cpp:47
ProjectAudioManager::OnAudioIOStopRecording
void OnAudioIOStopRecording() override
Definition: ProjectAudioManager.cpp:870
TrackList::Channels
static auto Channels(TrackType *pTrack) -> TrackIterRange< TrackType >
Definition: Track.h:1484
ProjectAudioManager::ChooseExistingRecordingTracks
static WaveTrackArray ChooseExistingRecordingTracks(AudacityProject &proj, bool selectedOnly, double targetRate=RATE_NOT_SELECTED)
Definition: ProjectAudioManager.cpp:389
ProjectAudioManager::mDisplayedRate
int mDisplayedRate
Definition: ProjectAudioManager.h:163
TrackList
A flat linked list of tracks supporting Add, Remove, Clear, and Contains, serialization of the list o...
Definition: Track.h:1280
StatusBarField
StatusBarField
Definition: ProjectStatus.h:24
TracksPrefs.h
ToolManager::Get
static ToolManager & Get(AudacityProject &project)
Definition: ToolManager.cpp:356
ProjectAudioManager::OnCheckpointFailure
void OnCheckpointFailure(wxCommandEvent &evt)
Definition: ProjectAudioManager.cpp:963
ReservedCommandFlag
Definition: CommandFlag.h:89
TrackPanelAx.h
ProjectAudioManager::~ProjectAudioManager
~ProjectAudioManager() override
ToolBar::EnableDisableButtons
virtual void EnableDisableButtons()=0
XO
#define XO(s)
Definition: Internat.h:31
XC
#define XC(s, c)
Definition: Internat.h:37
ProjectFileIO::Get
static ProjectFileIO & Get(AudacityProject &project)
Definition: ProjectFileIO.cpp:265
ProjectSettings::Get
static ProjectSettings & Get(AudacityProject &project)
Definition: ProjectSettings.cpp:41
ProjectAudioManager::CancelRecording
void CancelRecording()
Definition: ProjectAudioManager.cpp:846
Track::Any
bool Any() const
Definition: Track.cpp:370
DefaultSpeedPlayOptions
AudioIOStartStreamOptions DefaultSpeedPlayOptions(AudacityProject &project)
Definition: ProjectAudioManager.cpp:1022
ProjectSettings.h
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
TimeTrack.h
CommandFlag
std::bitset< NCommandFlags > CommandFlag
Definition: CommandFlag.h:31
ProjectAudioManager.h
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:22
Meter.h
TracksPrefs::GetDefaultAudioTrackNamePreference
static wxString GetDefaultAudioTrackNamePreference()
Definition: TracksPrefs.cpp:422
AudioIOStartStreamOptions::playLooped
bool playLooped
Definition: AudioIOBase.h:92
ClientData::Site::RegisteredFactory
Client code makes static instance from a factory of attachments; passes it to Get or Find as a retrie...
Definition: ClientData.h:266
TransportTracks::otherPlayableTracks
PlayableTrackConstArray otherPlayableTracks
Definition: AudioIO.h:67
ProjectAudioManager::mLastPlayMode
PlayMode mLastPlayMode
Definition: ProjectAudioManager.h:152
WaveTrack::Reinit
void Reinit(const WaveTrack &orig)
Definition: WaveTrack.cpp:191
ProjectAudioManager::ResetTimerRecordCancelled
void ResetTimerRecordCancelled()
Definition: ProjectAudioManager.h:70
Setting::Read
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:128
PlayMode::normalPlay
@ normalPlay
TrackList::RegisterPendingChangedTrack
std::shared_ptr< Track > RegisterPendingChangedTrack(Updater updater, Track *src)
Definition: Track.cpp:1044
ProjectAudioManager::CanStopAudioStream
bool CanStopAudioStream() const
Definition: ProjectAudioManager.cpp:990
UndoPush::NOAUTOSAVE
@ NOAUTOSAVE
ProjectAudioManager::IsTimerRecordCancelled
bool IsTimerRecordCancelled()
Definition: ProjectAudioManager.h:68
ProjectStatus::Set
void Set(const TranslatableString &msg, StatusBarField field=mainStatusBarField)
Definition: ProjectStatus.cpp:77
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:196
XXO
#define XXO(s)
Definition: Internat.h:44
ToolManager::GetToolBar
ToolBar * GetToolBar(int type) const
Definition: ToolManager.cpp:1029
TrackList::ClearPendingTracks
void ClearPendingTracks(ListOfTracks *pAdded=nullptr)
Definition: Track.cpp:1090
ScrubbingBarID
@ ScrubbingBarID
Definition: ToolBar.h:80
PropertiesOfSelected
Definition: ProjectAudioManager.h:175
TrackList::MakeMultiChannelTrack
bool MakeMultiChannelTrack(Track &first, int nChannels, bool aligned)
Converts channels to a multichannel track.
Definition: Track.cpp:756
anonymous_namespace{TimeTrack.cpp}::GetRate
double GetRate()
Definition: TimeTrack.cpp:175
ProjectAudioManager::Recording
bool Recording() const
Definition: ProjectAudioManager.cpp:981
name
const TranslatableString name
Definition: Distortion.cpp:98
rateStatusBarField
@ rateStatusBarField
Definition: ProjectStatus.h:27
ProjectAudioManager::UseDuplex
static bool UseDuplex()
Definition: ProjectAudioManager.cpp:563
Track::IsSelected
bool IsSelected() const
Definition: Track.cpp:373
Warning.h
Scrubbing.h
AudioIOBase::Get
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:89
UndoManager.h
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:755
ProjectAudioManager::OnCommitRecording
void OnCommitRecording() override
Definition: ProjectAudioManager.cpp:948
AudioIOStartStreamOptions
struct holding stream options, including a pointer to the time warp info and AudioIOListener and whet...
Definition: AudioIOBase.h:74
PausedFlag
const ReservedCommandFlag & PausedFlag()
Definition: CommonCommandFlags.cpp:318
anonymous_namespace{NoteTrack.cpp}::swap
void swap(std::unique_ptr< Alg_seq > &a, std::unique_ptr< Alg_seq > &b)
Definition: NoteTrack.cpp:735
ProjectRate::GetRate
double GetRate() const
Definition: ProjectRate.cpp:68
TrackList::RegisterPendingNewTrack
void RegisterPendingNewTrack(const std::shared_ptr< Track > &pTrack)
Definition: Track.cpp:1066
ProjectAudioManager::Stop
void Stop(bool stopStream=true)
Definition: ProjectAudioManager.cpp:310
PlayableTrack
AudioTrack subclass that can also be audibly replayed by the program.
Definition: Track.h:854
ViewInfo.h
AudioIOStartStreamOptions::playNonWaveTracks
bool playNonWaveTracks
Definition: AudioIOBase.h:98
MenuManager::TryToMakeActionAllowed
bool TryToMakeActionAllowed(CommandFlag &flags, CommandFlag flagsRqd)
Definition: Menus.cpp:712
BasicUI::ErrorDialogOptions
Options for variations of error dialogs; the default is for modal dialogs.
Definition: BasicUI.h:49
Menus.h
LabelTrack.h
TransportTracks
Definition: AudioIO.h:64
ProjectAudioManager::OnAudioIONewBlocks
void OnAudioIONewBlocks(const WaveTrackArray *tracks) override
Definition: ProjectAudioManager.cpp:941
ProjectWindows.h
accessors for certain important windows associated with each project
ProjectAudioManager::mCutPreviewTracks
std::shared_ptr< TrackList > mCutPreviewTracks
Definition: ProjectAudioManager.h:150
ProjectStatus::StatusWidthResult
std::pair< std::vector< TranslatableString >, unsigned > StatusWidthResult
Definition: ProjectStatus.h:59
ProjectAudioManager::PlayPlayRegion
int PlayPlayRegion(const SelectedRegion &selectedRegion, const AudioIOStartStreamOptions &options, PlayMode playMode, bool backwards=false, bool playWhiteSpace=false)
Definition: ProjectAudioManager.cpp:102
TrackList::UpdatePendingTracks
void UpdatePendingTracks()
Definition: Track.cpp:1072
BasicUI.h
Toolkit-neutral facade for basic user interface services.
ProjectAudioIO::SetAudioIOToken
void SetAudioIOToken(int token)
Definition: ProjectAudioIO.cpp:46
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
RATE_NOT_SELECTED
constexpr int RATE_NOT_SELECTED
Definition: ProjectAudioManager.h:21
SelectedRegion::t0
double t0() const
Definition: SelectedRegion.h:91
ProjectAudioManager::OnAudioIORate
void OnAudioIORate(int rate) override
Definition: ProjectAudioManager.cpp:852
BasicUI
Definition: Export.h:39
RegisteredMenuItemEnabler
Definition: CommandFlag.h:119
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:506
ProjectAudioManager::SetupCutPreviewTracks
void SetupCutPreviewTracks(double playStart, double cutStart, double cutEnd, double playEnd)
Definition: ProjectAudioManager.cpp:815
TrackList::ApplyPendingTracks
bool ApplyPendingTracks()
Definition: Track.cpp:1131
ProjectAudioManager::OnAudioIOStartRecording
void OnAudioIOStartRecording() override
Definition: ProjectAudioManager.cpp:863
Track
Abstract base class for an object holding data associated with points on a time axis.
Definition: Track.h:239
ProjectAudioManager::mProject
AudacityProject & mProject
Definition: ProjectAudioManager.h:148
AudioIOStartStreamOptions::cutPreviewGapStart
double cutPreviewGapStart
Definition: AudioIOBase.h:93
_
#define _(s)
Definition: Internat.h:75
ProjectAudioManager::ClearCutPreviewTracks
void ClearCutPreviewTracks()
Definition: ProjectAudioManager.cpp:839
ProjectSettings::GetTracksFitVerticallyZoomed
bool GetTracksFitVerticallyZoomed() const
Definition: ProjectSettings.h:78
AudioIO.h
ProjectStatus::Get
static ProjectStatus & Get(AudacityProject &project)
Definition: ProjectStatus.cpp:35
ProjectStatus::RegisteredStatusWidthFunction
Definition: ProjectStatus.h:67
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:92
MeterPanelBase.h
AudioIOStartStreamOptions::cutPreviewGapLen
double cutPreviewGapLen
Definition: AudioIOBase.h:94
ProjectAudioManager
Definition: ProjectAudioManager.h:46
AudacityMessageBox.h
GetProjectFrame
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 ...
Definition: ProjectWindows.cpp:72
ProjectAudioManager::ProjectAudioManager
ProjectAudioManager(AudacityProject &project)
Definition: ProjectAudioManager.cpp:65
MenuManager::Get
static MenuManager & Get(AudacityProject &project)
Definition: Menus.cpp:70
ProjectHistory.h
ProjectRate.h
an object holding per-project preferred sample rate
TrackList::Create
static std::shared_ptr< TrackList > Create(AudacityProject *pOwner)
Definition: Track.cpp:523
ProjectAudioManager::StopIfPaused
void StopIfPaused()
Definition: ProjectAudioManager.cpp:1062
NotifyingSelectedRegion::t0
double t0() const
Definition: ViewInfo.h:47
ProjectAudioManager::OnSoundActivationThreshold
void OnSoundActivationThreshold() override
Definition: ProjectAudioManager.cpp:954
ProjectAudioManager::DoRecord
bool DoRecord(AudacityProject &project, const TransportTracks &transportTracks, double t0, double t1, bool altAppearance, const AudioIOStartStreamOptions &options)
Definition: ProjectAudioManager.cpp:576
GetPropertiesOfSelected
PropertiesOfSelected GetPropertiesOfSelected(const AudacityProject &proj)
Definition: ProjectAudioManager.cpp:1153
TrackList::Any
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1371
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:138
PlayMode::loopedPlay
@ loopedPlay
CommonCommandFlags.h
TrackList::Selected
auto Selected() -> TrackIterRange< TrackType >
Definition: Track.h:1388
MenuManager::mStopIfWasPaused
bool mStopIfWasPaused
Definition: Menus.h:123
WaveTrackFactory::NewWaveTrack
std::shared_ptr< WaveTrack > NewWaveTrack(sampleFormat format=(sampleFormat) 0, double rate=0)
Definition: WaveTrack.cpp:113
PropertiesOfSelected::rateOfSelected
int rateOfSelected
Definition: ProjectAudioManager.h:177
ProjectAudioIO.h
TimeTrack
A kind of Track used to 'warp time'.
Definition: TimeTrack.h:24
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
AudioIORecordChannels
IntSetting AudioIORecordChannels
Definition: AudioIOBase.cpp:972
ProjectAudioManager::Playing
bool Playing() const
Definition: ProjectAudioManager.cpp:969
ProjectAudioManager::StatusWidthFunction
static std::pair< TranslatableStrings, unsigned > StatusWidthFunction(const AudacityProject &project, StatusBarField field)
Definition: ProjectAudioManager.cpp:86
stopIfPaused
static RegisteredMenuItemEnabler stopIfPaused
Definition: ProjectAudioManager.cpp:1139
FormatRate
static TranslatableString FormatRate(int rate)
Definition: ProjectAudioManager.cpp:76
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:35
ProjectAudioManager::OnPause
void OnPause()
Definition: ProjectAudioManager.cpp:774