Audacity 3.2.0
TransportMenus.cpp
Go to the documentation of this file.
1#include "AudioIO.h"
2#include "../CommonCommandFlags.h"
3#include "DeviceManager.h"
4#include "../LabelTrack.h"
5#include "../Menus.h"
6#include "Prefs.h"
7#include "Project.h"
8#include "ProjectAudioIO.h"
9#include "../ProjectAudioManager.h"
10#include "ProjectHistory.h"
11#include "../ProjectSettings.h"
12#include "../ProjectWindows.h"
13#include "../ProjectWindow.h"
14#include "../SelectUtilities.h"
15#include "../SoundActivatedRecord.h"
16#include "../TrackPanelAx.h"
17#include "../TrackPanel.h"
18#include "../TransportUtilities.h"
19#include "UndoManager.h"
20#include "../prefs/RecordingPrefs.h"
21#include "../prefs/TracksPrefs.h"
22#include "WaveTrack.h"
23#include "ViewInfo.h"
24#include "../commands/CommandContext.h"
25#include "../commands/CommandManager.h"
26#include "../toolbars/ControlToolBar.h"
27#include "../toolbars/ToolManager.h"
28#include "AudacityMessageBox.h"
29#include "BasicUI.h"
30#include "ProgressDialog.h"
31
32#include <thread>
33#include <float.h>
34#include <wx/app.h>
35
36// private helper classes and functions
37namespace {
38
39// TODO: Should all these functions which involve
40// the toolbar actually move into ControlToolBar?
41
47{
48 auto &toolbar = ControlToolBar::Get( project );
49 wxCommandEvent evt;
50
51 // If this project is playing, stop playing
52 auto gAudioIO = AudioIOBase::Get();
53 if (gAudioIO->IsStreamActive(
55 )) {
56 // Make momentary changes of button appearances
57 toolbar.SetPlay(false); //Pops
58 toolbar.SetStop(); //Pushes stop down
59 toolbar.OnStop(evt);
60
61 using namespace std::chrono;
62 std::this_thread::sleep_for(100ms);
63 }
64
65 // If it didn't stop playing quickly, or if some other
66 // project is playing, return
67 if (gAudioIO->IsBusy())
68 return false;
69
70 return true;
71}
72
74{
75 auto &tracks = TrackList::Get( project );
76 auto &trackFocus = TrackFocus::Get( project );
77 auto &window = ProjectWindow::Get( project );
78 auto &projectAudioManager = ProjectAudioManager::Get(project);
79
80 // Find the number of label tracks, and ptr to last track found
81 auto trackRange = tracks.Any<LabelTrack>();
82 auto lt = *trackRange.rbegin();
83 auto nLabelTrack = trackRange.size();
84
85 if (nLabelTrack == 0 ) {
86 trackFocus.MessageForScreenReader(XO("no label track"));
87 }
88 else if (nLabelTrack > 1) {
89 // find first label track, if any, starting at the focused track
90 lt =
91 *tracks.Find(trackFocus.Get()).Filter<LabelTrack>();
92 if (!lt)
93 trackFocus.MessageForScreenReader(
94 XO("no label track at or below focused track"));
95 }
96
97 // If there is a single label track, or there is a label track at or below
98 // the focused track
99 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
100 if (lt) {
101 int i;
102 if (next)
103 i = lt->FindNextLabel(selectedRegion);
104 else
105 i = lt->FindPrevLabel(selectedRegion);
106
107 if (i >= 0) {
108 const LabelStruct* label = lt->GetLabel(i);
109 bool newDefault = projectAudioManager.Looping();
110 if (ProjectAudioIO::Get( project ).IsAudioActive()) {
112 selectedRegion = label->selectedRegion;
113 window.RedrawProject();
115 }
116 else {
117 selectedRegion = label->selectedRegion;
118 window.ScrollIntoView(selectedRegion.t0());
119 window.RedrawProject();
120 }
121 /* i18n-hint:
122 String is replaced by the name of a label,
123 first number gives the position of that label in a sequence
124 of labels,
125 and the last number is the total number of labels in the sequence.
126 */
127 auto message = XO("%s %d of %d")
128 .Format( label->title, i + 1, lt->GetNumLabels() );
129 trackFocus.MessageForScreenReader(message);
130 }
131 else {
132 trackFocus.MessageForScreenReader(XO("no labels in label track"));
133 }
134 }
135}
136
138{
139 auto &playRegion = ViewInfo::Get(project).playRegion;
140 return playRegion.Active();
141}
142
143}
144
145// Strings for menu items and also for dialog titles
146/* i18n-hint Sets a starting point for looping play */
147static const auto SetLoopInTitle = XXO("Set Loop &In");
148/* i18n-hint Sets an ending point for looping play */
149static const auto SetLoopOutTitle = XXO("Set Loop &Out");
150
151// Menu handler functions
152
153namespace {
154
155// This plays (once, with fixed bounds) OR Stops audio. It's a toggle.
156// The default binding for Shift+SPACE.
158{
160 return;
162}
163
165{
167}
168
169// This plays (looping, maybe adjusting the loop) OR Stops audio. It's a toggle.
170// The default binding for SPACE
172{
173 auto &project = context.project;
175 return;
176
178 return;
179
180 // Now play in a loop
181 // Will automatically set mLastPlayMode
183}
184
185void OnPause(const CommandContext &context)
186{
188}
189
190void OnRecord(const CommandContext &context)
191{
192 TransportUtilities::RecordAndWait(context, false);
193}
194
195// If first choice is record same track 2nd choice is record NEW track
196// and vice versa.
198{
200}
201
202#ifdef EXPERIMENTAL_PUNCH_AND_ROLL
203void OnPunchAndRoll(const CommandContext &context)
204{
206 auto &viewInfo = ViewInfo::Get( project );
207
208 static const auto url =
209 wxT("Punch_and_Roll_Record#Using_Punch_and_Roll_Record");
210
211 auto gAudioIO = AudioIO::Get();
212 if (gAudioIO->IsBusy())
213 return;
214
215 // Ignore all but left edge of the selection.
216 viewInfo.selectedRegion.collapseToT0();
217 double t1 = std::max(0.0, viewInfo.selectedRegion.t1());
218
219 // Checking the selected tracks: making sure they all have the same rate
220 const auto selectedTracks{ GetPropertiesOfSelected(project) };
221 const int rateOfSelected{ selectedTracks.rateOfSelected };
222 const bool allSameRate{ selectedTracks.allSameRate };
223
224 if (!allSameRate) {
225 AudacityMessageBox(XO("The tracks selected "
226 "for recording must all have the same sampling rate"),
227 XO("Mismatched Sampling Rates"),
228 wxICON_ERROR | wxCENTRE);
229
230 return;
231 }
232
233 // Decide which tracks to record in.
234 auto tracks =
236 if (tracks.empty()) {
237 auto recordingChannels =
238 std::max(0, AudioIORecordChannels.Read());
239 auto message =
240 (recordingChannels == 1)
241 ? XO("Please select in a mono track.")
242 : (recordingChannels == 2)
243 ? XO("Please select in a stereo track or two mono tracks.")
244 : XO("Please select at least %d channels.").Format( recordingChannels );
246 XO("Error"), message, url);
247 return;
248 }
249
250 // Delete the portion of the target tracks right of the selection, but first,
251 // remember a part of the deletion for crossfading with the new recording.
252 // We may also adjust the starting point leftward if it is too close to the
253 // end of the track, so that at least some nonzero crossfade data can be
254 // taken.
255 PRCrossfadeData crossfadeData;
256 const double crossFadeDuration = std::max(0.0,
258 / 1000.0
259 );
260
261 // The test for t1 == 0.0 stops punch and roll deleting everything where the
262 // selection is at zero. There wouldn't be any cued audio to play in
263 // that case, so a normal record, not a punch and roll, is called for.
264 bool error = (t1 == 0.0);
265
266 double newt1 = t1;
267 using Iterator =
269 IteratorRange<Iterator> intervals{ {}, {} };
270 for (const auto &wt : tracks) {
271 auto rate = wt->GetRate();
272 sampleCount testSample(floor(t1 * rate));
273 if (wt->IsLeader())
274 intervals = as_const(*wt).Intervals();
275 else
276 // non-leader channel is assumed to have the same intervals
277 ;
278 auto pred = [rate](sampleCount testSample){ return
279 [rate, testSample](const auto &pInterval){
280 auto start = floor(pInterval->Start() * rate + 0.5);
281 auto end = floor(pInterval->End() * rate + 0.5);
282 auto ts = testSample.as_double();
283 return ts >= start && ts < end;
284 };
285 };
286 auto begin = intervals.begin(), end = intervals.end(),
287 iter = std::find_if(begin, end, pred(testSample));
288 if (iter == end)
289 // Bug 1890 (an enhancement request)
290 // Try again, a little to the left.
291 // Subtract 10 to allow a selection exactly at or slightly after the
292 // end time
293 iter = std::find_if(begin, end, pred(testSample - 10));
294 if (iter == end)
295 error = true;
296 else {
297 // May adjust t1 left
298 // Let's ignore the possibility of a clip even shorter than the
299 // crossfade duration!
300 newt1 = std::min(newt1, (*iter).get()->End() - crossFadeDuration);
301 }
302 }
303
304 if (error) {
305 auto message = XO("Please select a time within a clip.");
307 *ProjectFramePlacement(&project), XO("Error"), message, url);
308 return;
309 }
310
311 t1 = newt1;
312 double endTime{};
313 for (const auto &wt : tracks) {
314 if (wt->IsLeader())
315 endTime = wt->GetEndTime();
316 const auto duration =
317 std::max(0.0, std::min(crossFadeDuration, endTime - t1));
318 const size_t getLen = floor(duration * wt->GetRate());
319 std::vector<float> data(getLen);
320 if (getLen > 0) {
321 float *const samples = data.data();
322 const sampleCount pos = wt->TimeToLongSamples(t1);
323 wt->GetFloats(samples, pos, getLen);
324 }
325 crossfadeData.push_back(std::move(data));
326 }
327
328 // Change tracks only after passing the error checks above
329 for (const auto &wt : tracks)
330 if (wt->IsLeader())
331 wt->Clear(t1, wt->GetEndTime());
332
333 // Choose the tracks for playback.
334 TransportSequences transportTracks;
335 const auto duplex = ProjectAudioManager::UseDuplex();
336 if (duplex)
337 // play all
338 transportTracks = MakeTransportTracks(
339 TrackList::Get( project ), false, true);
340 else
341 // play recording tracks only
342 for (auto &pTrack : tracks)
343 if (pTrack->IsLeader())
344 transportTracks.playbackSequences.push_back(pTrack);
345
346 // Unlike with the usual recording, a track may be chosen both for playback
347 // and recording.
348 std::copy(tracks.begin(), tracks.end(),
349 back_inserter(transportTracks.captureSequences));
350
351 // Try to start recording
353 options.rate = rateOfSelected;
354 options.preRoll = std::max(0.0,
356 options.pCrossfadeData = &crossfadeData;
358 transportTracks,
359 t1, DBL_MAX,
360 false, // altAppearance
361 options);
362
363 if (success)
364 // Undo state will get pushed elsewhere, when record finishes
365 ;
366 else
367 // Roll back the deletions
369}
370#endif
371
373{
375}
376
378{
380}
381
383{
384 auto &project = context.project;
385 auto &playRegion = ViewInfo::Get(project).playRegion;
386 if (!playRegion.Active())
389 true, false, SetLoopInTitle.Stripped());
390}
391
392
394{
395 auto &project = context.project;
396 auto &playRegion = ViewInfo::Get(project).playRegion;
397 if (!playRegion.Active())
400 false, false, SetLoopOutTitle.Stripped());
401}
402
404{
406}
407
408void OnRescanDevices(const CommandContext &WXUNUSED(context) )
409{
411}
412
414{
416
417 SoundActivatedRecordDialog dialog( &GetProjectFrame( project ) /* parent */ );
418 dialog.ShowModal();
419}
420
421void OnToggleSoundActivated(const CommandContext &WXUNUSED(context) )
422{
424 gPrefs->Flush();
426}
427
428void OnTogglePlayRecording(const CommandContext &WXUNUSED(context) )
429{
430 bool Duplex;
431#ifdef EXPERIMENTAL_DA
432 gPrefs->Read(wxT("/AudioIO/Duplex"), &Duplex, false);
433#else
434 gPrefs->Read(wxT("/AudioIO/Duplex"), &Duplex, true);
435#endif
436 gPrefs->Write(wxT("/AudioIO/Duplex"), !Duplex);
437 gPrefs->Flush();
439}
440
441void OnToggleSWPlaythrough(const CommandContext &WXUNUSED(context) )
442{
443 bool SWPlaythrough;
444 gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &SWPlaythrough, false);
445 gPrefs->Write(wxT("/AudioIO/SWPlaythrough"), !SWPlaythrough);
446 gPrefs->Flush();
448}
449
450#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
451void OnToggleAutomatedInputLevelAdjustment(
452 const CommandContext &WXUNUSED(context) )
453{
454 bool AVEnabled;
455 gPrefs->Read(
456 wxT("/AudioIO/AutomatedInputLevelAdjustment"), &AVEnabled, false);
457 gPrefs->Write(wxT("/AudioIO/AutomatedInputLevelAdjustment"), !AVEnabled);
458 gPrefs->Flush();
460}
461#endif
462
463void OnStop(const CommandContext &context)
464{
466}
467
468void OnPlayOneSecond(const CommandContext &context)
469{
470 auto &project = context.project;
472 return;
473
474 auto &trackPanel = TrackPanel::Get( project );
476
477 double pos = trackPanel.GetMostRecentXPos();
479 context, SelectedRegion(pos - 0.5, pos + 0.5),
480 options, PlayMode::oneSecondPlay);
481}
482
491{
492 auto &project = context.project;
493
495 return;
496
497 auto &trackPanel = TrackPanel::Get( project );
498 auto &viewInfo = ViewInfo::Get( project );
499 const auto &selectedRegion = viewInfo.selectedRegion;
500
501 double pos = trackPanel.GetMostRecentXPos();
502
503 double t0,t1;
504 // check region between pointer and the nearest selection edge
505 if (fabs(pos - selectedRegion.t0()) <
506 fabs(pos - selectedRegion.t1())) {
507 t0 = t1 = selectedRegion.t0();
508 } else {
509 t0 = t1 = selectedRegion.t1();
510 }
511 if( pos < t1)
512 t0=pos;
513 else
514 t1=pos;
515
516 // JKC: oneSecondPlay mode disables auto scrolling
517 // On balance I think we should always do this in this function
518 // since you are typically interested in the sound EXACTLY
519 // where the cursor is.
520 // TODO: have 'playing attributes' such as 'with_autoscroll'
521 // rather than modes, since that's how we're now using the modes.
522
523 // An alternative, commented out below, is to disable autoscroll
524 // only when playing a short region, less than or equal to a second.
525// mLastPlayMode = ((t1-t0) > 1.0) ? normalPlay : oneSecondPlay;
526
527 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
528
530 context, SelectedRegion(t0, t1),
531 playOptions, PlayMode::oneSecondPlay);
532}
533
534// The next 4 functions provide a limited version of the
535// functionality of OnPlayToSelection() for keyboard users
536
538{
539 auto &project = context.project;
540
542 return;
543
544 auto &viewInfo = ViewInfo::Get( project );
545 const auto &selectedRegion = viewInfo.selectedRegion;
546
547 double t0 = selectedRegion.t0();
548 double beforeLen;
549 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
550
551 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
552
554 context, SelectedRegion(t0 - beforeLen, t0),
555 playOptions, PlayMode::oneSecondPlay);
556}
557
559{
560 auto &project = context.project;
561
563 return;
564
565 auto &viewInfo = ViewInfo::Get( project );
566 const auto &selectedRegion = viewInfo.selectedRegion;
567
568 double t0 = selectedRegion.t0();
569 double t1 = selectedRegion.t1();
570 double afterLen;
571 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
572
573 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
574
575 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
577 context, SelectedRegion(t0, t1),
578 playOptions, PlayMode::oneSecondPlay);
579 else
581 context, SelectedRegion(t0, t0 + afterLen),
582 playOptions, PlayMode::oneSecondPlay);
583}
584
586{
587 auto &project = context.project;
588
590 return;
591
592 auto &viewInfo = ViewInfo::Get( project );
593 const auto &selectedRegion = viewInfo.selectedRegion;
594
595 double t0 = selectedRegion.t0();
596 double t1 = selectedRegion.t1();
597 double beforeLen;
598 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
599
600 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
601
602 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
604 context, SelectedRegion(t0, t1),
605 playOptions, PlayMode::oneSecondPlay);
606 else
608 context, SelectedRegion(t1 - beforeLen, t1),
609 playOptions, PlayMode::oneSecondPlay);
610}
611
613{
614 auto &project = context.project;
615
617 return;
618
619 auto &viewInfo = ViewInfo::Get( project );
620 const auto &selectedRegion = viewInfo.selectedRegion;
621
622 double t1 = selectedRegion.t1();
623 double afterLen;
624 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
625
626 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
627
629 context, SelectedRegion(t1, t1 + afterLen),
630 playOptions, PlayMode::oneSecondPlay);
631}
632
634(const CommandContext &context)
635{
636 auto &project = context.project;
637
639 return;
640
641 auto &viewInfo = ViewInfo::Get( project );
642 const auto &selectedRegion = viewInfo.selectedRegion;
643
644 double t0 = selectedRegion.t0();
645 double t1 = selectedRegion.t1();
646 double beforeLen;
647 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
648 double afterLen;
649 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
650
651 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
652
653 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
655 context, SelectedRegion(t0 - beforeLen, t1),
656 playOptions, PlayMode::oneSecondPlay);
657 else
659 context, SelectedRegion(t0 - beforeLen, t0 + afterLen),
660 playOptions, PlayMode::oneSecondPlay);
661}
662
664(const CommandContext &context)
665{
666 auto &project = context.project;
667
669 return;
670
671 auto &viewInfo = ViewInfo::Get( project );
672 const auto &selectedRegion = viewInfo.selectedRegion;
673
674 double t0 = selectedRegion.t0();
675 double t1 = selectedRegion.t1();
676 double beforeLen;
677 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
678 double afterLen;
679 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
680
681 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
682
683 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
685 context, SelectedRegion(t0, t1 + afterLen),
686 playOptions, PlayMode::oneSecondPlay);
687 else
689 context, SelectedRegion(t1 - beforeLen, t1 + afterLen),
690 playOptions, PlayMode::oneSecondPlay);
691}
692
694{
695 auto &project = context.project;
696
697 if ( !MakeReadyToPlay(project) )
698 return;
699
700 // Play with cut preview
702}
703
705{
706 auto &project = context.project;
707 DoMoveToLabel(project, false);
708}
709
711{
712 auto &project = context.project;
713 DoMoveToLabel(project, true);
714}
715
716#if 0
717// Legacy handlers, not used as of version 2.3.0
718void OnStopSelect(const CommandContext &context)
719{
720 auto &project = context.project;
721 auto &history = ProjectHistory::Get( project );
722 auto &viewInfo = project.GetViewInfo();
723 auto &selectedRegion = viewInfo.selectedRegion;
724
725 auto gAudioIO = AudioIOBase::Get();
726 if (gAudioIO->IsStreamActive()) {
727 selectedRegion.setT0(gAudioIO->GetStreamTime(), false);
729 history.ModifyState(false); // without bWantsAutoSave
730 }
731}
732#endif
733
734// Menu definitions
735
736// Under /MenuBar
737using namespace MenuTable;
739{
741
743
744 static BaseItemSharedPtr menu{
745 /* i18n-hint: 'Transport' is the name given to the set of controls that
746 play, record, pause etc. */
747 Menu( wxT("Transport"), XXO("Tra&nsport"),
748 Section( "Basic",
749 Menu( wxT("Play"), XXO("Pl&aying"),
750 /* i18n-hint: (verb) Start or Stop audio playback*/
751 Command( wxT("DefaultPlayStop"), XXO("Pl&ay/Stop"), OnPlayDefaultOrStop,
752 CanStopAudioStreamFlag(), wxT("Space") ),
753 Command( wxT("PlayStopSelect"), XXO("Play/Stop and &Set Cursor"),
755 Command( wxT("OncePlayStop"), XXO("Play &Once/Stop"), OnPlayOnceOrStop,
756 CanStopAudioStreamFlag(), wxT("Shift+Space") ),
757 Command( wxT("Pause"), XXO("&Pause"), OnPause,
759 ),
760
761 Menu( wxT("Record"), XXO("&Recording"),
762 /* i18n-hint: (verb)*/
763 Command( wxT("Record1stChoice"), XXO("&Record"), OnRecord,
764 CanStopFlags, wxT("R") ),
765
766 // The OnRecord2ndChoice function is: if normal record records beside,
767 // it records below, if normal record records below, it records beside.
768 // TODO: Do 'the right thing' with other options like TimerRecord.
769 // Delayed evaluation in case gPrefs is not yet defined
770 [](const AudacityProject&)
771 { return Command( wxT("Record2ndChoice"),
772 // Our first choice is bound to R (by default)
773 // and gets the prime position.
774 // We supply the name for the 'other one' here.
775 // It should be bound to Shift+R
776 (gPrefs->ReadBool("/GUI/PreferNewTrackRecord", false)
777 ? XXO("&Append Record") : XXO("Record &New Track")),
779 wxT("Shift+R")
780 ); },
781
782 #ifdef EXPERIMENTAL_PUNCH_AND_ROLL
783 Command( wxT("PunchAndRoll"), XXO("Punch and Rol&l Record"),
784 OnPunchAndRoll,
785 WaveTracksExistFlag() | AudioIONotBusyFlag(), wxT("Shift+D") ),
786 #endif
787
788 // JKC: I decided to duplicate this between play and record,
789 // rather than put it at the top level.
790 // CommandManger::AddItem can now cope with simple duplicated items.
791 // PRL: caution, this is a duplicated command name!
792 Command( wxT("Pause"), XXO("&Pause"), OnPause,
794 )
795 ),
796
797 Section( "Other",
798 Section( "",
799 Menu( wxT("PlayRegion"), XXO("&Looping"),
800 Command( wxT("TogglePlayRegion"), LoopToggleText,
802 Options(L"L").CheckTest([](const AudacityProject& project){
804 } )),
805 Command( wxT("ClearPlayRegion"), XXO("&Clear Loop"),
806 OnClearPlayRegion, AlwaysEnabledFlag, L"Shift+Alt+L" ),
807 Command( wxT("SetPlayRegionToSelection"),
808 XXO("&Set Loop to Selection"),
810 L"Shift+L" ),
811 Command( wxT("SetPlayRegionIn"),
814 Command( wxT("SetPlayRegionOut"),
817 )
818 ),
819
820 Command( wxT("RescanDevices"), XXO("R&escan Audio Devices"),
822
823 Menu( wxT("Options"), XXO("Transport &Options"),
824 Section( "Part1",
825 // Sound Activated recording options
826 Command( wxT("SoundActivationLevel"),
827 XXO("Set sound activation le&vel..."), OnSoundActivated,
829 Command( wxT("SoundActivation"),
830 XXO("Enable sound a&ctivated recording"),
834 ),
835
836 Section( "Part2",
837 Command( wxT("Overdub"), XXO("Hear &other tracks during recording"),
840 Options{}.CheckTest( wxT("/AudioIO/Duplex"),
841#ifdef EXPERIMENTAL_DA
842 false
843#else
844 true
845#endif
846 ) ),
847 Command( wxT("SWPlaythrough"), XXO("Enable audible input &monitoring"),
850 Options{}.CheckTest( wxT("/AudioIO/SWPlaythrough"), false ) )
851
852
853 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
854 ,
855 Command( wxT("AutomatedInputLevelAdjustmentOnOff"),
856 XXO("A&utomated Recording Level Adjustment (on/off)"),
857 OnToggleAutomatedInputLevelAdjustment,
860 wxT("/AudioIO/AutomatedInputLevelAdjustment"), false ) )
861 #endif
862 )
863 )
864 )
865 ) };
866 return menu;
867}
868
870 wxT(""),
872};
873
875{
876 static BaseItemSharedPtr menu{
877 Menu( wxT("Transport"), XXO("T&ransport"),
878 // PlayStop is already in the menus.
879 /* i18n-hint: (verb) Start playing audio*/
880 Command( wxT("Play"), XXO("Pl&ay Once"), OnPlayOnceOrStop,
882 /* i18n-hint: (verb) Stop playing audio*/
883 Command( wxT("Stop"), XXO("Sto&p"), OnStop,
885 Command( wxT("PlayOneSec"), XXO("Play &One Second"), OnPlayOneSecond,
886 CaptureNotBusyFlag(), wxT("1") ),
887 Command( wxT("PlayToSelection"), XXO("Play to &Selection"),
889 CaptureNotBusyFlag(), wxT("B") ),
890 Command( wxT("PlayBeforeSelectionStart"),
891 XXO("Play &Before Selection Start"), OnPlayBeforeSelectionStart,
892 CaptureNotBusyFlag(), wxT("Shift+F5") ),
893 Command( wxT("PlayAfterSelectionStart"),
894 XXO("Play Af&ter Selection Start"), OnPlayAfterSelectionStart,
895 CaptureNotBusyFlag(), wxT("Shift+F6") ),
896 Command( wxT("PlayBeforeSelectionEnd"),
897 XXO("Play Be&fore Selection End"), OnPlayBeforeSelectionEnd,
898 CaptureNotBusyFlag(), wxT("Shift+F7") ),
899 Command( wxT("PlayAfterSelectionEnd"),
900 XXO("Play Aft&er Selection End"), OnPlayAfterSelectionEnd,
901 CaptureNotBusyFlag(), wxT("Shift+F8") ),
902 Command( wxT("PlayBeforeAndAfterSelectionStart"),
903 XXO("Play Before a&nd After Selection Start"),
905 wxT("Ctrl+Shift+F5") ),
906 Command( wxT("PlayBeforeAndAfterSelectionEnd"),
907 XXO("Play Before an&d After Selection End"),
909 wxT("Ctrl+Shift+F7") ),
910 Command( wxT("PlayCutPreview"), XXO("Play C&ut Preview"),
912 CaptureNotBusyFlag(), wxT("C") )
913 ) };
914 return menu;
915}
916
918 wxT("Optional/Extra/Part1"),
920};
921
923{
925 static BaseItemSharedPtr items{
926 Items(wxT("MoveToLabel"),
927 Command(wxT("MoveToPrevLabel"), XXO("Move to Pre&vious Label"),
929 CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Left")),
930 Command(wxT("MoveToNextLabel"), XXO("Move to Ne&xt Label"),
932 CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Right"))
933 ) };
934 return items;
935}
936
938 { wxT("Optional/Extra/Part1/Select"), { OrderingHint::End, {} } },
940};
941
942}
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
BoolSetting SoundActivatedRecord
Definition: AudioIO.cpp:3300
IntSetting AudioIORecordChannels
std::vector< std::vector< float > > PRCrossfadeData
Definition: AudioIOBase.h:36
Toolkit-neutral facade for basic user interface services.
AttachedItem sAttachment1
AttachedItem sAttachment2
constexpr CommandFlag AlwaysEnabledFlag
Definition: CommandFlag.h:34
const ReservedCommandFlag & CaptureNotBusyFlag()
const ReservedCommandFlag & AudioIOBusyFlag()
const ReservedCommandFlag & AudioIONotBusyFlag()
const ReservedCommandFlag & WaveTracksExistFlag()
const ReservedCommandFlag & TrackPanelHasFocus()
int min(int a, int b)
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
std::unique_ptr< const BasicUI::WindowPlacement > ProjectFramePlacement(AudacityProject *project)
Make a WindowPlacement object suitable for project (which may be null)
Definition: Project.cpp:129
const ReservedCommandFlag & CanStopAudioStreamFlag()
PropertiesOfSelected GetPropertiesOfSelected(const AudacityProject &proj)
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 ...
#define AUDIO_PRE_ROLL_KEY
#define DEFAULT_PRE_ROLL_SECONDS
#define DEFAULT_ROLL_CROSSFADE_MS
#define AUDIO_ROLL_CROSSFADE_KEY
TranslatableString label
Definition: TagsEditor.cpp:165
const auto tracks
const auto project
static const auto SetLoopInTitle
static const auto SetLoopOutTitle
TransportSequences MakeTransportTracks(TrackList &trackList, bool selectedOnly, bool nonWaveToo)
const TranslatableString LoopToggleText
Definition: ViewInfo.cpp:227
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
Definition: Project.h:90
static AudioIOBase * Get()
Definition: AudioIOBase.cpp:93
static AudioIO * Get()
Definition: AudioIO.cpp:123
bool Toggle()
Write the negation of the previous value, and then return the current value.
Definition: Prefs.cpp:529
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:251
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
static ControlToolBar & Get(AudacityProject &project)
static DeviceManager * Instance()
Gets the singleton instance.
A LabelStruct holds information for ONE label in a LabelTrack.
Definition: LabelTrack.h:29
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:87
int GetNumLabels() const
Definition: LabelTrack.cpp:920
int FindPrevLabel(const SelectedRegion &currentSelection)
const LabelStruct * GetLabel(int index) const
Definition: LabelTrack.cpp:925
int FindNextLabel(const SelectedRegion &currentSelection)
bool Active() const
Definition: ViewInfo.h:124
int GetAudioIOToken() const
static AudioIOStartStreamOptions GetDefaultOptions(AudacityProject &project, bool newDefaults=false)
Invoke the global hook, supplying a default argument.
static ProjectAudioIO & Get(AudacityProject &project)
void Stop(bool stopStream=true)
static WritableSampleTrackArray ChooseExistingRecordingTracks(AudacityProject &proj, bool selectedOnly, double targetRate=RATE_NOT_SELECTED)
static ProjectAudioManager & Get(AudacityProject &project)
bool DoPlayStopSelect(bool click, bool shift)
bool DoRecord(AudacityProject &project, const TransportSequences &transportSequences, double t0, double t1, bool altAppearance, const AudioIOStartStreamOptions &options)
static ProjectHistory & Get(AudacityProject &project)
static ProjectWindow & Get(AudacityProject &project)
Defines a selected portion of a project.
bool Read(T *pVar) const
overload of Read returning a boolean that is true if the value was previously defined *‍/
Definition: Prefs.h:205
Configures sound activated recording.
static void ModifyAllProjectToolbarMenus()
Track * Get()
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:354
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:232
PlayRegion playRegion
Definition: ViewInfo.h:220
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:219
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
bool ReadBool(const wxString &key, bool defaultValue) const
virtual bool Read(const wxString &key, bool *value) const =0
Positions or offsets within audio files need a wide type.
Definition: SampleCount.h:19
void ShowErrorDialog(const WindowPlacement &placement, const TranslatableString &dlogTitle, const TranslatableString &message, const ManualPageID &helpPage, const ErrorDialogOptions &options={})
Show an error dialog with a link to the manual for further help.
Definition: BasicUI.h:259
constexpr auto Section
constexpr auto Menu
Items will appear in a main toolbar menu or in a sub-menu.
constexpr auto Items
constexpr auto Command
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:159
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
Definition: PackedArray.h:150
std::unique_ptr< detail::IndirectItem< Item > > Indirect(const std::shared_ptr< Item > &ptr)
A convenience function.
Definition: Registry.h:113
std::shared_ptr< BaseItem > BaseItemSharedPtr
Definition: Registry.h:78
void SetPlayRegionToSelection(AudacityProject &project)
void ActivatePlayRegion(AudacityProject &project)
void OnSetRegion(AudacityProject &project, bool left, bool selection, const TranslatableString &dialogTitle)
Adjust left or right of selection or play region.
void ClearPlayRegion(AudacityProject &project)
void TogglePlayRegion(AudacityProject &project)
void OnPlayToSelection(const CommandContext &context)
void OnSetPlayRegionToSelection(const CommandContext &context)
void OnTogglePlayRecording(const CommandContext &WXUNUSED(context))
void OnMoveToNextLabel(const CommandContext &context)
void OnPlayBeforeAndAfterSelectionEnd(const CommandContext &context)
void OnSetPlayRegionIn(const CommandContext &context)
void OnToggleSWPlaythrough(const CommandContext &WXUNUSED(context))
bool MakeReadyToPlay(AudacityProject &project)
void OnMoveToPrevLabel(const CommandContext &context)
void OnPlayAfterSelectionStart(const CommandContext &context)
void OnSoundActivated(const CommandContext &context)
void OnPlayBeforeSelectionEnd(const CommandContext &context)
void OnToggleSoundActivated(const CommandContext &WXUNUSED(context))
void OnSetPlayRegionOut(const CommandContext &context)
void OnRecord(const CommandContext &context)
void DoMoveToLabel(AudacityProject &project, bool next)
void OnRecord2ndChoice(const CommandContext &context)
void OnPause(const CommandContext &context)
void OnPlayAfterSelectionEnd(const CommandContext &context)
void OnPlayBeforeAndAfterSelectionStart(const CommandContext &context)
void OnPlayDefaultOrStop(const CommandContext &context)
void OnRescanDevices(const CommandContext &WXUNUSED(context))
void OnPlayStopSelect(const CommandContext &context)
void OnTogglePlayRegion(const CommandContext &context)
void OnPlayCutPreview(const CommandContext &context)
void OnStop(const CommandContext &context)
void OnPlayOneSecond(const CommandContext &context)
void OnPlayOnceOrStop(const CommandContext &context)
void OnClearPlayRegion(const CommandContext &context)
void OnPlayBeforeSelectionStart(const CommandContext &context)
bool IsLoopingEnabled(const AudacityProject &project)
void copy(const T *src, T *dst, int32_t n)
Definition: VectorOps.h:32
Options && CheckTest(const CheckFn &fn) &&
A convenience for use with range-for.
Definition: MemoryX.h:277
RecordableSequences captureSequences
Definition: AudioIO.h:71
ConstPlayableSequences playbackSequences
Definition: AudioIO.h:70
static void PlayPlayRegionAndWait(const CommandContext &context, const SelectedRegion &selectedRegion, const AudioIOStartStreamOptions &options, PlayMode mode)
static bool DoStopPlaying(const CommandContext &context)
static void PlayCurrentRegionAndWait(const CommandContext &context, bool newDefault=false, bool cutpreview=false)
static void RecordAndWait(const CommandContext &context, bool altAppearance)
static void DoStartPlaying(const CommandContext &context, bool newDefault=false)