Mercurial > hg > qm-dsp
comparison tests/TestPhaseVocoder.cpp @ 117:7f5b96734c83 pvoc
A more difficult test
author | Chris Cannam |
---|---|
date | Wed, 02 Oct 2013 18:21:57 +0100 |
parents | f3c69325cca2 |
children | 2020c73dc997 |
comparison
equal
deleted
inserted
replaced
116:fac40444b8c3 | 117:7f5b96734c83 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
1 | 2 |
2 #include "dsp/phasevocoder/PhaseVocoder.h" | 3 #include "dsp/phasevocoder/PhaseVocoder.h" |
3 | 4 |
4 #include "base/Window.h" | 5 #include "base/Window.h" |
6 | |
7 #include <iostream> | |
8 | |
9 using std::cerr; | |
10 using std::endl; | |
5 | 11 |
6 #define BOOST_TEST_DYN_LINK | 12 #define BOOST_TEST_DYN_LINK |
7 #define BOOST_TEST_MAIN | 13 #define BOOST_TEST_MAIN |
8 | 14 |
9 #include <boost/test/unit_test.hpp> | 15 #include <boost/test/unit_test.hpp> |
10 | 16 |
11 BOOST_AUTO_TEST_SUITE(TestFFT) | 17 BOOST_AUTO_TEST_SUITE(TestFFT) |
12 | 18 |
13 #define COMPARE_CONST(a, n) \ | 19 #define COMPARE_CONST(a, n) \ |
14 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ | 20 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ |
15 BOOST_CHECK_SMALL(a[cmp_i] - n, 1e-14); \ | 21 BOOST_CHECK_SMALL(a[cmp_i] - n, 1e-7); \ |
16 } | 22 } |
17 | 23 |
18 #define COMPARE_ARRAY(a, b) \ | 24 #define COMPARE_ARRAY(a, b) \ |
19 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ | 25 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ |
20 BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-14); \ | 26 BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-7); \ |
21 } | 27 } |
22 | 28 |
23 #define COMPARE_ARRAY_EXACT(a, b) \ | 29 #define COMPARE_ARRAY_EXACT(a, b) \ |
24 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ | 30 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ |
25 BOOST_CHECK_EQUAL(a[cmp_i], b[cmp_i]); \ | 31 BOOST_CHECK_EQUAL(a[cmp_i], b[cmp_i]); \ |
64 COMPARE_ARRAY_EXACT(mag, magExpected1); | 70 COMPARE_ARRAY_EXACT(mag, magExpected1); |
65 | 71 |
66 double phaseExpected1[] = { 999, 0, 0, 0, 0, 0, 999 }; | 72 double phaseExpected1[] = { 999, 0, 0, 0, 0, 0, 999 }; |
67 COMPARE_ARRAY(phase, phaseExpected1); | 73 COMPARE_ARRAY(phase, phaseExpected1); |
68 | 74 |
69 // Derivation of values: | 75 // Derivation of unwrapped values: |
70 // | 76 // |
71 // * Bin 0 (DC) always has phase 0 and expected phase 0 | 77 // * Bin 0 (DC) always has phase 0 and expected phase 0 |
72 // | 78 // |
73 // * Bin 1 has expected phase pi (the hop size is half a cycle at | 79 // * Bin 1 has expected phase pi (the hop size is half a cycle at |
74 // its frequency), but measured phase 0 (because there is no | 80 // its frequency), but measured phase 0 (because there is no |
98 | 104 |
99 double unwExpected2[] = { 999, 0, 4*M_PI, 4*M_PI, 8*M_PI, 8*M_PI, 999 }; | 105 double unwExpected2[] = { 999, 0, 4*M_PI, 4*M_PI, 8*M_PI, 8*M_PI, 999 }; |
100 COMPARE_ARRAY(unw, unwExpected2); | 106 COMPARE_ARRAY(unw, unwExpected2); |
101 } | 107 } |
102 | 108 |
103 //!!! signal that starts mid-phase | 109 BOOST_AUTO_TEST_CASE(overlapping) |
110 { | |
111 // Sine (i.e. cosine starting at phase -pi/2) starting with the | |
112 // first sample, introducing a cosine of half the frequency | |
113 // starting at the fourth sample, i.e. the second hop. The cosine | |
114 // is introduced "by magic", i.e. it doesn't appear in the second | |
115 // half of the first frame (it would have quite strange effects on | |
116 // the first frame if it did). | |
104 | 117 |
118 double data[32] = { // 3 x 8-sample frames which we pretend are overlapping | |
119 0, 1, 0, -1, 0, 1, 0, -1, | |
120 1, 1.70710678, 0, -1.70710678, -1, 0.29289322, 0, -0.29289322, | |
121 -1, 0.29289322, 0, -0.29289322, 1, 1.70710678, 0, -1.70710678, | |
122 }; | |
123 | |
124 PhaseVocoder pvoc(8, 4); | |
125 | |
126 // Make these arrays one element too long at each end, so as to | |
127 // test for overruns. For frame size 8, we expect 8/2+1 = 5 | |
128 // mag/phase pairs. | |
129 double mag[] = { 999, 999, 999, 999, 999, 999, 999 }; | |
130 double phase[] = { 999, 999, 999, 999, 999, 999, 999 }; | |
131 double unw[] = { 999, 999, 999, 999, 999, 999, 999 }; | |
132 | |
133 cerr << "process 0" << endl; | |
134 | |
135 pvoc.process(data, mag + 1, phase + 1, unw + 1); | |
136 | |
137 double magExpected0[] = { 999, 0, 0, 4, 0, 0, 999 }; | |
138 COMPARE_ARRAY(mag, magExpected0); | |
139 | |
140 double phaseExpected0[] = { 999, 0, 0, -M_PI/2 , 0, 0, 999 }; | |
141 COMPARE_ARRAY(phase, phaseExpected0); | |
142 | |
143 double unwExpected0[] = { 999, 0, 0, -M_PI/2, 0, 0, 999 }; | |
144 COMPARE_ARRAY(unw, unwExpected0); | |
145 | |
146 cerr << "process 1" << endl; | |
147 | |
148 pvoc.process(data + 8, mag + 1, phase + 1, unw + 1); | |
149 | |
150 double magExpected1[] = { 999, 0, 4, 4, 0, 0, 999 }; | |
151 COMPARE_ARRAY(mag, magExpected1); | |
152 | |
153 //!!! I don't know why [2] here is -M_PI and not M_PI; and I definitely don't know why [4] here is M_PI. Check these with care | |
154 double phaseExpected1[] = { 999, 0, -M_PI, -M_PI/2, M_PI, 0, 999 }; | |
155 COMPARE_ARRAY(phase, phaseExpected1); | |
156 | |
157 double unwExpected1[] = { 999, 0, M_PI, 3*M_PI/2, 3*M_PI, 4*M_PI, 999 }; | |
158 COMPARE_ARRAY(unw, unwExpected1); | |
159 | |
160 cerr << "process 2" << endl; | |
161 | |
162 pvoc.process(data + 16, mag + 1, phase + 1, unw + 1); | |
163 | |
164 double magExpected2[] = { 999, 0, 4, 4, 0, 0, 999 }; | |
165 COMPARE_ARRAY(mag, magExpected2); | |
166 | |
167 double phaseExpected2[] = { 999, 0, 0, -M_PI/2, 0, 0, 999 }; | |
168 COMPARE_ARRAY(phase, phaseExpected2); | |
169 | |
170 double unwExpected2[] = { 999, 0, 2*M_PI, 7*M_PI/2, 6*M_PI, 8*M_PI, 999 }; | |
171 COMPARE_ARRAY(unw, unwExpected2); | |
172 } | |
105 | 173 |
106 BOOST_AUTO_TEST_SUITE_END() | 174 BOOST_AUTO_TEST_SUITE_END() |
107 | 175 |