28 static forcedinline
void pushInterpolationSample (
float* lastInputSamples,
float newValue)
noexcept
30 lastInputSamples[4] = lastInputSamples[3];
31 lastInputSamples[3] = lastInputSamples[2];
32 lastInputSamples[2] = lastInputSamples[1];
33 lastInputSamples[1] = lastInputSamples[0];
34 lastInputSamples[0] = newValue;
37 static forcedinline
void pushInterpolationSamples (
float* lastInputSamples,
const float* input,
int numOut)
noexcept
41 for (
int i = 0; i < 5; ++i)
42 lastInputSamples[i] = input[--numOut];
46 for (
int i = 0; i < numOut; ++i)
47 pushInterpolationSample (lastInputSamples, input[i]);
51 static forcedinline
void pushInterpolationSamples (
float* lastInputSamples,
const float* input,
52 int numOut,
int available,
int wrapAround)
noexcept
58 for (
int i = 0; i < 5; ++i)
59 lastInputSamples[i] = input[--numOut];
63 for (
int i = 0; i < available; ++i)
64 lastInputSamples[i] = input[--numOut];
70 for (
int i = available; i < 5; ++i)
71 lastInputSamples[i] = input[--numOut];
75 for (
int i = available; i < 5; ++i)
76 lastInputSamples[i] = 0.0f;
82 if (numOut > available)
84 for (
int i = 0; i < available; ++i)
85 pushInterpolationSample (lastInputSamples, input[i]);
89 for (
int i = 0; i < numOut - available; ++i)
90 pushInterpolationSample (lastInputSamples, input[i + available - wrapAround]);
94 for (
int i = 0; i < numOut - available; ++i)
95 pushInterpolationSample (lastInputSamples, 0);
100 for (
int i = 0; i < numOut; ++i)
101 pushInterpolationSample (lastInputSamples, input[i]);
106 template <
typename InterpolatorType>
107 static int interpolate (
float* lastInputSamples,
double& subSamplePos,
double actualRatio,
108 const float* in,
float* out,
int numOut)
noexcept
110 auto pos = subSamplePos;
112 if (actualRatio == 1.0 && pos == 1.0)
114 memcpy (out, in, (
size_t) numOut *
sizeof (
float));
115 pushInterpolationSamples (lastInputSamples, in, numOut);
125 pushInterpolationSample (lastInputSamples, in[numUsed++]);
129 *out++ = InterpolatorType::valueAtOffset (lastInputSamples, (
float) pos);
138 template <
typename InterpolatorType>
139 static int interpolate (
float* lastInputSamples,
double& subSamplePos,
double actualRatio,
140 const float* in,
float* out,
int numOut,
int available,
int wrap)
noexcept
142 if (actualRatio == 1.0)
144 if (available >= numOut)
146 memcpy (out, in, (
size_t) numOut *
sizeof (
float));
147 pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap);
151 memcpy (out, in, (
size_t) available *
sizeof (
float));
152 pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap);
156 memcpy (out + available, in + available - wrap, (
size_t) (numOut - available) *
sizeof (
float));
157 pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap);
161 for (
int i = 0; i < numOut - available; ++i)
162 pushInterpolationSample (lastInputSamples, 0);
169 auto originalIn = in;
170 auto pos = subSamplePos;
171 bool exceeded =
false;
173 if (actualRatio < 1.0)
175 for (
int i = numOut; --i >= 0;)
181 pushInterpolationSample (lastInputSamples, 0);
185 pushInterpolationSample (lastInputSamples, *in++);
187 if (--available <= 0)
204 *out++ = InterpolatorType::valueAtOffset (lastInputSamples, (
float) pos);
210 for (
int i = numOut; --i >= 0;)
212 while (pos < actualRatio)
216 pushInterpolationSample (lastInputSamples, 0);
220 pushInterpolationSample (lastInputSamples, *in++);
222 if (--available <= 0)
240 *out++ = InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (
float) pos));
247 return (
int) (in - originalIn);
249 return ((
int) (in - originalIn) + wrap) % wrap;
252 template <
typename InterpolatorType>
253 static int interpolateAdding (
float* lastInputSamples,
double& subSamplePos,
double actualRatio,
254 const float* in,
float* out,
int numOut,
255 int available,
int wrap,
float gain)
noexcept
257 if (actualRatio == 1.0)
259 if (available >= numOut)
262 pushInterpolationSamples (lastInputSamples, in, numOut, available, wrap);
267 pushInterpolationSamples (lastInputSamples, in, available, available, wrap);
272 pushInterpolationSamples (lastInputSamples, in - wrap, numOut - available, available, wrap);
276 for (
int i = 0; i < numOut-available; ++i)
277 pushInterpolationSample (lastInputSamples, 0.0);
284 auto originalIn = in;
285 auto pos = subSamplePos;
286 bool exceeded =
false;
288 if (actualRatio < 1.0)
290 for (
int i = numOut; --i >= 0;)
296 pushInterpolationSample (lastInputSamples, 0.0);
300 pushInterpolationSample (lastInputSamples, *in++);
302 if (--available <= 0)
319 *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (
float) pos);
325 for (
int i = numOut; --i >= 0;)
327 while (pos < actualRatio)
331 pushInterpolationSample (lastInputSamples, 0.0);
335 pushInterpolationSample (lastInputSamples, *in++);
337 if (--available <= 0)
355 *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, jmax (0.0f, 1.0f - (
float) pos));
362 return (
int) (in - originalIn);
364 return ((
int) (in - originalIn) + wrap) % wrap;
367 template <
typename InterpolatorType>
368 static int interpolateAdding (
float* lastInputSamples,
double& subSamplePos,
double actualRatio,
369 const float* in,
float* out,
int numOut,
float gain)
noexcept
371 auto pos = subSamplePos;
373 if (actualRatio == 1.0 && pos == 1.0)
376 pushInterpolationSamples (lastInputSamples, in, numOut);
386 pushInterpolationSample (lastInputSamples, in[numUsed++]);
390 *out++ += gain * InterpolatorType::valueAtOffset (lastInputSamples, (
float) pos);
402struct LagrangeResampleHelper
404 static forcedinline
void calc (
float& a,
float b)
noexcept { a *= b * (1.0f / k); }
408struct LagrangeResampleHelper<0>
410 static forcedinline
void calc (
float&,
float)
noexcept {}
413struct LagrangeAlgorithm
415 static forcedinline
float valueAtOffset (
const float* inputs,
float offset)
noexcept
417 return calcCoefficient<0> (inputs[4], offset)
418 + calcCoefficient<1> (inputs[3], offset)
419 + calcCoefficient<2> (inputs[2], offset)
420 + calcCoefficient<3> (inputs[1], offset)
421 + calcCoefficient<4> (inputs[0], offset);
425 static forcedinline
float calcCoefficient (
float input,
float offset)
noexcept
427 LagrangeResampleHelper<0 - k>::calc (input, -2.0f - offset);
428 LagrangeResampleHelper<1 - k>::calc (input, -1.0f - offset);
429 LagrangeResampleHelper<2 - k>::calc (input, 0.0f - offset);
430 LagrangeResampleHelper<3 - k>::calc (input, 1.0f - offset);
431 LagrangeResampleHelper<4 - k>::calc (input, 2.0f - offset);
436LagrangeInterpolator::LagrangeInterpolator() noexcept {
reset(); }
437LagrangeInterpolator::~LagrangeInterpolator() noexcept {}
443 for (
auto& s : lastInputSamples)
static void JUCE_CALLTYPE addWithMultiply(float *dest, const float *src, float multiplier, int numValues) noexcept
int processAdding(double speedRatio, const float *inputSamples, float *outputSamples, int numOutputSamplesToProduce, float gain) noexcept
int process(double speedRatio, const float *inputSamples, float *outputSamples, int numOutputSamplesToProduce) noexcept