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.

55 lines
1.8KB

  1. #pragma once
  2. #include "BiquadParams.h"
  3. #include "BiquadState.h"
  4. #include "BiquadFilter.h"
  5. #include "ObjectCache.h"
  6. /**
  7. * Inverse of the IIRDecimator.
  8. * takes a single sample at a lower sample rate, and converts it
  9. * to a buffer of data at the higher sample rate
  10. */
  11. class IIRUpsampler
  12. {
  13. public:
  14. /**
  15. * Will set the oversample factor, and set the filter cutoff.
  16. * Normalized cutoff is fixed at 1 / 4 * oversample, so that
  17. * much of the upper octave will be filtered out before upsampling.
  18. */
  19. void setup(int oversampleFactor)
  20. {
  21. oversample = oversampleFactor;
  22. params = ObjectCache<float>::get6PLPParams(1.f / (4.0f * oversample));
  23. }
  24. /**
  25. * processes one sample of input. Output is a buffer of data at the
  26. * higher sample rate. Buffer size is just the oversample amount.
  27. *
  28. * We are going to "zero" pack our data. For example, if input is [a, b],
  29. * and oversample is 4, then we would first zero pack like so:
  30. * [a, 0, 0, 0, b, 0, 0, 0]. Then we filter the results. Again, this is correct -
  31. * repeating the data like [a, a, a, a, b, b, b, b] would give a slight roll-off that
  32. * we don't want.
  33. */
  34. void process(float * outputBuffer, float input)
  35. {
  36. // The zero packing reduced the overall volume. To preserve the volume,
  37. // multiply be the reduction amount, which is oversample.
  38. input *= oversample;
  39. for (int i = 0; i < oversample; ++i) {
  40. outputBuffer[i] = BiquadFilter<float>::run(input, state, *params);
  41. input = 0; // just filter a delta - don't average the whole signal (i.e. zero pack)
  42. }
  43. }
  44. private:
  45. int oversample = 16;
  46. std::shared_ptr<BiquadParams<float, 3>> params;
  47. BiquadState<float, 3> state;
  48. };