You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

51 lines
1.0KB

  1. #pragma once
  2. #include <dsp/common.hpp>
  3. namespace rack {
  4. namespace dsp {
  5. /** Computes the minimum-phase bandlimited step (MinBLEP)
  6. z: number of zero-crossings
  7. o: oversample factor
  8. output: must be length `2 * z * o`.
  9. https://www.cs.cmu.edu/~eli/papers/icmc01-hardsync.pdf
  10. */
  11. void minBlepImpulse(int z, int o, float* output);
  12. template <int Z, int O, typename T = float>
  13. struct MinBlepGenerator {
  14. T buf[2 * Z] = {};
  15. int pos = 0;
  16. float impulse[2 * Z * O + 1];
  17. MinBlepGenerator() {
  18. minBlepImpulse(Z, O, impulse);
  19. impulse[2 * Z * O] = 1.f;
  20. }
  21. /** Places a discontinuity with magnitude `x` at -1 < p <= 0 relative to the current frame */
  22. void insertDiscontinuity(float p, T x) {
  23. if (!(-1 < p && p <= 0))
  24. return;
  25. for (int j = 0; j < 2 * Z; j++) {
  26. float minBlepIndex = ((float)j - p) * O;
  27. int index = (pos + j) % (2 * Z);
  28. buf[index] += x * (-1.f + math::interpolateLinear(impulse, minBlepIndex));
  29. }
  30. }
  31. T process() {
  32. T v = buf[pos];
  33. buf[pos] = T(0);
  34. pos = (pos + 1) % (2 * Z);
  35. return v;
  36. }
  37. };
  38. } // namespace dsp
  39. } // namespace rack