int interpolate()

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;
  }