28#include "../widgets/valnum.h"
47 PaulStretch(
float rap_,
size_t in_bufsize_,
float samplerate_);
51 void process(
float *smps,
size_t nsmps);
96 Parameters().Reset(*
this);
98 SetLinearEffectFlag(
true);
114 return XO(
"Paulstretch is only for an extreme time-stretch or \"stasis\" effect");
119 return L
"Paulstretch";
151 double trackStart = track->GetStartTime();
152 double trackEnd = track->GetEndTime();
153 double t0 =
mT0 < trackStart? trackStart:
mT0;
154 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);
228 tmp = log(tmp) / log(2.0);
229 tmp = pow(2.0, floor(tmp + 0.5));
231 auto stmp = size_t(tmp);
235 if (stmp >= 2 * stmp)
239 return std::max<size_t>(stmp, 128);
244 const auto badAllocMessage =
245 XO(
"Requested value exceeds memory capacity.");
248 if (stretch_buf_size == 0) {
257 auto len =
end - start;
259 const auto minDuration = stretch_buf_size * 2 + 1;
260 if (minDuration < stretch_buf_size) {
266 if (len < minDuration) {
268 float maxTimeRes = log( len.as_double() ) / log(2.0);
269 maxTimeRes = pow(2.0, floor(maxTimeRes) + 0.5);
270 maxTimeRes = maxTimeRes / track->
GetRate();
273 double defaultPreviewLen;
274 gPrefs->Read(
wxT(
"/AudioIO/EffectsPreviewLen"), &defaultPreviewLen, 6.0);
279 XO(
"Audio selection too short to preview.\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 );
290 XO(
"Unable to Preview.\n\n"
291 "For the current audio selection, the maximum\n"
292 "'Time Resolution' is %.1f seconds.")
293 .
Format( floor(maxTimeRes * 10.0) / 10.0 ),
294 wxOK | wxICON_EXCLAMATION );
300 XO(
"The 'Time Resolution' is too long for the selection.\n\n"
301 "Try increasing the audio selection to at least %.1f seconds,\n"
302 "or reducing the 'Time Resolution' to less than %.1f seconds.")
304 (minDuration / track->
GetRate()) + 0.05,
305 floor(maxTimeRes * 10.0) / 10.0),
306 wxOK | wxICON_EXCLAMATION );
313 auto dlen = len.as_double();
314 double adjust_amount = dlen /
315 (dlen - ((double)stretch_buf_size * 2.0));
316 amount = 1.0 + (amount - 1.0) * adjust_amount;
329 Floats buffer0{ bufsize };
330 float *bufferptr0 = buffer0.get();
331 bool first_time =
true;
333 const auto fade_len = std::min<size_t>(100, bufsize / 2 - 1);
334 bool cancelled =
false;
337 Floats fade_track_smps{ fade_len };
341 track->
GetFloats(bufferptr0, start + s, nget);
342 stretch.
process(buffer0.get(), nget);
345 stretch.
process(buffer0.get(), 0);
351 track->
GetFloats(fade_track_smps.get(), start, fade_len);
353 for (
size_t i = 0; i < fade_len; i++){
354 float fi = (float)i / (
float)fade_len;
356 stretch.
out_buf[i] * fi + (1.0 - fi) * fade_track_smps[i];
360 track->
GetFloats(fade_track_smps.get(),
end - fade_len, fade_len);
361 for (
size_t i = 0; i < fade_len; i++){
362 float fi = (float)i / (
float)fade_len;
363 auto i2 = bufsize / 2 - 1 - i;
365 stretch.
out_buf[i2] * fi + (1.0 - fi) *
366 fade_track_smps[fade_len - 1 - i];
374 s.as_double() / len.as_double()
383 outputTrack->Flush();
386 track->
Paste(t0, outputTrack.get());
387 m_t1 =
mT0 + outputTrack->GetEndTime();
392 catch (
const std::bad_alloc& ) {
402 : samplerate { samplerate_ }
403 , rap {
std::max(1.0f, rap_) }
404 , in_bufsize { in_bufsize_ }
405 , out_bufsize {
std::max(size_t{ 8 }, in_bufsize) }
406 , out_buf { out_bufsize }
407 , old_out_smp_buf { out_bufsize * 2, true }
408 , poolsize { in_bufsize_ * 2 }
409 , in_pool { poolsize, true }
410 , remained_samples { 0.0 }
411 , fft_smps { poolsize, true }
412 , fft_c { poolsize, true }
413 , fft_s { poolsize, true }
414 , fft_freq { poolsize, true }
415 , fft_tmp { poolsize }
426 if ((smps != NULL) && (nsmps != 0)) {
433 for (
int i = 0; i < nleft; i++)
437 for (
size_t i = 0; i < nsmps; i++)
442 for (
size_t i = 0; i <
poolsize; i++)
448 for (
size_t i = 0; i <
poolsize / 2; i++)
454 float inv_2p15_2pi = 1.0 / 16384.0 * (float)
M_PI;
455 for (
size_t i = 1; i <
poolsize / 2; i++) {
456 unsigned int random = (rand()) & 0x7fff;
457 float phase = random * inv_2p15_2pi;
470 float max = 0.0, max2 = 0.0;
471 for (
size_t i = 0; i <
poolsize; i++) {
472 max = std::max(max, fabsf(
fft_tmp[i]));
473 max2 = std::max(max2, fabsf(
fft_smps[i]));
479 float hinv_sqrt2 = 0.853553390593f;
481 float ampfactor = 1.0;
483 ampfactor =
rap * 0.707;
488 float a = (0.5 + 0.5 * cos(i * tmp));
491 out * (hinv_sqrt2 - (1.0 - hinv_sqrt2) * cos(i * 2.0 * tmp)) *
503 auto ri = (size_t)floor(r);
504 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)
XXO("&Cut/Copy/Paste Toolbar")
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)
static bool EnableApply(wxWindow *parent, bool enable=true)
Enable or disable the Apply button of the dialog that contains parent.
void CopyInputTracks(bool allSyncLockSelected=false)
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Performs effect computation.
Hold values to send to effect output meters.
Interface for manipulations of an Effect's settings.
An Extreme Time Stretch and Time Smear effect.
bool TransferDataToWindow(const EffectSettings &settings) override
static constexpr EffectParameter Time
const EffectParameterMethods & Parameters() const override
virtual ~EffectPaulstretch()
bool TransferDataFromWindow(EffectSettings &settings) override
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
EffectType GetType() const override
Type determines how it behaves.
wxWeakRef< wxWindow > mUIParent
bool ProcessOne(WaveTrack *track, double t0, double t1, int count)
std::unique_ptr< EffectEditor > PopulateOrExchange(ShuttleGui &S, EffectInstance &instance, EffectSettingsAccess &access, const EffectOutputs *pOutputs) override
Add controls to effect panel; always succeeds.
void OnText(wxCommandEvent &evt)
bool Process(EffectInstance &instance, EffectSettings &settings) override
size_t GetBufferSize(double rate) const
ComponentInterfaceSymbol GetSymbol() const override
static constexpr EffectParameter Amount
static int DoMessageBox(const EffectPlugin &plugin, const TranslatableString &message, long style=DefaultMessageBoxStyle, const TranslatableString &titleStr={})
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.