in pedalboard/juce_overrides/juce_FastWindowedSincInterpolators.h [239:318]
int interpolate(double speedRatio, const float *input, float *output,
int numOutputSamplesToProduce) noexcept {
auto pos = subSamplePos;
int numUsed = 0;
const float *lookupTablePointer = lookupTable->data();
// Pre-compute the sinc interpolation tables if possible:
if (cachedSincValueTables.empty()) {
static constexpr int MAX_CACHED_SINC_TABLES = 64;
double tempPos = pos;
std::map<double, int> offsetHistogram;
for (int i = 0; i < MAX_CACHED_SINC_TABLES; i++) {
while (tempPos >= 1.0) {
tempPos -= 1.0;
}
offsetHistogram[tempPos]++;
tempPos += speedRatio;
}
// Count the common offset values:
for (auto &pair : offsetHistogram) {
if (pair.second > 1) {
if (cachedSincValueTables.find({speedRatio, pair.first}) ==
cachedSincValueTables.end()) {
// We have a common offset value, so we can precompute the sinc
// table for this offset value:
cachedSincValueTables[{speedRatio, pair.first}] =
InterpolatorTraits::subsampleSincFilter(lookupTablePointer,
pair.first, speedRatio);
}
}
}
}
if (!cachedSincValueTables.empty()) {
while (numOutputSamplesToProduce > 0) {
while (pos >= 1.0) {
pushInterpolationSample(input[numUsed++]);
pos -= 1.0;
}
// Check if we have a cached sinc table and create one if necessary:
if (cachedSincValueTables.find({speedRatio, pos}) ==
cachedSincValueTables.end()) {
// This should not happen; we should have precomputed all sinc tables
// above. Create a new sinc table on the stack:
auto sincValues = InterpolatorTraits::subsampleSincFilter(
lookupTablePointer, (float)pos, speedRatio);
*output++ = InterpolatorTraits::valueAtOffset(
lastInputSamples, indexBuffer, speedRatio, sincValues);
} else {
const auto &sincValues = cachedSincValueTables[{speedRatio, pos}];
*output++ = InterpolatorTraits::valueAtOffset(
lastInputSamples, indexBuffer, speedRatio, sincValues);
}
pos += speedRatio;
--numOutputSamplesToProduce;
}
} else {
while (numOutputSamplesToProduce > 0) {
while (pos >= 1.0) {
pushInterpolationSample(input[numUsed++]);
pos -= 1.0;
}
auto sincValues = InterpolatorTraits::subsampleSincFilter(
lookupTablePointer, pos, speedRatio);
*output++ = InterpolatorTraits::valueAtOffset(
lastInputSamples, indexBuffer, speedRatio, sincValues);
pos += speedRatio;
--numOutputSamplesToProduce;
}
}
subSamplePos = pos;
return numUsed;
}