Calculate temporary tracks of limited length with effect applied and play.
26{
28
29
30
34 auto &mT0 = effect.
mT0;
35 auto &mT1 = effect.
mT1;
39
40
43
44 if (numTracks == 0) {
45 return;
46 }
47
49 if (gAudioIO->IsBusy()) {
50 return;
51 }
52
54 assert(FocusDialog);
55
56 double previewDuration;
59
60
61 double previewLen;
62 gPrefs->
Read(
wxT(
"/AudioIO/EffectsPreviewLen"), &previewLen, 6.0);
63
65 if (isNyquist && isGenerator)
67 else
70
71 double t1 = mT0 + previewDuration;
72
73 if ((t1 > mT1) && !isGenerator) {
74 t1 = mT1;
75 }
76
77 if (t1 <= mT0)
78 return;
79
80 bool success = true;
81
82 auto cleanup = finally( [&] {
83
84
85
86
87 if (!dryOnly)
88
89
90 if (auto pInstance =
91 std::dynamic_pointer_cast<EffectInstanceEx>(effect.
MakeInstance())
92 )
93 pInstance->Init();
94 } );
95
98
99 if (!previewFullSelection)
100 mT1 = t1;
101
102
103 if (updateUI)
104 updateUI();
105
106
107 auto saveTracks = mTracks;
108
109 auto cleanup2 = finally( [&] {
110 mTracks = saveTracks;
111 if (*FocusDialog)
113 } );
114
115
116
117 const auto pProject = saveTracks->GetOwner();
119
120
121
122 if (isLinearEffect && !isGenerator) {
126 wxString{},
128 if (!newTrack)
129 return;
130 mTracks->Add(newTrack);
131
132 newTrack->MoveTo(0);
133 newTrack->SetSelected(true);
134 }
135 else {
136 for (
auto src : saveTracks->Selected<
const WaveTrack>()) {
137 auto dest = src->Copy(mT0, t1);
138 dest->SetSelected(true);
139 mTracks->Add(dest);
140 }
141 }
142
143
144
145
146 mT1 -= mT0;
147 mT0 = 0.0;
148
149
151
152
153 if (!dryOnly) {
157 XO(
"Preparing preview"),
159 );
161
163
165
166 auto pInstance =
167 std::dynamic_pointer_cast<EffectInstanceEx>(effect.
MakeInstance());
168 success = pInstance && pInstance->Process(
settings);
169 return nullptr;
170 });
171 }
172
173 if (success)
174 {
176
177
178
179 t1 =
std::min(mT0 + previewLen, mT1);
180
181
183 int token = gAudioIO->StartStream(
tracks, mT0, t1, t1, options);
184
185 if (token) {
188
189
190
191 {
194
196 using namespace std::chrono;
197 std::this_thread::sleep_for(100ms);
198 previewing = progress->Poll(
199 gAudioIO->GetStreamTime() - mT0, t1 - mT0);
200 }
201 }
202
203 gAudioIO->StopStream();
204
205 while (gAudioIO->IsBusy()) {
206 using namespace std::chrono;
207 std::this_thread::sleep_for(100ms);
208 }
209 }
210 else {
213 *FocusDialog,
XO(
"Error"),
214 XO(
"Error opening sound device.\nTry changing the audio host, playback device and the project sample rate."),
215 wxT(
"Error_opening_sound_device"),
217 }
218 }
219}
#define NYQUISTEFFECTS_FAMILY
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
Track::Holder MixAndRender(const TrackIterRange< const WaveTrack > &trackRange, const Mixer::WarpOptions &warpOptions, const wxString &newTrackName, WaveTrackFactory *trackFactory, double rate, sampleFormat format, double startTime, double endTime)
Mixes together all input tracks, applying any envelopes, per-track real-time effects,...
audacity::BasicSettings * gPrefs
static Settings & settings()
TransportSequences MakeTransportTracks(TrackList &trackList, bool selectedOnly, bool nonWaveToo)
TranslatableString GetName() const
WaveTrackFactory * mFactory
bool PreviewsFullSelection() const
virtual std::any BeginPreview(const EffectSettings &settings)
Called when Preview() starts, to allow temporary effect state changes.
bool IsLinearEffect() const
BasicUI::ProgressDialog * mProgress
std::shared_ptr< TrackList > mTracks
virtual double CalcPreviewInputLength(const EffectSettings &settings, double previewLength) const =0
virtual EffectType GetType() const =0
Type determines how it behaves.
virtual EffectFamilySymbol GetFamily() const =0
Report identifier and user-visible name of the effect protocol.
virtual std::shared_ptr< EffectInstance > MakeInstance() const =0
Make an object maintaining short-term state of an Effect.
void ModifySettings(Function &&function)
Do a correct read-modify-write of settings.
virtual const EffectSettings & Get()=0
static AudioIOStartStreamOptions GetDefaultOptions(AudacityProject &project, bool newDefaults=false)
Invoke the global hook, supplying a default argument.
static TrackListHolder Create(AudacityProject *pOwner)
A Track that contains audio waveform data.
virtual bool Read(const wxString &key, bool *value) const =0
void SetFocus(const WindowPlacement &focus)
Set the window that accepts keyboard input.
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< ProgressDialog > MakeProgress(const TranslatableString &title, const TranslatableString &message, unsigned flags=(ProgressShowStop|ProgressShowCancel), const TranslatableString &remainingLabelText={})
Create and display a progress dialog.
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Options for variations of error dialogs; the default is for modal dialogs.
Externalized state of a plug-in.
Immutable structure is an argument to Mixer's constructor.