2#include "../CommonCommandFlags.h"
4#include "../LabelTrack.h"
9#include "../ProjectAudioManager.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"
20#include "../prefs/RecordingPrefs.h"
21#include "../prefs/TracksPrefs.h"
24#include "../commands/CommandContext.h"
25#include "../commands/CommandManager.h"
26#include "../toolbars/ControlToolBar.h"
27#include "../toolbars/ToolManager.h"
53 if (gAudioIO->IsStreamActive(
57 toolbar.SetPlay(
false);
61 using namespace std::chrono;
62 std::this_thread::sleep_for(100ms);
67 if (gAudioIO->IsBusy())
82 auto lt = *trackRange.rbegin();
83 auto nLabelTrack = trackRange.
size();
85 if (nLabelTrack == 0 ) {
86 trackFocus.MessageForScreenReader(
XO(
"no label track"));
88 else if (nLabelTrack > 1) {
91 *tracks.
Find(trackFocus.Get()).Filter<LabelTrack>();
93 trackFocus.MessageForScreenReader(
94 XO(
"no label track at or below focused track"));
109 bool newDefault = projectAudioManager.Looping();
112 selectedRegion =
label->selectedRegion;
113 window.RedrawProject();
117 selectedRegion =
label->selectedRegion;
118 window.ScrollIntoView(selectedRegion.t0());
119 window.RedrawProject();
127 auto message =
XO(
"%s %d of %d")
129 trackFocus.MessageForScreenReader(message);
132 trackFocus.MessageForScreenReader(
XO(
"no labels in label track"));
140 return playRegion.
Active();
173 auto &project = context.
project;
202#ifdef EXPERIMENTAL_PUNCH_AND_ROLL
208 static const auto url =
209 wxT(
"Punch_and_Roll_Record#Using_Punch_and_Roll_Record");
212 if (gAudioIO->IsBusy())
216 viewInfo.selectedRegion.collapseToT0();
217 double t1 = std::max(0.0, viewInfo.selectedRegion.t1());
222 const bool allSameRate{ selectedTracks.allSameRate };
226 "for recording must all have the same sampling rate"),
227 XO(
"Mismatched Sampling Rates"),
228 wxICON_ERROR | wxCENTRE);
236 if (tracks.empty()) {
237 auto recordingChannels =
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);
256 const double crossFadeDuration = std::max(0.0,
264 bool error = (t1 == 0.0);
267 for (
const auto &wt : tracks) {
268 auto rate = wt->GetRate();
270 auto intervals = wt->GetIntervals();
273 auto start = floor(interval.Start() * rate + 0.5);
274 auto end = floor(interval.End() * rate + 0.5);
275 auto ts = testSample.as_double();
276 return ts >= start && ts <
end;
279 auto begin = intervals.begin(),
end = intervals.end(),
280 iter = std::find_if(
begin,
end, pred(testSample));
286 iter = std::find_if(
begin,
end, pred(testSample - 10));
293 newt1 =
std::min(newt1, iter->End() - crossFadeDuration);
298 auto message =
XO(
"Please select a time within a clip.");
305 for (
const auto &wt : tracks) {
306 const auto endTime = wt->GetEndTime();
307 const auto duration =
308 std::max(0.0,
std::min(crossFadeDuration, endTime - t1));
309 const size_t getLen = floor(duration * wt->GetRate());
310 std::vector<float> data(getLen);
312 float *
const samples = data.data();
314 wt->GetFloats(samples, pos, getLen);
316 crossfadeData.push_back(std::move(data));
320 for (
const auto &wt : tracks) {
321 wt->Clear(t1, wt->GetEndTime());
333 std::copy(tracks.begin(), tracks.end(),
342 options.rate = rateOfSelected;
343 options.preRoll = std::max(0L,
345 options.pCrossfadeData = &crossfadeData;
373 auto &project = context.
project;
375 if (!playRegion.Active())
384 auto &project = context.
project;
386 if (!playRegion.Active())
420#ifdef EXPERIMENTAL_DA
421 gPrefs->Read(
wxT(
"/AudioIO/Duplex"), &Duplex,
false);
423 gPrefs->Read(
wxT(
"/AudioIO/Duplex"), &Duplex,
true);
425 gPrefs->Write(
wxT(
"/AudioIO/Duplex"), !Duplex);
433 gPrefs->Read(
wxT(
"/AudioIO/SWPlaythrough"), &SWPlaythrough,
false);
434 gPrefs->Write(
wxT(
"/AudioIO/SWPlaythrough"), !SWPlaythrough);
439#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
440void OnToggleAutomatedInputLevelAdjustment(
445 wxT(
"/AudioIO/AutomatedInputLevelAdjustment"), &AVEnabled,
false);
446 gPrefs->Write(
wxT(
"/AudioIO/AutomatedInputLevelAdjustment"), !AVEnabled);
459 auto &project = context.
project;
466 double pos = trackPanel.GetMostRecentXPos();
481 auto &project = context.
project;
488 const auto &selectedRegion = viewInfo.selectedRegion;
490 double pos = trackPanel.GetMostRecentXPos();
494 if (fabs(pos - selectedRegion.t0()) <
495 fabs(pos - selectedRegion.t1())) {
496 t0 = t1 = selectedRegion.t0();
498 t0 = t1 = selectedRegion.t1();
528 auto &project = context.
project;
534 const auto &selectedRegion = viewInfo.selectedRegion;
536 double t0 = selectedRegion.t0();
538 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
549 auto &project = context.
project;
555 const auto &selectedRegion = viewInfo.selectedRegion;
557 double t0 = selectedRegion.t0();
558 double t1 = selectedRegion.t1();
560 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
564 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
576 auto &project = context.
project;
582 const auto &selectedRegion = viewInfo.selectedRegion;
584 double t0 = selectedRegion.t0();
585 double t1 = selectedRegion.t1();
587 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
591 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
603 auto &project = context.
project;
609 const auto &selectedRegion = viewInfo.selectedRegion;
611 double t1 = selectedRegion.t1();
613 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
625 auto &project = context.
project;
631 const auto &selectedRegion = viewInfo.selectedRegion;
633 double t0 = selectedRegion.t0();
634 double t1 = selectedRegion.t1();
636 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
638 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
642 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
655 auto &project = context.
project;
661 const auto &selectedRegion = viewInfo.selectedRegion;
663 double t0 = selectedRegion.t0();
664 double t1 = selectedRegion.t1();
666 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
668 gPrefs->Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
672 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
684 auto &project = context.
project;
695 auto &project = context.
project;
701 auto &project = context.
project;
709 auto &project = context.
project;
711 auto &viewInfo = project.GetViewInfo();
712 auto &selectedRegion = viewInfo.selectedRegion;
715 if (gAudioIO->IsStreamActive()) {
716 selectedRegion.setT0(gAudioIO->GetStreamTime(),
false);
718 history.ModifyState(
false);
742 Command(
wxT(
"PlayStopSelect"),
XXO(
"Play/Stop and &Set Cursor"),
765 (
gPrefs->ReadBool(
"/GUI/PreferNewTrackRecord",
false)
766 ?
XXO(
"&Append Record") :
XXO(
"Record &New Track")),
771 #ifdef EXPERIMENTAL_PUNCH_AND_ROLL
797 XXO(
"&Set Loop to Selection"),
812 Menu(
wxT(
"Options"),
XXO(
"Transport &Options"),
819 XXO(
"Sound A&ctivated Recording (on/off)"),
830#ifdef EXPERIMENTAL_DA
836 Command(
wxT(
"SWPlaythrough"),
XXO(
"So&ftware Playthrough (on/off)"),
842 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
844 Command(
wxT(
"AutomatedInputLevelAdjustmentOnOff"),
845 XXO(
"A&utomated Recording Level Adjustment (on/off)"),
846 OnToggleAutomatedInputLevelAdjustment,
849 wxT(
"/AudioIO/AutomatedInputLevelAdjustment"),
false ) )
891 Command(
wxT(
"PlayBeforeAndAfterSelectionStart"),
892 XXO(
"Play Before a&nd After Selection Start"),
894 wxT(
"Ctrl+Shift+F5") ),
895 Command(
wxT(
"PlayBeforeAndAfterSelectionEnd"),
896 XXO(
"Play Before an&d After Selection End"),
898 wxT(
"Ctrl+Shift+F7") ),
907 wxT(
"Optional/Extra/Part1"),
916 Command(
wxT(
"MoveToPrevLabel"),
XXO(
"Move to Pre&vious Label"),
927 {
wxT(
"Optional/Extra/Part1/Select"), { OrderingHint::End, {} } },
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
BoolSetting SoundActivatedRecord
IntSetting AudioIORecordChannels
std::vector< std::vector< float > > PRCrossfadeData
Toolkit-neutral facade for basic user interface services.
AttachedItem sAttachment1
AttachedItem sAttachment2
constexpr CommandFlag AlwaysEnabledFlag
const ReservedCommandFlag & CaptureNotBusyFlag()
const ReservedCommandFlag & AudioIOBusyFlag()
const ReservedCommandFlag & AudioIONotBusyFlag()
const ReservedCommandFlag & WaveTracksExistFlag()
const ReservedCommandFlag & TrackPanelHasFocus()
XXO("&Cut/Copy/Paste Toolbar")
std::unique_ptr< const BasicUI::WindowPlacement > ProjectFramePlacement(AudacityProject *project)
Make a WindowPlacement object suitable for project (which may be null)
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
const TranslatableString LoopToggleText
The top-level handle to an Audacity project. It serves as a source of events that other objects can b...
static AudioIOBase * Get()
bool Toggle()
Write the negation of the previous value, and then return the current value.
size_t size() const
How many attachment pointers are in the Site.
Subclass * Find(const RegisteredFactory &key)
Get a (bare) pointer to an attachment, or null, down-cast it to Subclass *; will not create on demand...
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
static DeviceManager * Instance()
Gets the singleton instance.
virtual bool Flush(bool bCurrentOnly=false) wxOVERRIDE
A LabelStruct holds information for ONE label in a LabelTrack.
A LabelTrack is a Track that holds labels (LabelStruct).
int FindPrevLabel(const SelectedRegion ¤tSelection)
const LabelStruct * GetLabel(int index) const
int FindNextLabel(const SelectedRegion ¤tSelection)
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 TransportTracks &transportTracks, 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 */
Configures sound activated recording.
A start and an end time, and mutative access to optional extra information.
static TrackList & Get(AudacityProject &project)
static TrackPanel & Get(AudacityProject &project)
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
Positions or offsets within audio files need a wide type.
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.
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
auto begin(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
std::shared_ptr< BaseItem > BaseItemSharedPtr
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)
CommandManager::Options Options
Options && CheckTest(const CheckFn &fn) &&
WritableSampleTrackArray captureTracks
SampleTrackConstArray playbackTracks
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)