28#include "../ShuttleGui.h"
30#include "../widgets/valnum.h"
31#include "../widgets/AudacityMessageBox.h"
34#include "../WaveTrack.h"
49 PaulStretch(
float rap_,
size_t in_bufsize_,
float samplerate_);
53 void process(
float *smps,
size_t nsmps);
98 Parameters().Reset(*
this);
100 SetLinearEffectFlag(
true);
116 return XO(
"Paulstretch is only for an extreme time-stretch or \"stasis\" effect");
121 return L
"Paulstretch";
153 double trackStart = track->GetStartTime();
154 double trackEnd = track->GetEndTime();
155 double t0 =
mT0 < trackStart? trackStart:
mT0;
156 double t1 =
mT1 > trackEnd? trackEnd:
mT1;
176 S.StartMultiColumn(2, wxALIGN_CENTER);
179 .Validator<FloatingPointValidator<float>>(
185 .AddTextBox(
XXO(
"&Stretch Factor:"), wxT(
""), 10);
188 .Validator<FloatingPointValidator<float>>(
190 .AddTextBox(
XXO(
"&Time Resolution (seconds):"), L
"", 10);
207 tmp = log(tmp) / log(2.0);
208 tmp = pow(2.0, floor(tmp + 0.5));
210 auto stmp = size_t(tmp);
214 if (stmp >= 2 * stmp)
218 return std::max<size_t>(stmp, 128);
223 const auto badAllocMessage =
224 XO(
"Requested value exceeds memory capacity.");
227 if (stretch_buf_size == 0) {
236 auto len =
end - start;
238 const auto minDuration = stretch_buf_size * 2 + 1;
239 if (minDuration < stretch_buf_size) {
245 if (len < minDuration) {
247 float maxTimeRes = log( len.as_double() ) / log(2.0);
248 maxTimeRes = pow(2.0, floor(maxTimeRes) + 0.5);
249 maxTimeRes = maxTimeRes / track->
GetRate();
252 double defaultPreviewLen;
253 gPrefs->Read(wxT(
"/AudioIO/EffectsPreviewLen"), &defaultPreviewLen, 6.0);
258 XO(
"Audio selection too short to preview.\n\n"
259 "Try increasing the audio selection to at least %.1f seconds,\n"
260 "or reducing the 'Time Resolution' to less than %.1f seconds.")
262 (minDuration / track->
GetRate()) + 0.05,
263 floor(maxTimeRes * 10.0) / 10.0),
264 wxOK | wxICON_EXCLAMATION );
269 XO(
"Unable to Preview.\n\n"
270 "For the current audio selection, the maximum\n"
271 "'Time Resolution' is %.1f seconds.")
272 .
Format( floor(maxTimeRes * 10.0) / 10.0 ),
273 wxOK | wxICON_EXCLAMATION );
279 XO(
"The 'Time Resolution' is too long for the selection.\n\n"
280 "Try increasing the audio selection to at least %.1f seconds,\n"
281 "or reducing the 'Time Resolution' to less than %.1f seconds.")
283 (minDuration / track->
GetRate()) + 0.05,
284 floor(maxTimeRes * 10.0) / 10.0),
285 wxOK | wxICON_EXCLAMATION );
292 auto dlen = len.as_double();
293 double adjust_amount = dlen /
294 (dlen - ((double)stretch_buf_size * 2.0));
295 amount = 1.0 + (amount - 1.0) * adjust_amount;
308 Floats buffer0{ bufsize };
309 float *bufferptr0 = buffer0.get();
310 bool first_time =
true;
312 const auto fade_len = std::min<size_t>(100, bufsize / 2 - 1);
313 bool cancelled =
false;
316 Floats fade_track_smps{ fade_len };
320 track->
GetFloats(bufferptr0, start + s, nget);
321 stretch.
process(buffer0.get(), nget);
324 stretch.
process(buffer0.get(), 0);
330 track->
GetFloats(fade_track_smps.get(), start, fade_len);
332 for (
size_t i = 0; i < fade_len; i++){
333 float fi = (float)i / (
float)fade_len;
335 stretch.
out_buf[i] * fi + (1.0 - fi) * fade_track_smps[i];
339 track->
GetFloats(fade_track_smps.get(),
end - fade_len, fade_len);
340 for (
size_t i = 0; i < fade_len; i++){
341 float fi = (float)i / (
float)fade_len;
342 auto i2 = bufsize / 2 - 1 - i;
344 stretch.
out_buf[i2] * fi + (1.0 - fi) *
345 fade_track_smps[fade_len - 1 - i];
353 s.as_double() / len.as_double()
362 outputTrack->Flush();
365 track->
Paste(t0, outputTrack.get());
366 m_t1 =
mT0 + outputTrack->GetEndTime();
371 catch (
const std::bad_alloc& ) {
381 : samplerate { samplerate_ }
382 , rap {
std::max(1.0f, rap_) }
383 , in_bufsize { in_bufsize_ }
384 , out_bufsize {
std::max(size_t{ 8 }, in_bufsize) }
385 , out_buf { out_bufsize }
386 , old_out_smp_buf { out_bufsize * 2, true }
387 , poolsize { in_bufsize_ * 2 }
388 , in_pool { poolsize, true }
389 , remained_samples { 0.0 }
390 , fft_smps { poolsize, true }
391 , fft_c { poolsize, true }
392 , fft_s { poolsize, true }
393 , fft_freq { poolsize, true }
394 , fft_tmp { poolsize }
405 if ((smps != NULL) && (nsmps != 0)) {
412 for (
int i = 0; i < nleft; i++)
416 for (
size_t i = 0; i < nsmps; i++)
421 for (
size_t i = 0; i <
poolsize; i++)
427 for (
size_t i = 0; i <
poolsize / 2; i++)
433 float inv_2p15_2pi = 1.0 / 16384.0 * (float)
M_PI;
434 for (
size_t i = 1; i <
poolsize / 2; i++) {
435 unsigned int random = (rand()) & 0x7fff;
436 float phase = random * inv_2p15_2pi;
449 float max = 0.0, max2 = 0.0;
450 for (
size_t i = 0; i <
poolsize; i++) {
451 max = std::max(max, fabsf(
fft_tmp[i]));
452 max2 = std::max(max2, fabsf(
fft_smps[i]));
458 float hinv_sqrt2 = 0.853553390593f;
460 float ampfactor = 1.0;
462 ampfactor =
rap * 0.707;
467 float a = (0.5 + 0.5 * cos(i * tmp));
470 out * (hinv_sqrt2 - (1.0 - hinv_sqrt2) * cos(i * 2.0 * tmp)) *
482 auto ri = (size_t)floor(r);
483 double rf = r - floor(r);
void WindowFunc(int whichFunction, size_t NumSamples, float *in)
void RealFFT(size_t NumSamples, const float *RealIn, float *RealOut, float *ImagOut)
void FFT(size_t NumSamples, bool InverseTransform, const float *RealIn, const float *ImagIn, float *RealOut, float *ImagOut)
Generates EffectParameterMethods overrides from variadic template arguments.
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
std::shared_ptr< TrackList > mOutputTracks
bool IsPreviewing() const
void ReplaceProcessedTracks(const bool bGoodResult)
void CopyInputTracks(bool allSyncLockSelected=false)
int MessageBox(const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={}) const
bool EnableApply(bool enable=true)
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Performs effect computation.
Interface for manipulations of an Effect's settings.
An Extreme Time Stretch and Time Smear effect.
std::unique_ptr< EffectUIValidator > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access) override
Add controls to effect panel; always succeeds.
static constexpr EffectParameter Time
const EffectParameterMethods & Parameters() const override
virtual ~EffectPaulstretch()
static const ComponentInterfaceSymbol Symbol
TranslatableString GetDescription() const override
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
double CalcPreviewInputLength(const EffectSettings &settings, double previewLength) const override
Default implementation returns previewLength
EffectType GetType() const override
Type determines how it behaves.
bool ProcessOne(WaveTrack *track, double t0, double t1, int count)
void OnText(wxCommandEvent &evt)
bool Process(EffectInstance &instance, EffectSettings &settings) override
Actually do the effect here.
size_t GetBufferSize(double rate) const
ComponentInterfaceSymbol GetSymbol() const override
static constexpr EffectParameter Amount
Class that helps EffectPaulStretch. It does the FFTs and inner loop of the effect.
void process(float *smps, size_t nsmps)
const Floats old_out_smp_buf
size_t get_nsamples_for_fill()
PaulStretch(float rap_, size_t in_bufsize_, float samplerate_)
void process_spectrum(float *WXUNUSED(freq))
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
Retrieve samples from a track in floating-point format, regardless of the storage format.
sampleCount TimeToLongSamples(double t0) const
Convert correctly between an (absolute) time in seconds and a number of samples.
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Holds a msgid for the translation catalog; may also bind format arguments.
A Track that contains audio waveform data.
void Paste(double t0, const Track *src) override
void Clear(double t0, double t1) override
double GetRate() const override
Holder EmptyCopy(const SampleBlockFactoryPtr &pFactory={}, bool keepLink=true) const
auto end(const Ptr< Type, BaseDeleter > &p)
Enables range-for.
BuiltinEffectsModule::Registration< EffectPaulstretch > reg
const Type min
Minimum value.
Externalized state of a plug-in.