comparison tests/TestPhaseVocoder.cpp @ 342:c6e2a313d153

A more difficult test
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 02 Oct 2013 18:21:57 +0100
parents c99d83236f0d
children 2020c73dc997
comparison
equal deleted inserted replaced
341:92e38bbf4099 342:c6e2a313d153
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