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.

101 lines
2.3KB

  1. #include <assert.h>
  2. #include <vector>
  3. #include "Analyzer.h"
  4. #include "asserts.h"
  5. #include "AudioMath.h"
  6. #include "FFTData.h"
  7. #include "SinOscillator.h"
  8. #include "MeasureTime.h"
  9. static void ana1()
  10. {
  11. FFTDataCpx x(2);
  12. x.set(0, cpx(float(AudioMath::gainFromDb(0)), 0));
  13. auto data = Analyzer::getFeatures(x, 3, 44100, -100);
  14. assert(data.size() == 1);
  15. assertClose(data[0].gainDb, 0, .0001);
  16. assertClose(data[0].freq, 0, .0001);
  17. }
  18. // test Analyzer::getFeatures with two bins of
  19. // very different gains
  20. static void ana2()
  21. {
  22. FFTDataCpx x(4);
  23. x.set(0, cpx(float(AudioMath::gainFromDb(0)), 0));
  24. x.set(1, cpx(float(AudioMath::gainFromDb(10)), 0));
  25. auto data = Analyzer::getFeatures(x, 3, 44100, -100);
  26. assert(data.size() == 2);
  27. assertClose(data[0].gainDb, 0, .0001);
  28. assertClose(data[0].freq, 0, .0001);
  29. assertClose(data[1].gainDb, 10, .0001);
  30. // bin 1 (last bin) is sr/2 ... sr
  31. assertClose(data[1].freq, 44100 / 4, .0001);
  32. }
  33. static void ana3()
  34. {
  35. const int size = 1024;
  36. std::vector<float> buffer(size);
  37. Analyzer::generateSweep(44100., buffer.data(), size, 20, 20000);
  38. auto minMax = AudioMath::getMinMax(buffer.data(), size);
  39. assertClose(minMax.first, -1, .01);
  40. assertClose(minMax.second, 1, .01);
  41. }
  42. static void ana7()
  43. {
  44. const int size = 64;
  45. FFTDataCpx x(size);
  46. std::function<float(float)> unity = [](float x) {
  47. return x;
  48. };
  49. Analyzer::getFreqResponse(x, unity);
  50. for (int i = 0; i < size / 2; ++i) {
  51. assertClose(std::abs(x.get(i)), 1, .0001);
  52. }
  53. }
  54. // test that we get a good spectrum from synchronous sin
  55. static void testSyncSin()
  56. {
  57. float desiredFreq = 500.0f;
  58. int numSamples = 16 * 1024;
  59. const float sampleRate = 44100.0f;
  60. const double actualFreq = Analyzer::makeEvenPeriod(desiredFreq, sampleRate, numSamples);
  61. SinOscillatorParams<float> sinParams;
  62. SinOscillatorState<float> sinState;
  63. SinOscillator<float, false>::setFrequency(sinParams, float(actualFreq / sampleRate));
  64. FFTDataCpx spectrum(numSamples);
  65. Analyzer::getSpectrum(spectrum, false, [&sinState, &sinParams]() {
  66. return SinOscillator<float, false>::run(sinState, sinParams);
  67. });
  68. Analyzer::assertSingleFreq(spectrum, float(actualFreq), sampleRate);
  69. }
  70. void testAnalyzer()
  71. {
  72. ana1();
  73. ana2();
  74. ana3();
  75. ana7();
  76. testSyncSin();
  77. }