comparison tests/xttest_scalar.cpp @ 268:b371ffcecb74

Add F0 quantization test
author Jamie Bullock <jamie@jamiebullock.com>
date Tue, 11 Nov 2014 17:01:47 +0000
parents 41fe82c7ff80
children 446f6d3dc809
comparison
equal deleted inserted replaced
267:41fe82c7ff80 268:b371ffcecb74
9 9
10 SCENARIO( "F0 is correctly detected for a sine wave", "[xtract_f0]" ) 10 SCENARIO( "F0 is correctly detected for a sine wave", "[xtract_f0]" )
11 { 11 {
12 uint16_t expected = 0; 12 uint16_t expected = 0;
13 uint16_t actual = 0; 13 uint16_t actual = 0;
14 14
15 GIVEN( "a 512 sample block with a sample rate of 44100" ) 15 GIVEN( "a 512 sample block with a sample rate of 44100" )
16 { 16 {
17 uint32_t blocksize = 512; 17 uint32_t blocksize = 512;
18 double samplerate = 44100; 18 double samplerate = 44100;
19 double result = -1.0; 19 double result = -1.0;
20 double amplitude = 1.0; 20 double amplitude = 1.0;
21 double table[blocksize]; 21 double table[blocksize];
22 22
23 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 1 cycles in the block 23 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 1 cycles in the block
24 { 24 {
25 double frequency = 86.1328125; 25 double frequency = 86.1328125;
26 26
27 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 27 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
28 int rv = xtract_f0(table, blocksize, &samplerate, &result); 28 int rv = xtract_f0(table, blocksize, &samplerate, &result);
29 29
30 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) 30 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" )
31 { 31 {
32 REQUIRE(rv == XTRACT_NO_RESULT); 32 REQUIRE(rv == XTRACT_NO_RESULT);
33 REQUIRE(result == 0.0); 33 REQUIRE(result == 0.0);
34 } 34 }
35 } 35 }
36 36
37 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 2 cycles in the block 37 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 2 cycles in the block
38 { 38 {
39 double frequency = 172.265625; 39 double frequency = 172.265625;
40 40
41 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 41 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
42 int rv = xtract_f0(table, blocksize, &samplerate, &result); 42 int rv = xtract_f0(table, blocksize, &samplerate, &result);
43 43
44 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) 44 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" )
45 { 45 {
46 REQUIRE(rv == XTRACT_NO_RESULT); 46 REQUIRE(rv == XTRACT_NO_RESULT);
47 REQUIRE(result == 0.0); 47 REQUIRE(result == 0.0);
48 } 48 }
49 } 49 }
50 50
51
51 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 4 cycles in the block 52 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 4 cycles in the block
52 { 53 {
53 double frequency = 344.53125; 54 double frequency = 344.53125;
54 55
55 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 56 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
56 xtract_f0(table, blocksize, &samplerate, &result); 57 xtract_f0(table, blocksize, &samplerate, &result);
57 58
58 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 59 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
59 { 60 {
61 expected = xttest_ftom(frequency); 62 expected = xttest_ftom(frequency);
62 CAPTURE( actual ); 63 CAPTURE( actual );
63 CAPTURE( expected ); 64 CAPTURE( expected );
64 REQUIRE(actual == expected); 65 REQUIRE(actual == expected);
65 } 66 }
66 67
67 68
68 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case 69 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case
69 { 70 {
70 double amplitude = 0.01; 71 double amplitude = 0.01;
71 72
72 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 73 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
73 xtract_f0(table, blocksize, &samplerate, &result); 74 xtract_f0(table, blocksize, &samplerate, &result);
74 75
75 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 76 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
76 { 77 {
77 actual = xttest_ftom(result); 78 actual = xttest_ftom(result);
78 expected = xttest_ftom(frequency); 79 expected = xttest_ftom(frequency);
79 CAPTURE( actual ); 80 CAPTURE( actual );
81 REQUIRE(actual == expected); 82 REQUIRE(actual == expected);
82 } 83 }
83 } 84 }
84 } 85 }
85 } 86 }
86 87
87 GIVEN( "a 1024 sample block with a sample rate of 44100" ) 88 GIVEN( "a 1024 sample block with a sample rate of 44100" )
88 { 89 {
89 uint32_t blocksize = 1024; 90 uint32_t blocksize = 1024;
90 double samplerate = 44100; 91 double samplerate = 44100;
91 double result = -1.0; 92 double result = -1.0;
93 double amplitude = 1.0;
92 double table[blocksize]; 94 double table[blocksize];
93 95
94 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block 96 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block
95 { 97 {
96 double frequency = 86.1328125; 98 double frequency = 86.1328125;
97 double amplitude = 1.0; 99
98
99 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 100 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
100 int rv = xtract_f0(table, blocksize, &samplerate, &result); 101 int rv = xtract_f0(table, blocksize, &samplerate, &result);
101 102
102 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) 103 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" )
103 { 104 {
104 REQUIRE(rv == XTRACT_NO_RESULT); 105 REQUIRE(rv == XTRACT_NO_RESULT);
105 REQUIRE(result == 0.0); 106 REQUIRE(result == 0.0);
106 } 107 }
107 } 108 }
108 109
110 WHEN( "the frequency is 140 Hz" ) // period of 315 samples: 3.25 cycles in the block
111 {
112 double frequency = 140;
113
114 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
115 xtract_f0(table, blocksize, &samplerate, &result);
116
117 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
118 {
119 actual = xttest_ftom(result);
120 expected = xttest_ftom(frequency);
121 CAPTURE( actual );
122 CAPTURE( expected );
123 REQUIRE(actual == expected);
124 }
125 }
126
127 WHEN( "the frequency is 155 Hz" ) // period of 284.52 samples: 3.6 cycles in the block
128 {
129 double frequency = 155;
130
131 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
132 xtract_f0(table, blocksize, &samplerate, &result);
133
134 THEN( "the detected F0 is quantized to the nearest whole number of samples" )
135 {
136 actual = xttest_ftom(result);
137 expected = xttest_ftom(155.28169014); // period of 284 samples
138 CAPTURE( result );
139 CAPTURE( expected );
140 REQUIRE(actual == expected);
141 }
142 }
143
144
109 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block 145 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block
110 { 146 {
111 double frequency = 172.265625; 147 double frequency = 172.265625;
112 double amplitude = 1.0;
113 148
114 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 149 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
115 xtract_f0(table, blocksize, &samplerate, &result); 150 xtract_f0(table, blocksize, &samplerate, &result);
116 151
117 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 152 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
125 } 160 }
126 161
127 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block 162 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block
128 { 163 {
129 double frequency = 344.53125; 164 double frequency = 344.53125;
165 double noise[blocksize];
130 expected = xttest_ftom(frequency); 166 expected = xttest_ftom(frequency);
131 CAPTURE( expected ); 167 CAPTURE( expected );
132 168
133 WHEN( "the amplitude is 1.0" ) 169 WHEN( "the amplitude is 1.0" )
134 { 170 {
135 double amplitude = 1.0;
136
137 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 171 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
138 xtract_f0(table, blocksize, &samplerate, &result); 172 xtract_f0(table, blocksize, &samplerate, &result);
139 173
140 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 174 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
141 { 175 {
142 actual = xttest_ftom(result); 176 actual = xttest_ftom(result);
143 CAPTURE( actual ); 177 CAPTURE( actual );
144 REQUIRE(actual == expected); 178 REQUIRE(actual == expected);
145 } 179 }
146 } 180 }
147 181
148 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case 182 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case
149 { 183 {
150 double amplitude = 0.01; 184 amplitude = 0.01;
151 185
152 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 186 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
153 xtract_f0(table, blocksize, &samplerate, &result); 187 xtract_f0(table, blocksize, &samplerate, &result);
154 188
155 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 189 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
157 actual = xttest_ftom(result); 191 actual = xttest_ftom(result);
158 CAPTURE( actual ); 192 CAPTURE( actual );
159 REQUIRE(actual == expected); 193 REQUIRE(actual == expected);
160 } 194 }
161 } 195 }
162 196
163 WHEN( "white noise is added at 10%" ) // Only test noise for one case 197 WHEN( "white noise is added at 10%" ) // Only test noise for one case
164 { 198 {
165 double amplitude = 0.1; 199 amplitude = 0.1;
166 double noise[blocksize]; 200
167 201 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
168 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 202 xttest_gen_noise(noise, blocksize, amplitude);
169 xttest_gen_noise(noise, blocksize, amplitude); 203 xttest_add(table, noise, blocksize);
170 xttest_add(table, noise, blocksize); 204 xtract_f0(table, blocksize, &samplerate, &result);
171 xtract_f0(table, blocksize, &samplerate, &result); 205
172 206 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
173 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 207 {
174 { 208 actual = xttest_ftom(result);
175 actual = xttest_ftom(result); 209 CAPTURE( actual );
176 CAPTURE( actual ); 210 REQUIRE(actual == expected);
177 REQUIRE(actual == expected); 211 }
178 } 212 }
179 } 213
180
181 WHEN( "white noise is added at 20%" ) 214 WHEN( "white noise is added at 20%" )
182 { 215 {
183 double amplitude = 0.2; 216 amplitude = 0.2;
184 double noise[blocksize]; 217
185 218 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
186 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 219 xttest_gen_noise(noise, blocksize, amplitude);
187 xttest_gen_noise(noise, blocksize, amplitude); 220 xttest_add(table, noise, blocksize);
188 xttest_add(table, noise, blocksize); 221 xtract_f0(table, blocksize, &samplerate, &result);
189 xtract_f0(table, blocksize, &samplerate, &result); 222
190 223 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
191 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 224 {
192 { 225 actual = xttest_ftom(result);
193 actual = xttest_ftom(result); 226 CAPTURE( actual );
194 CAPTURE( actual ); 227 REQUIRE(actual == expected);
195 REQUIRE(actual == expected); 228 }
196 } 229 }
197 } 230
198
199 WHEN( "white noise is added at 25%" ) 231 WHEN( "white noise is added at 25%" )
200 { 232 {
201 double amplitude = 0.25; 233 amplitude = 0.25;
202 double noise[blocksize]; 234
203 235 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
204 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 236 xttest_gen_noise(noise, blocksize, amplitude);
205 xttest_gen_noise(noise, blocksize, amplitude); 237 xttest_add(table, noise, blocksize);
206 xttest_add(table, noise, blocksize); 238 xtract_f0(table, blocksize, &samplerate, &result);
207 xtract_f0(table, blocksize, &samplerate, &result); 239
208
209 THEN( "the detected F0 is accurate to the nearest semitone" ) 240 THEN( "the detected F0 is accurate to the nearest semitone" )
210 { 241 {
211 actual = xttest_ftom(result); 242 actual = xttest_ftom(result);
212 uint16_t min = expected - 100; 243 uint16_t min = expected - 100;
213 uint16_t max = expected + 100; 244 uint16_t max = expected + 100;
214 CAPTURE( actual ); 245 CAPTURE( actual );
215 REQUIRE( actual > min ); 246 REQUIRE( actual > min );
216 REQUIRE( actual < max ); 247 REQUIRE( actual < max );
217 } 248 }
218 } 249 }
219 250
220 WHEN( "white noise is added at 30%" ) 251 WHEN( "white noise is added at 30%" )
221 { 252 {
222 double amplitude = 0.25; 253 amplitude = 0.25;
223 double noise[blocksize]; 254
224 255 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
225 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 256 xttest_gen_noise(noise, blocksize, amplitude);
226 xttest_gen_noise(noise, blocksize, amplitude); 257 xttest_add(table, noise, blocksize);
227 xttest_add(table, noise, blocksize); 258 xtract_f0(table, blocksize, &samplerate, &result);
228 xtract_f0(table, blocksize, &samplerate, &result); 259
229
230 THEN( "the detected F0 is accurate to the nearest quarter-tone" ) 260 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
231 { 261 {
232 actual = xttest_ftom(result); 262 actual = xttest_ftom(result);
233 uint16_t min = expected - 50; 263 uint16_t min = expected - 50;
234 uint16_t max = expected + 50; 264 uint16_t max = expected + 50;
235 CAPTURE( actual ); 265 CAPTURE( actual );
236 REQUIRE( actual > min ); 266 REQUIRE( actual > min );
237 REQUIRE( actual < max ); 267 REQUIRE( actual < max );
238 } 268 }
239 } 269 }
240 270
241 WHEN( "white noise is added at 35%" ) 271 WHEN( "white noise is added at 35%" )
242 { 272 {
243 double amplitude = 0.35; 273 amplitude = 0.35;
244 double noise[blocksize]; 274
245 275 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
246 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 276 xttest_gen_noise(noise, blocksize, amplitude);
247 xttest_gen_noise(noise, blocksize, amplitude); 277 xttest_add(table, noise, blocksize);
248 xttest_add(table, noise, blocksize); 278 xtract_f0(table, blocksize, &samplerate, &result);
249 xtract_f0(table, blocksize, &samplerate, &result); 279
250
251 THEN( "the detected F0 is inaccurate by more than one semitone" ) 280 THEN( "the detected F0 is inaccurate by more than one semitone" )
252 { 281 {
253 actual = xttest_ftom(result); 282 actual = xttest_ftom(result);
254 uint16_t difference = abs(expected - actual); 283 uint16_t difference = abs(expected - actual);
255 CAPTURE( actual ); 284 CAPTURE( actual );
256 REQUIRE( difference > 100 ); 285 REQUIRE( difference > 100 );
257 } 286 }
258 } 287 }
259 } 288 }
260 } 289 }
261 290
262 GIVEN( "a 1024 sample block with a sample rate of 11025" ) 291 GIVEN( "a 1024 sample block with a sample rate of 11025" )
263 { 292 {
264 uint32_t blocksize = 1024; 293 uint32_t blocksize = 1024;
265 double samplerate = 11025; 294 double samplerate = 11025;
266 double result = -1.0; 295 double result = -1.0;
267 double table[blocksize]; 296 double table[blocksize];
268 297
269 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block 298 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block
270 { 299 {
271 double frequency = 86.1328125; 300 double frequency = 86.1328125;
272 double amplitude = 1.0; 301 double amplitude = 1.0;
273 302
274 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 303 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
275 int rv = xtract_f0(table, blocksize, &samplerate, &result); 304 int rv = xtract_f0(table, blocksize, &samplerate, &result);
276 305
277 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 306 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
278 { 307 {
279 actual = xttest_ftom(result); 308 actual = xttest_ftom(result);
280 expected = xttest_ftom(frequency); 309 expected = xttest_ftom(frequency);
281 CAPTURE( actual ); 310 CAPTURE( actual );
282 CAPTURE( expected ); 311 CAPTURE( expected );
283 REQUIRE(actual == expected); 312 REQUIRE(actual == expected);
284 } 313 }
285 } 314 }
286 315
287 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block 316 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block
288 { 317 {
289 double frequency = 172.265625; 318 double frequency = 172.265625;
290 double amplitude = 1.0; 319 double amplitude = 1.0;
291 320
292 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 321 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
293 xtract_f0(table, blocksize, &samplerate, &result); 322 xtract_f0(table, blocksize, &samplerate, &result);
294 323
295 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 324 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
296 { 325 {
297 actual = xttest_ftom(result); 326 actual = xttest_ftom(result);
298 expected = xttest_ftom(frequency); 327 expected = xttest_ftom(frequency);
299 CAPTURE( actual ); 328 CAPTURE( actual );
300 CAPTURE( expected ); 329 CAPTURE( expected );
301 REQUIRE(actual == expected); 330 REQUIRE(actual == expected);
302 } 331 }
303 } 332 }
304 333
305 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block 334 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block
306 { 335 {
307 double frequency = 344.53125; 336 double frequency = 344.53125;
308 expected = xttest_ftom(frequency); 337 expected = xttest_ftom(frequency);
309 CAPTURE( expected ); 338 CAPTURE( expected );
310 339
311 WHEN( "the amplitude is 1.0" ) 340 WHEN( "the amplitude is 1.0" )
312 { 341 {
313 double amplitude = 1.0; 342 double amplitude = 1.0;
314 343
315 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 344 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
316 xtract_f0(table, blocksize, &samplerate, &result); 345 xtract_f0(table, blocksize, &samplerate, &result);
317 346
318 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 347 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
319 { 348 {
320 actual = xttest_ftom(result); 349 actual = xttest_ftom(result);
321 CAPTURE( actual ); 350 CAPTURE( actual );
322 REQUIRE(actual == expected); 351 REQUIRE(actual == expected);
323 } 352 }
324 } 353 }
325 354
326 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case 355 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case
327 { 356 {
328 double amplitude = 0.01; 357 double amplitude = 0.01;
329 358
330 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 359 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
331 xtract_f0(table, blocksize, &samplerate, &result); 360 xtract_f0(table, blocksize, &samplerate, &result);
332 361
333 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 362 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
334 { 363 {
335 actual = xttest_ftom(result); 364 actual = xttest_ftom(result);
336 CAPTURE( actual ); 365 CAPTURE( actual );
337 REQUIRE(actual == expected); 366 REQUIRE(actual == expected);
338 } 367 }
339 } 368 }
340 369
341 WHEN( "white noise is added at 20%" ) 370 WHEN( "white noise is added at 20%" )
342 { 371 {
343 double amplitude = 0.2; 372 double amplitude = 0.2;
344 double noise[blocksize]; 373 double noise[blocksize];
345 374
346 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 375 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
347 xttest_gen_noise(noise, blocksize, amplitude); 376 xttest_gen_noise(noise, blocksize, amplitude);
348 xttest_add(table, noise, blocksize); 377 xttest_add(table, noise, blocksize);
349 xtract_f0(table, blocksize, &samplerate, &result); 378 xtract_f0(table, blocksize, &samplerate, &result);
350 379
351 THEN( "the detected F0 is accurate to the nearest quarter-tone" ) 380 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
352 { 381 {
353 actual = xttest_ftom(result); 382 actual = xttest_ftom(result);
354 uint16_t min = expected - 50; 383 uint16_t min = expected - 50;
355 uint16_t max = expected + 50; 384 uint16_t max = expected + 50;
356 CAPTURE( actual ); 385 CAPTURE( actual );
357 REQUIRE( actual > min ); 386 REQUIRE( actual > min );
358 REQUIRE( actual < max ); 387 REQUIRE( actual < max );
359 } 388 }
360 } 389 }
361 390
362 WHEN( "white noise is added at 40%" ) 391 WHEN( "white noise is added at 40%" )
363 { 392 {
364 double amplitude = 0.4; 393 double amplitude = 0.4;
365 double noise[blocksize]; 394 double noise[blocksize];
366 395
367 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 396 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
368 xttest_gen_noise(noise, blocksize, amplitude); 397 xttest_gen_noise(noise, blocksize, amplitude);
369 xttest_add(table, noise, blocksize); 398 xttest_add(table, noise, blocksize);
370 xtract_f0(table, blocksize, &samplerate, &result); 399 xtract_f0(table, blocksize, &samplerate, &result);
371 400
372 THEN( "the detected F0 is accurate to the nearest semi-tone" ) 401 THEN( "the detected F0 is accurate to the nearest semi-tone" )
373 { 402 {
374 actual = xttest_ftom(result); 403 actual = xttest_ftom(result);
375 uint16_t min = expected - 100; 404 uint16_t min = expected - 100;
376 uint16_t max = expected + 100; 405 uint16_t max = expected + 100;
377 CAPTURE( actual ); 406 CAPTURE( actual );
378 REQUIRE( actual > min ); 407 REQUIRE( actual > min );
379 REQUIRE( actual < max ); 408 REQUIRE( actual < max );
380 } 409 }
381 } 410 }
382 411
383 WHEN( "white noise is added at 60%" ) 412 WHEN( "white noise is added at 60%" )
384 { 413 {
385 double amplitude = 0.6; 414 double amplitude = 0.6;
386 double noise[blocksize]; 415 double noise[blocksize];
387 416
388 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 417 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
389 xttest_gen_noise(noise, blocksize, amplitude); 418 xttest_gen_noise(noise, blocksize, amplitude);
390 xttest_add(table, noise, blocksize); 419 xttest_add(table, noise, blocksize);
391 xtract_f0(table, blocksize, &samplerate, &result); 420 xtract_f0(table, blocksize, &samplerate, &result);
392 421
393 THEN( "the detected F0 is accurate to the nearest semi-tone" ) 422 THEN( "the detected F0 is accurate to the nearest semi-tone" )
394 { 423 {
395 actual = xttest_ftom(result); 424 actual = xttest_ftom(result);
396 uint16_t min = expected - 100; 425 uint16_t min = expected - 100;
397 uint16_t max = expected + 100; 426 uint16_t max = expected + 100;
398 CAPTURE( actual ); 427 CAPTURE( actual );
399 REQUIRE( actual > min ); 428 REQUIRE( actual > min );
400 REQUIRE( actual < max ); 429 REQUIRE( actual < max );
401 } 430 }
402 } 431 }
403 432
404 WHEN( "white noise is added at 80%" ) 433 WHEN( "white noise is added at 80%" )
405 { 434 {
406 double amplitude = 0.8; 435 double amplitude = 0.8;
407 double noise[blocksize]; 436 double noise[blocksize];
408 437
409 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); 438 xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude);
410 xttest_gen_noise(noise, blocksize, amplitude); 439 xttest_gen_noise(noise, blocksize, amplitude);
411 xttest_add(table, noise, blocksize); 440 xttest_add(table, noise, blocksize);
412 xtract_f0(table, blocksize, &samplerate, &result); 441 xtract_f0(table, blocksize, &samplerate, &result);
413 442
414 THEN( "the detected F0 is inaccurate by more than one semitone" ) 443 THEN( "the detected F0 is inaccurate by more than one semitone" )
415 { 444 {
416 actual = xttest_ftom(result); 445 actual = xttest_ftom(result);
417 uint16_t difference = abs(expected - actual); 446 uint16_t difference = abs(expected - actual);
418 CAPTURE( actual ); 447 CAPTURE( actual );
419 REQUIRE( difference > 100 ); 448 REQUIRE( difference > 100 );
420 } 449 }
421 } 450 }
422 } 451 }
423 } 452 }
424 453
425 GIVEN( "a 2048 sample block with a sample rate of 44100" ) 454 GIVEN( "a 2048 sample block with a sample rate of 44100" )
426 { 455 {
427 uint32_t blocksize = 2048; 456 uint32_t blocksize = 2048;
428 double samplerate = 44100; 457 double samplerate = 44100;
429 double result = -1.0; 458 double result = -1.0;
430 double table[blocksize]; 459 double table[blocksize];
431 460
432 WHEN( "the frequency is 43.06640625 Hz" ) // period of exactly 256 samples: 2 cycles in the block 461 WHEN( "the frequency is 43.06640625 Hz" ) // period of exactly 256 samples: 2 cycles in the block
433 { 462 {
434 double frequency = 43.06640625; 463 double frequency = 43.06640625;
435 double amplitude = 1.0; 464 double amplitude = 1.0;
436 465
437 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 466 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
438 int rv = xtract_f0(table, blocksize, &samplerate, &result); 467 int rv = xtract_f0(table, blocksize, &samplerate, &result);
439 468
440 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) 469 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" )
441 { 470 {
442 REQUIRE(rv == XTRACT_NO_RESULT); 471 REQUIRE(rv == XTRACT_NO_RESULT);
443 REQUIRE(result == 0.0); 472 REQUIRE(result == 0.0);
444 } 473 }
445 } 474 }
446 475
447 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 4 cycles in the block 476 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 4 cycles in the block
448 { 477 {
449 double frequency = 86.1328125; 478 double frequency = 86.1328125;
450 double amplitude = 1.0; 479 double amplitude = 1.0;
451 480
452 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 481 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
453 int rv = xtract_f0(table, blocksize, &samplerate, &result); 482 int rv = xtract_f0(table, blocksize, &samplerate, &result);
454 483
455 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 484 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
456 { 485 {
457 actual = xttest_ftom(result); 486 actual = xttest_ftom(result);
458 expected = xttest_ftom(frequency); 487 expected = xttest_ftom(frequency);
459 CAPTURE( actual ); 488 CAPTURE( actual );
460 CAPTURE( expected ); 489 CAPTURE( expected );
461 REQUIRE(actual == expected); 490 REQUIRE(actual == expected);
462 } 491 }
463 } 492 }
464 493
465 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 8 cycles in the block 494 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 8 cycles in the block
466 { 495 {
467 double frequency = 172.265625; 496 double frequency = 172.265625;
468 double amplitude = 1.0; 497 double amplitude = 1.0;
469 498
470 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 499 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
471 xtract_f0(table, blocksize, &samplerate, &result); 500 xtract_f0(table, blocksize, &samplerate, &result);
472 501
473 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 502 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
474 { 503 {
475 actual = xttest_ftom(result); 504 actual = xttest_ftom(result);
476 expected = xttest_ftom(frequency); 505 expected = xttest_ftom(frequency);
477 CAPTURE( actual ); 506 CAPTURE( actual );
478 CAPTURE( expected ); 507 CAPTURE( expected );
479 REQUIRE(actual == expected); 508 REQUIRE(actual == expected);
480 } 509 }
481 } 510 }
482 511
483 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 16 cycles in the block 512 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 16 cycles in the block
484 { 513 {
485 double frequency = 344.53125; 514 double frequency = 344.53125;
486 515
487 WHEN( "the amplitude is 1.0" ) 516 WHEN( "the amplitude is 1.0" )
488 { 517 {
489 double amplitude = 1.0; 518 double amplitude = 1.0;
490 519
491 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); 520 xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude);
492 xtract_f0(table, blocksize, &samplerate, &result); 521 xtract_f0(table, blocksize, &samplerate, &result);
493 522
494 THEN( "the detected F0 is accurate to the nearest MIDI cent" ) 523 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
495 { 524 {
496 actual = xttest_ftom(result); 525 actual = xttest_ftom(result);
497 expected = xttest_ftom(frequency); 526 expected = xttest_ftom(frequency);
498 CAPTURE( actual ); 527 CAPTURE( actual );
499 CAPTURE( expected ); 528 CAPTURE( expected );
500 REQUIRE(actual == expected); 529 REQUIRE(actual == expected);
501 } 530 }
502 } 531 }
503 } 532 }
504 } 533 }
505 } 534 }