annotate test/TestCQTime.cpp @ 196:da283326bcd3 tip master

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