40 PaulStretch(
float rap_,
size_t in_bufsize_,
float samplerate_);
44 void process(
float* smps,
size_t nsmps);
100 "Paulstretch is only for an extreme time-stretch or \"stasis\" effect");
105 return L
"Paulstretch";
139 for (
const auto track : outputs.Get().Selected<
WaveTrack>())
141 double trackStart = track->GetStartTime();
142 double trackEnd = track->GetEndTime();
143 double t0 =
mT0 < trackStart ? trackStart :
mT0;
144 double t1 =
mT1 > trackEnd ? trackEnd :
mT1;
147 auto tempTrack = track->EmptyCopy();
148 const auto channels = track->Channels();
149 auto iter = tempTrack->Channels().begin();
150 for (
const auto pChannel : channels)
152 if (!
ProcessOne(*pChannel, **iter++, t0, t1, count++))
156 newT1 = std::max(newT1,
mT0 + tempTrack->GetEndTime());
158 constexpr auto preserve =
false;
159 constexpr auto merge =
true;
160 track->ClearAndPaste(t0, t1, *tempTrack, preserve, merge, &warper);
163 count += track->NChannels();
167 outputs.Get().Any().Visit(
168 [&](
auto&& fallthrough) {
170 if (!track.IsSelected())
176 track.SyncLockAdjust(
mT1, newT1);
189 const auto badAllocMessage =
XO(
"Requested value exceeds memory capacity.");
193 if (stretch_buf_size == 0)
203 auto len =
end - start;
205 const auto minDuration = stretch_buf_size * 2 + 1;
206 if (minDuration < stretch_buf_size)
213 if (len < minDuration)
216 float maxTimeRes = log(len.as_double()) / log(2.0);
217 maxTimeRes = pow(2.0, floor(maxTimeRes) + 0.5);
218 maxTimeRes = maxTimeRes / rate;
223 double defaultPreviewLen;
225 wxT(
"/AudioIO/EffectsPreviewLen"), &defaultPreviewLen, 6.0);
232 XO(
"Audio selection too short to preview.\n\n"
233 "Try increasing the audio selection to at least %.1f seconds,\n"
234 "or reducing the 'Time Resolution' to less than %.1f seconds.")
236 (minDuration / rate) + 0.05,
237 floor(maxTimeRes * 10.0) / 10.0),
245 XO(
"Unable to Preview.\n\n"
246 "For the current audio selection, the maximum\n"
247 "'Time Resolution' is %.1f seconds.")
248 .
Format(floor(maxTimeRes * 10.0) / 10.0),
257 XO(
"The 'Time Resolution' is too long for the selection.\n\n"
258 "Try increasing the audio selection to at least %.1f seconds,\n"
259 "or reducing the 'Time Resolution' to less than %.1f seconds.")
261 (minDuration / rate) + 0.05,
262 floor(maxTimeRes * 10.0) / 10.0),
269 auto dlen = len.as_double();
270 double adjust_amount = dlen / (dlen - ((double)stretch_buf_size * 2.0));
271 amount = 1.0 + (amount - 1.0) * adjust_amount;
278 PaulStretch stretch(amount, stretch_buf_size, rate);
283 Floats buffer0 { bufsize };
284 float* bufferptr0 = buffer0.get();
285 bool first_time =
true;
287 const auto fade_len = std::min<size_t>(100, bufsize / 2 - 1);
288 bool cancelled =
false;
291 Floats fade_track_smps { fade_len };
296 track.
GetFloats(bufferptr0, start + s, nget);
297 stretch.
process(buffer0.get(), nget);
301 stretch.
process(buffer0.get(), 0);
308 track.
GetFloats(fade_track_smps.get(), start, fade_len);
310 for (
size_t i = 0; i < fade_len; i++)
312 float fi = (float)i / (
float)fade_len;
314 stretch.
out_buf[i] * fi + (1.0 - fi) * fade_track_smps[i];
319 track.
GetFloats(fade_track_smps.get(),
end - fade_len, fade_len);
320 for (
size_t i = 0; i < fade_len; i++)
322 float fi = (float)i / (
float)fade_len;
323 auto i2 = bufsize / 2 - 1 - i;
326 (1.0 - fi) * fade_track_smps[fade_len - 1 - i];
346 catch (
const std::bad_alloc&)
357 tmp = log(tmp) / log(2.0);
358 tmp = pow(2.0, floor(tmp + 0.5));
360 auto stmp = size_t(tmp);
364 if (stmp >= 2 * stmp)
368 return std::max<size_t>(stmp, 128);
374 : samplerate { samplerate_ }
375 , rap {
std::max(1.0f, rap_) }
376 , in_bufsize { in_bufsize_ }
377 , out_bufsize {
std::max(size_t { 8 }, in_bufsize) }
378 , out_buf { out_bufsize }
379 , old_out_smp_buf { out_bufsize * 2, true }
380 , poolsize { in_bufsize_ * 2 }
381 , in_pool { poolsize, true }
382 , remained_samples { 0.0 }
383 , fft_smps { poolsize, true }
384 , fft_c { poolsize, true }
385 , fft_s { poolsize, true }
386 , fft_freq { poolsize, true }
387 , fft_tmp { poolsize }
398 if ((smps != NULL) && (nsmps != 0))
407 for (
int i = 0; i < nleft; i++)
411 for (
size_t i = 0; i < nsmps; i++)
416 for (
size_t i = 0; i <
poolsize; i++)
422 for (
size_t i = 0; i <
poolsize / 2; i++)
427 float inv_2p15_2pi = 1.0 / 16384.0 * (float)
M_PI;
428 for (
size_t i = 1; i <
poolsize / 2; i++)
430 unsigned int random = (rand()) & 0x7fff;
431 float phase = random * inv_2p15_2pi;
445 float max = 0.0, max2 = 0.0;
446 for (
size_t i = 0; i <
poolsize; i++)
448 max = std::max(max, fabsf(
fft_tmp[i]));
449 max2 = std::max(max2, fabsf(
fft_smps[i]));
454 float hinv_sqrt2 = 0.853553390593f;
456 float ampfactor = 1.0;
458 ampfactor =
rap * 0.707;
464 float a = (0.5 + 0.5 * cos(i * tmp));
468 (hinv_sqrt2 - (1.0 - hinv_sqrt2) * cos(i * 2.0 * tmp)) *
480 auto ri = (size_t)floor(r);
481 double rf = r - floor(r);
Toolkit-neutral facade for basic user interface services.
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)
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
void SetLinearEffectFlag(bool linearEffectFlag)
std::shared_ptr< TrackList > mTracks
bool TrackProgress(int whichTrack, double frac, const TranslatableString &={}) const
Performs effect computation.
Use this object to copy the input tracks to tentative outputTracks.
Interface for manipulations of an Effect's settings.
virtual void Reset(Effect &effect) const =0
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))
TranslatableString GetDescription() const override
const EffectParameterMethods & Parameters() const override
bool ProcessOne(const WaveChannel &track, WaveChannel &outputTrack, double t0, double t1, int count)
EffectType GetType() const override
Type determines how it behaves.
ManualPageID ManualPage() const override
Name of a page in the Audacity alpha manual, default is empty.
bool Process(EffectInstance &instance, EffectSettings &settings) override
size_t GetBufferSize(double rate) const
double CalcPreviewInputLength(const EffectSettings &settings, double previewLength) const override
virtual ~PaulstretchBase()
static const ComponentInterfaceSymbol Symbol
ComponentInterfaceSymbol GetSymbol() const override
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
MessageBoxResult ShowMessageBox(const TranslatableString &message, MessageBoxOptions options={})
Show a modal message box with either Ok or Yes and No, and optionally Cancel.
const char * end(const char *str) noexcept
__finl float_x4 __vecc sqrt(const float_x4 &a)
MessageBoxOptions && IconStyle(Icon style) &&
Externalized state of a plug-in.