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 }
|
jamie@269
|
535
|
jamie@269
|
536 SCENARIO( "F0 is correctly detected for a sawtooth wave", "[xtract_f0]" )
|
jamie@269
|
537 {
|
jamie@269
|
538 uint16_t expected = 0;
|
jamie@269
|
539 uint16_t actual = 0;
|
jamie@269
|
540
|
jamie@269
|
541 GIVEN( "a 512 sample block with a sample rate of 44100" )
|
jamie@269
|
542 {
|
jamie@269
|
543 uint32_t blocksize = 512;
|
jamie@269
|
544 double samplerate = 44100;
|
jamie@269
|
545 double result = -1.0;
|
jamie@269
|
546 double amplitude = 1.0;
|
jamie@269
|
547 double table[blocksize];
|
jamie@269
|
548
|
jamie@269
|
549 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 1 cycles in the block
|
jamie@269
|
550 {
|
jamie@269
|
551 double frequency = 86.1328125;
|
jamie@269
|
552
|
jamie@269
|
553 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
554 int rv = xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
555
|
jamie@269
|
556 THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" )
|
jamie@269
|
557 {
|
jamie@269
|
558 REQUIRE(rv == XTRACT_NO_RESULT);
|
jamie@269
|
559 REQUIRE(result == 0.0);
|
jamie@269
|
560 }
|
jamie@269
|
561 }
|
jamie@269
|
562
|
jamie@269
|
563 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 2 cycles in the block
|
jamie@269
|
564 {
|
jamie@269
|
565 double frequency = 172.265625;
|
jamie@269
|
566
|
jamie@269
|
567 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
568 int rv = xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
569
|
jamie@269
|
570 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
571 {
|
jamie@269
|
572 actual = xttest_ftom(result);
|
jamie@269
|
573 expected = xttest_ftom(frequency);
|
jamie@269
|
574 uint16_t min = expected - 50;
|
jamie@269
|
575 uint16_t max = expected + 50;
|
jamie@269
|
576 CAPTURE( actual );
|
jamie@269
|
577 CAPTURE( expected );
|
jamie@269
|
578 REQUIRE( actual > min );
|
jamie@269
|
579 REQUIRE( actual < max );
|
jamie@269
|
580 }
|
jamie@269
|
581 }
|
jamie@269
|
582
|
jamie@269
|
583
|
jamie@269
|
584 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 4 cycles in the block
|
jamie@269
|
585 {
|
jamie@269
|
586 double frequency = 344.53125;
|
jamie@269
|
587
|
jamie@269
|
588 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
589 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
590
|
jamie@269
|
591 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
592 {
|
jamie@269
|
593 actual = xttest_ftom(result);
|
jamie@269
|
594 expected = xttest_ftom(frequency);
|
jamie@269
|
595 uint16_t min = expected - 50;
|
jamie@269
|
596 uint16_t max = expected + 50;
|
jamie@269
|
597 CAPTURE( actual );
|
jamie@269
|
598 CAPTURE( expected );
|
jamie@269
|
599 REQUIRE( actual > min );
|
jamie@269
|
600 REQUIRE( actual < max );
|
jamie@269
|
601 }
|
jamie@269
|
602
|
jamie@269
|
603
|
jamie@269
|
604 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case
|
jamie@269
|
605 {
|
jamie@269
|
606 double amplitude = 0.01;
|
jamie@269
|
607
|
jamie@269
|
608 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
609 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
610
|
jamie@269
|
611 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
612 {
|
jamie@269
|
613 actual = xttest_ftom(result);
|
jamie@269
|
614 expected = xttest_ftom(frequency);
|
jamie@269
|
615 uint16_t min = expected - 50;
|
jamie@269
|
616 uint16_t max = expected + 50;
|
jamie@269
|
617 CAPTURE( actual );
|
jamie@269
|
618 CAPTURE( expected );
|
jamie@269
|
619 REQUIRE( actual > min );
|
jamie@269
|
620 REQUIRE( actual < max );
|
jamie@269
|
621 }
|
jamie@269
|
622 }
|
jamie@269
|
623 }
|
jamie@269
|
624 }
|
jamie@269
|
625
|
jamie@269
|
626 GIVEN( "a 1024 sample block with a sample rate of 44100" )
|
jamie@269
|
627 {
|
jamie@269
|
628 uint32_t blocksize = 1024;
|
jamie@269
|
629 double samplerate = 44100;
|
jamie@269
|
630 double result = -1.0;
|
jamie@269
|
631 double amplitude = 1.0;
|
jamie@269
|
632 double table[blocksize];
|
jamie@269
|
633
|
jamie@269
|
634 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block
|
jamie@269
|
635 {
|
jamie@269
|
636 double frequency = 86.1328125;
|
jamie@269
|
637
|
jamie@269
|
638 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
639 int rv = xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
640
|
jamie@269
|
641 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
642 {
|
jamie@269
|
643 actual = xttest_ftom(result);
|
jamie@269
|
644 expected = xttest_ftom(frequency);
|
jamie@269
|
645 uint16_t min = expected - 50;
|
jamie@269
|
646 uint16_t max = expected + 50;
|
jamie@269
|
647 CAPTURE( actual );
|
jamie@269
|
648 CAPTURE( expected );
|
jamie@269
|
649 REQUIRE( actual > min );
|
jamie@269
|
650 REQUIRE( actual < max );
|
jamie@269
|
651 }
|
jamie@269
|
652 }
|
jamie@269
|
653
|
jamie@269
|
654 WHEN( "the frequency is 140 Hz" ) // period of 315 samples: 3.25 cycles in the block
|
jamie@269
|
655 {
|
jamie@269
|
656 double frequency = 140;
|
jamie@269
|
657
|
jamie@269
|
658 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
659 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
660
|
jamie@269
|
661 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
|
jamie@269
|
662 {
|
jamie@269
|
663 actual = xttest_ftom(result);
|
jamie@269
|
664 expected = xttest_ftom(frequency);
|
jamie@269
|
665 CAPTURE( actual );
|
jamie@269
|
666 CAPTURE( expected );
|
jamie@269
|
667 REQUIRE(actual == expected);
|
jamie@269
|
668 }
|
jamie@269
|
669 }
|
jamie@269
|
670
|
jamie@269
|
671 WHEN( "the frequency is 155 Hz" ) // period of 284.52 samples: 3.6 cycles in the block
|
jamie@269
|
672 {
|
jamie@269
|
673 double frequency = 155;
|
jamie@269
|
674
|
jamie@269
|
675 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
676 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
677
|
jamie@269
|
678 THEN( "the detected F0 is quantized to the nearest whole number of samples" )
|
jamie@269
|
679 {
|
jamie@269
|
680 actual = xttest_ftom(result);
|
jamie@269
|
681 expected = xttest_ftom(155.28169014); // period of 284 samples
|
jamie@269
|
682 CAPTURE( result );
|
jamie@269
|
683 CAPTURE( expected );
|
jamie@269
|
684 REQUIRE(actual == expected);
|
jamie@269
|
685 }
|
jamie@269
|
686 }
|
jamie@269
|
687
|
jamie@269
|
688
|
jamie@269
|
689 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block
|
jamie@269
|
690 {
|
jamie@269
|
691 double frequency = 172.265625;
|
jamie@269
|
692
|
jamie@269
|
693 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
694 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
695
|
jamie@269
|
696 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
697 {
|
jamie@269
|
698 actual = xttest_ftom(result);
|
jamie@269
|
699 expected = xttest_ftom(frequency);
|
jamie@269
|
700 uint16_t min = expected - 50;
|
jamie@269
|
701 uint16_t max = expected + 50;
|
jamie@269
|
702 CAPTURE( actual );
|
jamie@269
|
703 CAPTURE( expected );
|
jamie@269
|
704 REQUIRE( actual > min );
|
jamie@269
|
705 REQUIRE( actual < max );
|
jamie@269
|
706 }
|
jamie@269
|
707 }
|
jamie@269
|
708
|
jamie@269
|
709 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block
|
jamie@269
|
710 {
|
jamie@269
|
711 double frequency = 344.53125;
|
jamie@269
|
712 double noise[blocksize];
|
jamie@269
|
713 expected = xttest_ftom(frequency);
|
jamie@269
|
714 CAPTURE( expected );
|
jamie@269
|
715
|
jamie@269
|
716 WHEN( "the amplitude is 1.0" )
|
jamie@269
|
717 {
|
jamie@269
|
718 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
719 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
720
|
jamie@269
|
721 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
722 {
|
jamie@269
|
723 actual = xttest_ftom(result);
|
jamie@269
|
724 expected = xttest_ftom(frequency);
|
jamie@269
|
725 uint16_t min = expected - 50;
|
jamie@269
|
726 uint16_t max = expected + 50;
|
jamie@269
|
727 CAPTURE( actual );
|
jamie@269
|
728 CAPTURE( expected );
|
jamie@269
|
729 REQUIRE( actual > min );
|
jamie@269
|
730 REQUIRE( actual < max );
|
jamie@269
|
731 }
|
jamie@269
|
732 }
|
jamie@269
|
733
|
jamie@269
|
734 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case
|
jamie@269
|
735 {
|
jamie@269
|
736 amplitude = 0.01;
|
jamie@269
|
737
|
jamie@269
|
738 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
739 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
740
|
jamie@269
|
741 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
742 {
|
jamie@269
|
743 actual = xttest_ftom(result);
|
jamie@269
|
744 expected = xttest_ftom(frequency);
|
jamie@269
|
745 uint16_t min = expected - 50;
|
jamie@269
|
746 uint16_t max = expected + 50;
|
jamie@269
|
747 CAPTURE( actual );
|
jamie@269
|
748 CAPTURE( expected );
|
jamie@269
|
749 REQUIRE( actual > min );
|
jamie@269
|
750 REQUIRE( actual < max );
|
jamie@269
|
751 }
|
jamie@269
|
752 }
|
jamie@269
|
753
|
jamie@269
|
754 WHEN( "white noise is added at 10%" ) // Only test noise for one case
|
jamie@269
|
755 {
|
jamie@269
|
756 amplitude = 0.1;
|
jamie@269
|
757
|
jamie@269
|
758 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, 1.0 - amplitude);
|
jamie@269
|
759 xttest_gen_noise(noise, blocksize, amplitude);
|
jamie@269
|
760 xttest_add(table, noise, blocksize);
|
jamie@269
|
761 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
762
|
jamie@269
|
763 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
764 {
|
jamie@269
|
765 actual = xttest_ftom(result);
|
jamie@269
|
766 expected = xttest_ftom(frequency);
|
jamie@269
|
767 uint16_t min = expected - 50;
|
jamie@269
|
768 uint16_t max = expected + 50;
|
jamie@269
|
769 CAPTURE( actual );
|
jamie@269
|
770 CAPTURE( expected );
|
jamie@269
|
771 REQUIRE( actual > min );
|
jamie@269
|
772 REQUIRE( actual < max );
|
jamie@269
|
773 }
|
jamie@269
|
774 }
|
jamie@269
|
775
|
jamie@269
|
776 WHEN( "white noise is added at 20%" )
|
jamie@269
|
777 {
|
jamie@269
|
778 amplitude = 0.2;
|
jamie@269
|
779
|
jamie@269
|
780 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, 1.0 - amplitude);
|
jamie@269
|
781 xttest_gen_noise(noise, blocksize, amplitude);
|
jamie@269
|
782 xttest_add(table, noise, blocksize);
|
jamie@269
|
783 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
784
|
jamie@269
|
785 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
786 {
|
jamie@269
|
787 actual = xttest_ftom(result);
|
jamie@269
|
788 expected = xttest_ftom(frequency);
|
jamie@269
|
789 uint16_t min = expected - 50;
|
jamie@269
|
790 uint16_t max = expected + 50;
|
jamie@269
|
791 CAPTURE( actual );
|
jamie@269
|
792 CAPTURE( expected );
|
jamie@269
|
793 REQUIRE( actual > min );
|
jamie@269
|
794 REQUIRE( actual < max );
|
jamie@269
|
795 }
|
jamie@269
|
796 }
|
jamie@269
|
797
|
jamie@269
|
798 WHEN( "white noise is added at 25%" )
|
jamie@269
|
799 {
|
jamie@269
|
800 amplitude = 0.25;
|
jamie@269
|
801
|
jamie@269
|
802 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, 1.0 - amplitude);
|
jamie@269
|
803 xttest_gen_noise(noise, blocksize, amplitude);
|
jamie@269
|
804 xttest_add(table, noise, blocksize);
|
jamie@269
|
805 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
806
|
jamie@269
|
807 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
808 {
|
jamie@269
|
809 actual = xttest_ftom(result);
|
jamie@269
|
810 expected = xttest_ftom(frequency);
|
jamie@269
|
811 uint16_t min = expected - 50;
|
jamie@269
|
812 uint16_t max = expected + 50;
|
jamie@269
|
813 CAPTURE( actual );
|
jamie@269
|
814 CAPTURE( expected );
|
jamie@269
|
815 REQUIRE( actual > min );
|
jamie@269
|
816 REQUIRE( actual < max );
|
jamie@269
|
817 }
|
jamie@269
|
818 }
|
jamie@269
|
819
|
jamie@269
|
820 WHEN( "white noise is added at 30%" )
|
jamie@269
|
821 {
|
jamie@269
|
822 amplitude = 0.25;
|
jamie@269
|
823
|
jamie@269
|
824 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, 1.0 - amplitude);
|
jamie@269
|
825 xttest_gen_noise(noise, blocksize, amplitude);
|
jamie@269
|
826 xttest_add(table, noise, blocksize);
|
jamie@269
|
827 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
828
|
jamie@269
|
829 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
830 {
|
jamie@269
|
831 actual = xttest_ftom(result);
|
jamie@269
|
832 uint16_t min = expected - 50;
|
jamie@269
|
833 uint16_t max = expected + 50;
|
jamie@269
|
834 CAPTURE( actual );
|
jamie@269
|
835 REQUIRE( actual > min );
|
jamie@269
|
836 REQUIRE( actual < max );
|
jamie@269
|
837 }
|
jamie@269
|
838 }
|
jamie@269
|
839
|
jamie@269
|
840 WHEN( "white noise is added at 35%" )
|
jamie@269
|
841 {
|
jamie@269
|
842 amplitude = 0.35;
|
jamie@269
|
843
|
jamie@269
|
844 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, 1.0 - amplitude);
|
jamie@269
|
845 xttest_gen_noise(noise, blocksize, amplitude);
|
jamie@269
|
846 xttest_add(table, noise, blocksize);
|
jamie@269
|
847 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
848
|
jamie@269
|
849 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
850 {
|
jamie@269
|
851 actual = xttest_ftom(result);
|
jamie@269
|
852 expected = xttest_ftom(frequency);
|
jamie@269
|
853 uint16_t min = expected - 50;
|
jamie@269
|
854 uint16_t max = expected + 50;
|
jamie@269
|
855 CAPTURE( actual );
|
jamie@269
|
856 CAPTURE( expected );
|
jamie@269
|
857 REQUIRE( actual > min );
|
jamie@269
|
858 REQUIRE( actual < max );
|
jamie@269
|
859 }
|
jamie@269
|
860 }
|
jamie@269
|
861 }
|
jamie@269
|
862 }
|
jamie@269
|
863
|
jamie@269
|
864 GIVEN( "a 1024 sample block with a sample rate of 11025" )
|
jamie@269
|
865 {
|
jamie@269
|
866 uint32_t blocksize = 1024;
|
jamie@269
|
867 double samplerate = 11025;
|
jamie@269
|
868 double result = -1.0;
|
jamie@269
|
869 double table[blocksize];
|
jamie@269
|
870
|
jamie@269
|
871 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block
|
jamie@269
|
872 {
|
jamie@269
|
873 double frequency = 86.1328125;
|
jamie@269
|
874 double amplitude = 1.0;
|
jamie@269
|
875
|
jamie@269
|
876 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
877 int rv = xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
878
|
jamie@269
|
879 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
880 {
|
jamie@269
|
881 actual = xttest_ftom(result);
|
jamie@269
|
882 expected = xttest_ftom(frequency);
|
jamie@269
|
883 uint16_t min = expected - 50;
|
jamie@269
|
884 uint16_t max = expected + 50;
|
jamie@269
|
885 CAPTURE( actual );
|
jamie@269
|
886 CAPTURE( expected );
|
jamie@269
|
887 REQUIRE( actual > min );
|
jamie@269
|
888 REQUIRE( actual < max );
|
jamie@269
|
889 }
|
jamie@269
|
890 }
|
jamie@269
|
891
|
jamie@269
|
892 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block
|
jamie@269
|
893 {
|
jamie@269
|
894 double frequency = 172.265625;
|
jamie@269
|
895 double amplitude = 1.0;
|
jamie@269
|
896
|
jamie@269
|
897 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
898 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
899
|
jamie@269
|
900 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
901 {
|
jamie@269
|
902 actual = xttest_ftom(result);
|
jamie@269
|
903 expected = xttest_ftom(frequency);
|
jamie@269
|
904 uint16_t min = expected - 50;
|
jamie@269
|
905 uint16_t max = expected + 50;
|
jamie@269
|
906 CAPTURE( actual );
|
jamie@269
|
907 CAPTURE( expected );
|
jamie@269
|
908 REQUIRE( actual > min );
|
jamie@269
|
909 REQUIRE( actual < max );
|
jamie@269
|
910 }
|
jamie@269
|
911 }
|
jamie@269
|
912
|
jamie@269
|
913 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block
|
jamie@269
|
914 {
|
jamie@269
|
915 double frequency = 344.53125;
|
jamie@269
|
916 expected = xttest_ftom(frequency);
|
jamie@269
|
917 CAPTURE( expected );
|
jamie@269
|
918
|
jamie@269
|
919 WHEN( "the amplitude is 1.0" )
|
jamie@269
|
920 {
|
jamie@269
|
921 double amplitude = 1.0;
|
jamie@269
|
922
|
jamie@269
|
923 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
924 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
925
|
jamie@269
|
926 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
927 {
|
jamie@269
|
928 actual = xttest_ftom(result);
|
jamie@269
|
929 expected = xttest_ftom(frequency);
|
jamie@269
|
930 uint16_t min = expected - 50;
|
jamie@269
|
931 uint16_t max = expected + 50;
|
jamie@269
|
932 CAPTURE( actual );
|
jamie@269
|
933 CAPTURE( expected );
|
jamie@269
|
934 REQUIRE( actual > min );
|
jamie@269
|
935 REQUIRE( actual < max );
|
jamie@269
|
936 }
|
jamie@269
|
937 }
|
jamie@269
|
938
|
jamie@269
|
939 WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case
|
jamie@269
|
940 {
|
jamie@269
|
941 double amplitude = 0.01;
|
jamie@269
|
942
|
jamie@269
|
943 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
944 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
945
|
jamie@269
|
946 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
947 {
|
jamie@269
|
948 actual = xttest_ftom(result);
|
jamie@269
|
949 expected = xttest_ftom(frequency);
|
jamie@269
|
950 uint16_t min = expected - 50;
|
jamie@269
|
951 uint16_t max = expected + 50;
|
jamie@269
|
952 CAPTURE( actual );
|
jamie@269
|
953 CAPTURE( expected );
|
jamie@269
|
954 REQUIRE( actual > min );
|
jamie@269
|
955 REQUIRE( actual < max );
|
jamie@269
|
956 }
|
jamie@269
|
957 }
|
jamie@269
|
958
|
jamie@269
|
959 WHEN( "white noise is added at 20%" )
|
jamie@269
|
960 {
|
jamie@269
|
961 double amplitude = 0.2;
|
jamie@269
|
962 double noise[blocksize];
|
jamie@269
|
963
|
jamie@269
|
964 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, 1.0 - amplitude);
|
jamie@269
|
965 xttest_gen_noise(noise, blocksize, amplitude);
|
jamie@269
|
966 xttest_add(table, noise, blocksize);
|
jamie@269
|
967 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
968
|
jamie@269
|
969 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
970 {
|
jamie@269
|
971 actual = xttest_ftom(result);
|
jamie@269
|
972 uint16_t min = expected - 50;
|
jamie@269
|
973 uint16_t max = expected + 50;
|
jamie@269
|
974 CAPTURE( actual );
|
jamie@269
|
975 REQUIRE( actual > min );
|
jamie@269
|
976 REQUIRE( actual < max );
|
jamie@269
|
977 }
|
jamie@269
|
978 }
|
jamie@269
|
979
|
jamie@269
|
980 WHEN( "white noise is added at 40%" )
|
jamie@269
|
981 {
|
jamie@269
|
982 double amplitude = 0.4;
|
jamie@269
|
983 double noise[blocksize];
|
jamie@269
|
984
|
jamie@269
|
985 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, 1.0 - amplitude);
|
jamie@269
|
986 xttest_gen_noise(noise, blocksize, amplitude);
|
jamie@269
|
987 xttest_add(table, noise, blocksize);
|
jamie@269
|
988 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
989
|
jamie@269
|
990 THEN( "the detected F0 is inaccurate by more than one semitone" )
|
jamie@269
|
991 {
|
jamie@269
|
992 actual = xttest_ftom(result);
|
jamie@269
|
993 uint16_t difference = abs(expected - actual);
|
jamie@269
|
994 CAPTURE( actual );
|
jamie@269
|
995 REQUIRE( difference > 100 );
|
jamie@269
|
996 }
|
jamie@269
|
997 }
|
jamie@269
|
998 }
|
jamie@269
|
999 }
|
jamie@269
|
1000
|
jamie@269
|
1001 GIVEN( "a 2048 sample block with a sample rate of 44100" )
|
jamie@269
|
1002 {
|
jamie@269
|
1003 uint32_t blocksize = 2048;
|
jamie@269
|
1004 double samplerate = 44100;
|
jamie@269
|
1005 double result = -1.0;
|
jamie@269
|
1006 double table[blocksize];
|
jamie@269
|
1007
|
jamie@269
|
1008 WHEN( "the frequency is 43.06640625 Hz" ) // period of exactly 256 samples: 2 cycles in the block
|
jamie@269
|
1009 {
|
jamie@269
|
1010 double frequency = 43.06640625;
|
jamie@269
|
1011 double amplitude = 1.0;
|
jamie@269
|
1012
|
jamie@269
|
1013 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
1014 int rv = xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
1015
|
jamie@269
|
1016 THEN( "the detected F0 is accurate to the nearest quarter-tone" )
|
jamie@269
|
1017 {
|
jamie@269
|
1018 actual = xttest_ftom(result);
|
jamie@269
|
1019 expected = xttest_ftom(frequency);
|
jamie@269
|
1020 uint16_t min = expected - 50;
|
jamie@269
|
1021 uint16_t max = expected + 50;
|
jamie@269
|
1022 CAPTURE( actual );
|
jamie@269
|
1023 CAPTURE( expected );
|
jamie@269
|
1024 REQUIRE( actual > min );
|
jamie@269
|
1025 REQUIRE( actual < max );
|
jamie@269
|
1026 }
|
jamie@269
|
1027 }
|
jamie@269
|
1028
|
jamie@269
|
1029 WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 4 cycles in the block
|
jamie@269
|
1030 {
|
jamie@269
|
1031 double frequency = 86.1328125;
|
jamie@269
|
1032 double amplitude = 1.0;
|
jamie@269
|
1033
|
jamie@269
|
1034 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
1035 int rv = xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
1036
|
jamie@269
|
1037 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
|
jamie@269
|
1038 {
|
jamie@269
|
1039 actual = xttest_ftom(result);
|
jamie@269
|
1040 expected = xttest_ftom(frequency);
|
jamie@269
|
1041 CAPTURE( actual );
|
jamie@269
|
1042 CAPTURE( expected );
|
jamie@269
|
1043 REQUIRE(actual == expected);
|
jamie@269
|
1044 }
|
jamie@269
|
1045 }
|
jamie@269
|
1046
|
jamie@269
|
1047 WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 8 cycles in the block
|
jamie@269
|
1048 {
|
jamie@269
|
1049 double frequency = 172.265625;
|
jamie@269
|
1050 double amplitude = 1.0;
|
jamie@269
|
1051
|
jamie@269
|
1052 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
1053 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
1054
|
jamie@269
|
1055 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
|
jamie@269
|
1056 {
|
jamie@269
|
1057 actual = xttest_ftom(result);
|
jamie@269
|
1058 expected = xttest_ftom(frequency);
|
jamie@269
|
1059 CAPTURE( actual );
|
jamie@269
|
1060 CAPTURE( expected );
|
jamie@269
|
1061 REQUIRE(actual == expected);
|
jamie@269
|
1062 }
|
jamie@269
|
1063 }
|
jamie@269
|
1064
|
jamie@269
|
1065 WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 16 cycles in the block
|
jamie@269
|
1066 {
|
jamie@269
|
1067 double frequency = 344.53125;
|
jamie@269
|
1068
|
jamie@269
|
1069 WHEN( "the amplitude is 1.0" )
|
jamie@269
|
1070 {
|
jamie@269
|
1071 double amplitude = 1.0;
|
jamie@269
|
1072
|
jamie@269
|
1073 xttest_gen_sawtooth(table, blocksize, samplerate, frequency, amplitude);
|
jamie@269
|
1074 xtract_f0(table, blocksize, &samplerate, &result);
|
jamie@269
|
1075
|
jamie@269
|
1076 THEN( "the detected F0 is accurate to the nearest MIDI cent" )
|
jamie@269
|
1077 {
|
jamie@269
|
1078 actual = xttest_ftom(result);
|
jamie@269
|
1079 expected = xttest_ftom(frequency);
|
jamie@269
|
1080 CAPTURE( actual );
|
jamie@269
|
1081 CAPTURE( expected );
|
jamie@269
|
1082 REQUIRE(actual == expected);
|
jamie@269
|
1083 }
|
jamie@269
|
1084 }
|
jamie@269
|
1085 }
|
jamie@269
|
1086 }
|
jamie@269
|
1087 }
|
jamie@269
|
1088
|