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
199void OnPunchAndRoll(const CommandContext &context)
200{
202 auto &viewInfo = ViewInfo::Get( project );
203
204 static const auto url =
205 wxT("Punch_and_Roll_Record#Using_Punch_and_Roll_Record");
206
207 auto gAudioIO = AudioIO::Get();
208 if (gAudioIO->IsBusy())
209 return;
210
211 // Ignore all but left edge of the selection.
212 viewInfo.selectedRegion.collapseToT0();
213 double t1 = std::max(0.0, viewInfo.selectedRegion.t1());
214
215 // Checking the selected tracks: making sure they all have the same rate
216 const auto selectedTracks{ GetPropertiesOfSelected(project) };
217 const int rateOfSelected{ selectedTracks.rateOfSelected };
218 const bool allSameRate{ selectedTracks.allSameRate };
219
220 if (!allSameRate) {
221 AudacityMessageBox(XO("The tracks selected "
222 "for recording must all have the same sampling rate"),
223 XO("Mismatched Sampling Rates"),
224 wxICON_ERROR | wxCENTRE);
225
226 return;
227 }
228
229 // Decide which tracks to record in.
230 auto tracks =
232 if (tracks.empty()) {
233 auto recordingChannels =
234 std::max(0, AudioIORecordChannels.Read());
235 auto message =
236 (recordingChannels == 1)
237 ? XO("Please select in a mono track.")
238 : (recordingChannels == 2)
239 ? XO("Please select in a stereo track or two mono tracks.")
240 : XO("Please select at least %d channels.").Format( recordingChannels );
242 XO("Error"), message, url);
243 return;
244 }
245
246 // Delete the portion of the target tracks right of the selection, but first,
247 // remember a part of the deletion for crossfading with the new recording.
248 // We may also adjust the starting point leftward if it is too close to the
249 // end of the track, so that at least some nonzero crossfade data can be
250 // taken.
251 PRCrossfadeData crossfadeData;
252 const double crossFadeDuration = std::max(0.0,
254 / 1000.0
255 );
256
257 // The test for t1 == 0.0 stops punch and roll deleting everything where the
258 // selection is at zero. There wouldn't be any cued audio to play in
259 // that case, so a normal record, not a punch and roll, is called for.
260 bool error = (t1 == 0.0);
261
262 double newt1 = t1;
263 for (const auto &wt : tracks) {
264 auto rate = wt->GetRate();
265 sampleCount testSample(floor(t1 * rate));
266 const auto &intervals = as_const(*wt).Intervals();
267 auto pred = [rate](sampleCount testSample){ return
268 [rate, testSample](const auto &pInterval){
269 auto start = floor(pInterval->Start() * rate + 0.5);
270 auto end = floor(pInterval->End() * rate + 0.5);
271 auto ts = testSample.as_double();
272 return ts >= start && ts < end;
273 };
274 };
275 auto begin = intervals.begin(), end = intervals.end(),
276 iter = std::find_if(begin, end, pred(testSample));
277 if (iter == end)
278 // Bug 1890 (an enhancement request)
279 // Try again, a little to the left.
280 // Subtract 10 to allow a selection exactly at or slightly after the
281 // end time
282 iter = std::find_if(begin, end, pred(testSample - 10));
283 if (iter == end)
284 error = true;
285 else {
286 // May adjust t1 left
287 // Let's ignore the possibility of a clip even shorter than the
288 // crossfade duration!
289 newt1 = std::min(newt1, (*iter).get()->End() - crossFadeDuration);
290 }
291 }
292
293 if (error) {
294 auto message = XO("Please select a time within a clip.");
296 *ProjectFramePlacement(&project), XO("Error"), message, url);
297 return;
298 }
299
300 t1 = newt1;
301 for (const auto &wt : tracks) {
302 const auto endTime = wt->GetEndTime();
303 const auto duration =
304 std::max(0.0, std::min(crossFadeDuration, endTime - t1));
305 const size_t getLen = floor(duration * wt->GetRate());
306 if (getLen > 0) {
307 // TODO more-than-two-channels
308 const auto nChannels = std::min<size_t>(2, wt->NChannels());
309 crossfadeData.resize(nChannels);
310 float *buffers[2]{};
311 for (size_t ii = 0; ii < nChannels; ++ii) {
312 auto &data = crossfadeData[ii];
313 data.resize(getLen);
314 buffers[ii] = data.data();
315 }
316 const sampleCount pos = wt->TimeToLongSamples(t1);
317 if (!wt->GetFloats(0, nChannels, buffers, pos, getLen))
318 // TODO error message
319 return;
320 }
321 }
322
323 // Change tracks only after passing the error checks above
324 for (const auto &wt : tracks)
325 wt->Clear(t1, wt->GetEndTime());
326
327 // Choose the tracks for playback.
328 TransportSequences transportTracks;
329 const auto duplex = ProjectAudioManager::UseDuplex();
330 if (duplex)
331 // play all
332 transportTracks = MakeTransportTracks(
333 TrackList::Get( project ), false, true);
334 else
335 // play recording tracks only
336 for (auto &pTrack : tracks)
337 transportTracks.playbackSequences.push_back(pTrack);
338
339 // Unlike with the usual recording, a track may be chosen both for playback
340 // and recording.
341 std::copy(tracks.begin(), tracks.end(),
342 back_inserter(transportTracks.captureSequences));
343
344 // Try to start recording
346 options.rate = rateOfSelected;
347 options.preRoll = std::max(0.0,
349 options.pCrossfadeData = &crossfadeData;
351 transportTracks,
352 t1, DBL_MAX,
353 false, // altAppearance
354 options);
355
356 if (success)
357 // Undo state will get pushed elsewhere, when record finishes
358 ;
359 else
360 // Roll back the deletions
362}
363
365{
367}
368
370{
372}
373
375{
376 auto &project = context.project;
377 auto &playRegion = ViewInfo::Get(project).playRegion;
378 if (!playRegion.Active())
381 true, false, SetLoopInTitle.Stripped());
382}
383
384
386{
387 auto &project = context.project;
388 auto &playRegion = ViewInfo::Get(project).playRegion;
389 if (!playRegion.Active())
392 false, false, SetLoopOutTitle.Stripped());
393}
394
396{
398}
399
400void OnRescanDevices(const CommandContext &WXUNUSED(context) )
401{
403}
404
406{
408
409 SoundActivatedRecordDialog dialog( &GetProjectFrame( project ) /* parent */ );
410 dialog.ShowModal();
411}
412
413void OnToggleSoundActivated(const CommandContext &WXUNUSED(context) )
414{
416 gPrefs->Flush();
418}
419
420void OnTogglePlayRecording(const CommandContext &WXUNUSED(context) )
421{
422 bool Duplex;
423 gPrefs->Read(wxT("/AudioIO/Duplex"), &Duplex, true);
424 gPrefs->Write(wxT("/AudioIO/Duplex"), !Duplex);
425 gPrefs->Flush();
427}
428
429void OnToggleSWPlaythrough(const CommandContext &WXUNUSED(context) )
430{
431 bool SWPlaythrough;
432 gPrefs->Read(wxT("/AudioIO/SWPlaythrough"), &SWPlaythrough, false);
433 gPrefs->Write(wxT("/AudioIO/SWPlaythrough"), !SWPlaythrough);
434 gPrefs->Flush();
436}
437
438#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
439void OnToggleAutomatedInputLevelAdjustment(
440 const CommandContext &WXUNUSED(context) )
441{
442 bool AVEnabled;
443 gPrefs->Read(
444 wxT("/AudioIO/AutomatedInputLevelAdjustment"), &AVEnabled, false);
445 gPrefs->Write(wxT("/AudioIO/AutomatedInputLevelAdjustment"), !AVEnabled);
446 gPrefs->Flush();
448}
449#endif
450
451void OnStop(const CommandContext &context)
452{
454}
455
456void OnPlayOneSecond(const CommandContext &context)
457{
458 auto &project = context.project;
460 return;
461
462 auto &trackPanel = TrackPanel::Get( project );
464
465 double pos = trackPanel.GetMostRecentXPos();
467 context, SelectedRegion(pos - 0.5, pos + 0.5),
468 options, PlayMode::oneSecondPlay);
469}
470
479{
480 auto &project = context.project;
481
483 return;
484
485 auto &trackPanel = TrackPanel::Get( project );
486 auto &viewInfo = ViewInfo::Get( project );
487 const auto &selectedRegion = viewInfo.selectedRegion;
488
489 double pos = trackPanel.GetMostRecentXPos();
490
491 double t0,t1;
492 // check region between pointer and the nearest selection edge
493 if (fabs(pos - selectedRegion.t0()) <
494 fabs(pos - selectedRegion.t1())) {
495 t0 = t1 = selectedRegion.t0();
496 } else {
497 t0 = t1 = selectedRegion.t1();
498 }
499 if( pos < t1)
500 t0=pos;
501 else
502 t1=pos;
503
504 // JKC: oneSecondPlay mode disables auto scrolling
505 // On balance I think we should always do this in this function
506 // since you are typically interested in the sound EXACTLY
507 // where the cursor is.
508 // TODO: have 'playing attributes' such as 'with_autoscroll'
509 // rather than modes, since that's how we're now using the modes.
510
511 // An alternative, commented out below, is to disable autoscroll
512 // only when playing a short region, less than or equal to a second.
513// mLastPlayMode = ((t1-t0) > 1.0) ? normalPlay : oneSecondPlay;
514
515 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
516
518 context, SelectedRegion(t0, t1),
519 playOptions, PlayMode::oneSecondPlay);
520}
521
522// The next 4 functions provide a limited version of the
523// functionality of OnPlayToSelection() for keyboard users
524
526{
527 auto &project = context.project;
528
530 return;
531
532 auto &viewInfo = ViewInfo::Get( project );
533 const auto &selectedRegion = viewInfo.selectedRegion;
534
535 double t0 = selectedRegion.t0();
536 double beforeLen;
537 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
538
539 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
540
542 context, SelectedRegion(t0 - beforeLen, t0),
543 playOptions, PlayMode::oneSecondPlay);
544}
545
547{
548 auto &project = context.project;
549
551 return;
552
553 auto &viewInfo = ViewInfo::Get( project );
554 const auto &selectedRegion = viewInfo.selectedRegion;
555
556 double t0 = selectedRegion.t0();
557 double t1 = selectedRegion.t1();
558 double afterLen;
559 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
560
561 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
562
563 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
565 context, SelectedRegion(t0, t1),
566 playOptions, PlayMode::oneSecondPlay);
567 else
569 context, SelectedRegion(t0, t0 + afterLen),
570 playOptions, PlayMode::oneSecondPlay);
571}
572
574{
575 auto &project = context.project;
576
578 return;
579
580 auto &viewInfo = ViewInfo::Get( project );
581 const auto &selectedRegion = viewInfo.selectedRegion;
582
583 double t0 = selectedRegion.t0();
584 double t1 = selectedRegion.t1();
585 double beforeLen;
586 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
587
588 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
589
590 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
592 context, SelectedRegion(t0, t1),
593 playOptions, PlayMode::oneSecondPlay);
594 else
596 context, SelectedRegion(t1 - beforeLen, t1),
597 playOptions, PlayMode::oneSecondPlay);
598}
599
601{
602 auto &project = context.project;
603
605 return;
606
607 auto &viewInfo = ViewInfo::Get( project );
608 const auto &selectedRegion = viewInfo.selectedRegion;
609
610 double t1 = selectedRegion.t1();
611 double afterLen;
612 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
613
614 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
615
617 context, SelectedRegion(t1, t1 + afterLen),
618 playOptions, PlayMode::oneSecondPlay);
619}
620
622(const CommandContext &context)
623{
624 auto &project = context.project;
625
627 return;
628
629 auto &viewInfo = ViewInfo::Get( project );
630 const auto &selectedRegion = viewInfo.selectedRegion;
631
632 double t0 = selectedRegion.t0();
633 double t1 = selectedRegion.t1();
634 double beforeLen;
635 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
636 double afterLen;
637 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
638
639 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
640
641 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
643 context, SelectedRegion(t0 - beforeLen, t1),
644 playOptions, PlayMode::oneSecondPlay);
645 else
647 context, SelectedRegion(t0 - beforeLen, t0 + afterLen),
648 playOptions, PlayMode::oneSecondPlay);
649}
650
652(const CommandContext &context)
653{
654 auto &project = context.project;
655
657 return;
658
659 auto &viewInfo = ViewInfo::Get( project );
660 const auto &selectedRegion = viewInfo.selectedRegion;
661
662 double t0 = selectedRegion.t0();
663 double t1 = selectedRegion.t1();
664 double beforeLen;
665 gPrefs->Read(wxT("/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
666 double afterLen;
667 gPrefs->Read(wxT("/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
668
669 auto playOptions = ProjectAudioIO::GetDefaultOptions(project);
670
671 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
673 context, SelectedRegion(t0, t1 + afterLen),
674 playOptions, PlayMode::oneSecondPlay);
675 else
677 context, SelectedRegion(t1 - beforeLen, t1 + afterLen),
678 playOptions, PlayMode::oneSecondPlay);
679}
680
682{
683 auto &project = context.project;
684
685 if ( !MakeReadyToPlay(project) )
686 return;
687
688 // Play with cut preview
690}
691
693{
694 auto &project = context.project;
695 DoMoveToLabel(project, false);
696}
697
699{
700 auto &project = context.project;
701 DoMoveToLabel(project, true);
702}
703
704#if 0
705// Legacy handlers, not used as of version 2.3.0
706void OnStopSelect(const CommandContext &context)
707{
708 auto &project = context.project;
709 auto &history = ProjectHistory::Get( project );
710 auto &viewInfo = project.GetViewInfo();
711 auto &selectedRegion = viewInfo.selectedRegion;
712
713 auto gAudioIO = AudioIOBase::Get();
714 if (gAudioIO->IsStreamActive()) {
715 selectedRegion.setT0(gAudioIO->GetStreamTime(), false);
717 history.ModifyState(false); // without bWantsAutoSave
718 }
719}
720#endif
721
722// Menu definitions
723
724// Under /MenuBar
725using namespace MenuRegistry;
727{
728 static const auto CanStopFlags =
730 static auto menu = std::shared_ptr{
731 /* i18n-hint: 'Transport' is the name given to the set of controls that
732 play, record, pause etc. */
733 Menu( wxT("Transport"), XXO("Tra&nsport"),
734 Section( "Basic",
735 Menu( wxT("Play"), XXO("Pl&aying"),
736 /* i18n-hint: (verb) Start or Stop audio playback*/
737 Command( wxT("DefaultPlayStop"), XXO("Pl&ay/Stop"), OnPlayDefaultOrStop,
738 CanStopAudioStreamFlag(), wxT("Space") ),
739 Command( wxT("PlayStopSelect"), XXO("Play/Stop and &Set Cursor"),
741 Command( wxT("OncePlayStop"), XXO("Play &Once/Stop"), OnPlayOnceOrStop,
742 CanStopAudioStreamFlag(), wxT("Shift+Space") ),
743 Command( wxT("Pause"), XXO("&Pause"), OnPause,
745 ),
746
747 Menu( wxT("Record"), XXO("&Recording"),
748 /* i18n-hint: (verb)*/
749 Command( wxT("Record1stChoice"), XXO("&Record"), OnRecord,
750 CanStopFlags, wxT("R") ),
751
752 // The OnRecord2ndChoice function is: if normal record records beside,
753 // it records below, if normal record records below, it records beside.
754 // TODO: Do 'the right thing' with other options like TimerRecord.
755 // Delayed evaluation in case gPrefs is not yet defined
756 [](const AudacityProject&)
757 { return Command( wxT("Record2ndChoice"),
758 // Our first choice is bound to R (by default)
759 // and gets the prime position.
760 // We supply the name for the 'other one' here.
761 // It should be bound to Shift+R
762 (gPrefs->ReadBool("/GUI/PreferNewTrackRecord", false)
763 ? XXO("&Append Record") : XXO("Record &New Track")),
765 wxT("Shift+R")
766 ); },
767
768 Command( wxT("PunchAndRoll"), XXO("Punch and Rol&l Record"),
770 WaveTracksExistFlag() | AudioIONotBusyFlag(), wxT("Shift+D") ),
771
772 // JKC: I decided to duplicate this between play and record,
773 // rather than put it at the top level.
774 // CommandManger::AddItem can now cope with simple duplicated items.
775 // PRL: caution, this is a duplicated command name!
776 Command( wxT("Pause"), XXO("&Pause"), OnPause,
778 )
779 ),
780
781 Section( "Other",
782 Section( "",
783 Menu( wxT("PlayRegion"), XXO("&Looping"),
784 Command( wxT("TogglePlayRegion"), LoopToggleText,
786 Options(L"L").CheckTest([](const AudacityProject& project){
788 } )),
789 Command( wxT("ClearPlayRegion"), XXO("&Clear Loop"),
790 OnClearPlayRegion, AlwaysEnabledFlag, L"Shift+Alt+L" ),
791 Command( wxT("SetPlayRegionToSelection"),
792 XXO("&Set Loop to Selection"),
794 L"Shift+L" ),
795 Command( wxT("SetPlayRegionIn"),
798 Command( wxT("SetPlayRegionOut"),
801 )
802 ),
803
804 Command( wxT("RescanDevices"), XXO("R&escan Audio Devices"),
806
807 Menu( wxT("Options"), XXO("Transport &Options"),
808 Section( "Part1",
809 // Sound Activated recording options
810 Command( wxT("SoundActivationLevel"),
811 XXO("Set sound activation le&vel..."), OnSoundActivated,
813 Command( wxT("SoundActivation"),
814 XXO("Enable sound a&ctivated recording"),
818 ),
819
820 Section( "Part2",
821 Command( wxT("Overdub"), XXO("Hear &other tracks during recording"),
824 Options{}.CheckTest( wxT("/AudioIO/Duplex"), true) ),
825 Command( wxT("SWPlaythrough"), XXO("Enable audible input &monitoring"),
828 Options{}.CheckTest( wxT("/AudioIO/SWPlaythrough"), false ) )
829
830
831 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
832 ,
833 Command( wxT("AutomatedInputLevelAdjustmentOnOff"),
834 XXO("A&utomated Recording Level Adjustment (on/off)"),
835 OnToggleAutomatedInputLevelAdjustment,
838 wxT("/AudioIO/AutomatedInputLevelAdjustment"), false ) )
839 #endif
840 )
841 )
842 )
843 ) };
844 return menu;
845}
846
848
850{
851 static auto menu = std::shared_ptr{
852 Menu( wxT("Transport"), XXO("T&ransport"),
853 // PlayStop is already in the menus.
854 /* i18n-hint: (verb) Start playing audio*/
855 Command( wxT("Play"), XXO("Pl&ay Once"), OnPlayOnceOrStop,
857 /* i18n-hint: (verb) Stop playing audio*/
858 Command( wxT("Stop"), XXO("Sto&p"), OnStop,
860 Command( wxT("PlayOneSec"), XXO("Play &One Second"), OnPlayOneSecond,
861 CaptureNotBusyFlag(), wxT("1") ),
862 Command( wxT("PlayToSelection"), XXO("Play to &Selection"),
864 CaptureNotBusyFlag(), wxT("B") ),
865 Command( wxT("PlayBeforeSelectionStart"),
866 XXO("Play &Before Selection Start"), OnPlayBeforeSelectionStart,
867 CaptureNotBusyFlag(), wxT("Shift+F5") ),
868 Command( wxT("PlayAfterSelectionStart"),
869 XXO("Play Af&ter Selection Start"), OnPlayAfterSelectionStart,
870 CaptureNotBusyFlag(), wxT("Shift+F6") ),
871 Command( wxT("PlayBeforeSelectionEnd"),
872 XXO("Play Be&fore Selection End"), OnPlayBeforeSelectionEnd,
873 CaptureNotBusyFlag(), wxT("Shift+F7") ),
874 Command( wxT("PlayAfterSelectionEnd"),
875 XXO("Play Aft&er Selection End"), OnPlayAfterSelectionEnd,
876 CaptureNotBusyFlag(), wxT("Shift+F8") ),
877 Command( wxT("PlayBeforeAndAfterSelectionStart"),
878 XXO("Play Before a&nd After Selection Start"),
880 wxT("Ctrl+Shift+F5") ),
881 Command( wxT("PlayBeforeAndAfterSelectionEnd"),
882 XXO("Play Before an&d After Selection End"),
884 wxT("Ctrl+Shift+F7") ),
885 Command( wxT("PlayCutPreview"), XXO("Play C&ut Preview"),
887 CaptureNotBusyFlag(), wxT("C") )
888 ) };
889 return menu;
890}
891
893 wxT("Optional/Extra/Part1")
894};
895
897{
898 static auto items = std::shared_ptr{
899 Items(wxT("MoveToLabel"),
900 Command(wxT("MoveToPrevLabel"), XXO("Move to Pre&vious Label"),
902 CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Left")),
903 Command(wxT("MoveToNextLabel"), XXO("Move to Ne&xt Label"),
905 CaptureNotBusyFlag() | TrackPanelHasFocus(), wxT("Alt+Right"))
906 ) };
907 return items;
908}
909
911 { wxT("Optional/Extra/Part1/Select"), { OrderingHint::End, {} } }
912};
913
914}
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
BoolSetting SoundActivatedRecord
Definition: AudioIO.cpp:3354
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:260
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:37
A LabelTrack is a Track that holds labels (LabelStruct).
Definition: LabelTrack.h:95
int GetNumLabels() const
int FindPrevLabel(const SelectedRegion &currentSelection)
const LabelStruct * GetLabel(int index) const
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)
Find suitable tracks to record into, or return an empty array.
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:314
static TrackPanel & Get(AudacityProject &project)
Definition: TrackPanel.cpp:234
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:33
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
double as_double() const
Definition: SampleCount.h:46
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:264
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
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 OnPunchAndRoll(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)
const char * end(const char *str) noexcept
Definition: StringUtils.h:106
const char * begin(const char *str) noexcept
Definition: StringUtils.h:101
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)