42 static auto processReplacingCallback()
44 return [] (
auto,
auto newValue) {
return newValue; };
47 static auto processAddingCallback (
float gain)
49 return [gain] (
auto oldValue,
auto newValue) {
return oldValue + gain * newValue; };
65 return InterpolatorTraits::algorithmicLatency;
76 std::fill (std::begin (lastInputSamples), std::end (lastInputSamples), 0.0f);
98 processReplacingCallback());
129 processReplacingCallback());
157 processAddingCallback (gain));
194 processAddingCallback (gain));
199 forcedinline
void pushInterpolationSample (
float newValue)
noexcept
201 lastInputSamples[indexBuffer] = newValue;
207 forcedinline
void pushInterpolationSamples (
const float* input,
208 int numOutputSamplesToProduce)
noexcept
210 if (numOutputSamplesToProduce >= memorySize)
212 const auto*
const offsetInput = input + (numOutputSamplesToProduce - memorySize);
214 for (
int i = 0; i < memorySize; ++i)
215 pushInterpolationSample (offsetInput[i]);
219 for (
int i = 0; i < numOutputSamplesToProduce; ++i)
220 pushInterpolationSample (input[i]);
224 forcedinline
void pushInterpolationSamples (
const float* input,
225 int numOutputSamplesToProduce,
226 int numInputSamplesAvailable,
227 int wrapAround)
noexcept
229 if (numOutputSamplesToProduce >= memorySize)
231 if (numInputSamplesAvailable >= memorySize)
233 pushInterpolationSamples (input,
234 numOutputSamplesToProduce);
238 pushInterpolationSamples (input + ((numOutputSamplesToProduce - numInputSamplesAvailable) - 1),
239 numInputSamplesAvailable);
243 numOutputSamplesToProduce -= wrapAround;
245 pushInterpolationSamples (input + ((numOutputSamplesToProduce - (memorySize - numInputSamplesAvailable)) - 1),
246 memorySize - numInputSamplesAvailable);
250 for (
int i = numInputSamplesAvailable; i < memorySize; ++i)
251 pushInterpolationSample (0.0f);
257 if (numOutputSamplesToProduce > numInputSamplesAvailable)
259 for (
int i = 0; i < numInputSamplesAvailable; ++i)
260 pushInterpolationSample (input[i]);
262 const auto extraSamples = numOutputSamplesToProduce - numInputSamplesAvailable;
266 const auto*
const offsetInput = input + (numInputSamplesAvailable - wrapAround);
268 for (
int i = 0; i < extraSamples; ++i)
269 pushInterpolationSample (offsetInput[i]);
273 for (
int i = 0; i < extraSamples; ++i)
274 pushInterpolationSample (0.0f);
279 for (
int i = 0; i < numOutputSamplesToProduce; ++i)
280 pushInterpolationSample (input[i]);
286 template <
typename Process>
287 int interpolateImpl (
double speedRatio,
290 int numOutputSamplesToProduce,
291 int numInputSamplesAvailable,
295 auto originalIn = input;
296 bool exceeded =
false;
298 const auto pushSample = [&]
302 pushInterpolationSample (0.0);
306 pushInterpolationSample (*input++);
308 if (--numInputSamplesAvailable <= 0)
313 numInputSamplesAvailable += wrap;
323 interpolateImpl (speedRatio,
325 numOutputSamplesToProduce,
330 return (
int) (input - originalIn);
332 return ((
int) (input - originalIn) + wrap) % wrap;
335 template <
typename Process>
336 int interpolateImpl (
double speedRatio,
339 int numOutputSamplesToProduce,
344 interpolateImpl (speedRatio,
346 numOutputSamplesToProduce,
348 [
this, input, &numUsed] { pushInterpolationSample (input[numUsed++]); });
353 template <
typename Process,
typename PushSample>
354 void interpolateImpl (
double speedRatio,
356 int numOutputSamplesToProduce,
358 PushSample pushSample)
360 auto pos = subSamplePos;
362 for (
auto i = 0; i < numOutputSamplesToProduce; ++i)
370 *output = process (*output, InterpolatorTraits::valueAtOffset (lastInputSamples, (
float) pos, indexBuffer));
379 float lastInputSamples[(size_t) memorySize];
380 double subSamplePos = 1.0;
383 JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (GenericInterpolator)