Chris@126
|
1
|
Chris@126
|
2 #include "FeatureExtractor.h"
|
Chris@126
|
3
|
Chris@126
|
4 #include <vector>
|
Chris@126
|
5 #include <iostream>
|
Chris@126
|
6 #include <cmath>
|
Chris@126
|
7
|
Chris@126
|
8 using namespace std;
|
Chris@126
|
9
|
Chris@126
|
10 #define BOOST_TEST_DYN_LINK
|
Chris@126
|
11 #define BOOST_TEST_MAIN
|
Chris@126
|
12
|
Chris@126
|
13 #include <boost/test/unit_test.hpp>
|
Chris@126
|
14
|
Chris@126
|
15 static int freq2mid(double freq)
|
Chris@126
|
16 {
|
Chris@126
|
17 return round(57.0 + 12.0 * log(freq / 220.) / log(2.));
|
Chris@126
|
18 }
|
Chris@126
|
19
|
Chris@126
|
20 static int freq2chroma(double freq)
|
Chris@126
|
21 {
|
Chris@126
|
22 return freq2mid(freq) % 12;
|
Chris@126
|
23 }
|
Chris@126
|
24
|
Chris@126
|
25 BOOST_AUTO_TEST_SUITE(TestFeatureExtractor)
|
Chris@126
|
26
|
Chris@126
|
27 BOOST_AUTO_TEST_CASE(chroma)
|
Chris@126
|
28 {
|
Chris@126
|
29 int rate = 44100;
|
Chris@126
|
30 int sz = 2048;
|
Chris@126
|
31 int hs = sz / 2 + 1;
|
Chris@126
|
32 int fsz = 13;
|
Chris@126
|
33
|
Chris@126
|
34 FeatureExtractor::Parameters params(rate, sz);
|
Chris@126
|
35 params.useChromaFrequencyMap = true;
|
Chris@126
|
36 FeatureExtractor fe(params);
|
Chris@126
|
37 BOOST_CHECK_EQUAL(fe.getFeatureSize(), fsz);
|
Chris@126
|
38
|
Chris@126
|
39 for (int bin = 0; bin < hs; ++bin) {
|
Chris@126
|
40
|
Chris@126
|
41 vector<double> real, imag;
|
Chris@126
|
42 real.resize(hs, 0.0);
|
Chris@126
|
43 imag.resize(hs, 0.0);
|
Chris@126
|
44
|
Chris@126
|
45 real[bin] += 10.0;
|
Chris@126
|
46 imag[bin] += 10.0;
|
Chris@126
|
47
|
Chris@126
|
48 // use two input sweeps, so we can test that they are properly
|
Chris@126
|
49 // summed into the output bin
|
Chris@126
|
50 real[hs-bin-1] += 5.0;
|
Chris@126
|
51 imag[hs-bin-1] += 5.0;
|
Chris@126
|
52
|
Chris@126
|
53 vector<double> out = fe.process(real, imag);
|
Chris@126
|
54
|
Chris@126
|
55 // We expect to find all bins are 0 except for:
|
Chris@126
|
56 //
|
Chris@126
|
57 // * two bins of 200 and 50 respectively, if the two input
|
Chris@126
|
58 // bins are distinct and their output chroma are also distinct
|
Chris@126
|
59 //
|
Chris@126
|
60 // * one bin of value 250 (= 10^2 + 5^2), if the two input
|
Chris@126
|
61 // bins are distinct but their output chroma are not
|
Chris@126
|
62 //
|
Chris@126
|
63 // * one bin of value 450 (= 15^2 + 15^2), if the input bins
|
Chris@126
|
64 // are not distinct
|
Chris@126
|
65 //
|
Chris@126
|
66 // The bin corresponding to each input frequency is that of
|
Chris@126
|
67 // its semitone value (with C=0), except that input bin
|
Chris@126
|
68 // frequencies less than 362Hz are shepherded into the
|
Chris@126
|
69 // separate bin 0 (see docs in FeatureExtractor.h)
|
Chris@126
|
70
|
Chris@126
|
71 vector<double> expected(fsz);
|
Chris@126
|
72
|
Chris@126
|
73 double infreq1 = (double(bin) * rate) / sz;
|
Chris@126
|
74
|
Chris@126
|
75 if (bin == hs-bin-1) {
|
Chris@126
|
76 expected[freq2chroma(infreq1) + 1] += 450;
|
Chris@126
|
77 } else {
|
Chris@126
|
78 if (infreq1 < 362) {
|
Chris@126
|
79 expected[0] += 200;
|
Chris@126
|
80 } else {
|
Chris@126
|
81 expected[freq2chroma(infreq1) + 1] += 200;
|
Chris@126
|
82 }
|
Chris@126
|
83 double infreq2 = (double(hs-bin-1) * rate) / sz;
|
Chris@126
|
84 if (infreq2 < 362) {
|
Chris@126
|
85 expected[0] += 50;
|
Chris@126
|
86 } else {
|
Chris@126
|
87 expected[freq2chroma(infreq2) + 1] += 50;
|
Chris@126
|
88 }
|
Chris@126
|
89 }
|
Chris@126
|
90
|
Chris@126
|
91 BOOST_CHECK_EQUAL_COLLECTIONS(out.begin(), out.end(),
|
Chris@126
|
92 expected.begin(), expected.end());
|
Chris@126
|
93 }
|
Chris@126
|
94 }
|
Chris@126
|
95
|
Chris@126
|
96 BOOST_AUTO_TEST_SUITE_END()
|