Mercurial > hg > qm-dsp
comparison tests/TestPhaseVocoder.cpp @ 340:c99d83236f0d
Do actual phase unwrapping in the phase vocoder!
| author | Chris Cannam <c.cannam@qmul.ac.uk> |
|---|---|
| date | Wed, 02 Oct 2013 15:05:34 +0100 |
| parents | 35db1b24a848 |
| children | 7f5b96734c83 |
comparison
equal
deleted
inserted
replaced
| 339:9c8ee77db9de | 340:c99d83236f0d |
|---|---|
| 25 BOOST_CHECK_EQUAL(a[cmp_i], b[cmp_i]); \ | 25 BOOST_CHECK_EQUAL(a[cmp_i], b[cmp_i]); \ |
| 26 } | 26 } |
| 27 | 27 |
| 28 BOOST_AUTO_TEST_CASE(fullcycle) | 28 BOOST_AUTO_TEST_CASE(fullcycle) |
| 29 { | 29 { |
| 30 // Cosine with one cycle exactly equal to pvoc hopsize. We aren't | 30 // Cosine with one cycle exactly equal to pvoc hopsize. This is |
| 31 // windowing the input frame because (for once) it actually *is* | 31 // pretty much the most trivial case -- in fact it's |
| 32 // just a short part of a continuous infinite sinusoid. | 32 // indistinguishable from totally silent input (in the phase |
| 33 // values) because the measured phases are zero throughout. | |
| 34 | |
| 35 // We aren't windowing the input frame because (for once) it | |
| 36 // actually *is* just a short part of a continuous infinite | |
| 37 // sinusoid. | |
| 33 | 38 |
| 34 double frame[] = { 1, 0, -1, 0, 1, 0, -1, 0 }; | 39 double frame[] = { 1, 0, -1, 0, 1, 0, -1, 0 }; |
| 35 | 40 |
| 36 PhaseVocoder pvoc(8); | 41 PhaseVocoder pvoc(8, 4); |
| 37 | 42 |
| 38 // Make these arrays one element too long at each end, so as to | 43 // Make these arrays one element too long at each end, so as to |
| 39 // test for overruns. For frame size 8, we expect 8/2+1 = 5 | 44 // test for overruns. For frame size 8, we expect 8/2+1 = 5 |
| 40 // mag/phase pairs. | 45 // mag/phase pairs. |
| 41 double mag[] = { 999, 999, 999, 999, 999, 999, 999 }; | 46 double mag[] = { 999, 999, 999, 999, 999, 999, 999 }; |
| 42 double phase[] = { 999, 999, 999, 999, 999, 999, 999 }; | 47 double phase[] = { 999, 999, 999, 999, 999, 999, 999 }; |
| 48 double unw[] = { 999, 999, 999, 999, 999, 999, 999 }; | |
| 43 | 49 |
| 44 pvoc.process(frame, mag + 1, phase + 1); | 50 pvoc.process(frame, mag + 1, phase + 1, unw + 1); |
| 45 | 51 |
| 46 double magExpected0[] = { 999, 0, 0, 4, 0, 0, 999 }; | 52 double magExpected0[] = { 999, 0, 0, 4, 0, 0, 999 }; |
| 47 COMPARE_ARRAY_EXACT(mag, magExpected0); | 53 COMPARE_ARRAY_EXACT(mag, magExpected0); |
| 48 | 54 |
| 49 double phaseExpected0[] = { 999, 0, 0, 0, 0, 0, 999 }; | 55 double phaseExpected0[] = { 999, 0, 0, 0, 0, 0, 999 }; |
| 50 COMPARE_ARRAY_EXACT(phase, phaseExpected0); | 56 COMPARE_ARRAY_EXACT(phase, phaseExpected0); |
| 51 | 57 |
| 52 pvoc.process(frame, mag + 1, phase + 1); | 58 double unwExpected0[] = { 999, 0, 0, 0, 0, 0, 999 }; |
| 59 COMPARE_ARRAY(unw, unwExpected0); | |
| 60 | |
| 61 pvoc.process(frame, mag + 1, phase + 1, unw + 1); | |
| 53 | 62 |
| 54 double magExpected1[] = { 999, 0, 0, 4, 0, 0, 999 }; | 63 double magExpected1[] = { 999, 0, 0, 4, 0, 0, 999 }; |
| 55 COMPARE_ARRAY_EXACT(mag, magExpected1); | 64 COMPARE_ARRAY_EXACT(mag, magExpected1); |
| 56 | 65 |
| 57 double phaseExpected1[] = { 999, 0, 0, 2 * M_PI, 0, 0, 999 }; | 66 double phaseExpected1[] = { 999, 0, 0, 0, 0, 0, 999 }; |
| 58 COMPARE_ARRAY(phase, phaseExpected1); | 67 COMPARE_ARRAY(phase, phaseExpected1); |
| 59 | 68 |
| 60 pvoc.process(frame, mag + 1, phase + 1); | 69 // Derivation of values: |
| 70 // | |
| 71 // * Bin 0 (DC) always has phase 0 and expected phase 0 | |
| 72 // | |
| 73 // * 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 | |
| 75 // signal in that bin). So it has phase error -pi, which is | |
| 76 // mapped into (-pi,pi] range as pi, giving an unwrapped phase | |
| 77 // of 2*pi. | |
| 78 // | |
| 79 // * Bin 2 has expected unwrapped phase 2*pi, measured phase 0, | |
| 80 // hence error 0 and unwrapped phase 2*pi. | |
| 81 // | |
| 82 // * Bin 3 is like bin 1: it has expected phase 3*pi, measured | |
| 83 // phase 0, so phase error -pi and unwrapped phase 4*pi. | |
| 84 // | |
| 85 // * Bin 4 (Nyquist) is like bin 2: expected phase 4*pi, measured | |
| 86 // phase 0, hence error 0 and unwrapped phase 4*pi. | |
| 87 | |
| 88 double unwExpected1[] = { 999, 0, 2*M_PI, 2*M_PI, 4*M_PI, 4*M_PI, 999 }; | |
| 89 COMPARE_ARRAY(unw, unwExpected1); | |
| 90 | |
| 91 pvoc.process(frame, mag + 1, phase + 1, unw + 1); | |
| 61 | 92 |
| 62 double magExpected2[] = { 999, 0, 0, 4, 0, 0, 999 }; | 93 double magExpected2[] = { 999, 0, 0, 4, 0, 0, 999 }; |
| 63 COMPARE_ARRAY_EXACT(mag, magExpected2); | 94 COMPARE_ARRAY_EXACT(mag, magExpected2); |
| 64 | 95 |
| 65 double phaseExpected2[] = { 999, 0, 0, 4 * M_PI, 0, 0, 999 }; | 96 double phaseExpected2[] = { 999, 0, 0, 0, 0, 0, 999 }; |
| 66 COMPARE_ARRAY(phase, phaseExpected2); | 97 COMPARE_ARRAY(phase, phaseExpected2); |
| 98 | |
| 99 double unwExpected2[] = { 999, 0, 4*M_PI, 4*M_PI, 8*M_PI, 8*M_PI, 999 }; | |
| 100 COMPARE_ARRAY(unw, unwExpected2); | |
| 67 } | 101 } |
| 102 | |
| 103 //!!! signal that starts mid-phase | |
| 104 | |
| 68 | 105 |
| 69 BOOST_AUTO_TEST_SUITE_END() | 106 BOOST_AUTO_TEST_SUITE_END() |
| 70 | 107 |
