Mercurial > hg > silvet
comparison constant-q-cpp/test/TestCQTime.cpp @ 366:5d0a2ebb4d17
Bring dependent libraries in to repo
author | Chris Cannam |
---|---|
date | Fri, 24 Jun 2016 14:47:45 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
365:112766f4c34b | 366:5d0a2ebb4d17 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 #include "cq/CQSpectrogram.h" | |
4 | |
5 #include "dsp/Window.h" | |
6 | |
7 #include <cmath> | |
8 #include <vector> | |
9 #include <iostream> | |
10 | |
11 using std::vector; | |
12 using std::cerr; | |
13 using std::endl; | |
14 | |
15 #define BOOST_TEST_DYN_LINK | |
16 #define BOOST_TEST_MAIN | |
17 | |
18 #include <boost/test/unit_test.hpp> | |
19 | |
20 BOOST_AUTO_TEST_SUITE(TestCQTime) | |
21 | |
22 // Principle: Run a Dirac impulse through the CQ transform and check | |
23 // that its output has all the peak bins aligned correctly in time. | |
24 | |
25 // Set up fs/2 = 50, frequency range 10 -> 40 i.e. 2 octaves, fixed | |
26 // duration of 2 seconds | |
27 static const double sampleRate = 100; | |
28 static const double cqmin = 10; | |
29 static const double cqmax = 40; | |
30 static const double bpo = 4; | |
31 static const int duration = sampleRate * 2; | |
32 | |
33 // Threshold below which to ignore a column completely | |
34 static const double threshold = 0.08; | |
35 | |
36 void | |
37 testCQTime(double t) | |
38 { | |
39 vector<CQSpectrogram::Interpolation> interpolationTypes; | |
40 interpolationTypes.push_back(CQSpectrogram::InterpolateZeros); | |
41 interpolationTypes.push_back(CQSpectrogram::InterpolateHold); | |
42 interpolationTypes.push_back(CQSpectrogram::InterpolateLinear); | |
43 | |
44 for (int k = 0; k < int(interpolationTypes.size()); ++k) { | |
45 | |
46 CQSpectrogram::Interpolation interp = interpolationTypes[k]; | |
47 | |
48 CQParameters params(sampleRate, cqmin, cqmax, bpo); | |
49 CQSpectrogram cq(params, interp); | |
50 | |
51 BOOST_CHECK_EQUAL(cq.getBinsPerOctave(), bpo); | |
52 BOOST_CHECK_EQUAL(cq.getOctaves(), 2); | |
53 | |
54 vector<double> input(duration, 0.0); | |
55 int ix = int(floor(t * sampleRate)); | |
56 if (ix >= duration) ix = duration-1; | |
57 input[ix] = 1.0; | |
58 | |
59 CQSpectrogram::RealBlock output = cq.process(input); | |
60 CQSpectrogram::RealBlock rest = cq.getRemainingOutput(); | |
61 output.insert(output.end(), rest.begin(), rest.end()); | |
62 | |
63 BOOST_CHECK_EQUAL(output[0].size(), | |
64 cq.getBinsPerOctave() * cq.getOctaves()); | |
65 | |
66 vector<int> peaks; | |
67 double eps = 1e-8; | |
68 | |
69 for (int j = 0; j < int(output[0].size()); ++j) { | |
70 | |
71 int maxidx = -1; | |
72 double max = 0.0; | |
73 for (int i = 0; i < int(output.size()); ++i) { | |
74 double value = output[i][j]; | |
75 if (i == 0 || value + eps > max) { | |
76 max = value; | |
77 maxidx = i; | |
78 } | |
79 } | |
80 | |
81 peaks.push_back(maxidx); | |
82 } | |
83 | |
84 for (int j = 1; j < int(peaks.size()); ++j) { | |
85 int oct = j / bpo; | |
86 int spacing = (1 << oct); | |
87 int actual = peaks[j]/spacing; | |
88 int expected = int(round(double(peaks[0])/spacing)); | |
89 if (actual != expected) { | |
90 cerr << "ERROR: In row " << j << " (bin freq " | |
91 << cq.getBinFrequency(j) << "), interpolation " << interp | |
92 << ", maximum value for time " << t | |
93 << "\n found at index " << peaks[j] | |
94 << " of " << output.size() << " which does not align with" | |
95 << " highest frequency\n bin peak at " << peaks[0] | |
96 << " given octave spacing of " << spacing | |
97 << "\n [latency = " << cq.getLatency() | |
98 << ", hop = " << cq.getColumnHop() << ", duration = " | |
99 << duration << ", ix = " << ix << "]" << endl; | |
100 cerr << "row contains: "; | |
101 for (int i = 0; i < int(output.size()); ++i) { | |
102 if (i == expected * spacing) cerr << "*"; | |
103 if (i == peaks[j]) cerr << "**"; | |
104 cerr << output[i][j] << " "; | |
105 } | |
106 cerr << endl; | |
107 | |
108 BOOST_CHECK_EQUAL(actual, expected); | |
109 } | |
110 } | |
111 } | |
112 } | |
113 | |
114 BOOST_AUTO_TEST_CASE(time_zero) { testCQTime(0); } | |
115 BOOST_AUTO_TEST_CASE(time_half) { testCQTime(0.5); } | |
116 BOOST_AUTO_TEST_CASE(time_one) { testCQTime(1.0); } | |
117 BOOST_AUTO_TEST_CASE(time_two) { testCQTime(2.0); } | |
118 | |
119 BOOST_AUTO_TEST_SUITE_END() | |
120 |