comparison tests/TestPhaseVocoder.cpp @ 344:5eb9c2387108

Phase vocoder: provide time-domain and freq-domain inputs separately; update tests etc
author Chris Cannam <c.cannam@qmul.ac.uk>
date Thu, 03 Oct 2013 12:58:36 +0100
parents c6e2a313d153
children b0e98fcfacd7
comparison
equal deleted inserted replaced
343:24d8ea972643 344:5eb9c2387108
51 // mag/phase pairs. 51 // mag/phase pairs.
52 double mag[] = { 999, 999, 999, 999, 999, 999, 999 }; 52 double mag[] = { 999, 999, 999, 999, 999, 999, 999 };
53 double phase[] = { 999, 999, 999, 999, 999, 999, 999 }; 53 double phase[] = { 999, 999, 999, 999, 999, 999, 999 };
54 double unw[] = { 999, 999, 999, 999, 999, 999, 999 }; 54 double unw[] = { 999, 999, 999, 999, 999, 999, 999 };
55 55
56 pvoc.process(frame, mag + 1, phase + 1, unw + 1); 56 pvoc.processTimeDomain(frame, mag + 1, phase + 1, unw + 1);
57 57
58 double magExpected0[] = { 999, 0, 0, 4, 0, 0, 999 }; 58 double magExpected0[] = { 999, 0, 0, 4, 0, 0, 999 };
59 COMPARE_ARRAY_EXACT(mag, magExpected0); 59 COMPARE_ARRAY_EXACT(mag, magExpected0);
60 60
61 double phaseExpected0[] = { 999, 0, 0, 0, 0, 0, 999 }; 61 double phaseExpected0[] = { 999, 0, 0, 0, 0, 0, 999 };
62 COMPARE_ARRAY_EXACT(phase, phaseExpected0); 62 COMPARE_ARRAY(phase, phaseExpected0);
63 63
64 double unwExpected0[] = { 999, 0, 0, 0, 0, 0, 999 }; 64 double unwExpected0[] = { 999, 0, 0, 0, 0, 0, 999 };
65 COMPARE_ARRAY(unw, unwExpected0); 65 COMPARE_ARRAY(unw, unwExpected0);
66 66
67 pvoc.process(frame, mag + 1, phase + 1, unw + 1); 67 pvoc.processTimeDomain(frame, mag + 1, phase + 1, unw + 1);
68 68
69 double magExpected1[] = { 999, 0, 0, 4, 0, 0, 999 }; 69 double magExpected1[] = { 999, 0, 0, 4, 0, 0, 999 };
70 COMPARE_ARRAY_EXACT(mag, magExpected1); 70 COMPARE_ARRAY_EXACT(mag, magExpected1);
71 71
72 double phaseExpected1[] = { 999, 0, 0, 0, 0, 0, 999 }; 72 double phaseExpected1[] = { 999, 0, 0, 0, 0, 0, 999 };
80 // its frequency), but measured phase 0 (because there is no 80 // its frequency), but measured phase 0 (because there is no
81 // signal in that bin). So it has phase error -pi, which is 81 // signal in that bin). So it has phase error -pi, which is
82 // mapped into (-pi,pi] range as pi, giving an unwrapped phase 82 // mapped into (-pi,pi] range as pi, giving an unwrapped phase
83 // of 2*pi. 83 // of 2*pi.
84 // 84 //
85 // * Bin 2 has expected unwrapped phase 2*pi, measured phase 0, 85 // * Bin 2 has expected phase 2*pi, measured phase 0, hence error
86 // hence error 0 and unwrapped phase 2*pi. 86 // 0 and unwrapped phase 2*pi.
87 // 87 //
88 // * Bin 3 is like bin 1: it has expected phase 3*pi, measured 88 // * Bin 3 is like bin 1: it has expected phase 3*pi, measured
89 // phase 0, so phase error -pi and unwrapped phase 4*pi. 89 // phase 0, so phase error -pi and unwrapped phase 4*pi.
90 // 90 //
91 // * Bin 4 (Nyquist) is like bin 2: expected phase 4*pi, measured 91 // * Bin 4 (Nyquist) has expected phase 4*pi, measured phase 0,
92 // phase 0, hence error 0 and unwrapped phase 4*pi. 92 // hence error 0 and unwrapped phase 4*pi.
93 93
94 double unwExpected1[] = { 999, 0, 2*M_PI, 2*M_PI, 4*M_PI, 4*M_PI, 999 }; 94 double unwExpected1[] = { 999, 0, 2*M_PI, 2*M_PI, 4*M_PI, 4*M_PI, 999 };
95 COMPARE_ARRAY(unw, unwExpected1); 95 COMPARE_ARRAY(unw, unwExpected1);
96 96
97 pvoc.process(frame, mag + 1, phase + 1, unw + 1); 97 pvoc.processTimeDomain(frame, mag + 1, phase + 1, unw + 1);
98 98
99 double magExpected2[] = { 999, 0, 0, 4, 0, 0, 999 }; 99 double magExpected2[] = { 999, 0, 0, 4, 0, 0, 999 };
100 COMPARE_ARRAY_EXACT(mag, magExpected2); 100 COMPARE_ARRAY_EXACT(mag, magExpected2);
101 101
102 double phaseExpected2[] = { 999, 0, 0, 0, 0, 0, 999 }; 102 double phaseExpected2[] = { 999, 0, 0, 0, 0, 0, 999 };
128 // mag/phase pairs. 128 // mag/phase pairs.
129 double mag[] = { 999, 999, 999, 999, 999, 999, 999 }; 129 double mag[] = { 999, 999, 999, 999, 999, 999, 999 };
130 double phase[] = { 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 }; 131 double unw[] = { 999, 999, 999, 999, 999, 999, 999 };
132 132
133 cerr << "process 0" << endl; 133 pvoc.processTimeDomain(data, mag + 1, phase + 1, unw + 1);
134
135 pvoc.process(data, mag + 1, phase + 1, unw + 1);
136 134
137 double magExpected0[] = { 999, 0, 0, 4, 0, 0, 999 }; 135 double magExpected0[] = { 999, 0, 0, 4, 0, 0, 999 };
138 COMPARE_ARRAY(mag, magExpected0); 136 COMPARE_ARRAY(mag, magExpected0);
139 137
140 double phaseExpected0[] = { 999, 0, 0, -M_PI/2 , 0, 0, 999 }; 138 double phaseExpected0[] = { 999, 0, 0, -M_PI/2 , 0, 0, 999 };
141 COMPARE_ARRAY(phase, phaseExpected0); 139 COMPARE_ARRAY(phase, phaseExpected0);
142 140
143 double unwExpected0[] = { 999, 0, 0, -M_PI/2, 0, 0, 999 }; 141 double unwExpected0[] = { 999, 0, 0, -M_PI/2, 0, 0, 999 };
144 COMPARE_ARRAY(unw, unwExpected0); 142 COMPARE_ARRAY(unw, unwExpected0);
145 143
146 cerr << "process 1" << endl; 144 pvoc.processTimeDomain(data + 8, mag + 1, phase + 1, unw + 1);
147
148 pvoc.process(data + 8, mag + 1, phase + 1, unw + 1);
149 145
150 double magExpected1[] = { 999, 0, 4, 4, 0, 0, 999 }; 146 double magExpected1[] = { 999, 0, 4, 4, 0, 0, 999 };
151 COMPARE_ARRAY(mag, magExpected1); 147 COMPARE_ARRAY(mag, magExpected1);
152 148
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 149 //!!! 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
150
151 // Derivation of unwrapped values:
152 //
153 // * Bin 0 (DC) always has phase 0 and expected phase 0
154 //
155 // * Bin 1 has a new signal, a cosine starting with phase 0. But
156 // because of the "FFT shift" which the phase vocoder carries
157 // out to place zero phase in the centre of the (usually
158 // windowed) frame, and because a single cycle at this frequency
159 // spans the whole frame, this bin actually has measured phase
160 // of either pi or -pi. (The shift doesn't affect those
161 // higher-frequency bins whose signals fit exact multiples of a
162 // cycle into a frame.) This maps into (-pi,pi] as pi, which
163 // matches the expected phase, hence unwrapped phase is also pi.
164 //
165 // * Bin 2 has expected phase 3pi/2 (being the previous measured
166 // phase of -pi/2 plus advance of 2pi). It has the same measured
167 // phase as last time around, -pi/2, which is consistent with
168 // the expected phase, so the unwrapped phase is 3pi/2.
169 //!!!
170 // * Bin 3 is a bit of a puzzle -- it has an effectively zero
171 // magnitude but a non-zero measured phase. Spectral leakage?
172 //
173 // * Bin 4 (Nyquist) has expected phase 4*pi, measured phase 0,
174 // hence error 0 and unwrapped phase 4*pi.
175
154 double phaseExpected1[] = { 999, 0, -M_PI, -M_PI/2, M_PI, 0, 999 }; 176 double phaseExpected1[] = { 999, 0, -M_PI, -M_PI/2, M_PI, 0, 999 };
155 COMPARE_ARRAY(phase, phaseExpected1); 177 COMPARE_ARRAY(phase, phaseExpected1);
156 178
157 double unwExpected1[] = { 999, 0, M_PI, 3*M_PI/2, 3*M_PI, 4*M_PI, 999 }; 179 double unwExpected1[] = { 999, 0, M_PI, 3*M_PI/2, 3*M_PI, 4*M_PI, 999 };
158 COMPARE_ARRAY(unw, unwExpected1); 180 COMPARE_ARRAY(unw, unwExpected1);
159 181
160 cerr << "process 2" << endl; 182 pvoc.processTimeDomain(data + 16, mag + 1, phase + 1, unw + 1);
161
162 pvoc.process(data + 16, mag + 1, phase + 1, unw + 1);
163 183
164 double magExpected2[] = { 999, 0, 4, 4, 0, 0, 999 }; 184 double magExpected2[] = { 999, 0, 4, 4, 0, 0, 999 };
165 COMPARE_ARRAY(mag, magExpected2); 185 COMPARE_ARRAY(mag, magExpected2);
166 186
167 double phaseExpected2[] = { 999, 0, 0, -M_PI/2, 0, 0, 999 }; 187 double phaseExpected2[] = { 999, 0, 0, -M_PI/2, 0, 0, 999 };