annotate test/TestFeatureExtractor.cpp @ 126:0ed1adb2d522 refactors

Chroma feature test case
author Chris Cannam
date Thu, 11 Dec 2014 11:41:25 +0000
parents
children 2ed42b7616c5
rev   line source
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()