2#include "../CommonCommandFlags.h"
8#include "../ProjectAudioManager.h"
10#include "../ProjectWindows.h"
11#include "../SelectUtilities.h"
12#include "../SoundActivatedRecord.h"
14#include "../TrackPanel.h"
15#include "../TransportUtilities.h"
17#include "../prefs/RecordingPrefs.h"
18#include "../prefs/TracksPrefs.h"
23#include "../toolbars/ControlToolBar.h"
24#include "../toolbars/ToolManager.h"
50 if (gAudioIO->IsStreamActive(
54 toolbar.SetPlay(
false);
58 using namespace std::chrono;
59 std::this_thread::sleep_for(100ms);
64 if (gAudioIO->IsBusy())
79 auto lt = *trackRange.rbegin();
80 auto nLabelTrack = trackRange.
size();
82 if (nLabelTrack == 0 ) {
83 trackFocus.MessageForScreenReader(
XO(
"no label track"));
85 else if (nLabelTrack > 1) {
88 *
tracks.Find(trackFocus.Get()).Filter<LabelTrack>();
90 trackFocus.MessageForScreenReader(
91 XO(
"no label track at or below focused track"));
106 bool newDefault = projectAudioManager.Looping();
109 selectedRegion =
label->selectedRegion;
114 selectedRegion =
label->selectedRegion;
115 viewport.ScrollIntoView(selectedRegion.t0());
124 auto message =
XO(
"%s %d of %d")
126 trackFocus.MessageForScreenReader(message);
129 trackFocus.MessageForScreenReader(
XO(
"no labels in label track"));
137 return playRegion.
Active();
204 static const auto url =
205 wxT(
"Punch_and_Roll_Record#Using_Punch_and_Roll_Record");
208 if (gAudioIO->IsBusy())
212 viewInfo.selectedRegion.collapseToT0();
213 double t1 = std::max(0.0, viewInfo.selectedRegion.t1());
218 const bool allSameRate{ selectedTracks.allSameRate };
222 "for recording must all have the same sampling rate"),
223 XO(
"Mismatched Sampling Rates"),
224 wxICON_ERROR | wxCENTRE);
233 auto recordingChannels =
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);
252 const double crossFadeDuration = std::max(0.0,
260 bool error = (t1 == 0.0);
263 for (
const auto &wt :
tracks) {
264 auto rate = wt->GetRate();
266 const auto &intervals = as_const(*wt).Intervals();
268 [rate, testSample](
const auto &pInterval){
269 auto start = floor(pInterval->Start() * rate + 0.5);
270 auto end = floor(pInterval->End() * rate + 0.5);
272 return ts >= start && ts <
end;
275 auto begin = intervals.begin(),
end = intervals.end(),
276 iter = std::find_if(
begin,
end, pred(testSample));
282 iter = std::find_if(
begin,
end, pred(testSample - 10));
289 newt1 =
std::min(newt1, (*iter).get()->End() - crossFadeDuration);
294 auto message =
XO(
"Please select a time within a clip.");
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());
308 const auto nChannels = std::min<size_t>(2, wt->NChannels());
309 crossfadeData.resize(nChannels);
311 for (
size_t ii = 0; ii < nChannels; ++ii) {
312 auto &data = crossfadeData[ii];
314 buffers[ii] = data.data();
317 if (!wt->GetFloats(0, nChannels, buffers, pos, getLen))
324 for (
const auto &wt :
tracks)
325 wt->Clear(t1, wt->GetEndTime());
336 for (
auto &pTrack :
tracks)
346 options.rate = rateOfSelected;
347 options.preRoll = std::max(0.0,
349 options.pCrossfadeData = &crossfadeData;
378 if (!playRegion.Active())
389 if (!playRegion.Active())
432 gPrefs->
Read(
wxT(
"/AudioIO/SWPlaythrough"), &SWPlaythrough,
false);
438#ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
439void OnToggleAutomatedInputLevelAdjustment(
444 wxT(
"/AudioIO/AutomatedInputLevelAdjustment"), &AVEnabled,
false);
445 gPrefs->
Write(
wxT(
"/AudioIO/AutomatedInputLevelAdjustment"), !AVEnabled);
465 double pos = trackPanel.GetMostRecentXPos();
487 const auto &selectedRegion = viewInfo.selectedRegion;
489 double pos = trackPanel.GetMostRecentXPos();
493 if (fabs(pos - selectedRegion.t0()) <
494 fabs(pos - selectedRegion.t1())) {
495 t0 = t1 = selectedRegion.t0();
497 t0 = t1 = selectedRegion.t1();
533 const auto &selectedRegion = viewInfo.selectedRegion;
535 double t0 = selectedRegion.t0();
537 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
554 const auto &selectedRegion = viewInfo.selectedRegion;
556 double t0 = selectedRegion.t0();
557 double t1 = selectedRegion.t1();
559 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
563 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
581 const auto &selectedRegion = viewInfo.selectedRegion;
583 double t0 = selectedRegion.t0();
584 double t1 = selectedRegion.t1();
586 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
590 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
608 const auto &selectedRegion = viewInfo.selectedRegion;
610 double t1 = selectedRegion.t1();
612 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
630 const auto &selectedRegion = viewInfo.selectedRegion;
632 double t0 = selectedRegion.t0();
633 double t1 = selectedRegion.t1();
635 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
637 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
641 if ( t1 - t0 > 0.0 && t1 - t0 < afterLen )
660 const auto &selectedRegion = viewInfo.selectedRegion;
662 double t0 = selectedRegion.t0();
663 double t1 = selectedRegion.t1();
665 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewBeforeLen"), &beforeLen, 2.0);
667 gPrefs->
Read(
wxT(
"/AudioIO/CutPreviewAfterLen"), &afterLen, 1.0);
671 if ( t1 - t0 > 0.0 && t1 - t0 < beforeLen )
710 auto &viewInfo =
project.GetViewInfo();
711 auto &selectedRegion = viewInfo.selectedRegion;
714 if (gAudioIO->IsStreamActive()) {
715 selectedRegion.setT0(gAudioIO->GetStreamTime(),
false);
717 history.ModifyState(
false);
730 static auto menu = std::shared_ptr{
739 Command(
wxT(
"PlayStopSelect"),
XXO(
"Play/Stop and &Set Cursor"),
763 ?
XXO(
"&Append Record") :
XXO(
"Record &New Track")),
792 XXO(
"&Set Loop to Selection"),
807 Menu(
wxT(
"Options"),
XXO(
"Transport &Options"),
814 XXO(
"Enable sound a&ctivated recording"),
821 Command(
wxT(
"Overdub"),
XXO(
"Hear &other tracks during recording"),
825 Command(
wxT(
"SWPlaythrough"),
XXO(
"Enable audible input &monitoring"),
831 #ifdef EXPERIMENTAL_AUTOMATED_INPUT_LEVEL_ADJUSTMENT
833 Command(
wxT(
"AutomatedInputLevelAdjustmentOnOff"),
834 XXO(
"A&utomated Recording Level Adjustment (on/off)"),
835 OnToggleAutomatedInputLevelAdjustment,
838 wxT(
"/AudioIO/AutomatedInputLevelAdjustment"),
false ) )
851 static auto menu = std::shared_ptr{
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") ),
893 wxT(
"Optional/Extra/Part1")
898 static auto items = std::shared_ptr{
900 Command(
wxT(
"MoveToPrevLabel"),
XXO(
"Move to Pre&vious Label"),
911 {
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")
audacity::BasicSettings * gPrefs
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
TransportSequences MakeTransportTracks(TrackList &trackList, bool selectedOnly, bool nonWaveToo)
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 return true if successful.
size_t size() const
How many attachment pointers are in the Site.
CommandContext provides additional information to an 'Apply()' command. It provides the project,...
AudacityProject & project
static DeviceManager * Instance()
Gets the singleton instance.
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)
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.
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.
static TrackList & Get(AudacityProject &project)
static TrackPanel & Get(AudacityProject &project)
NotifyingSelectedRegion selectedRegion
static ViewInfo & Get(AudacityProject &project)
static Viewport & Get(AudacityProject &project)
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.
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.
std::unique_ptr< detail::IndirectItem< Item > > Indirect(const std::shared_ptr< Item > &ptr)
A convenience function.
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)
const char * end(const char *str) noexcept
const char * begin(const char *str) noexcept
void copy(const T *src, T *dst, int32_t n)
RecordableSequences captureSequences
ConstPlayableSequences playbackSequences
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)