Audacity  3.0.3
TransportMenus.cpp
Go to the documentation of this file.
1 
2 
3 #include "../AdornedRulerPanel.h"
4 #include "../AudioIO.h"
5 #include "../CommonCommandFlags.h"
6 #include "../DeviceManager.h"
7 #include "../LabelTrack.h"
8 #include "../Menus.h"
9 #include "../Prefs.h"
10 #include "../Project.h"
11 #include "../ProjectAudioIO.h"
12 #include "../ProjectAudioManager.h"
13 #include "../ProjectFileIO.h"
14 #include "../ProjectHistory.h"
15 #include "../ProjectSettings.h"
16 #include "../ProjectWindow.h"
17 #include "../ProjectManager.h"
18 #include "../SoundActivatedRecord.h"
19 #include "../TimerRecordDialog.h"
20 #include "../TrackPanelAx.h"
21 #include "../TrackPanel.h"
22 #include "../UndoManager.h"
23 #include "../WaveClip.h"
24 #include "../prefs/RecordingPrefs.h"
25 #include "../prefs/TracksPrefs.h"
26 #include "../WaveTrack.h"
27 #include "../ViewInfo.h"
28 #include "../commands/CommandContext.h"
29 #include "../commands/CommandManager.h"
30 #include "../toolbars/ControlToolBar.h"
31 #include "../toolbars/TranscriptionToolBar.h"
32 #include "../widgets/AudacityMessageBox.h"
33 #include "../widgets/ErrorDialog.h"
34 #include "../widgets/ProgressDialog.h"
35 
36 #include <float.h>
37 
38 // private helper classes and functions
39 namespace {
40 
42  bool looped = false,
43  bool cutpreview = false)
44 {
45  auto &project = context.project;
46  auto &projectAudioManager = ProjectAudioManager::Get(project);
47 
48  const auto &playRegion = ViewInfo::Get(project).playRegion;
49  double t0 = playRegion.GetStart();
50  double t1 = playRegion.GetEnd();
51 
52  projectAudioManager.PlayCurrentRegion(looped, cutpreview);
53 
54  if (project.mBatchMode > 0 && t0 != t1 && !looped) {
55  wxYieldIfNeeded();
56 
57  /* i18n-hint: This title appears on a dialog that indicates the progress
58  in doing something.*/
59  ProgressDialog progress(XO("Progress"), XO("Playing"), pdlgHideCancelButton);
60  auto gAudioIO = AudioIO::Get();
61 
62  while (projectAudioManager.Playing()) {
63  ProgressResult result = progress.Update(gAudioIO->GetStreamTime() - t0, t1 - t0);
64  if (result != ProgressResult::Success) {
65  projectAudioManager.Stop();
66  if (result != ProgressResult::Stopped) {
67  context.Error(wxT("Playing interrupted"));
68  }
69  break;
70  }
71 
72  wxMilliSleep(100);
73  wxYieldIfNeeded();
74  }
75 
76  projectAudioManager.Stop();
77  wxYieldIfNeeded();
78  }
79 }
80 
82  const SelectedRegion &selectedRegion,
83  const AudioIOStartStreamOptions &options,
84  PlayMode mode)
85 {
86  auto &project = context.project;
87  auto &projectAudioManager = ProjectAudioManager::Get(project);
88 
89  double t0 = selectedRegion.t0();
90  double t1 = selectedRegion.t1();
91 
92  projectAudioManager.PlayPlayRegion(selectedRegion, options, mode);
93 
94  if (project.mBatchMode > 0) {
95  wxYieldIfNeeded();
96 
97  /* i18n-hint: This title appears on a dialog that indicates the progress
98  in doing something.*/
99  ProgressDialog progress(XO("Progress"), XO("Playing"), pdlgHideCancelButton);
100  auto gAudioIO = AudioIO::Get();
101 
102  while (projectAudioManager.Playing()) {
103  ProgressResult result = progress.Update(gAudioIO->GetStreamTime() - t0, t1 - t0);
104  if (result != ProgressResult::Success) {
105  projectAudioManager.Stop();
106  if (result != ProgressResult::Stopped) {
107  context.Error(wxT("Playing interrupted"));
108  }
109  break;
110  }
111 
112  wxMilliSleep(100);
113  wxYieldIfNeeded();
114  }
115 
116  projectAudioManager.Stop();
117  wxYieldIfNeeded();
118  }
119 }
120 
121 void RecordAndWait(const CommandContext &context, bool altAppearance)
122 {
123  auto &project = context.project;
124  auto &projectAudioManager = ProjectAudioManager::Get(project);
125 
126  const auto &selectedRegion = ViewInfo::Get(project).selectedRegion;
127  double t0 = selectedRegion.t0();
128  double t1 = selectedRegion.t1();
129 
130  projectAudioManager.OnRecord(altAppearance);
131 
132  if (project.mBatchMode > 0 && t1 != t0) {
133  wxYieldIfNeeded();
134 
135  /* i18n-hint: This title appears on a dialog that indicates the progress
136  in doing something.*/
137  ProgressDialog progress(XO("Progress"), XO("Recording"), pdlgHideCancelButton);
138  auto gAudioIO = AudioIO::Get();
139 
140  while (projectAudioManager.Recording()) {
141  ProgressResult result = progress.Update(gAudioIO->GetStreamTime() - t0, t1 - t0);
142  if (result != ProgressResult::Success) {
143  projectAudioManager.Stop();
144  if (result != ProgressResult::Stopped) {
145  context.Error(wxT("Recording interrupted"));
146  }
147  break;
148  }
149 
150  wxMilliSleep(100);
151  wxYieldIfNeeded();
152  }
153 
154  projectAudioManager.Stop();
155  wxYieldIfNeeded();
156  }
157 }
158 
159 // TODO: Should all these functions which involve
160 // the toolbar actually move into ControlToolBar?
161 
167 {
168  auto &toolbar = ControlToolBar::Get( project );
169  wxCommandEvent evt;
170 
171  // If this project is playing, stop playing
172  auto gAudioIO = AudioIOBase::Get();
173  if (gAudioIO->IsStreamActive(
175  )) {
176  // Make momentary changes of button appearances
177  toolbar.SetPlay(false); //Pops
178  toolbar.SetStop(); //Pushes stop down
179  toolbar.OnStop(evt);
180 
181  ::wxMilliSleep(100);
182  }
183 
184  // If it didn't stop playing quickly, or if some other
185  // project is playing, return
186  if (gAudioIO->IsBusy())
187  return false;
188 
189  return true;
190 }
191 
192 // Returns true if this project was stopped, otherwise false.
193 // (it may though have stopped another project playing)
194 bool DoStopPlaying(const CommandContext &context)
195 {
196  auto &project = context.project;
197  auto &projectAudioManager = ProjectAudioManager::Get(project);
198  auto gAudioIO = AudioIOBase::Get();
199  auto &toolbar = ControlToolBar::Get(project);
200  auto &window = ProjectWindow::Get(project);
201  auto token = ProjectAudioIO::Get(project).GetAudioIOToken();
202 
203  //If this project is playing, stop playing, make sure everything is unpaused.
204  if (gAudioIO->IsStreamActive(token)) {
205  toolbar.SetStop(); //Pushes stop down
206  projectAudioManager.Stop();
207  // Playing project was stopped. All done.
208  return true;
209  }
210 
211  // This project isn't playing.
212  // If some other project is playing, stop playing it
213  if (gAudioIO->IsStreamActive()) {
214 
215  //find out which project we need;
216  auto start = AllProjects{}.begin(), finish = AllProjects{}.end(),
217  iter = std::find_if(start, finish,
218  [&](const AllProjects::value_type &ptr) {
219  return gAudioIO->IsStreamActive(
221 
222  //stop playing the other project
223  if (iter != finish) {
224  auto otherProject = *iter;
225  auto &otherToolbar = ControlToolBar::Get(*otherProject);
226  auto &otherProjectAudioManager =
227  ProjectAudioManager::Get(*otherProject);
228  otherToolbar.SetStop(); //Pushes stop down
229  otherProjectAudioManager.Stop();
230  }
231  }
232  return false;
233 }
234 
235 void DoStartPlaying(const CommandContext &context, bool looping = false)
236 {
237  auto &project = context.project;
238  auto &projectAudioManager = ProjectAudioManager::Get(project);
239  auto gAudioIO = AudioIOBase::Get();
240  //play the front project
241  if (!gAudioIO->IsBusy()) {
242  //Otherwise, start playing (assuming audio I/O isn't busy)
243 
244  // Will automatically set mLastPlayMode
245  PlayCurrentRegionAndWait(context, looping);
246  }
247 }
248 
249 void DoMoveToLabel(AudacityProject &project, bool next)
250 {
251  auto &tracks = TrackList::Get( project );
252  auto &trackFocus = TrackFocus::Get( project );
253  auto &window = ProjectWindow::Get( project );
254  auto &projectAudioManager = ProjectAudioManager::Get(project);
255 
256  // Find the number of label tracks, and ptr to last track found
257  auto trackRange = tracks.Any<LabelTrack>();
258  auto lt = *trackRange.rbegin();
259  auto nLabelTrack = trackRange.size();
260 
261  if (nLabelTrack == 0 ) {
262  trackFocus.MessageForScreenReader(XO("no label track"));
263  }
264  else if (nLabelTrack > 1) {
265  // find first label track, if any, starting at the focused track
266  lt =
267  *tracks.Find(trackFocus.Get()).Filter<LabelTrack>();
268  if (!lt)
269  trackFocus.MessageForScreenReader(
270  XO("no label track at or below focused track"));
271  }
272 
273  // If there is a single label track, or there is a label track at or below
274  // the focused track
275  auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
276  if (lt) {
277  int i;
278  if (next)
279  i = lt->FindNextLabel(selectedRegion);
280  else
281  i = lt->FindPrevLabel(selectedRegion);
282 
283  if (i >= 0) {
284  const LabelStruct* label = lt->GetLabel(i);
285  bool looping = projectAudioManager.Looping();
286  if (ProjectAudioIO::Get( project ).IsAudioActive()) {
287  DoStopPlaying(project);
288  selectedRegion = label->selectedRegion;
289  window.RedrawProject();
290  DoStartPlaying(project, looping);
291  }
292  else {
293  selectedRegion = label->selectedRegion;
294  window.ScrollIntoView(selectedRegion.t0());
295  window.RedrawProject();
296  }
297  auto message = XO("%s %d of %d")
298  .Format( label->title, i + 1, lt->GetNumLabels() );
299  trackFocus.MessageForScreenReader(message);
300  }
301  else {
302  trackFocus.MessageForScreenReader(XO("no labels in label track"));
303  }
304  }
305 }
306 
307 }
308 
309 // Menu handler functions
310 
311 namespace TransportActions {
312 
314 
315 // This Plays OR Stops audio. It's a toggle.
316 // It is usually bound to the SPACE key.
317 void OnPlayStop(const CommandContext &context)
318 {
319  if (DoStopPlaying(context.project))
320  return;
321  DoStartPlaying(context.project);
322 }
323 
324 void OnPlayStopSelect(const CommandContext &context)
325 {
327 }
328 
329 void OnPlayLooped(const CommandContext &context)
330 {
331  auto &project = context.project;
332 
333  if( !MakeReadyToPlay(project) )
334  return;
335 
336  // Now play in a loop
337  // Will automatically set mLastPlayMode
338  PlayCurrentRegionAndWait(context, true);
339 }
340 
341 void OnPause(const CommandContext &context)
342 {
344 }
345 
346 void OnRecord(const CommandContext &context)
347 {
348  RecordAndWait(context, false);
349 }
350 
351 // If first choice is record same track 2nd choice is record NEW track
352 // and vice versa.
353 void OnRecord2ndChoice(const CommandContext &context)
354 {
355  RecordAndWait(context, true);
356 }
357 
358 void OnTimerRecord(const CommandContext &context)
359 {
360  auto &project = context.project;
361  const auto &settings = ProjectSettings::Get( project );
362  auto &undoManager = UndoManager::Get( project );
363  auto &window = ProjectWindow::Get( project );
364 
365  // MY: Due to improvements in how Timer Recording saves and/or exports
366  // it is now safer to disable Timer Recording when there is more than
367  // one open project.
368  if (AllProjects{}.size() > 1) {
370  XO(
371 "Timer Recording cannot be used with more than one open project.\n\nPlease close any additional projects and try again."),
372  XO("Timer Recording"),
373  wxICON_INFORMATION | wxOK);
374  return;
375  }
376 
377  // MY: If the project has unsaved changes then we no longer allow access
378  // to Timer Recording. This decision has been taken as the safest approach
379  // preventing issues surrounding "dirty" projects when Automatic Save/Export
380  // is used in Timer Recording.
381  if ((undoManager.UnsavedChanges()) &&
382  (TrackList::Get( project ).Any() || settings.EmptyCanBeDirty())) {
384  XO(
385 "Timer Recording cannot be used while you have unsaved changes.\n\nPlease save or close this project and try again."),
386  XO("Timer Recording"),
387  wxICON_INFORMATION | wxOK);
388  return;
389  }
390 
391  // We check the selected tracks to see if there is enough of them to accommodate
392  // all input channels and all of them have the same sampling rate.
393  // Those checks will be later performed by recording function anyway,
394  // but we want to warn the user about potential problems from the very start.
395  const auto selectedTracks{ GetPropertiesOfSelected(project) };
396  const int rateOfSelected{ selectedTracks.rateOfSelected };
397  const int numberOfSelected{ selectedTracks.numberOfSelected };
398  const bool allSameRate{ selectedTracks.allSameRate };
399 
400  if (!allSameRate) {
401  AudacityMessageBox(XO("The tracks selected "
402  "for recording must all have the same sampling rate"),
403  XO("Mismatched Sampling Rates"),
404  wxICON_ERROR | wxCENTRE);
405 
406  return;
407  }
408 
409  const auto existingTracks{ ProjectAudioManager::ChooseExistingRecordingTracks(project, true, rateOfSelected) };
410  if (existingTracks.empty()) {
411  if (numberOfSelected > 0 && rateOfSelected != settings.GetRate()) {
413  "Too few tracks are selected for recording at this sample rate.\n"
414  "(Audacity requires two channels at the same sample rate for\n"
415  "each stereo track)"),
416  XO("Too Few Compatible Tracks Selected"),
417  wxICON_ERROR | wxCENTRE);
418 
419  return;
420  }
421  }
422 
423  // We use this variable to display "Current Project" in the Timer Recording
424  // save project field
425  bool bProjectSaved = !ProjectFileIO::Get( project ).IsModified();
426 
427  //we break the prompting and waiting dialogs into two sections
428  //because they both give the user a chance to click cancel
429  //and therefore remove the newly inserted track.
430 
431  TimerRecordDialog dialog(
432  &window, project, bProjectSaved); /* parent, project, project saved? */
433  int modalResult = dialog.ShowModal();
434  if (modalResult == wxID_CANCEL)
435  {
436  // Cancelled before recording - don't need to do anything.
437  }
438  else
439  {
440  // Bug #2382
441  // Allow recording to start at current cursor position.
442  #if 0
443  // Timer Record should not record into a selection.
444  bool bPreferNewTrack;
445  gPrefs->Read("/GUI/PreferNewTrackRecord",&bPreferNewTrack, false);
446  if (bPreferNewTrack) {
447  window.Rewind(false);
448  } else {
449  window.SkipEnd(false);
450  }
451  #endif
452 
453  int iTimerRecordingOutcome = dialog.RunWaitDialog();
454  switch (iTimerRecordingOutcome) {
456  // Canceled on the wait dialog
457  ProjectHistory::Get( project ).RollbackState();
458  break;
460  // RunWaitDialog() shows the "wait for start" as well as "recording"
461  // dialog if it returned POST_TIMER_RECORD_CANCEL it means the user
462  // cancelled while the recording, so throw out the fresh track.
463  // However, we can't undo it here because the PushState() is called in TrackPanel::OnTimer(),
464  // which is blocked by this function.
465  // so instead we mark a flag to undo it there.
467  break;
469  // No action required
470  break;
472  wxTheApp->CallAfter( []{
473  // Simulate the application Exit menu item
474  wxCommandEvent evt{ wxEVT_MENU, wxID_EXIT };
475  wxTheApp->AddPendingEvent( evt );
476  } );
477  ProjectManager::Get(project).SetSkipSavePrompt(true);
478  break;
479 
480 #ifdef __WINDOWS__
481  case POST_TIMER_RECORD_RESTART:
482  // Restart System
483  ProjectManager::Get(project).SetSkipSavePrompt(true);
484  system("shutdown /r /f /t 30");
485  break;
486  case POST_TIMER_RECORD_SHUTDOWN:
487  // Shutdown System
488  ProjectManager::Get(project).SetSkipSavePrompt(true);
489  system("shutdown /s /f /t 30");
490  break;
491 #endif
492  }
493  }
494 }
495 
496 #ifdef EXPERIMENTAL_PUNCH_AND_ROLL
497 void OnPunchAndRoll(const CommandContext &context)
498 {
499  AudacityProject &project = context.project;
500  auto &viewInfo = ViewInfo::Get( project );
501  auto &window = GetProjectFrame( project );
502 
503  static const auto url =
504  wxT("Punch_and_Roll_Record#Using_Punch_and_Roll_Record");
505 
506  auto gAudioIO = AudioIO::Get();
507  if (gAudioIO->IsBusy())
508  return;
509 
510  // Ignore all but left edge of the selection.
511  viewInfo.selectedRegion.collapseToT0();
512  double t1 = std::max(0.0, viewInfo.selectedRegion.t1());
513 
514  // Checking the selected tracks: making sure they all have the same rate
515  const auto selectedTracks{ GetPropertiesOfSelected(project) };
516  const int rateOfSelected{ selectedTracks.rateOfSelected };
517  const bool allSameRate{ selectedTracks.allSameRate };
518 
519  if (!allSameRate) {
520  AudacityMessageBox(XO("The tracks selected "
521  "for recording must all have the same sampling rate"),
522  XO("Mismatched Sampling Rates"),
523  wxICON_ERROR | wxCENTRE);
524 
525  return;
526  }
527 
528  // Decide which tracks to record in.
529  auto tracks =
530  ProjectAudioManager::ChooseExistingRecordingTracks(project, true, rateOfSelected);
531  if (tracks.empty()) {
532  auto recordingChannels =
533  std::max(0, AudioIORecordChannels.Read());
534  auto message =
535  (recordingChannels == 1)
536  ? XO("Please select in a mono track.")
537  : (recordingChannels == 2)
538  ? XO("Please select in a stereo track or two mono tracks.")
539  : XO("Please select at least %d channels.").Format( recordingChannels );
540  ShowErrorDialog(&window, XO("Error"), message, url);
541  return;
542  }
543 
544  // Delete the portion of the target tracks right of the selection, but first,
545  // remember a part of the deletion for crossfading with the new recording.
546  // We may also adjust the starting point leftward if it is too close to the
547  // end of the track, so that at least some nonzero crossfade data can be
548  // taken.
549  PRCrossfadeData crossfadeData;
550  const double crossFadeDuration = std::max(0.0,
552  / 1000.0
553  );
554 
555  // The test for t1 == 0.0 stops punch and roll deleting everything where the
556  // selection is at zero. There wouldn't be any cued audio to play in
557  // that case, so a normal record, not a punch and roll, is called for.
558  bool error = (t1 == 0.0);
559 
560  double newt1 = t1;
561  for (const auto &wt : tracks) {
562  sampleCount testSample(floor(t1 * wt->GetRate()));
563  auto clip = wt->GetClipAtSample(testSample);
564  if (!clip)
565  // Bug 1890 (an enhancement request)
566  // Try again, a little to the left.
567  // Subtract 10 to allow a selection exactly at or slightly after the
568  // end time
569  clip = wt->GetClipAtSample(testSample - 10);
570  if (!clip)
571  error = true;
572  else {
573  // May adjust t1 left
574  // Let's ignore the possibility of a clip even shorter than the
575  // crossfade duration!
576  newt1 = std::min(newt1, clip->GetEndTime() - crossFadeDuration);
577  }
578  }
579 
580  if (error) {
581  auto message = XO("Please select a time within a clip.");
582  ShowErrorDialog( &window, XO("Error"), message, url);
583  return;
584  }
585 
586  t1 = newt1;
587  for (const auto &wt : tracks) {
588  const auto endTime = wt->GetEndTime();
589  const auto duration =
590  std::max(0.0, std::min(crossFadeDuration, endTime - t1));
591  const size_t getLen = floor(duration * wt->GetRate());
592  std::vector<float> data(getLen);
593  if (getLen > 0) {
594  float *const samples = data.data();
595  const sampleCount pos = wt->TimeToLongSamples(t1);
596  wt->GetFloats(samples, pos, getLen);
597  }
598  crossfadeData.push_back(std::move(data));
599  }
600 
601  // Change tracks only after passing the error checks above
602  for (const auto &wt : tracks) {
603  wt->Clear(t1, wt->GetEndTime());
604  }
605 
606  // Choose the tracks for playback.
607  TransportTracks transportTracks;
608  const auto duplex = ProjectAudioManager::UseDuplex();
609  if (duplex)
610  // play all
611  transportTracks =
613  TrackList::Get( project ), false, true);
614  else
615  // play recording tracks only
616  std::copy(tracks.begin(), tracks.end(),
617  std::back_inserter(transportTracks.playbackTracks));
618 
619  // Unlike with the usual recording, a track may be chosen both for playback
620  // and recording.
621  transportTracks.captureTracks = std::move(tracks);
622 
623  // Try to start recording
624  auto options = DefaultPlayOptions( project );
625  options.rate = rateOfSelected;
626  options.preRoll = std::max(0L,
628  options.pCrossfadeData = &crossfadeData;
629  bool success = ProjectAudioManager::Get( project ).DoRecord(project,
630  transportTracks,
631  t1, DBL_MAX,
632  false, // altAppearance
633  options);
634 
635  if (success)
636  // Undo state will get pushed elsewhere, when record finishes
637  ;
638  else
639  // Roll back the deletions
640  ProjectHistory::Get( project ).RollbackState();
641 }
642 #endif
643 
644 void OnLockPlayRegion(const CommandContext &context)
645 {
647 }
648 
649 void OnUnlockPlayRegion(const CommandContext &context)
650 {
652 }
653 
654 void OnRescanDevices(const CommandContext &WXUNUSED(context) )
655 {
657 }
658 
659 void OnSoundActivated(const CommandContext &context)
660 {
661  AudacityProject &project = context.project;
662 
663  SoundActivatedRecordDialog dialog( &GetProjectFrame( project ) /* parent */ );
664  dialog.ShowModal();
665 }
666 
667 void OnToggleSoundActivated(const CommandContext &WXUNUSED(context) )
668 {
669  bool pause;
670  gPrefs->Read(wxT("/AudioIO/SoundActivatedRecord"), &pause, false);
671  gPrefs->Write(wxT("/AudioIO/SoundActivatedRecord"), !pause);
672  gPrefs->Flush();
674 }
675 
676 void OnTogglePinnedHead(const CommandContext &context)
677 {
679 }
680 
681 void OnTogglePlayRecording(const CommandContext &WXUNUSED(context) )
682 {
683  bool Duplex;
684 #ifdef EXPERIMENTAL_DA
685  gPrefs->Read(wxT("/AudioIO/Duplex"), &Duplex, false);
686 #else
687  gPrefs->Read(wxT("/AudioIO/Duplex"), &Duplex, true);
688 #endif
689  gPrefs->Write(wxT("/AudioIO/Duplex"), !Duplex);
690  gPrefs->Flush();
692 }
693 
694 void OnToggleSWPlaythrough(const CommandContext &WXUNUSED(context) )
695 {
696  bool SWPlaythrough;
697  gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &SWPlaythrough, false);
698  gPrefs->Write(wxT("/AudioIO/SWPlaythrough"), !SWPlaythrough);
699  gPrefs->Flush();
701 }
702 
703 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
704 void OnToggleAutomatedInputLevelAdjustment(
705  const CommandContext &WXUNUSED(context) )
706 {
707  bool AVEnabled;
708  gPrefs->Read(
709  wxT("/AudioIO/AutomatedInputLevelAdjustment"), &AVEnabled, false);
710  gPrefs->Write(wxT("/AudioIO/AutomatedInputLevelAdjustment"), !AVEnabled);
711  gPrefs->Flush();
713 }
714 #endif
715 
716 void OnStop(const CommandContext &context)
717 {
719 }
720 
721 void OnPlayOneSecond(const CommandContext &context)
722 {
723  auto &project = context.project;
724  if( !MakeReadyToPlay(project) )
725  return;
726 
727  auto &trackPanel = TrackPanel::Get( project );
728  auto options = DefaultPlayOptions( project );
729 
730  double pos = trackPanel.GetMostRecentXPos();
731  PlayPlayRegionAndWait(context, SelectedRegion(pos - 0.5, pos + 0.5),
732  options, PlayMode::oneSecondPlay);
733 }
734 
742 void OnPlayToSelection(const CommandContext &context)
743 {
744  auto &project = context.project;
745 
746  if( !MakeReadyToPlay(project) )
747  return;
748 
749  auto &trackPanel = TrackPanel::Get( project );
750  auto &viewInfo = ViewInfo::Get( project );
751  const auto &selectedRegion = viewInfo.selectedRegion;
752 
753  double pos = trackPanel.GetMostRecentXPos();
754 
755  double t0,t1;
756  // check region between pointer and the nearest selection edge
757  if (fabs(pos - selectedRegion.t0()) <
758  fabs(pos - selectedRegion.t1())) {
759  t0 = t1 = selectedRegion.t0();
760  } else {
761  t0 = t1 = selectedRegion.t1();
762  }
763  if( pos < t1)
764  t0=pos;
765  else
766  t1=pos;
767 
768  // JKC: oneSecondPlay mode disables auto scrolling
769  // On balance I think we should always do this in this function
770  // since you are typically interested in the sound EXACTLY
771  // where the cursor is.
772  // TODO: have 'playing attributes' such as 'with_autoscroll'
773  // rather than modes, since that's how we're now using the modes.
774 
775  // An alternative, commented out below, is to disable autoscroll
776  // only when playing a short region, less than or equal to a second.
777 // mLastPlayMode = ((t1-t0) > 1.0) ? normalPlay : oneSecondPlay;
778 
779  auto playOptions = DefaultPlayOptions( project );
780 
781  PlayPlayRegionAndWait(context, SelectedRegion(t0, t1),
782  playOptions, PlayMode::oneSecondPlay);
783 }
784 
785 // The next 4 functions provide a limited version of the
786 // functionality of OnPlayToSelection() for keyboard users
787 
789 {
790  auto &project = context.project;
791 
792  if( !MakeReadyToPlay(project) )
793  return;
794 
795  auto &viewInfo = ViewInfo::Get( project );
796  const auto &selectedRegion = viewInfo.selectedRegion;
797 
798  double t0 = selectedRegion.t0();
799  double beforeLen;
800  gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
801 
802  auto playOptions = DefaultPlayOptions( project );
803 
804  PlayPlayRegionAndWait(context, SelectedRegion(t0 - beforeLen, t0),
805  playOptions, PlayMode::oneSecondPlay);
806 }
807 
809 {
810  auto &project = context.project;
811 
812  if( !MakeReadyToPlay(project) )
813  return;
814 
815  auto &viewInfo = ViewInfo::Get( project );
816  const auto &selectedRegion = viewInfo.selectedRegion;
817 
818  double t0 = selectedRegion.t0();
819  double t1 = selectedRegion.t1();
820  double afterLen;
821  gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
822 
823  auto playOptions = DefaultPlayOptions( project );
824 
825  if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
826  PlayPlayRegionAndWait(context, SelectedRegion(t0, t1),
827  playOptions, PlayMode::oneSecondPlay);
828  else
829  PlayPlayRegionAndWait(context, SelectedRegion(t0, t0 + afterLen),
830  playOptions, PlayMode::oneSecondPlay);
831 }
832 
834 {
835  auto &project = context.project;
836 
837  if( !MakeReadyToPlay(project) )
838  return;
839 
840  auto &viewInfo = ViewInfo::Get( project );
841  const auto &selectedRegion = viewInfo.selectedRegion;
842 
843  double t0 = selectedRegion.t0();
844  double t1 = selectedRegion.t1();
845  double beforeLen;
846  gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
847 
848  auto playOptions = DefaultPlayOptions( project );
849 
850  if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
851  PlayPlayRegionAndWait(context, SelectedRegion(t0, t1),
852  playOptions, PlayMode::oneSecondPlay);
853  else
854  PlayPlayRegionAndWait(context, SelectedRegion(t1 - beforeLen, t1),
855  playOptions, PlayMode::oneSecondPlay);
856 }
857 
859 {
860  auto &project = context.project;
861 
862  if( !MakeReadyToPlay(project) )
863  return;
864 
865  auto &viewInfo = ViewInfo::Get( project );
866  const auto &selectedRegion = viewInfo.selectedRegion;
867 
868  double t1 = selectedRegion.t1();
869  double afterLen;
870  gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
871 
872  auto playOptions = DefaultPlayOptions( project );
873 
874  PlayPlayRegionAndWait(context, SelectedRegion(t1, t1 + afterLen),
875  playOptions, PlayMode::oneSecondPlay);
876 }
877 
879 (const CommandContext &context)
880 {
881  auto &project = context.project;
882 
883  if (!MakeReadyToPlay(project))
884  return;
885 
886  auto &viewInfo = ViewInfo::Get( project );
887  const auto &selectedRegion = viewInfo.selectedRegion;
888 
889  double t0 = selectedRegion.t0();
890  double t1 = selectedRegion.t1();
891  double beforeLen;
892  gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
893  double afterLen;
894  gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
895 
896  auto playOptions = DefaultPlayOptions( project );
897 
898  if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
899  PlayPlayRegionAndWait(context, SelectedRegion(t0 - beforeLen, t1),
900  playOptions, PlayMode::oneSecondPlay);
901  else
902  PlayPlayRegionAndWait(context, SelectedRegion(t0 - beforeLen, t0 + afterLen),
903  playOptions, PlayMode::oneSecondPlay);
904 }
905 
907 (const CommandContext &context)
908 {
909  auto &project = context.project;
910 
911  if (!MakeReadyToPlay(project))
912  return;
913 
914  auto &viewInfo = ViewInfo::Get( project );
915  const auto &selectedRegion = viewInfo.selectedRegion;
916 
917  double t0 = selectedRegion.t0();
918  double t1 = selectedRegion.t1();
919  double beforeLen;
920  gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
921  double afterLen;
922  gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
923 
924  auto playOptions = DefaultPlayOptions( project );
925 
926  if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
927  PlayPlayRegionAndWait(context, SelectedRegion(t0, t1 + afterLen),
928  playOptions, PlayMode::oneSecondPlay);
929  else
930  PlayPlayRegionAndWait(context, SelectedRegion(t1 - beforeLen, t1 + afterLen),
931  playOptions, PlayMode::oneSecondPlay);
932 }
933 
934 void OnPlayCutPreview(const CommandContext &context)
935 {
936  auto &project = context.project;
937 
938  if ( !MakeReadyToPlay(project) )
939  return;
940 
941  // Play with cut preview
942  PlayCurrentRegionAndWait(context, false, true);
943 }
944 
945 void OnPlayAtSpeed(const CommandContext &context)
946 {
947  auto &project = context.project;
948  auto tb = &TranscriptionToolBar::Get( project );
949 
950  if (tb) {
951  tb->PlayAtSpeed(false, false);
952  }
953 }
954 
956 {
957  auto &project = context.project;
958  auto tb = &TranscriptionToolBar::Get( project );
959 
960  if (tb) {
961  tb->PlayAtSpeed(true, false);
962  }
963 }
964 
966 {
967  auto &project = context.project;
968  auto tb = &TranscriptionToolBar::Get( project );
969 
970  if (tb) {
971  tb->PlayAtSpeed(false, true);
972  }
973 }
974 
975 void OnSetPlaySpeed(const CommandContext &context)
976 {
977  auto &project = context.project;
978  auto tb = &TranscriptionToolBar::Get( project );
979 
980  if (tb) {
981  tb->ShowPlaySpeedDialog();
982  }
983 }
984 
985 void OnPlaySpeedInc(const CommandContext &context)
986 {
987  auto &project = context.project;
988  auto tb = &TranscriptionToolBar::Get( project );
989 
990  if (tb) {
991  tb->AdjustPlaySpeed(0.1f);
992  }
993 }
994 
995 void OnPlaySpeedDec(const CommandContext &context)
996 {
997  auto &project = context.project;
998  auto tb = &TranscriptionToolBar::Get( project );
999 
1000  if (tb) {
1001  tb->AdjustPlaySpeed(-0.1f);
1002  }
1003 }
1004 
1005 void OnMoveToPrevLabel(const CommandContext &context)
1006 {
1007  auto &project = context.project;
1008  DoMoveToLabel(project, false);
1009 }
1010 
1011 void OnMoveToNextLabel(const CommandContext &context)
1012 {
1013  auto &project = context.project;
1014  DoMoveToLabel(project, true);
1015 }
1016 
1017 #if 0
1018 // Legacy handlers, not used as of version 2.3.0
1019 void OnStopSelect(const CommandContext &context)
1020 {
1021  auto &project = context.project;
1022  auto &history = ProjectHistory::Get( project );
1023  auto &viewInfo = project.GetViewInfo();
1024  auto &selectedRegion = viewInfo.selectedRegion;
1025 
1026  auto gAudioIO = AudioIOBase::Get();
1027  if (gAudioIO->IsStreamActive()) {
1028  selectedRegion.setT0(gAudioIO->GetStreamTime(), false);
1029  ProjectAudioManager::Get( project ).Stop();
1030  history.ModifyState(false); // without bWantsAutoSave
1031  }
1032 }
1033 #endif
1034 
1035 }; // struct Handler
1036 
1037 } // namespace
1038 
1040  // Handler is not stateful. Doesn't need a factory registered with
1041  // AudacityProject.
1042  static TransportActions::Handler instance;
1043  return instance;
1044 };
1045 
1046 // Menu definitions
1047 
1048 #define FN(X) (& TransportActions::Handler :: X)
1049 
1050 // Under /MenuBar
1051 namespace {
1052 using namespace MenuTable;
1054 {
1056 
1057  static const auto CanStopFlags = AudioIONotBusyFlag() | CanStopAudioStreamFlag();
1058 
1059  static BaseItemSharedPtr menu{
1061  /* i18n-hint: 'Transport' is the name given to the set of controls that
1062  play, record, pause etc. */
1063  Menu( wxT("Transport"), XXO("Tra&nsport"),
1064  Section( "Basic",
1065  Menu( wxT("Play"), XXO("Pl&aying"),
1066  /* i18n-hint: (verb) Start or Stop audio playback*/
1067  Command( wxT("PlayStop"), XXO("Pl&ay/Stop"), FN(OnPlayStop),
1068  CanStopAudioStreamFlag(), wxT("Space") ),
1069  Command( wxT("PlayStopSelect"), XXO("Play/Stop and &Set Cursor"),
1070  FN(OnPlayStopSelect), CanStopAudioStreamFlag(), wxT("X") ),
1071  Command( wxT("PlayLooped"), XXO("&Loop Play"), FN(OnPlayLooped),
1072  CanStopAudioStreamFlag(), wxT("Shift+Space") ),
1073  Command( wxT("Pause"), XXO("&Pause"), FN(OnPause),
1074  CanStopAudioStreamFlag(), wxT("P") )
1075  ),
1076 
1077  Menu( wxT("Record"), XXO("&Recording"),
1078  /* i18n-hint: (verb)*/
1079  Command( wxT("Record1stChoice"), XXO("&Record"), FN(OnRecord),
1080  CanStopFlags, wxT("R") ),
1081 
1082  // The OnRecord2ndChoice function is: if normal record records beside,
1083  // it records below, if normal record records below, it records beside.
1084  // TODO: Do 'the right thing' with other options like TimerRecord.
1085  // Delayed evaluation in case gPrefs is not yet defined
1086  [](const AudacityProject&)
1087  { return Command( wxT("Record2ndChoice"),
1088  // Our first choice is bound to R (by default)
1089  // and gets the prime position.
1090  // We supply the name for the 'other one' here.
1091  // It should be bound to Shift+R
1092  (gPrefs->ReadBool("/GUI/PreferNewTrackRecord", false)
1093  ? XXO("&Append Record") : XXO("Record &New Track")),
1094  FN(OnRecord2ndChoice), CanStopFlags,
1095  wxT("Shift+R"),
1097  ); },
1098 
1099  Command( wxT("TimerRecord"), XXO("&Timer Record..."),
1100  FN(OnTimerRecord), CanStopFlags, wxT("Shift+T") ),
1101 
1102  #ifdef EXPERIMENTAL_PUNCH_AND_ROLL
1103  Command( wxT("PunchAndRoll"), XXO("Punch and Rol&l Record"),
1104  FN(OnPunchAndRoll),
1105  WaveTracksExistFlag() | AudioIONotBusyFlag(), wxT("Shift+D") ),
1106  #endif
1107 
1108  // JKC: I decided to duplicate this between play and record,
1109  // rather than put it at the top level.
1110  // CommandManger::AddItem can now cope with simple duplicated items.
1111  // PRL: caution, this is a duplicated command name!
1112  Command( wxT("Pause"), XXO("&Pause"), FN(OnPause),
1113  CanStopAudioStreamFlag(), wxT("P") )
1114  )
1115  ),
1116 
1117  Section( "Other",
1118  Section( "",
1119  Menu( wxT("PlayRegion"), XXO("Pla&y Region"),
1120  Command( wxT("LockPlayRegion"), XXO("&Lock"), FN(OnLockPlayRegion),
1122  Command( wxT("UnlockPlayRegion"), XXO("&Unlock"),
1123  FN(OnUnlockPlayRegion), PlayRegionLockedFlag() )
1124  )
1125  ),
1126 
1127  Command( wxT("RescanDevices"), XXO("R&escan Audio Devices"),
1128  FN(OnRescanDevices), AudioIONotBusyFlag() | CanStopAudioStreamFlag() ),
1129 
1130  Menu( wxT("Options"), XXO("Transport &Options"),
1131  Section( "",
1132  // Sound Activated recording options
1133  Command( wxT("SoundActivationLevel"),
1134  XXO("Sound Activation Le&vel..."), FN(OnSoundActivated),
1136  Command( wxT("SoundActivation"),
1137  XXO("Sound A&ctivated Recording (on/off)"),
1138  FN(OnToggleSoundActivated),
1140  Options{}.CheckTest(wxT("/AudioIO/SoundActivatedRecord"), false) )
1141  ),
1142 
1143  Section( "",
1144  Command( wxT("PinnedHead"), XXO("Pinned Play/Record &Head (on/off)"),
1145  FN(OnTogglePinnedHead),
1146  // Switching of scrolling on and off is permitted
1147  // even during transport
1149  Options{}.CheckTest([](const AudacityProject&){
1150  return TracksPrefs::GetPinnedHeadPreference(); } ) ),
1151 
1152  Command( wxT("Overdub"), XXO("&Overdub (on/off)"),
1153  FN(OnTogglePlayRecording),
1155  Options{}.CheckTest( wxT("/AudioIO/Duplex"),
1156 #ifdef EXPERIMENTAL_DA
1157  false
1158 #else
1159  true
1160 #endif
1161  ) ),
1162  Command( wxT("SWPlaythrough"), XXO("So&ftware Playthrough (on/off)"),
1163  FN(OnToggleSWPlaythrough),
1165  Options{}.CheckTest( wxT("/AudioIO/SWPlaythrough"), false ) )
1166 
1167 
1168  #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
1169  ,
1170  Command( wxT("AutomatedInputLevelAdjustmentOnOff"),
1171  XXO("A&utomated Recording Level Adjustment (on/off)"),
1172  FN(OnToggleAutomatedInputLevelAdjustment),
1174  Options{}.CheckTest(
1175  wxT("/AudioIO/AutomatedInputLevelAdjustment"), false ) )
1176  #endif
1177  )
1178  )
1179  )
1180  ) ) };
1181  return menu;
1182 }
1183 
1185  wxT(""),
1186  Shared( TransportMenu() )
1187 };
1188 
1190 {
1191  static BaseItemSharedPtr menu{
1193  Menu( wxT("Transport"), XXO("T&ransport"),
1194  // PlayStop is already in the menus.
1195  /* i18n-hint: (verb) Start playing audio*/
1196  Command( wxT("Play"), XXO("Pl&ay"), FN(OnPlayStop),
1198  /* i18n-hint: (verb) Stop playing audio*/
1199  Command( wxT("Stop"), XXO("Sto&p"), FN(OnStop),
1201  Command( wxT("PlayOneSec"), XXO("Play &One Second"), FN(OnPlayOneSecond),
1202  CaptureNotBusyFlag(), wxT("1") ),
1203  Command( wxT("PlayToSelection"), XXO("Play to &Selection"),
1204  FN(OnPlayToSelection),
1205  CaptureNotBusyFlag(), wxT("B") ),
1206  Command( wxT("PlayBeforeSelectionStart"),
1207  XXO("Play &Before Selection Start"), FN(OnPlayBeforeSelectionStart),
1208  CaptureNotBusyFlag(), wxT("Shift+F5") ),
1209  Command( wxT("PlayAfterSelectionStart"),
1210  XXO("Play Af&ter Selection Start"), FN(OnPlayAfterSelectionStart),
1211  CaptureNotBusyFlag(), wxT("Shift+F6") ),
1212  Command( wxT("PlayBeforeSelectionEnd"),
1213  XXO("Play Be&fore Selection End"), FN(OnPlayBeforeSelectionEnd),
1214  CaptureNotBusyFlag(), wxT("Shift+F7") ),
1215  Command( wxT("PlayAfterSelectionEnd"),
1216  XXO("Play Aft&er Selection End"), FN(OnPlayAfterSelectionEnd),
1217  CaptureNotBusyFlag(), wxT("Shift+F8") ),
1218  Command( wxT("PlayBeforeAndAfterSelectionStart"),
1219  XXO("Play Before a&nd After Selection Start"),
1220  FN(OnPlayBeforeAndAfterSelectionStart), CaptureNotBusyFlag(),
1221  wxT("Ctrl+Shift+F5") ),
1222  Command( wxT("PlayBeforeAndAfterSelectionEnd"),
1223  XXO("Play Before an&d After Selection End"),
1224  FN(OnPlayBeforeAndAfterSelectionEnd), CaptureNotBusyFlag(),
1225  wxT("Ctrl+Shift+F7") ),
1226  Command( wxT("PlayCutPreview"), XXO("Play C&ut Preview"),
1227  FN(OnPlayCutPreview),
1228  CaptureNotBusyFlag(), wxT("C") )
1229  ) ) };
1230  return menu;
1231 }
1232 
1234  wxT("Optional/Extra/Part1"),
1236 };
1237 
1239 {
1240  static BaseItemSharedPtr menu{
1242  Menu( wxT("PlayAtSpeed"), XXO("&Play-at-Speed"),
1243  /* i18n-hint: 'Normal Play-at-Speed' doesn't loop or cut preview. */
1244  Command( wxT("PlayAtSpeed"), XXO("Normal Pl&ay-at-Speed"),
1245  FN(OnPlayAtSpeed), CaptureNotBusyFlag() ),
1246  Command( wxT("PlayAtSpeedLooped"), XXO("&Loop Play-at-Speed"),
1247  FN(OnPlayAtSpeedLooped), CaptureNotBusyFlag() ),
1248  Command( wxT("PlayAtSpeedCutPreview"), XXO("Play C&ut Preview-at-Speed"),
1249  FN(OnPlayAtSpeedCutPreview), CaptureNotBusyFlag() ),
1250  Command( wxT("SetPlaySpeed"), XXO("Ad&just Playback Speed..."),
1251  FN(OnSetPlaySpeed), CaptureNotBusyFlag() ),
1252  Command( wxT("PlaySpeedInc"), XXO("&Increase Playback Speed"),
1253  FN(OnPlaySpeedInc), CaptureNotBusyFlag() ),
1254  Command( wxT("PlaySpeedDec"), XXO("&Decrease Playback Speed"),
1255  FN(OnPlaySpeedDec), CaptureNotBusyFlag() )
1256  ) ) };
1257  return menu;
1258 }
1259 
1261  wxT("Optional/Extra/Part1"),
1263 };
1264 
1266 {
1268  static BaseItemSharedPtr items{
1270  Items(wxT("MoveToLabel"),
1271  Command(wxT("MoveToPrevLabel"), XXO("Move to Pre&vious Label"),
1272  FN(OnMoveToPrevLabel),
1273  CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Left")),
1274  Command(wxT("MoveToNextLabel"), XXO("Move to Ne&xt Label"),
1275  FN(OnMoveToNextLabel),
1276  CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Right"))
1277  )) };
1278  return items;
1279 }
1280 
1282  { wxT("Optional/Extra/Part1/Select"), { OrderingHint::End, {} } },
1284 };
1285 
1286 }
1287 
1288 #undef FN
anonymous_namespace{TransportMenus.cpp}::ExtraTransportMenu
BaseItemSharedPtr ExtraTransportMenu()
Definition: TransportMenus.cpp:1189
TransportActions::Handler::OnMoveToPrevLabel
void OnMoveToPrevLabel(const CommandContext &context)
Definition: TransportMenus.cpp:1005
DeviceManager::Rescan
void Rescan()
Definition: DeviceManager.cpp:253
ViewInfo::Get
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:156
TransportTracks::playbackTracks
WaveTrackArray playbackTracks
Definition: AudioIO.h:87
Registry::OrderingHint::End
@ End
Definition: Registry.h:30
AllProjects::begin
const_iterator begin() const
Definition: Project.cpp:31
anonymous_namespace{TransportMenus.cpp}::DoMoveToLabel
void DoMoveToLabel(AudacityProject &project, bool next)
Definition: TransportMenus.cpp:249
ProjectAudioIO::GetAudioIOToken
int GetAudioIOToken() const
Definition: ProjectAudioIO.cpp:42
CanStopAudioStreamFlag
const ReservedCommandFlag & CanStopAudioStreamFlag()
Definition: ProjectAudioManager.cpp:993
AdornedRulerPanel::UnlockPlayRegion
void UnlockPlayRegion()
Definition: AdornedRulerPanel.cpp:2371
ProjectAudioManager::Get
static ProjectAudioManager & Get(AudacityProject &project)
Definition: ProjectAudioManager.cpp:51
MenuTable::FinderScope
Definition: CommandManager.h:472
PlayMode
PlayMode
Definition: ProjectAudioManager.h:30
PlayRegionNotLockedFlag
const ReservedCommandFlag & PlayRegionNotLockedFlag()
Definition: CommonCommandFlags.cpp:279
gPrefs
FileConfig * gPrefs
Definition: Prefs.cpp:68
ClientData::Site::Find
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
Definition: ClientData.h:333
TransportActions::Handler::OnSetPlaySpeed
void OnSetPlaySpeed(const CommandContext &context)
Definition: TransportMenus.cpp:975
SelectedRegion::t1
double t1() const
Definition: SelectedRegion.h:95
AudacityMessageBox
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption=AudacityMessageBoxCaptionStr(), long style=wxOK|wxCENTRE, wxWindow *parent=NULL, int x=wxDefaultCoord, int y=wxDefaultCoord)
Definition: AudacityMessageBox.h:20
TransportTracks::captureTracks
WaveTrackArray captureTracks
Definition: AudioIO.h:88
DefaultPlayOptions
AudioIOStartStreamOptions DefaultPlayOptions(AudacityProject &project)
Definition: ProjectAudioManager.cpp:1002
ViewInfo::playRegion
PlayRegion playRegion
Definition: ViewInfo.h:200
TransportActions::Handler::OnTogglePlayRecording
void OnTogglePlayRecording(const CommandContext &WXUNUSED(context))
Definition: TransportMenus.cpp:681
TransportActions::Handler::OnPlayBeforeSelectionStart
void OnPlayBeforeSelectionStart(const CommandContext &context)
Definition: TransportMenus.cpp:788
anonymous_namespace{TransportMenus.cpp}::DoStartPlaying
void DoStartPlaying(const CommandContext &context, bool looping=false)
Definition: TransportMenus.cpp:235
AudioIONotBusyFlag
const ReservedCommandFlag & AudioIONotBusyFlag()
Definition: CommonCommandFlags.cpp:127
AllProjects::end
const_iterator end() const
Definition: Project.cpp:36
anonymous_namespace{TransportMenus.cpp}::TransportMenu
BaseItemSharedPtr TransportMenu()
Definition: TransportMenus.cpp:1053
ProjectAudioManager::ChooseExistingRecordingTracks
static WaveTrackArray ChooseExistingRecordingTracks(AudacityProject &proj, bool selectedOnly, double targetRate=RATE_NOT_SELECTED)
Definition: ProjectAudioManager.cpp:388
AudioIOBusyFlag
const ReservedCommandFlag & AudioIOBusyFlag()
Definition: CommonCommandFlags.cpp:208
WaveTracksExistFlag
const ReservedCommandFlag & WaveTracksExistFlag()
Definition: CommonCommandFlags.cpp:286
TransportActions::Handler::OnPlayStopSelect
void OnPlayStopSelect(const CommandContext &context)
Definition: TransportMenus.cpp:324
TransportActions::Handler::OnPlaySpeedInc
void OnPlaySpeedInc(const CommandContext &context)
Definition: TransportMenus.cpp:985
PlayRegion::GetStart
double GetStart() const
Definition: ViewInfo.h:137
anonymous_namespace{TransportMenus.cpp}::sAttachment4
AttachedItem sAttachment4
Definition: TransportMenus.cpp:1281
PlayRegionLockedFlag
const ReservedCommandFlag & PlayRegionLockedFlag()
Definition: CommonCommandFlags.cpp:273
Registry::Shared
std::unique_ptr< SharedItem > Shared(const BaseItemSharedPtr &ptr)
Definition: Registry.h:93
TransportActions::Handler::OnMoveToNextLabel
void OnMoveToNextLabel(const CommandContext &context)
Definition: TransportMenus.cpp:1011
TrackPanel::Get
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:222
XO
#define XO(s)
Definition: Internat.h:31
anonymous_namespace{TransportMenus.cpp}::sAttachment2
AttachedItem sAttachment2
Definition: TransportMenus.cpp:1233
ProjectFileIO::Get
static ProjectFileIO & Get(AudacityProject &project)
Definition: ProjectFileIO.cpp:268
ClientData::Site::size
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:251
ProjectSettings::Get
static ProjectSettings & Get(AudacityProject &project)
Definition: ProjectSettings.cpp:40
findCommandHandler
static CommandHandlerObject & findCommandHandler(AudacityProject &)
Definition: TransportMenus.cpp:1039
LabelTrack
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:88
ProjectWindow::Get
static ProjectWindow & Get(AudacityProject &project)
Definition: ProjectWindow.cpp:532
AlwaysEnabledFlag
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:35
TransportActions::Handler::OnPlayAfterSelectionStart
void OnPlayAfterSelectionStart(const CommandContext &context)
Definition: TransportMenus.cpp:808
anonymous_namespace{TransportMenus.cpp}::ExtraPlayAtSpeedMenu
BaseItemSharedPtr ExtraPlayAtSpeedMenu()
Definition: TransportMenus.cpp:1238
MenuTable::AttachedItem
Definition: CommandManager.h:695
ControlToolBar::Get
static ControlToolBar & Get(AudacityProject &project)
Definition: ControlToolBar.cpp:134
MenuManager::ModifyAllProjectToolbarMenus
static void ModifyAllProjectToolbarMenus()
Definition: Menus.cpp:583
TransportActions::Handler::OnPlayBeforeSelectionEnd
void OnPlayBeforeSelectionEnd(const CommandContext &context)
Definition: TransportMenus.cpp:833
ProjectAudioIO::Get
static ProjectAudioIO & Get(AudacityProject &project)
Definition: ProjectAudioIO.cpp:23
TimerRecordDialog::RunWaitDialog
int RunWaitDialog()
Runs the wait for start dialog. Returns false if the user clicks stop.
Definition: TimerRecordDialog.cpp:480
TransportActions::Handler::OnPlayAtSpeedLooped
void OnPlayAtSpeedLooped(const CommandContext &context)
Definition: TransportMenus.cpp:955
anonymous_namespace{TransportMenus.cpp}::sAttachment1
AttachedItem sAttachment1
Definition: TransportMenus.cpp:1184
anonymous_namespace{TransportMenus.cpp}::RecordAndWait
void RecordAndWait(const CommandContext &context, bool altAppearance)
Definition: TransportMenus.cpp:121
LabelStruct
A LabelStruct holds information for ONE label in a LabelTrack.
Definition: LabelTrack.h:30
TransportActions::Handler::OnToggleSoundActivated
void OnToggleSoundActivated(const CommandContext &WXUNUSED(context))
Definition: TransportMenus.cpp:667
DEFAULT_PRE_ROLL_SECONDS
#define DEFAULT_PRE_ROLL_SECONDS
Definition: RecordingPrefs.h:37
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:124
POST_TIMER_RECORD_CLOSE
@ POST_TIMER_RECORD_CLOSE
Definition: TimerRecordDialog.h:45
ProjectManager::SetSkipSavePrompt
void SetSkipSavePrompt(bool bSkip)
Definition: ProjectManager.h:110
DEFAULT_ROLL_CROSSFADE_MS
#define DEFAULT_ROLL_CROSSFADE_MS
Definition: RecordingPrefs.h:40
AllProjects::size
size_t size() const
Definition: Project.cpp:26
AdornedRulerPanel::Get
static AdornedRulerPanel & Get(AudacityProject &project)
Definition: AdornedRulerPanel.cpp:873
TransportActions::Handler::OnPlayAfterSelectionEnd
void OnPlayAfterSelectionEnd(const CommandContext &context)
Definition: TransportMenus.cpp:858
TransportActions::Handler::OnPlayAtSpeedCutPreview
void OnPlayAtSpeedCutPreview(const CommandContext &context)
Definition: TransportMenus.cpp:965
ProjectManager::Get
static ProjectManager & Get(AudacityProject &project)
Definition: ProjectManager.cpp:67
AdornedRulerPanel::TogglePinnedHead
void TogglePinnedHead()
Definition: AdornedRulerPanel.cpp:2380
ViewInfo::selectedRegion
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:199
XXO
#define XXO(s)
Definition: Internat.h:44
ProgressDialog
ProgressDialog Class.
Definition: ProgressDialog.h:56
TransportActions::Handler::OnPlayCutPreview
void OnPlayCutPreview(const CommandContext &context)
Definition: TransportMenus.cpp:934
POST_TIMER_RECORD_NOTHING
@ POST_TIMER_RECORD_NOTHING
Definition: TimerRecordDialog.h:44
CommandContext
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
Definition: CommandContext.h:22
ProgressResult
ProgressResult
Definition: ProgressDialog.h:33
label
TranslatableString label
Definition: Tags.cpp:755
AUDIO_PRE_ROLL_KEY
#define AUDIO_PRE_ROLL_KEY
Definition: RecordingPrefs.h:36
ProgressResult::Success
@ Success
FN
#define FN(X)
Definition: TransportMenus.cpp:1048
Registry::BaseItemSharedPtr
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:72
TransportActions::Handler::OnPlayOneSecond
void OnPlayOneSecond(const CommandContext &context)
Definition: TransportMenus.cpp:721
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: Project.cpp:186
anonymous_namespace{TransportMenus.cpp}::DoStopPlaying
bool DoStopPlaying(const CommandContext &context)
Definition: TransportMenus.cpp:194
TransportActions::Handler::OnTimerRecord
void OnTimerRecord(const CommandContext &context)
Definition: TransportMenus.cpp:358
ProgressResult::Stopped
@ Stopped
TransportActions::Handler::OnStop
void OnStop(const CommandContext &context)
Definition: TransportMenus.cpp:716
ProjectAudioManager::UseDuplex
static bool UseDuplex()
Definition: ProjectAudioManager.cpp:561
ProgressDialog::Update
ProgressResult Update(int value, const TranslatableString &message={})
Definition: ProgressDialog.cpp:1327
AudioIOBase::Get
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:94
TransportActions::Handler::OnPlayAtSpeed
void OnPlayAtSpeed(const CommandContext &context)
Definition: TransportMenus.cpp:945
MenuTable::Items
std::unique_ptr< MenuItems > Items(const Identifier &internalName, Args &&... args)
Definition: CommandManager.h:587
TrackFocus::Get
Track * Get()
Definition: TrackPanelAx.cpp:755
AudioIOStartStreamOptions
struct holding stream options, including a pointer to the time warp info and AudioIOListener and whet...
Definition: AudioIOBase.h:77
TransportActions::Handler::OnPlaySpeedDec
void OnPlaySpeedDec(const CommandContext &context)
Definition: TransportMenus.cpp:995
anonymous_namespace{TransportMenus.cpp}::sAttachment3
AttachedItem sAttachment3
Definition: TransportMenus.cpp:1260
CommandContext::Error
virtual void Error(const wxString &message) const
Definition: CommandContext.cpp:73
TransportActions::Handler::OnPlayBeforeAndAfterSelectionEnd
void OnPlayBeforeAndAfterSelectionEnd(const CommandContext &context)
Definition: TransportMenus.cpp:907
TransportActions::Handler::OnUnlockPlayRegion
void OnUnlockPlayRegion(const CommandContext &context)
Definition: TransportMenus.cpp:649
ProjectAudioManager::Stop
void Stop(bool stopStream=true)
Definition: ProjectAudioManager.cpp:309
AUDIO_ROLL_CROSSFADE_KEY
#define AUDIO_ROLL_CROSSFADE_KEY
Definition: RecordingPrefs.h:39
TransportTracks
Definition: AudioIO.h:86
ProjectAudioManager::DoPlayStopSelect
bool DoPlayStopSelect(bool click, bool shift)
Definition: ProjectAudioManager.cpp:1070
TransportActions::Handler::OnLockPlayRegion
void OnLockPlayRegion(const CommandContext &context)
Definition: TransportMenus.cpp:644
CaptureNotBusyFlag
const ReservedCommandFlag & CaptureNotBusyFlag()
Definition: CommonCommandFlags.cpp:213
PRCrossfadeData
std::vector< std::vector< float > > PRCrossfadeData
Definition: AudioIOBase.h:39
ShowErrorDialog
void ShowErrorDialog(wxWindow *parent, const TranslatableString &dlogTitle, const TranslatableString &message, const wxString &helpPage, const bool Close, const wxString &log)
Displays an error dialog with a button that offers help.
Definition: ErrorDialog.cpp:152
anonymous_namespace{TransportMenus.cpp}::ExtraSelectionItems
BaseItemSharedPtr ExtraSelectionItems()
Definition: TransportMenus.cpp:1265
anonymous_namespace{TransportMenus.cpp}::PlayCurrentRegionAndWait
void PlayCurrentRegionAndWait(const CommandContext &context, bool looped=false, bool cutpreview=false)
Definition: TransportMenus.cpp:41
min
int min(int a, int b)
Definition: CompareAudioCommand.cpp:106
anonymous_namespace{TransportMenus.cpp}::PlayPlayRegionAndWait
void PlayPlayRegionAndWait(const CommandContext &context, const SelectedRegion &selectedRegion, const AudioIOStartStreamOptions &options, PlayMode mode)
Definition: TransportMenus.cpp:81
TracksPrefs::GetPinnedHeadPreference
static bool GetPinnedHeadPreference()
Definition: TracksPrefs.cpp:387
AdornedRulerPanel::LockPlayRegion
void LockPlayRegion()
Definition: AdornedRulerPanel.cpp:2353
SelectedRegion::t0
double t0() const
Definition: SelectedRegion.h:94
LabelTrack::GetNumLabels
int GetNumLabels() const
Definition: LabelTrack.cpp:920
TrackPanelHasFocus
const ReservedCommandFlag & TrackPanelHasFocus()
Definition: CommonCommandFlags.cpp:196
TransportActions::Handler::OnPlayLooped
void OnPlayLooped(const CommandContext &context)
Definition: TransportMenus.cpp:329
FileConfig::Flush
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
Definition: FileConfig.cpp:153
SoundActivatedRecordDialog
Configures sound activated recording.
Definition: SoundActivatedRecord.h:24
TrackList::Get
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:495
TransportActions::Handler::OnPlayToSelection
void OnPlayToSelection(const CommandContext &context)
Definition: TransportMenus.cpp:742
ProjectAudioManager::SetTimerRecordCancelled
void SetTimerRecordCancelled()
Definition: ProjectAudioManager.h:66
POST_TIMER_RECORD_CANCEL
@ POST_TIMER_RECORD_CANCEL
Definition: TimerRecordDialog.h:42
ProjectHistory::RollbackState
void RollbackState()
Definition: ProjectHistory.cpp:117
UndoManager::Get
static UndoManager & Get(AudacityProject &project)
Definition: UndoManager.cpp:57
MenuTable::Command
std::unique_ptr< CommandItem > Command(const CommandID &name, const TranslatableString &label_in, void(Handler::*pmf)(const CommandContext &), CommandFlag flags, const CommandManager::Options &options={}, CommandHandlerFinder finder=FinderScope::DefaultFinder())
Definition: CommandManager.h:662
sampleCount
Definition: Types.h:66
AudacityProject
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:112
TransportActions::Handler::OnToggleSWPlaythrough
void OnToggleSWPlaythrough(const CommandContext &WXUNUSED(context))
Definition: TransportMenus.cpp:694
DeviceManager::Instance
static DeviceManager * Instance()
Gets the singleton instance.
Definition: DeviceManager.cpp:47
AllProjects
an object of class AllProjects acts like a standard library container, but refers to a global array o...
Definition: Project.h:38
PlayMode::oneSecondPlay
@ oneSecondPlay
CommandHandlerObject
wxEvtHandler CommandHandlerObject
Definition: CommandFunctors.h:28
TransportActions::Handler::OnSoundActivated
void OnSoundActivated(const CommandContext &context)
Definition: TransportMenus.cpp:659
MenuTable::Menu
std::unique_ptr< MenuItem > Menu(const Identifier &internalName, const TranslatableString &title, Args &&... args)
Definition: CommandManager.h:610
TransportActions::Handler::OnPause
void OnPause(const CommandContext &context)
Definition: TransportMenus.cpp:341
TransportActions
Definition: TransportMenus.cpp:311
LabelTrack::GetLabel
const LabelStruct * GetLabel(int index) const
Definition: LabelTrack.cpp:925
ProjectAudioManager::GetAllPlaybackTracks
static TransportTracks GetAllPlaybackTracks(TrackList &trackList, bool selectedOnly, bool useMidi=false)
Definition: ProjectAudioManager.cpp:1038
TransportActions::Handler::OnPlayBeforeAndAfterSelectionStart
void OnPlayBeforeAndAfterSelectionStart(const CommandContext &context)
Definition: TransportMenus.cpp:879
MenuTable::Section
std::unique_ptr< MenuPart > Section(const Identifier &internalName, Args &&... args)
Definition: CommandManager.h:598
NotifyingSelectedRegion::t0
double t0() const
Definition: ViewInfo.h:45
ProjectAudioManager::DoRecord
bool DoRecord(AudacityProject &project, const TransportTracks &transportTracks, double t0, double t1, bool altAppearance, const AudioIOStartStreamOptions &options)
Definition: ProjectAudioManager.cpp:574
TimerRecordDialog
Dialog for Timer Record, i.e., timed or long recording.
Definition: TimerRecordDialog.h:56
TranscriptionToolBar::Get
static TranscriptionToolBar & Get(AudacityProject &project)
Definition: TranscriptionToolBar.cpp:110
GetPropertiesOfSelected
PropertiesOfSelected GetPropertiesOfSelected(const AudacityProject &proj)
Definition: ProjectAudioManager.cpp:1155
MenuTable
Definition: CommandManager.h:403
TrackList::Any
auto Any() -> TrackIterRange< TrackType >
Definition: Track.h:1354
ProjectFileIO::IsModified
bool IsModified() const
Definition: ProjectFileIO.cpp:2272
LabelTrack::FindNextLabel
int FindNextLabel(const SelectedRegion &currentSelection)
Definition: LabelTrack.cpp:1022
TransportActions::Handler::OnRecord
void OnRecord(const CommandContext &context)
Definition: TransportMenus.cpp:346
POST_TIMER_RECORD_CANCEL_WAIT
@ POST_TIMER_RECORD_CANCEL_WAIT
Definition: TimerRecordDialog.h:41
AudioIO::Get
static AudioIO * Get()
Definition: AudioIO.cpp:505
TransportActions::Handler
Definition: TransportMenus.cpp:313
settings
static Settings & settings()
Definition: TrackInfo.cpp:87
CommandContext::project
AudacityProject & project
Definition: CommandContext.h:52
anonymous_namespace{Menus.cpp}::Options
std::vector< CommandFlagOptions > & Options()
Definition: Menus.cpp:526
PropertiesOfSelected::rateOfSelected
int rateOfSelected
Definition: ProjectAudioManager.h:174
TransportActions::Handler::OnRescanDevices
void OnRescanDevices(const CommandContext &WXUNUSED(context))
Definition: TransportMenus.cpp:654
AllProjects::value_type
Container::value_type value_type
Definition: Project.h:58
pdlgHideCancelButton
@ pdlgHideCancelButton
Definition: ProgressDialog.h:44
ProjectHistory::Get
static ProjectHistory & Get(AudacityProject &project)
Definition: ProjectHistory.cpp:26
AudioIORecordChannels
IntSetting AudioIORecordChannels
Definition: AudioIOBase.cpp:1068
LabelTrack::FindPrevLabel
int FindPrevLabel(const SelectedRegion &currentSelection)
Definition: LabelTrack.cpp:1048
TransportActions::Handler::OnRecord2ndChoice
void OnRecord2ndChoice(const CommandContext &context)
Definition: TransportMenus.cpp:353
anonymous_namespace{TransportMenus.cpp}::MakeReadyToPlay
bool MakeReadyToPlay(AudacityProject &project)
Definition: TransportMenus.cpp:166
TransportActions::Handler::OnPlayStop
void OnPlayStop(const CommandContext &context)
Definition: TransportMenus.cpp:317
SelectedRegion
Defines a selected portion of a project.
Definition: SelectedRegion.h:38
ProjectAudioManager::OnPause
void OnPause()
Definition: ProjectAudioManager.cpp:768
TransportActions::Handler::OnTogglePinnedHead
void OnTogglePinnedHead(const CommandContext &context)
Definition: TransportMenus.cpp:676