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 "Prefs.h"
6#include "Project.h"
7#include "ProjectAudioIO.h"
8#include "../ProjectAudioManager.h"
9#include "ProjectHistory.h"
10#include "../ProjectWindows.h"
11#include "../SelectUtilities.h"
12#include "../SoundActivatedRecord.h"
13#include "TrackFocus.h"
14#include "../TrackPanel.h"
15#include "../TransportUtilities.h"
16#include "UndoManager.h"
17#include "../prefs/RecordingPrefs.h"
18#include "../prefs/TracksPrefs.h"
19#include "WaveTrack.h"
20#include "ViewInfo.h"
21#include "Viewport.h"
22#include "CommandContext.h"
23#include "../toolbars/ControlToolBar.h"
24#include "../toolbars/ToolManager.h"
25#include "AudacityMessageBox.h"
26#include "BasicUI.h"
27#include "ProgressDialog.h"
28
29#include <thread>
30#include <float.h>
31#include <wx/app.h>
32
33// private helper classes and functions
34namespace {
35
36// TODO: Should all these functions which involve
37// the toolbar actually move into ControlToolBar?
38
44{
45 auto &toolbar = ControlToolBar::Get( project );
46 wxCommandEvent evt;
47
48 // If this project is playing, stop playing
49 auto gAudioIO = AudioIOBase::Get();
50 if (gAudioIO->IsStreamActive(
52 )) {
53 // Make momentary changes of button appearances
54 toolbar.SetPlay(false); //Pops
55 toolbar.SetStop(); //Pushes stop down
56 toolbar.OnStop(evt);
57
58 using namespace std::chrono;
59 std::this_thread::sleep_for(100ms);
60 }
61
62 // If it didn't stop playing quickly, or if some other
63 // project is playing, return
64 if (gAudioIO->IsBusy())
65 return false;
66
67 return true;
68}
69
71{
72 auto &tracks = TrackList::Get( project );
73 auto &trackFocus = TrackFocus::Get( project );
74 auto &viewport = Viewport::Get(project);
75 auto &projectAudioManager = ProjectAudioManager::Get(project);
76
77 // Find the number of label tracks, and ptr to last track found
78 auto trackRange = tracks.Any<LabelTrack>();
79 auto lt = *trackRange.rbegin();
80 auto nLabelTrack = trackRange.size();
81
82 if (nLabelTrack == 0 ) {
83 trackFocus.MessageForScreenReader(XO("no label track"));
84 }
85 else if (nLabelTrack > 1) {
86 // find first label track, if any, starting at the focused track
87 lt =
88 *tracks.Find(trackFocus.Get()).Filter<LabelTrack>();
89 if (!lt)
90 trackFocus.MessageForScreenReader(
91 XO("no label track at or below focused track"));
92 }
93
94 // If there is a single label track, or there is a label track at or below
95 // the focused track
96 auto &selectedRegion = ViewInfo::Get( project ).selectedRegion;
97 if (lt) {
98 int i;
99 if (next)
100 i = lt->FindNextLabel(selectedRegion);
101 else
102 i = lt->FindPrevLabel(selectedRegion);
103
104 if (i >= 0) {
105 const LabelStruct* label = lt->GetLabel(i);
106 bool newDefault = projectAudioManager.Looping();
107 if (ProjectAudioIO::Get( project ).IsAudioActive()) {
109 selectedRegion = label->selectedRegion;
110 viewport.Redraw();
112 }
113 else {
114 selectedRegion = label->selectedRegion;
115 viewport.ScrollIntoView(selectedRegion.t0());
116 viewport.Redraw();
117 }
118 /* i18n-hint:
119 String is replaced by the name of a label,
120 first number gives the position of that label in a sequence
121 of labels,
122 and the last number is the total number of labels in the sequence.
123 */
124 auto message = XO("%s %d of %d")
125 .Format( label->title, i + 1, lt->GetNumLabels() );
126 trackFocus.MessageForScreenReader(message);
127 }
128 else {
129 trackFocus.MessageForScreenReader(XO("no labels in label track"));
130 }
131 }
132}
133
135{
136 auto &playRegion = ViewInfo::Get(project).playRegion;
137 return playRegion.Active();
138}
139
140}
141
142// Strings for menu items and also for dialog titles
143/* i18n-hint Sets a starting point for looping play */
144static const auto SetLoopInTitle = XXO("Set Loop &In");
145/* i18n-hint Sets an ending point for looping play */
146static const auto SetLoopOutTitle = XXO("Set Loop &Out");
147
148// Menu handler functions
149
150namespace {
151
152// This plays (once, with fixed bounds) OR Stops audio. It's a toggle.
153// The default binding for Shift+SPACE.
155{
157 return;
159}
160
162{
164}
165
166// This plays (looping, maybe adjusting the loop) OR Stops audio. It's a toggle.
167// The default binding for SPACE
169{
170 auto &project = context.project;
172 return;
173
175 return;
176
177 // Now play in a loop
178 // Will automatically set mLastPlayMode
180}
181
182void OnPause(const CommandContext &context)
183{
185}
186
187void OnRecord(const CommandContext &context)
188{
189 TransportUtilities::RecordAndWait(context, false);
190}
191
192// If first choice is record same track 2nd choice is record NEW track
193// and vice versa.
195{
197}
198
199#ifdef EXPERIMENTAL_PUNCH_AND_ROLL
200void OnPunchAndRoll(const CommandContext &context)
201{
203 auto &viewInfo = ViewInfo::Get( project );
204
205 static const auto url =
206 wxT("Punch_and_Roll_Record#Using_Punch_and_Roll_Record");
207
208 auto gAudioIO = AudioIO::Get();
209 if (gAudioIO->IsBusy())
210 return;
211
212 // Ignore all but left edge of the selection.
213 viewInfo.selectedRegion.collapseToT0();
214 double t1 = std::max(0.0, viewInfo.selectedRegion.t1());
215
216 // Checking the selected tracks: making sure they all have the same rate
217 const auto selectedTracks{ GetPropertiesOfSelected(project) };
218 const int rateOfSelected{ selectedTracks.rateOfSelected };
219 const bool allSameRate{ selectedTracks.allSameRate };
220
221 if (!allSameRate) {
222 AudacityMessageBox(XO("The tracks selected "
223 "for recording must all have the same sampling rate"),
224 XO("Mismatched Sampling Rates"),
225 wxICON_ERROR | wxCENTRE);
226
227 return;
228 }
229
230 // Decide which tracks to record in.
231 auto tracks =
233 if (tracks.empty()) {
234 auto recordingChannels =
235 std::max(0, AudioIORecordChannels.Read());
236 auto message =
237 (recordingChannels == 1)
238 ? XO("Please select in a mono track.")
239 : (recordingChannels == 2)
240 ? XO("Please select in a stereo track or two mono tracks.")
241 : XO("Please select at least %d channels.").Format( recordingChannels );
243 XO("Error"), message, url);
244 return;
245 }
246
247 // Delete the portion of the target tracks right of the selection, but first,
248 // remember a part of the deletion for crossfading with the new recording.
249 // We may also adjust the starting point leftward if it is too close to the
250 // end of the track, so that at least some nonzero crossfade data can be
251 // taken.
252 PRCrossfadeData crossfadeData;
253 const double crossFadeDuration = std::max(0.0,
255 / 1000.0
256 );
257
258 // The test for t1 == 0.0 stops punch and roll deleting everything where the
259 // selection is at zero. There wouldn't be any cued audio to play in
260 // that case, so a normal record, not a punch and roll, is called for.
261 bool error = (t1 == 0.0);
262
263 double newt1 = t1;
264 using Iterator =
266 for (const auto &wt : tracks) {
267 auto rate = wt->GetRate();
268 sampleCount testSample(floor(t1 * rate));
269 const auto intervals = as_const(*wt).Intervals();
270 auto pred = [rate](sampleCount testSample){ return
271 [rate, testSample](const auto &pInterval){
272 auto start = floor(pInterval->Start() * rate + 0.5);
273 auto end = floor(pInterval->End() * rate + 0.5);
274 auto ts = testSample.as_double();
275 return ts >= start && ts < end;
276 };
277 };
278 auto begin = intervals.begin(), end = intervals.end(),
279 iter = std::find_if(begin, end, pred(testSample));
280 if (iter == end)
281 // Bug 1890 (an enhancement request)
282 // Try again, a little to the left.
283 // Subtract 10 to allow a selection exactly at or slightly after the
284 // end time
285 iter = std::find_if(begin, end, pred(testSample - 10));
286 if (iter == end)
287 error = true;
288 else {
289 // May adjust t1 left
290 // Let's ignore the possibility of a clip even shorter than the
291 // crossfade duration!
292 newt1 = std::min(newt1, (*iter).get()->End() - crossFadeDuration);
293 }
294 }
295
296 if (error) {
297 auto message = XO("Please select a time within a clip.");
299 *ProjectFramePlacement(&project), XO("Error"), message, url);
300 return;
301 }
302
303 t1 = newt1;
304 for (const auto &wt : tracks) {
305 const auto endTime = wt->GetEndTime();
306 const auto duration =
307 std::max(0.0, std::min(crossFadeDuration, endTime - t1));
308 const size_t getLen = floor(duration * wt->GetRate());
309 if (getLen > 0) {
310 // TODO more-than-two-channels
311 const auto nChannels = std::min<size_t>(2, wt->NChannels());
312 crossfadeData.resize(nChannels);
313 float *buffers[2]{};
314 for (size_t ii = 0; ii < nChannels; ++ii) {
315 auto &data = crossfadeData[ii];
316 data.resize(getLen);
317 buffers[ii] = data.data();
318 }
319 const sampleCount pos = wt->TimeToLongSamples(t1);
320 if (!wt->GetFloats(0, nChannels, buffers, pos, getLen))
321 // TODO error message
322 return;
323 }
324 }
325
326 // Change tracks only after passing the error checks above
327 for (const auto &wt : tracks)
328 wt->Clear(t1, wt->GetEndTime());
329
330 // Choose the tracks for playback.
331 TransportSequences transportTracks;
332 const auto duplex = ProjectAudioManager::UseDuplex();
333 if (duplex)
334 // play all
335 transportTracks = MakeTransportTracks(
336 TrackList::Get( project ), false, true);
337 else
338 // play recording tracks only
339 for (auto &pTrack : tracks)
340 transportTracks.playbackSequences.push_back(pTrack);
341
342 // Unlike with the usual recording, a track may be chosen both for playback
343 // and recording.
344 std::copy(tracks.begin(), tracks.end(),
345 back_inserter(transportTracks.captureSequences));
346
347 // Try to start recording
349 options.rate = rateOfSelected;
350 options.preRoll = std::max(0.0,
352 options.pCrossfadeData = &crossfadeData;
354 transportTracks,
355 t1, DBL_MAX,
356 false, // altAppearance
357 options);
358
359 if (success)
360 // Undo state will get pushed elsewhere, when record finishes
361 ;
362 else
363 // Roll back the deletions
365}
366#endif
367
369{
371}
372
374{
376}
377
379{
380 auto &project = context.project;
381 auto &playRegion = ViewInfo::Get(project).playRegion;
382 if (!playRegion.Active())
385 true, false, SetLoopInTitle.Stripped());
386}
387
388
390{
391 auto &project = context.project;
392 auto &playRegion = ViewInfo::Get(project).playRegion;
393 if (!playRegion.Active())
396 false, false, SetLoopOutTitle.Stripped());
397}
398
400{
402}
403
404void OnRescanDevices(const CommandContext &WXUNUSED(context) )
405{
407}
408
410{
412
413 SoundActivatedRecordDialog dialog( &GetProjectFrame( project ) /* parent */ );
414 dialog.ShowModal();
415}
416
417void OnToggleSoundActivated(const CommandContext &WXUNUSED(context) )
418{
420 gPrefs->Flush();
422}
423
424void OnTogglePlayRecording(const CommandContext &WXUNUSED(context) )
425{
426 bool Duplex;
427 gPrefs->Read(wxT("/AudioIO/Duplex"), &Duplex, true);
428 gPrefs->Write(wxT("/AudioIO/Duplex"), !Duplex);
429 gPrefs->Flush();
431}
432
433void OnToggleSWPlaythrough(const CommandContext &WXUNUSED(context) )
434{
435 bool SWPlaythrough;
436 gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &SWPlaythrough, false);
437 gPrefs->Write(wxT("/AudioIO/SWPlaythrough"), !SWPlaythrough);
438 gPrefs->Flush();
440}
441
442#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
443void OnToggleAutomatedInputLevelAdjustment(
444 const CommandContext &WXUNUSED(context) )
445{
446 bool AVEnabled;
447 gPrefs->Read(
448 wxT("/AudioIO/AutomatedInputLevelAdjustment"), &AVEnabled, false);
449 gPrefs->Write(wxT("/AudioIO/AutomatedInputLevelAdjustment"), !AVEnabled);
450 gPrefs->Flush();
452}
453#endif
454
455void OnStop(const CommandContext &context)
456{
458}
459
460void OnPlayOneSecond(const CommandContext &context)
461{
462 auto &project = context.project;
464 return;
465
466 auto &trackPanel = TrackPanel::Get( project );
468
469 double pos = trackPanel.GetMostRecentXPos();
471 context, SelectedRegion(pos - 0.5, pos + 0.5),
472 options, PlayMode::oneSecondPlay);
473}
474
483{
484 auto &project = context.project;
485
487 return;
488
489 auto &trackPanel = TrackPanel::Get( project );
490 auto &viewInfo = ViewInfo::Get( project );
491 const auto &selectedRegion = viewInfo.selectedRegion;
492
493 double pos = trackPanel.GetMostRecentXPos();
494
495 double t0,t1;
496 // check region between pointer and the nearest selection edge
497 if (fabs(pos - selectedRegion.t0()) <
498 fabs(pos - selectedRegion.t1())) {
499 t0 = t1 = selectedRegion.t0();
500 } else {
501 t0 = t1 = selectedRegion.t1();
502 }
503 if( pos < t1)
504 t0=pos;
505 else
506 t1=pos;
507
508 // JKC: oneSecondPlay mode disables auto scrolling
509 // On balance I think we should always do this in this function
510 // since you are typically interested in the sound EXACTLY
511 // where the cursor is.
512 // TODO: have 'playing attributes' such as 'with_autoscroll'
513 // rather than modes, since that's how we're now using the modes.
514
515 // An alternative, commented out below, is to disable autoscroll
516 // only when playing a short region, less than or equal to a second.
517// mLastPlayMode = ((t1-t0) > 1.0) ? normalPlay : oneSecondPlay;
518
519 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
520
522 context, SelectedRegion(t0, t1),
523 playOptions, PlayMode::oneSecondPlay);
524}
525
526// The next 4 functions provide a limited version of the
527// functionality of OnPlayToSelection() for keyboard users
528
530{
531 auto &project = context.project;
532
534 return;
535
536 auto &viewInfo = ViewInfo::Get( project );
537 const auto &selectedRegion = viewInfo.selectedRegion;
538
539 double t0 = selectedRegion.t0();
540 double beforeLen;
541 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
542
543 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
544
546 context, SelectedRegion(t0 - beforeLen, t0),
547 playOptions, PlayMode::oneSecondPlay);
548}
549
551{
552 auto &project = context.project;
553
555 return;
556
557 auto &viewInfo = ViewInfo::Get( project );
558 const auto &selectedRegion = viewInfo.selectedRegion;
559
560 double t0 = selectedRegion.t0();
561 double t1 = selectedRegion.t1();
562 double afterLen;
563 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
564
565 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
566
567 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
569 context, SelectedRegion(t0, t1),
570 playOptions, PlayMode::oneSecondPlay);
571 else
573 context, SelectedRegion(t0, t0 + afterLen),
574 playOptions, PlayMode::oneSecondPlay);
575}
576
578{
579 auto &project = context.project;
580
582 return;
583
584 auto &viewInfo = ViewInfo::Get( project );
585 const auto &selectedRegion = viewInfo.selectedRegion;
586
587 double t0 = selectedRegion.t0();
588 double t1 = selectedRegion.t1();
589 double beforeLen;
590 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
591
592 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
593
594 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
596 context, SelectedRegion(t0, t1),
597 playOptions, PlayMode::oneSecondPlay);
598 else
600 context, SelectedRegion(t1 - beforeLen, t1),
601 playOptions, PlayMode::oneSecondPlay);
602}
603
605{
606 auto &project = context.project;
607
609 return;
610
611 auto &viewInfo = ViewInfo::Get( project );
612 const auto &selectedRegion = viewInfo.selectedRegion;
613
614 double t1 = selectedRegion.t1();
615 double afterLen;
616 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
617
618 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
619
621 context, SelectedRegion(t1, t1 + afterLen),
622 playOptions, PlayMode::oneSecondPlay);
623}
624
626(const CommandContext &context)
627{
628 auto &project = context.project;
629
631 return;
632
633 auto &viewInfo = ViewInfo::Get( project );
634 const auto &selectedRegion = viewInfo.selectedRegion;
635
636 double t0 = selectedRegion.t0();
637 double t1 = selectedRegion.t1();
638 double beforeLen;
639 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
640 double afterLen;
641 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
642
643 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
644
645 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
647 context, SelectedRegion(t0 - beforeLen, t1),
648 playOptions, PlayMode::oneSecondPlay);
649 else
651 context, SelectedRegion(t0 - beforeLen, t0 + afterLen),
652 playOptions, PlayMode::oneSecondPlay);
653}
654
656(const CommandContext &context)
657{
658 auto &project = context.project;
659
661 return;
662
663 auto &viewInfo = ViewInfo::Get( project );
664 const auto &selectedRegion = viewInfo.selectedRegion;
665
666 double t0 = selectedRegion.t0();
667 double t1 = selectedRegion.t1();
668 double beforeLen;
669 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
670 double afterLen;
671 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
672
673 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
674
675 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
677 context, SelectedRegion(t0, t1 + afterLen),
678 playOptions, PlayMode::oneSecondPlay);
679 else
681 context, SelectedRegion(t1 - beforeLen, t1 + afterLen),
682 playOptions, PlayMode::oneSecondPlay);
683}
684
686{
687 auto &project = context.project;
688
689 if ( !MakeReadyToPlay(project) )
690 return;
691
692 // Play with cut preview
694}
695
697{
698 auto &project = context.project;
699 DoMoveToLabel(project, false);
700}
701
703{
704 auto &project = context.project;
705 DoMoveToLabel(project, true);
706}
707
708#if 0
709// Legacy handlers, not used as of version 2.3.0
710void OnStopSelect(const CommandContext &context)
711{
712 auto &project = context.project;
713 auto &history = ProjectHistory::Get( project );
714 auto &viewInfo = project.GetViewInfo();
715 auto &selectedRegion = viewInfo.selectedRegion;
716
717 auto gAudioIO = AudioIOBase::Get();
718 if (gAudioIO->IsStreamActive()) {
719 selectedRegion.setT0(gAudioIO->GetStreamTime(), false);
721 history.ModifyState(false); // without bWantsAutoSave
722 }
723}
724#endif
725
726// Menu definitions
727
728// Under /MenuBar
729using namespace MenuRegistry;
731{
732 static const auto CanStopFlags =
734 static auto menu = std::shared_ptr{
735 /* i18n-hint: 'Transport' is the name given to the set of controls that
736 play, record, pause etc. */
737 Menu( wxT("Transport"), XXO("Tra&nsport"),
738 Section( "Basic",
739 Menu( wxT("Play"), XXO("Pl&aying"),
740 /* i18n-hint: (verb) Start or Stop audio playback*/
741 Command( wxT("DefaultPlayStop"), XXO("Pl&ay/Stop"), OnPlayDefaultOrStop,
742 CanStopAudioStreamFlag(), wxT("Space") ),
743 Command( wxT("PlayStopSelect"), XXO("Play/Stop and &Set Cursor"),
745 Command( wxT("OncePlayStop"), XXO("Play &Once/Stop"), OnPlayOnceOrStop,
746 CanStopAudioStreamFlag(), wxT("Shift+Space") ),
747 Command( wxT("Pause"), XXO("&Pause"), OnPause,
749 ),
750
751 Menu( wxT("Record"), XXO("&Recording"),
752 /* i18n-hint: (verb)*/
753 Command( wxT("Record1stChoice"), XXO("&Record"), OnRecord,
754 CanStopFlags, wxT("R") ),
755
756 // The OnRecord2ndChoice function is: if normal record records beside,
757 // it records below, if normal record records below, it records beside.
758 // TODO: Do 'the right thing' with other options like TimerRecord.
759 // Delayed evaluation in case gPrefs is not yet defined
760 [](const AudacityProject&)
761 { return Command( wxT("Record2ndChoice"),
762 // Our first choice is bound to R (by default)
763 // and gets the prime position.
764 // We supply the name for the 'other one' here.
765 // It should be bound to Shift+R
766 (gPrefs->ReadBool("/GUI/PreferNewTrackRecord", false)
767 ? XXO("&Append Record") : XXO("Record &New Track")),
769 wxT("Shift+R")
770 ); },
771
772 #ifdef EXPERIMENTAL_PUNCH_AND_ROLL
773 Command( wxT("PunchAndRoll"), XXO("Punch and Rol&l Record"),
774 OnPunchAndRoll,
775 WaveTracksExistFlag() | AudioIONotBusyFlag(), wxT("Shift+D") ),
776 #endif
777
778 // JKC: I decided to duplicate this between play and record,
779 // rather than put it at the top level.
780 // CommandManger::AddItem can now cope with simple duplicated items.
781 // PRL: caution, this is a duplicated command name!
782 Command( wxT("Pause"), XXO("&Pause"), OnPause,
784 )
785 ),
786
787 Section( "Other",
788 Section( "",
789 Menu( wxT("PlayRegion"), XXO("&Looping"),
790 Command( wxT("TogglePlayRegion"), LoopToggleText,
792 Options(L"L").CheckTest([](const AudacityProject& project){
794 } )),
795 Command( wxT("ClearPlayRegion"), XXO("&Clear Loop"),
796 OnClearPlayRegion, AlwaysEnabledFlag, L"Shift+Alt+L" ),
797 Command( wxT("SetPlayRegionToSelection"),
798 XXO("&Set Loop to Selection"),
800 L"Shift+L" ),
801 Command( wxT("SetPlayRegionIn"),
804 Command( wxT("SetPlayRegionOut"),
807 )
808 ),
809
810 Command( wxT("RescanDevices"), XXO("R&escan Audio Devices"),
812
813 Menu( wxT("Options"), XXO("Transport &Options"),
814 Section( "Part1",
815 // Sound Activated recording options
816 Command( wxT("SoundActivationLevel"),
817 XXO("Set sound activation le&vel..."), OnSoundActivated,
819 Command( wxT("SoundActivation"),
820 XXO("Enable sound a&ctivated recording"),
824 ),
825
826 Section( "Part2",
827 Command( wxT("Overdub"), XXO("Hear &other tracks during recording"),
830 Options{}.CheckTest( wxT("/AudioIO/Duplex"), true) ),
831 Command( wxT("SWPlaythrough"), XXO("Enable audible input &monitoring"),
834 Options{}.CheckTest( wxT("/AudioIO/SWPlaythrough"), false ) )
835
836
837 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
838 ,
839 Command( wxT("AutomatedInputLevelAdjustmentOnOff"),
840 XXO("A&utomated Recording Level Adjustment (on/off)"),
841 OnToggleAutomatedInputLevelAdjustment,
844 wxT("/AudioIO/AutomatedInputLevelAdjustment"), false ) )
845 #endif
846 )
847 )
848 )
849 ) };
850 return menu;
851}
852
854
856{
857 static auto menu = std::shared_ptr{
858 Menu( wxT("Transport"), XXO("T&ransport"),
859 // PlayStop is already in the menus.
860 /* i18n-hint: (verb) Start playing audio*/
861 Command( wxT("Play"), XXO("Pl&ay Once"), OnPlayOnceOrStop,
863 /* i18n-hint: (verb) Stop playing audio*/
864 Command( wxT("Stop"), XXO("Sto&p"), OnStop,
866 Command( wxT("PlayOneSec"), XXO("Play &One Second"), OnPlayOneSecond,
867 CaptureNotBusyFlag(), wxT("1") ),
868 Command( wxT("PlayToSelection"), XXO("Play to &Selection"),
870 CaptureNotBusyFlag(), wxT("B") ),
871 Command( wxT("PlayBeforeSelectionStart"),
872 XXO("Play &Before Selection Start"), OnPlayBeforeSelectionStart,
873 CaptureNotBusyFlag(), wxT("Shift+F5") ),
874 Command( wxT("PlayAfterSelectionStart"),
875 XXO("Play Af&ter Selection Start"), OnPlayAfterSelectionStart,
876 CaptureNotBusyFlag(), wxT("Shift+F6") ),
877 Command( wxT("PlayBeforeSelectionEnd"),
878 XXO("Play Be&fore Selection End"), OnPlayBeforeSelectionEnd,
879 CaptureNotBusyFlag(), wxT("Shift+F7") ),
880 Command( wxT("PlayAfterSelectionEnd"),
881 XXO("Play Aft&er Selection End"), OnPlayAfterSelectionEnd,
882 CaptureNotBusyFlag(), wxT("Shift+F8") ),
883 Command( wxT("PlayBeforeAndAfterSelectionStart"),
884 XXO("Play Before a&nd After Selection Start"),
886 wxT("Ctrl+Shift+F5") ),
887 Command( wxT("PlayBeforeAndAfterSelectionEnd"),
888 XXO("Play Before an&d After Selection End"),
890 wxT("Ctrl+Shift+F7") ),
891 Command( wxT("PlayCutPreview"), XXO("Play C&ut Preview"),
893 CaptureNotBusyFlag(), wxT("C") )
894 ) };
895 return menu;
896}
897
899 wxT("Optional/Extra/Part1")
900};
901
903{
904 static auto items = std::shared_ptr{
905 Items(wxT("MoveToLabel"),
906 Command(wxT("MoveToPrevLabel"), XXO("Move to Pre&vious Label"),
908 CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Left")),
909 Command(wxT("MoveToNextLabel"), XXO("Move to Ne&xt Label"),
911 CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Right"))
912 ) };
913 return items;
914}
915
917 { wxT("Optional/Extra/Part1/Select"), { OrderingHint::End, {} } }
918};
919
920}
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
BoolSetting SoundActivatedRecord
Definition: AudioIO.cpp:3356
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:94
static AudioIO * Get()
Definition: AudioIO.cpp:126
bool Toggle()
Write the negation of the previous value, and then return the current value.
Definition: Prefs.cpp:555
size_t size() const
How many attachment pointers are in the Site.
Definition: ClientData.h:259
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:965
int FindPrevLabel(const SelectedRegion &currentSelection)
const LabelStruct * GetLabel(int index) const
Definition: LabelTrack.cpp:970
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)
Generates classes whose instances register items at construction.
Definition: Registry.h:388
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:207
Configures sound activated recording.
static void ModifyAllProjectToolbarMenus()
Track * Get()
Definition: TrackFocus.cpp:156
static TrackList & Get(AudacityProject &project)
Definition: Track.cpp:347
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:233
PlayRegion playRegion
Definition: ViewInfo.h:216
NotifyingSelectedRegion selectedRegion
Definition: ViewInfo.h:215
static ViewInfo & Get(AudacityProject &project)
Definition: ViewInfo.cpp:235
static Viewport & Get(AudacityProject &project)
Definition: Viewport.cpp:32
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:262
constexpr auto Section
Definition: MenuRegistry.h:436
constexpr auto Items
Definition: MenuRegistry.h:427
constexpr auto Command
Definition: MenuRegistry.h:456
constexpr auto Menu
Items will appear in a main toolbar menu or in a sub-menu.
Definition: MenuRegistry.h:445
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:175
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:40
Options && CheckTest(const CheckFn &fn) &&
Definition: MenuRegistry.h:74
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)