Mercurial > hg > libxtract
diff 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 |
line wrap: on
line diff
--- a/tests/xttest_scalar.cpp Tue Nov 11 16:15:28 2014 +0000 +++ b/tests/xttest_scalar.cpp Tue Nov 11 17:01:47 2014 +0000 @@ -11,7 +11,7 @@ { uint16_t expected = 0; uint16_t actual = 0; - + GIVEN( "a 512 sample block with a sample rate of 44100" ) { uint32_t blocksize = 512; @@ -19,39 +19,40 @@ double result = -1.0; double amplitude = 1.0; double table[blocksize]; - + WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 1 cycles in the block { double frequency = 86.1328125; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); int rv = xtract_f0(table, blocksize, &samplerate, &result); - + THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) { REQUIRE(rv == XTRACT_NO_RESULT); REQUIRE(result == 0.0); } } - + WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 2 cycles in the block { double frequency = 172.265625; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); int rv = xtract_f0(table, blocksize, &samplerate, &result); - + THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) { REQUIRE(rv == XTRACT_NO_RESULT); REQUIRE(result == 0.0); } } - + + WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 4 cycles in the block { double frequency = 344.53125; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); xtract_f0(table, blocksize, &samplerate, &result); @@ -63,15 +64,15 @@ CAPTURE( expected ); REQUIRE(actual == expected); } - - + + WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case { double amplitude = 0.01; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); xtract_f0(table, blocksize, &samplerate, &result); - + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) { actual = xttest_ftom(result); @@ -83,27 +84,233 @@ } } } - + GIVEN( "a 1024 sample block with a sample rate of 44100" ) { uint32_t blocksize = 1024; double samplerate = 44100; double result = -1.0; + double amplitude = 1.0; + double table[blocksize]; + + WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block + { + double frequency = 86.1328125; + + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); + int rv = xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) + { + REQUIRE(rv == XTRACT_NO_RESULT); + REQUIRE(result == 0.0); + } + } + + WHEN( "the frequency is 140 Hz" ) // period of 315 samples: 3.25 cycles in the block + { + double frequency = 140; + + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) + { + actual = xttest_ftom(result); + expected = xttest_ftom(frequency); + CAPTURE( actual ); + CAPTURE( expected ); + REQUIRE(actual == expected); + } + } + + WHEN( "the frequency is 155 Hz" ) // period of 284.52 samples: 3.6 cycles in the block + { + double frequency = 155; + + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is quantized to the nearest whole number of samples" ) + { + actual = xttest_ftom(result); + expected = xttest_ftom(155.28169014); // period of 284 samples + CAPTURE( result ); + CAPTURE( expected ); + REQUIRE(actual == expected); + } + } + + + WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block + { + double frequency = 172.265625; + + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) + { + actual = xttest_ftom(result); + expected = xttest_ftom(frequency); + CAPTURE( actual ); + CAPTURE( expected ); + REQUIRE(actual == expected); + } + } + + WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block + { + double frequency = 344.53125; + double noise[blocksize]; + expected = xttest_ftom(frequency); + CAPTURE( expected ); + + WHEN( "the amplitude is 1.0" ) + { + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) + { + actual = xttest_ftom(result); + CAPTURE( actual ); + REQUIRE(actual == expected); + } + } + + WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case + { + amplitude = 0.01; + + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) + { + actual = xttest_ftom(result); + CAPTURE( actual ); + REQUIRE(actual == expected); + } + } + + WHEN( "white noise is added at 10%" ) // Only test noise for one case + { + amplitude = 0.1; + + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); + xttest_gen_noise(noise, blocksize, amplitude); + xttest_add(table, noise, blocksize); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) + { + actual = xttest_ftom(result); + CAPTURE( actual ); + REQUIRE(actual == expected); + } + } + + WHEN( "white noise is added at 20%" ) + { + amplitude = 0.2; + + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); + xttest_gen_noise(noise, blocksize, amplitude); + xttest_add(table, noise, blocksize); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) + { + actual = xttest_ftom(result); + CAPTURE( actual ); + REQUIRE(actual == expected); + } + } + + WHEN( "white noise is added at 25%" ) + { + amplitude = 0.25; + + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); + xttest_gen_noise(noise, blocksize, amplitude); + xttest_add(table, noise, blocksize); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest semitone" ) + { + actual = xttest_ftom(result); + uint16_t min = expected - 100; + uint16_t max = expected + 100; + CAPTURE( actual ); + REQUIRE( actual > min ); + REQUIRE( actual < max ); + } + } + + WHEN( "white noise is added at 30%" ) + { + amplitude = 0.25; + + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); + xttest_gen_noise(noise, blocksize, amplitude); + xttest_add(table, noise, blocksize); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest quarter-tone" ) + { + actual = xttest_ftom(result); + uint16_t min = expected - 50; + uint16_t max = expected + 50; + CAPTURE( actual ); + REQUIRE( actual > min ); + REQUIRE( actual < max ); + } + } + + WHEN( "white noise is added at 35%" ) + { + amplitude = 0.35; + + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); + xttest_gen_noise(noise, blocksize, amplitude); + xttest_add(table, noise, blocksize); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is inaccurate by more than one semitone" ) + { + actual = xttest_ftom(result); + uint16_t difference = abs(expected - actual); + CAPTURE( actual ); + REQUIRE( difference > 100 ); + } + } + } + } + + GIVEN( "a 1024 sample block with a sample rate of 11025" ) + { + uint32_t blocksize = 1024; + double samplerate = 11025; + double result = -1.0; double table[blocksize]; WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block { double frequency = 86.1328125; double amplitude = 1.0; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); int rv = xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) + + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) { - REQUIRE(rv == XTRACT_NO_RESULT); - REQUIRE(result == 0.0); - } + actual = xttest_ftom(result); + expected = xttest_ftom(frequency); + CAPTURE( actual ); + CAPTURE( expected ); + REQUIRE(actual == expected); + } } WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block @@ -144,7 +351,7 @@ REQUIRE(actual == expected); } } - + WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case { double amplitude = 0.01; @@ -159,74 +366,17 @@ REQUIRE(actual == expected); } } - - WHEN( "white noise is added at 10%" ) // Only test noise for one case + + WHEN( "white noise is added at 20%" ) { - double amplitude = 0.1; + double amplitude = 0.2; double noise[blocksize]; - + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); xttest_gen_noise(noise, blocksize, amplitude); xttest_add(table, noise, blocksize); xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest MIDI cent" ) - { - actual = xttest_ftom(result); - CAPTURE( actual ); - REQUIRE(actual == expected); - } - } - - WHEN( "white noise is added at 20%" ) - { - double amplitude = 0.2; - double noise[blocksize]; - - xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); - xttest_gen_noise(noise, blocksize, amplitude); - xttest_add(table, noise, blocksize); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest MIDI cent" ) - { - actual = xttest_ftom(result); - CAPTURE( actual ); - REQUIRE(actual == expected); - } - } - - WHEN( "white noise is added at 25%" ) - { - double amplitude = 0.25; - double noise[blocksize]; - - xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); - xttest_gen_noise(noise, blocksize, amplitude); - xttest_add(table, noise, blocksize); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest semitone" ) - { - actual = xttest_ftom(result); - uint16_t min = expected - 100; - uint16_t max = expected + 100; - CAPTURE( actual ); - REQUIRE( actual > min ); - REQUIRE( actual < max ); - } - } - - WHEN( "white noise is added at 30%" ) - { - double amplitude = 0.25; - double noise[blocksize]; - - xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); - xttest_gen_noise(noise, blocksize, amplitude); - xttest_add(table, noise, blocksize); - xtract_f0(table, blocksize, &samplerate, &result); - + THEN( "the detected F0 is accurate to the nearest quarter-tone" ) { actual = xttest_ftom(result); @@ -235,19 +385,61 @@ CAPTURE( actual ); REQUIRE( actual > min ); REQUIRE( actual < max ); - } + } } - - WHEN( "white noise is added at 35%" ) + + WHEN( "white noise is added at 40%" ) { - double amplitude = 0.35; + double amplitude = 0.4; double noise[blocksize]; - + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); xttest_gen_noise(noise, blocksize, amplitude); xttest_add(table, noise, blocksize); xtract_f0(table, blocksize, &samplerate, &result); - + + THEN( "the detected F0 is accurate to the nearest semi-tone" ) + { + actual = xttest_ftom(result); + uint16_t min = expected - 100; + uint16_t max = expected + 100; + CAPTURE( actual ); + REQUIRE( actual > min ); + REQUIRE( actual < max ); + } + } + + WHEN( "white noise is added at 60%" ) + { + double amplitude = 0.6; + double noise[blocksize]; + + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); + xttest_gen_noise(noise, blocksize, amplitude); + xttest_add(table, noise, blocksize); + xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "the detected F0 is accurate to the nearest semi-tone" ) + { + actual = xttest_ftom(result); + uint16_t min = expected - 100; + uint16_t max = expected + 100; + CAPTURE( actual ); + REQUIRE( actual > min ); + REQUIRE( actual < max ); + } + } + + WHEN( "white noise is added at 80%" ) + { + double amplitude = 0.8; + double noise[blocksize]; + + xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); + xttest_gen_noise(noise, blocksize, amplitude); + xttest_add(table, noise, blocksize); + xtract_f0(table, blocksize, &samplerate, &result); + THEN( "the detected F0 is inaccurate by more than one semitone" ) { actual = xttest_ftom(result); @@ -258,40 +450,37 @@ } } } - - GIVEN( "a 1024 sample block with a sample rate of 11025" ) + + GIVEN( "a 2048 sample block with a sample rate of 44100" ) { - uint32_t blocksize = 1024; - double samplerate = 11025; + uint32_t blocksize = 2048; + double samplerate = 44100; double result = -1.0; double table[blocksize]; - - WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 2 cycles in the block + + WHEN( "the frequency is 43.06640625 Hz" ) // period of exactly 256 samples: 2 cycles in the block + { + double frequency = 43.06640625; + double amplitude = 1.0; + + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); + int rv = xtract_f0(table, blocksize, &samplerate, &result); + + THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) + { + REQUIRE(rv == XTRACT_NO_RESULT); + REQUIRE(result == 0.0); + } + } + + WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 4 cycles in the block { double frequency = 86.1328125; double amplitude = 1.0; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); int rv = xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest MIDI cent" ) - { - actual = xttest_ftom(result); - expected = xttest_ftom(frequency); - CAPTURE( actual ); - CAPTURE( expected ); - REQUIRE(actual == expected); - } - } - - WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 4 cycles in the block - { - double frequency = 172.265625; - double amplitude = 1.0; - - xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); - xtract_f0(table, blocksize, &samplerate, &result); - + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) { actual = xttest_ftom(result); @@ -301,157 +490,15 @@ REQUIRE(actual == expected); } } - - WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 8 cycles in the block + + WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 8 cycles in the block { - double frequency = 344.53125; - expected = xttest_ftom(frequency); - CAPTURE( expected ); - - WHEN( "the amplitude is 1.0" ) - { - double amplitude = 1.0; - - xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest MIDI cent" ) - { - actual = xttest_ftom(result); - CAPTURE( actual ); - REQUIRE(actual == expected); - } - } - - WHEN( "the amplitude is 0.01" ) // Only test a different amplitude for one case - { - double amplitude = 0.01; - - xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest MIDI cent" ) - { - actual = xttest_ftom(result); - CAPTURE( actual ); - REQUIRE(actual == expected); - } - } - - WHEN( "white noise is added at 20%" ) - { - double amplitude = 0.2; - double noise[blocksize]; - - xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); - xttest_gen_noise(noise, blocksize, amplitude); - xttest_add(table, noise, blocksize); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest quarter-tone" ) - { - actual = xttest_ftom(result); - uint16_t min = expected - 50; - uint16_t max = expected + 50; - CAPTURE( actual ); - REQUIRE( actual > min ); - REQUIRE( actual < max ); - } - } - - WHEN( "white noise is added at 40%" ) - { - double amplitude = 0.4; - double noise[blocksize]; - - xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); - xttest_gen_noise(noise, blocksize, amplitude); - xttest_add(table, noise, blocksize); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest semi-tone" ) - { - actual = xttest_ftom(result); - uint16_t min = expected - 100; - uint16_t max = expected + 100; - CAPTURE( actual ); - REQUIRE( actual > min ); - REQUIRE( actual < max ); - } - } - - WHEN( "white noise is added at 60%" ) - { - double amplitude = 0.6; - double noise[blocksize]; - - xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); - xttest_gen_noise(noise, blocksize, amplitude); - xttest_add(table, noise, blocksize); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest semi-tone" ) - { - actual = xttest_ftom(result); - uint16_t min = expected - 100; - uint16_t max = expected + 100; - CAPTURE( actual ); - REQUIRE( actual > min ); - REQUIRE( actual < max ); - } - } - - WHEN( "white noise is added at 80%" ) - { - double amplitude = 0.8; - double noise[blocksize]; - - xttest_gen_sine(table, blocksize, samplerate, frequency, 1.0 - amplitude); - xttest_gen_noise(noise, blocksize, amplitude); - xttest_add(table, noise, blocksize); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is inaccurate by more than one semitone" ) - { - actual = xttest_ftom(result); - uint16_t difference = abs(expected - actual); - CAPTURE( actual ); - REQUIRE( difference > 100 ); - } - } - } - } - - GIVEN( "a 2048 sample block with a sample rate of 44100" ) - { - uint32_t blocksize = 2048; - double samplerate = 44100; - double result = -1.0; - double table[blocksize]; - - WHEN( "the frequency is 43.06640625 Hz" ) // period of exactly 256 samples: 2 cycles in the block - { - double frequency = 43.06640625; + double frequency = 172.265625; double amplitude = 1.0; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); - int rv = xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "frequency detection fails correctly (XTRACT_NO_RESULT is returned, result set to 0.0)" ) - { - REQUIRE(rv == XTRACT_NO_RESULT); - REQUIRE(result == 0.0); - } - } - - WHEN( "the frequency is 86.1328125 Hz" ) // period of exactly 512 samples: 4 cycles in the block - { - double frequency = 86.1328125; - double amplitude = 1.0; - - xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); - int rv = xtract_f0(table, blocksize, &samplerate, &result); - + xtract_f0(table, blocksize, &samplerate, &result); + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) { actual = xttest_ftom(result); @@ -461,36 +508,18 @@ REQUIRE(actual == expected); } } - - WHEN( "the frequency is 172.265625 Hz" ) // period of exactly 256 samples: 8 cycles in the block - { - double frequency = 172.265625; - double amplitude = 1.0; - - xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); - xtract_f0(table, blocksize, &samplerate, &result); - - THEN( "the detected F0 is accurate to the nearest MIDI cent" ) - { - actual = xttest_ftom(result); - expected = xttest_ftom(frequency); - CAPTURE( actual ); - CAPTURE( expected ); - REQUIRE(actual == expected); - } - } - + WHEN( "the frequency is 344.53125 Hz" ) // period of exactly 128 samples: 16 cycles in the block { double frequency = 344.53125; - + WHEN( "the amplitude is 1.0" ) { double amplitude = 1.0; - + xttest_gen_sine(table, blocksize, samplerate, frequency, amplitude); xtract_f0(table, blocksize, &samplerate, &result); - + THEN( "the detected F0 is accurate to the nearest MIDI cent" ) { actual = xttest_ftom(result); @@ -499,7 +528,7 @@ CAPTURE( expected ); REQUIRE(actual == expected); } - } + } } } }