Mercurial > hg > qm-dsp
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 }; |
