Mercurial > hg > match-vamp
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 { |