Mercurial > hg > constant-q-cpp
comparison test/TestWindow.cpp @ 131:6b13f9c694a8
Start introducing the tests
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Mon, 19 May 2014 10:21:51 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
130:1e33f719dde1 | 131:6b13f9c694a8 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 #include "dsp/Window.h" | |
4 #include "dsp/KaiserWindow.h" | |
5 #include "dsp/SincWindow.h" | |
6 | |
7 #include <iostream> | |
8 | |
9 #define BOOST_TEST_DYN_LINK | |
10 #define BOOST_TEST_MAIN | |
11 | |
12 #include <boost/test/unit_test.hpp> | |
13 | |
14 BOOST_AUTO_TEST_SUITE(TestWindow) | |
15 | |
16 using std::cout; | |
17 using std::endl; | |
18 | |
19 #define COMPARE_ARRAY(a, b) \ | |
20 for (int cmp_i = 0; cmp_i < (int)(sizeof(a)/sizeof(a[0])); ++cmp_i) { \ | |
21 BOOST_CHECK_SMALL(a[cmp_i] - b[cmp_i], 1e-4); \ | |
22 } | |
23 | |
24 void | |
25 testSymmetric(double *d, int n) | |
26 { | |
27 for (int i = 0; i <= n/2; ++i) { | |
28 BOOST_CHECK_CLOSE(d[i], d[n-i-1], 1e-10); | |
29 } | |
30 } | |
31 | |
32 BOOST_AUTO_TEST_CASE(periodic) | |
33 { | |
34 // We can't actually test whether a function is periodic, given | |
35 // only one cycle of it! But we can make sure that all but the | |
36 // first sample is symmetric, which is what a symmetric window | |
37 // becomes when generated in periodic mode | |
38 double d[9]; | |
39 for (int n = 8; n <= 9; ++n) { | |
40 for (int wt = (int)FirstWindow; wt <= (int)LastWindow; ++wt) { | |
41 for (int i = 0; i < n; ++i) d[i] = 1.0; | |
42 Window<double> w((WindowType)wt, n); | |
43 w.cut(d); | |
44 testSymmetric(d + 1, n - 1); | |
45 } | |
46 } | |
47 } | |
48 | |
49 template <int N> | |
50 void testWindow(WindowType type, const double expected[N]) | |
51 { | |
52 double d[N]; | |
53 for (int i = 0; i < N; ++i) d[i] = 1.0; | |
54 Window<double> w(type, N); | |
55 w.cut(d); | |
56 COMPARE_ARRAY(d, expected); | |
57 | |
58 double d0[N], d1[N]; | |
59 for (int i = 0; i < N; ++i) d0[i] = 0.5 + (1.0 / (N * 2)) * (i + 1); | |
60 w.cut(d0, d1); | |
61 for (int i = 0; i < N; ++i) { | |
62 BOOST_CHECK_SMALL(d1[i] - d0[i] * expected[i], 1e-4); | |
63 } | |
64 } | |
65 | |
66 BOOST_AUTO_TEST_CASE(bartlett) | |
67 { | |
68 double e1[] = { 1 }; | |
69 testWindow<1>(BartlettWindow, e1); | |
70 | |
71 double e2[] = { 0, 0 }; | |
72 testWindow<2>(BartlettWindow, e2); | |
73 | |
74 double e3[] = { 0, 2./3., 2./3. }; | |
75 testWindow<3>(BartlettWindow, e3); | |
76 | |
77 double e4[] = { 0, 1./2., 1., 1./2. }; | |
78 testWindow<4>(BartlettWindow, e4); | |
79 | |
80 double e5[] = { 0, 1./2., 1., 1., 1./2. }; | |
81 testWindow<5>(BartlettWindow, e5); | |
82 | |
83 double e6[] = { 0, 1./3., 2./3., 1., 2./3., 1./3. }; | |
84 testWindow<6>(BartlettWindow, e6); | |
85 } | |
86 | |
87 BOOST_AUTO_TEST_CASE(hamming) | |
88 { | |
89 double e1[] = { 1 }; | |
90 testWindow<1>(HammingWindow, e1); | |
91 | |
92 double e10[] = { | |
93 0.0800, 0.1679, 0.3979, 0.6821, 0.9121, | |
94 1.0000, 0.9121, 0.6821, 0.3979, 0.1679 | |
95 }; | |
96 testWindow<10>(HammingWindow, e10); | |
97 } | |
98 | |
99 BOOST_AUTO_TEST_CASE(hann) | |
100 { | |
101 double e1[] = { 1 }; | |
102 testWindow<1>(HanningWindow, e1); | |
103 | |
104 double e10[] = { | |
105 0, 0.0955, 0.3455, 0.6545, 0.9045, | |
106 1.0000, 0.9045, 0.6545, 0.3455, 0.0955, | |
107 }; | |
108 testWindow<10>(HanningWindow, e10); | |
109 } | |
110 | |
111 BOOST_AUTO_TEST_CASE(blackman) | |
112 { | |
113 double e1[] = { 1 }; | |
114 testWindow<1>(BlackmanWindow, e1); | |
115 | |
116 double e10[] = { | |
117 0, 0.0402, 0.2008, 0.5098, 0.8492, | |
118 1.0000, 0.8492, 0.5098, 0.2008, 0.0402, | |
119 }; | |
120 testWindow<10>(BlackmanWindow, e10); | |
121 } | |
122 | |
123 BOOST_AUTO_TEST_CASE(blackmanHarris) | |
124 { | |
125 double e1[] = { 1 }; | |
126 testWindow<1>(BlackmanHarrisWindow, e1); | |
127 | |
128 double e10[] = { | |
129 0.0001, 0.0110, 0.1030, 0.3859, 0.7938, | |
130 1.0000, 0.7938, 0.3859, 0.1030, 0.0110, | |
131 }; | |
132 testWindow<10>(BlackmanHarrisWindow, e10); | |
133 } | |
134 | |
135 BOOST_AUTO_TEST_CASE(kaiser_4_10) | |
136 { | |
137 double d[10]; | |
138 for (int i = 0; i < 10; ++i) d[i] = 1.0; | |
139 double e[] = { | |
140 0.0885, 0.2943, 0.5644, 0.8216, 0.9789, | |
141 0.9789, 0.8216, 0.5644, 0.2943, 0.0885 | |
142 }; | |
143 KaiserWindow::Parameters p; | |
144 p.length = 10; | |
145 p.beta = 4; | |
146 KaiserWindow k(p); | |
147 k.cut(d); | |
148 COMPARE_ARRAY(d, e); | |
149 } | |
150 | |
151 BOOST_AUTO_TEST_CASE(kaiser_2p5_11) | |
152 { | |
153 double d[11]; | |
154 for (int i = 0; i < 11; ++i) d[i] = 1.0; | |
155 double e[] = { | |
156 0.3040, 0.5005, 0.6929, 0.8546, 0.9622, | |
157 1.0000, 0.9622, 0.8546, 0.6929, 0.5005, 0.3040 | |
158 }; | |
159 KaiserWindow::Parameters p; | |
160 p.length = 11; | |
161 p.beta = 2.5; | |
162 KaiserWindow k(p); | |
163 k.cut(d); | |
164 COMPARE_ARRAY(d, e); | |
165 } | |
166 | |
167 //!!! todo: tests for kaiser with attenuation and bandwidth parameters | |
168 | |
169 template <int N> | |
170 void testSinc(double p, const double expected[N]) | |
171 { | |
172 double d[N]; | |
173 for (int i = 0; i < N; ++i) d[i] = 1.0; | |
174 SincWindow w(N, p); | |
175 w.cut(d); | |
176 COMPARE_ARRAY(d, expected); | |
177 | |
178 double d0[N], d1[N]; | |
179 for (int i = 0; i < N; ++i) d0[i] = 0.5 + (1.0 / (N * 2)) * (i + 1); | |
180 w.cut(d0, d1); | |
181 for (int i = 0; i < N; ++i) { | |
182 BOOST_CHECK_SMALL(d1[i] - d0[i] * expected[i], 1e-4); | |
183 } | |
184 } | |
185 | |
186 BOOST_AUTO_TEST_CASE(sinc) | |
187 { | |
188 double e1[] = { 0, 0, 1, 0, 0 }; | |
189 testSinc<5>(1, e1); | |
190 | |
191 double e2[] = { 0, 0, 1, 0, 0 }; | |
192 testSinc<5>(2, e2); | |
193 | |
194 double e3[] = { -0.2122, 0.0, 0.6366, 1.0, 0.6366, 0, -0.2122 }; | |
195 testSinc<7>(4, e3); | |
196 | |
197 double e4[] = { -0.2122, 0, 0.6366, 1, 0.6366, 0 }; | |
198 testSinc<6>(4, e4); | |
199 } | |
200 | |
201 BOOST_AUTO_TEST_SUITE_END() | |
202 |