29#include "../widgets/valnum.h"
50 PaulStretch(
float rap_,
size_t in_bufsize_,
float samplerate_);
54 void process(
float *smps,
size_t nsmps);
99 Parameters().Reset(*
this);
101 SetLinearEffectFlag(
true);
117 return XO(
"Paulstretch is only for an extreme time-stretch or \"stasis\" effect");
122 return L
"Paulstretch";
155 for (
const auto track : outputs.Get().Selected<
WaveTrack>()) {
156 double trackStart = track->GetStartTime();
157 double trackEnd = track->GetEndTime();
158 double t0 =
mT0 < trackStart ? trackStart :
mT0;
159 double t1 =
mT1 > trackEnd ? trackEnd :
mT1;
161 auto tempTrack = track->EmptyCopy();
162 const auto channels = track->Channels();
163 auto iter = tempTrack->Channels().begin();
164 for (
const auto pChannel : channels) {
165 if (!
ProcessOne(*pChannel, **iter++, t0, t1, count++))
169 newT1 = std::max(newT1,
mT0 + tempTrack->GetEndTime());
171 constexpr auto preserve =
false;
172 constexpr auto merge =
true;
173 track->ClearAndPaste(t0, t1, *tempTrack, preserve, merge, &warper);
176 count += track->NChannels();
180 outputs.Get().Any().Visit(
181 [&](
auto &&fallthrough){
return [&](
WaveTrack &track) {
182 if (!track.IsSelected())
187 track.SyncLockAdjust(
mT1, newT1);
203 S.StartMultiColumn(2, wxALIGN_CENTER);
206 .Validator<FloatingPointValidator<float>>(
212 .AddTextBox(
XXO(
"&Stretch Factor:"),
wxT(
""), 10);
215 .Validator<FloatingPointValidator<float>>(
217 .AddTextBox(
XXO(
"&Time Resolution (seconds):"), L
"", 10);
255 tmp = log(tmp) / log(2.0);
256 tmp = pow(2.0, floor(tmp + 0.5));
258 auto stmp = size_t(tmp);
262 if (stmp >= 2 * stmp)
266 return std::max<size_t>(stmp, 128);
270 WaveChannel &outputTrack,
double t0,
double t1,
int count)
272 const auto badAllocMessage =
273 XO(
"Requested value exceeds memory capacity.");
277 if (stretch_buf_size == 0) {
286 auto len =
end - start;
288 const auto minDuration = stretch_buf_size * 2 + 1;
289 if (minDuration < stretch_buf_size) {
295 if (len < minDuration) {
297 float maxTimeRes = log( len.as_double() ) / log(2.0);
298 maxTimeRes = pow(2.0, floor(maxTimeRes) + 0.5);
299 maxTimeRes = maxTimeRes / rate;
302 double defaultPreviewLen;
303 gPrefs->
Read(
wxT(
"/AudioIO/EffectsPreviewLen"), &defaultPreviewLen, 6.0);
308 XO(
"Audio selection too short to preview.\n\n"
309 "Try increasing the audio selection to at least %.1f seconds,\n"
310 "or reducing the 'Time Resolution' to less than %.1f seconds.")
312 (minDuration / rate) + 0.05,
313 floor(maxTimeRes * 10.0) / 10.0),
314 wxOK | wxICON_EXCLAMATION );
319 XO(
"Unable to Preview.\n\n"
320 "For the current audio selection, the maximum\n"
321 "'Time Resolution' is %.1f seconds.")
322 .
Format( floor(maxTimeRes * 10.0) / 10.0 ),
323 wxOK | wxICON_EXCLAMATION );
329 XO(
"The 'Time Resolution' is too long for the selection.\n\n"
330 "Try increasing the audio selection to at least %.1f seconds,\n"
331 "or reducing the 'Time Resolution' to less than %.1f seconds.")
333 (minDuration / rate) + 0.05,
334 floor(maxTimeRes * 10.0) / 10.0),
335 wxOK | wxICON_EXCLAMATION );
341 auto dlen = len.as_double();
342 double adjust_amount = dlen /
343 (dlen - ((double)stretch_buf_size * 2.0));
344 amount = 1.0 + (amount - 1.0) * adjust_amount;
350 PaulStretch stretch(amount, stretch_buf_size, rate);
355 Floats buffer0{ bufsize };
356 float *bufferptr0 = buffer0.get();
357 bool first_time =
true;
359 const auto fade_len = std::min<size_t>(100, bufsize / 2 - 1);
360 bool cancelled =
false;
363 Floats fade_track_smps{ fade_len };
367 track.
GetFloats(bufferptr0, start + s, nget);
368 stretch.
process(buffer0.get(), nget);
371 stretch.
process(buffer0.get(), 0);
377 track.
GetFloats(fade_track_smps.get(), start, fade_len);
379 for (
size_t i = 0; i < fade_len; i++){
380 float fi = (float)i / (
float)fade_len;
382 stretch.
out_buf[i] * fi + (1.0 - fi) * fade_track_smps[i];
386 track.
GetFloats(fade_track_smps.get(),
end - fade_len, fade_len);
387 for (
size_t i = 0; i < fade_len; i++){
388 float fi = (float)i / (
float)fade_len;
389 auto i2 = bufsize / 2 - 1 - i;
391 stretch.
out_buf[i2] * fi + (1.0 - fi) *
392 fade_track_smps[fade_len - 1 - i];
400 s.as_double() / len.as_double()
411 catch (
const std::bad_alloc& ) {
421 : samplerate { samplerate_ }
422 , rap {
std::max(1.0f, rap_) }
423 , in_bufsize { in_bufsize_ }
424 , out_bufsize {
std::max(size_t{ 8 }, in_bufsize) }
425 , out_buf { out_bufsize }
426 , old_out_smp_buf { out_bufsize * 2, true }
427 , poolsize { in_bufsize_ * 2 }
428 , in_pool { poolsize, true }
429 , remained_samples { 0.0 }
430 , fft_smps { poolsize, true }
431 , fft_c { poolsize, true }
432 , fft_s { poolsize, true }
433 , fft_freq { poolsize, true }
434 , fft_tmp { poolsize }
445 if ((smps != NULL) && (nsmps != 0)) {
452 for (
int i = 0; i < nleft; i++)
456 for (
size_t i = 0; i < nsmps; i++)
461 for (
size_t i = 0; i <
poolsize; i++)
467 for (
size_t i = 0; i <
poolsize / 2; i++)
473 float inv_2p15_2pi = 1.0 / 16384.0 * (float)
M_PI;
474 for (
size_t i = 1; i <
poolsize / 2; i++) {
475 unsigned int random = (rand()) & 0x7fff;
476 float phase = random * inv_2p15_2pi;
489 float max = 0.0, max2 = 0.0;
490 for (
size_t i = 0; i <
poolsize; i++) {
491 max = std::max(max, fabsf(
fft_tmp[i]));
492 max2 = std::max(max2, fabsf(
fft_smps[i]));
498 float hinv_sqrt2 = 0.853553390593f;
500 float ampfactor = 1.0;
502 ampfactor =
rap * 0.707;
507 float a = (0.5 + 0.5 * cos(i * tmp));
510 out * (hinv_sqrt2 - (1.0 - hinv_sqrt2) * cos(i * 2.0 * tmp)) *
522 auto ri = (size_t)floor(r);
523 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")
audacity::BasicSettings * gPrefs
Contains declarations for TimeWarper, IdentityTimeWarper, ShiftTimeWarper, LinearTimeWarper,...
Generates EffectParameterMethods overrides from variadic template arguments.
ComponentInterfaceSymbol pairs a persistent string identifier used internally with an optional,...
bool IsPreviewing() const
std::shared_ptr< TrackList > mTracks
static bool EnableApply(wxWindow *parent, bool enable=true)
Enable or disable the Apply button of the dialog that contains parent.
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Performs effect computation.
Use this object to copy the input tracks to tentative outputTracks.
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 ProcessOne(const WaveChannel &track, WaveChannel &outputTrack, double t0, double t1, int count)
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
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={})
Unit slope but with either a jump (pasting more) or a flat interval (pasting less)
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))
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
static bool IsSyncLockSelected(const Track &track)
Abstract base class for an object holding data associated with points on a time axis.
Holds a msgid for the translation catalog; may also bind format arguments.
bool Append(constSamplePtr buffer, sampleFormat format, size_t len)
bool GetFloats(float *buffer, sampleCount start, size_t len, fillFormat fill=FillFormat::fillZero, bool mayThrow=true, sampleCount *pNumWithinClips=nullptr) const
"narrow" overload fetches from the unique channel
A Track that contains audio waveform data.
double GetRate() const override
sampleCount TimeToLongSamples(double t0) const
virtual bool Read(const wxString &key, bool *value) const =0
BuiltinEffectsModule::Registration< EffectPaulstretch > reg
const char * end(const char *str) noexcept
__finl float_x4 __vecc sqrt(const float_x4 &a)
const Type min
Minimum value.
Externalized state of a plug-in.