Mercurial > hg > libxtract
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 } |
