comparison data/model/test/TestFFTModel.h @ 1088:5fab8e4f5f19

Start making the FFT model tests into proper tests
author Chris Cannam
date Fri, 12 Jun 2015 12:41:19 +0100
parents 9f4505ac9072
children 655cd4e68e9a 1517d4c60e88
comparison
equal deleted inserted replaced
1087:dcf54a6964d0 1088:5fab8e4f5f19
24 #include <QObject> 24 #include <QObject>
25 #include <QtTest> 25 #include <QtTest>
26 #include <QDir> 26 #include <QDir>
27 27
28 #include <iostream> 28 #include <iostream>
29 #include <complex>
29 30
30 using namespace std; 31 using namespace std;
31 32
32 class TestFFTModel : public QObject 33 class TestFFTModel : public QObject
33 { 34 {
34 Q_OBJECT 35 Q_OBJECT
35 36
37 private:
38 void test(DenseTimeValueModel *model,
39 WindowType window, int windowSize, int windowIncrement, int fftSize,
40 int columnNo, vector<vector<complex<float>>> expectedValues,
41 int expectedWidth) {
42 for (int ch = 0; in_range_for(expectedValues, ch); ++ch) {
43 for (int polar = 0; polar <= 1; ++polar) {
44 FFTModel fftm(model, ch, window, windowSize, windowIncrement,
45 fftSize, bool(polar));
46 QCOMPARE(fftm.getWidth(), expectedWidth);
47 int hs1 = fftSize/2 + 1;
48 QCOMPARE(fftm.getHeight(), hs1);
49 vector<float> reals(hs1 + 1, 0.f);
50 vector<float> imags(hs1 + 1, 0.f);
51 reals[hs1] = 999.f; // overrun guards
52 imags[hs1] = 999.f;
53 fftm.getValuesAt(columnNo, &reals[0], &imags[0]);
54 for (int i = 0; i < hs1; ++i) {
55 float eRe = expectedValues[ch][i].real();
56 float eIm = expectedValues[ch][i].imag();
57 if (reals[i] != eRe || imags[i] != eIm) {
58 cerr << "ERROR: output is not as expected for column "
59 << i << " in channel " << ch << " (polar store = "
60 << polar << ")" << endl;
61 cerr << "expected : ";
62 for (int j = 0; j < hs1; ++j) {
63 cerr << expectedValues[ch][j] << " ";
64 }
65 cerr << "\nactual : ";
66 for (int j = 0; j < hs1; ++j) {
67 cerr << complex<float>(reals[j], imags[j]) << " ";
68 }
69 cerr << endl;
70 }
71 QCOMPARE(reals[i], eRe);
72 QCOMPARE(imags[i], eIm);
73 }
74 QCOMPARE(reals[hs1], 999.f);
75 QCOMPARE(imags[hs1], 999.f);
76 }
77 }
78 }
79
36 private slots: 80 private slots:
37 81
38 void example() { 82 // NB. FFTModel columns are centred on the sample frame, and in
39 MockWaveModel mwm({ DC }, 16); 83 // particular this means column 0 is centred at sample 0 (i.e. it
40 FFTModel fftm(&mwm, 0, RectangularWindow, 8, 8, 8, false); 84 // contains only half the window-size worth of real samples, the
41 float reals[6], imags[6]; 85 // others are 0-valued from before the origin). Generally in
42 reals[5] = 999.f; // overrun guards 86 // these tests we are padding our signal with half a window of
43 imags[5] = 999.f; 87 // zeros, in order that the result for column 0 is all zeros
44 fftm.getValuesAt(0, reals, imags); 88 // (rather than something with a step in it that is harder to
45 cerr << "reals: " << reals[0] << "," << reals[1] << "," << reals[2] << "," << reals[3] << "," << reals[4] << endl; 89 // reason about the FFT of) and the results for subsequent columns
46 cerr << "imags: " << imags[0] << "," << imags[1] << "," << imags[2] << "," << imags[3] << "," << imags[4] << endl; 90 // are those of our expected signal.
47 QCOMPARE(reals[0], 4.f); // rectangular window scales by 0.5 91
48 QCOMPARE(reals[1], 0.f); 92 void dc_simple_rect() {
49 QCOMPARE(reals[2], 0.f); 93 MockWaveModel mwm({ DC }, 16, 4);
50 QCOMPARE(reals[3], 0.f); 94 test(&mwm, RectangularWindow, 8, 8, 8, 0,
51 QCOMPARE(reals[4], 0.f); 95 { { {}, {}, {}, {}, {} } }, 4);
52 QCOMPARE(reals[5], 999.f); 96 test(&mwm, RectangularWindow, 8, 8, 8, 1,
53 QCOMPARE(imags[5], 999.f); 97 { { { 4.f, 0.f }, {}, {}, {}, {} } }, 4);
54 imags[5] = 0.f; 98 test(&mwm, RectangularWindow, 8, 8, 8, 2,
55 COMPARE_ALL_TO_F(imags, 0.f); 99 { { { 4.f, 0.f }, {}, {}, {}, {} } }, 4);
100 test(&mwm, RectangularWindow, 8, 8, 8, 3,
101 { { { }, {}, {}, {}, {} } }, 4);
102 }
103
104 void dc_simple_hann() {
105 // The Hann window function is a simple sinusoid with period
106 // equal to twice the window size, and it halves the DC energy
107 MockWaveModel mwm({ DC }, 16, 4);
108 test(&mwm, HanningWindow, 8, 8, 8, 0,
109 { { {}, {}, {}, {}, {} } }, 4);
110 test(&mwm, HanningWindow, 8, 8, 8, 1,
111 { { { 4.f, 0.f }, { 2.f, 0.f }, {}, {}, {} } }, 4);
112 test(&mwm, HanningWindow, 8, 8, 8, 2,
113 { { { 4.f, 0.f }, { 2.f, 0.f }, {}, {}, {} } }, 4);
114 test(&mwm, HanningWindow, 8, 8, 8, 3,
115 { { { }, {}, {}, {}, {} } }, 4);
56 } 116 }
57 117
58 }; 118 };
59 119
60 #endif 120 #endif