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