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.

102 lines
2.8KB

  1. #include "ButterworthLookup.h"
  2. #include "BiquadFilter.h"
  3. #include "BiquadState.h"
  4. #include "Analyzer.h"
  5. #include "FFT.h"
  6. #include "asserts.h"
  7. // test that the API does something
  8. static void testButterLookup0()
  9. {
  10. ButterworthLookup4PHP b;
  11. BiquadParams<float, 2> params;
  12. for (int i = 0; i < 10; ++i) {
  13. params.setAtIndex(0, i);
  14. }
  15. b.get(params, .1f);
  16. for (int i = 0; i < 10; ++i) {
  17. assert(params.getAtIndex(i) != 0);
  18. }
  19. }
  20. const float sampleRate = 44100;
  21. static void doHighTest(std::function<float(float)> filter, float Fc, float expectedSlope)
  22. {
  23. const int numSamples = 16 * 1024;
  24. FFTDataCpx response(numSamples);
  25. Analyzer::getFreqResponse(response, filter);
  26. auto x = Analyzer::getMaxAndShoulders(response, -3);
  27. printf("max and shoulders return %f, %f, %f\n",
  28. FFT::bin2Freq(std::get<0>(x), sampleRate, numSamples),
  29. FFT::bin2Freq(std::get<1>(x), sampleRate, numSamples),
  30. FFT::bin2Freq(std::get<2>(x), sampleRate, numSamples)
  31. );
  32. const double cutoff = FFT::bin2Freq(std::get<2>(x), sampleRate, numSamples);
  33. const float highestFreq = sampleRate / 2;
  34. const int highestBin = numSamples / 2;
  35. printf("highest freq = %f get0=%d get1=%d\n", highestFreq, std::get<0>(x), std::get<1>(x));
  36. /*
  37. test1
  38. max and shoulders return 99.591064, 21463.220215, -2.691650
  39. highest freq = 22050.000000 get0=37 get1=7974
  40. assertClose failed actual value =999.83 expected=1
  41. Assertion failed: false, file d:\vcvrack\x6\plugins\squinkyvcv\test\testbutterlookup.cpp, line 54
  42. * 0 = low freq bin #
  43. * 1 = peak bin #
  44. * 2 = high bin#
  45. */
  46. fflush(stdout);
  47. // Is the peak at zero? i.e. no ripple.
  48. if (std::get<1>(x) == highestFreq) {
  49. assertEQ(std::get<0>(x), -1); // no LF shoulder
  50. } else {
  51. // Some higher order filters have a tinny bit of ripple.
  52. // make sure that the peak is about the same as the extreme (in this case nyquist
  53. float peakMag = std::abs(response.get(std::get<1>(x)));
  54. float maxMag = std::abs(response.get(highestBin));
  55. assertClose(peakMag / maxMag, 1, .01);
  56. }
  57. assertClose(cutoff, Fc, 3); // 3db down at Fc
  58. double slope = Analyzer::getSlope(response, (float) Fc * 2, sampleRate);
  59. assertClose(slope, expectedSlope, 1); // to get accurate we need to go to higher freq, etc... this is fine
  60. }
  61. static void doHighTest(float fC)
  62. {
  63. ButterworthLookup4PHP b;
  64. BiquadParams<float, 2> params;
  65. BiquadState<float, 2> state;
  66. b.get(params, fC / sampleRate);
  67. auto filter = [&state, &params](float x) {
  68. return BiquadFilter<float>::run(x, state, params);
  69. };
  70. doHighTest(filter, fC, 24);
  71. }
  72. static void testButterLookup1()
  73. {
  74. printf("remove hi test\n");
  75. //doHighTest(100);
  76. }
  77. void testButterLookup()
  78. {
  79. testButterLookup0();
  80. //testButterLookup1();
  81. }