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