comparison test/TestFeatureExtractor.cpp @ 129:dad9fdc32a6a refactors

Generalise chroma test at least to other frame/samplerate etc
author Chris Cannam
date Thu, 11 Dec 2014 12:54:46 +0000
parents 3f32a88ee15a
children 8e240bbea845
comparison
equal deleted inserted replaced
128:3f32a88ee15a 129:dad9fdc32a6a
35 35
36 BOOST_AUTO_TEST_SUITE(TestFeatureExtractor) 36 BOOST_AUTO_TEST_SUITE(TestFeatureExtractor)
37 37
38 BOOST_AUTO_TEST_CASE(chroma) 38 BOOST_AUTO_TEST_CASE(chroma)
39 { 39 {
40 int rate = 44100; 40 int szs[] = { 1024, 2048, 4000 };
41 int sz = 2048; 41 int rates[] = { 44100, 48000 };
42 int hs = sz / 2 + 1;
43 int fsz = 13;
44 42
45 FeatureExtractor::Parameters params(rate, sz); 43 for (int irate = 0; irate < int(sizeof(rates)/sizeof(rates[0])); ++irate) {
46 params.useChromaFrequencyMap = true;
47 FeatureExtractor fe(params);
48 BOOST_CHECK_EQUAL(fe.getFeatureSize(), fsz);
49 44
50 for (int bin = 0; bin < hs; ++bin) { 45 int rate = rates[irate];
51 46
52 vector<double> real, imag; 47 for (int isz = 0; isz < int(sizeof(szs)/sizeof(szs[0])); ++isz) {
53 real.resize(hs, 0.0); 48
54 imag.resize(hs, 0.0); 49 int sz = szs[isz];
50
51 int hs = sz / 2 + 1;
52 int fsz = 13;
53
54 FeatureExtractor::Parameters params(rate, sz);
55 params.useChromaFrequencyMap = true;
56 FeatureExtractor fe(params);
57 BOOST_CHECK_EQUAL(fe.getFeatureSize(), fsz);
58
59 for (int bin = 0; bin < hs; ++bin) {
60
61 vector<double> real, imag;
62 real.resize(hs, 0.0);
63 imag.resize(hs, 0.0);
55 64
56 real[bin] += 10.0; 65 real[bin] += 10.0;
57 imag[bin] += 10.0; 66 imag[bin] += 10.0;
58 67
59 // use two input sweeps, so we can test that they are properly 68 // use two input sweeps, so we can test that they are
60 // summed into the output bin 69 // properly summed into the output bin
61 real[hs-bin-1] += 5.0; 70 real[hs-bin-1] += 5.0;
62 imag[hs-bin-1] += 5.0; 71 imag[hs-bin-1] += 5.0;
72
73 vector<double> out = fe.process(real, imag);
63 74
64 vector<double> out = fe.process(real, imag); 75 // We expect to find all bins are 0 except for:
76 //
77 // * two bins of 200 and 50 respectively, if the two input
78 // bins are distinct and their output chroma are also distinct
79 //
80 // * one bin of value 250 (= 10^2 + 5^2), if the two input
81 // bins are distinct but their output chroma are not
82 //
83 // * one bin of value 450 (= 15^2 + 15^2), if the input bins
84 // are not distinct (the feature extractor sums energies
85 // rather than magnitudes so as to integrate energy for a
86 // partial in the face of spectral leakage)
87 //
88 // The bin corresponding to each input frequency is
89 // that of its semitone value (with C=0), except that
90 // input bins less than the 17th are shepherded into
91 // the separate bin 0 (see docs in FeatureExtractor.h)
65 92
66 // We expect to find all bins are 0 except for: 93 double cutoff = (17.0 * rate) / sz;
67 // 94
68 // * two bins of 200 and 50 respectively, if the two input 95 vector<double> expected(fsz);
69 // bins are distinct and their output chroma are also distinct
70 //
71 // * one bin of value 250 (= 10^2 + 5^2), if the two input
72 // bins are distinct but their output chroma are not
73 //
74 // * one bin of value 450 (= 15^2 + 15^2), if the input bins
75 // are not distinct (the feature extractor sums energies
76 // rather than magnitudes so as to integrate energy for a
77 // partial in the face of spectral leakage)
78 //
79 // The bin corresponding to each input frequency is that of
80 // its semitone value (with C=0), except that input bin
81 // frequencies less than 362Hz are shepherded into the
82 // separate bin 0 (see docs in FeatureExtractor.h)
83 96
84 vector<double> expected(fsz); 97 double infreq1 = (double(bin) * rate) / sz;
85 98
86 double infreq1 = (double(bin) * rate) / sz; 99 if (bin == hs-bin-1) {
100 expected[freq2chroma(infreq1) + 1] += 450;
101 } else {
102 if (infreq1 < cutoff) {
103 expected[0] += 200;
104 } else {
105 expected[freq2chroma(infreq1) + 1] += 200;
106 }
107 double infreq2 = (double(hs-bin-1) * rate) / sz;
108 if (infreq2 < cutoff) {
109 expected[0] += 50;
110 } else {
111 expected[freq2chroma(infreq2) + 1] += 50;
112 }
113 }
87 114
88 if (bin == hs-bin-1) { 115 BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(),
89 expected[freq2chroma(infreq1) + 1] += 450; 116 expected.begin(), expected.end());
90 } else {
91 if (infreq1 < 362) {
92 expected[0] += 200;
93 } else {
94 expected[freq2chroma(infreq1) + 1] += 200;
95 }
96 double infreq2 = (double(hs-bin-1) * rate) / sz;
97 if (infreq2 < 362) {
98 expected[0] += 50;
99 } else {
100 expected[freq2chroma(infreq2) + 1] += 50;
101 } 117 }
102 } 118 }
103
104 BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(),
105 expected.begin(), expected.end());
106 } 119 }
107 } 120 }
108 121
109 BOOST_AUTO_TEST_CASE(nonchroma) 122 BOOST_AUTO_TEST_CASE(nonchroma)
110 { 123 {