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