changeset 135:cb0f0e317a33

Different interpolation types; start on timing tests
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 19 May 2014 13:02:08 +0100
parents 7b48d7ae41e4
children 8970f4838285
files Makefile.inc test/TestCQFrequency.cpp test/TestCQTime.cpp
diffstat 3 files changed, 118 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.inc	Mon May 19 12:50:26 2014 +0100
+++ b/Makefile.inc	Mon May 19 13:02:08 2014 +0100
@@ -69,6 +69,7 @@
 
 TEST_SOURCES	:= \
 	$(TEST_DIR)/TestCQFrequency.cpp \
+	$(TEST_DIR)/TestCQTime.cpp \
 	$(TEST_DIR)/TestFFT.cpp \
 	$(TEST_DIR)/TestMathUtilities.cpp \
 	$(TEST_DIR)/TestResampler.cpp \
@@ -146,6 +147,8 @@
 vamp/Pitch.o: vamp/Pitch.h
 test/TestCQFrequency.o: cq/CQSpectrogram.h cq/ConstantQ.h cq/CQBase.h
 test/TestCQFrequency.o: cq/CQParameters.h cq/CQKernel.h src/dsp/Window.h
+test/TestCQTime.o: cq/CQSpectrogram.h cq/ConstantQ.h cq/CQBase.h
+test/TestCQTime.o: cq/CQParameters.h cq/CQKernel.h src/dsp/Window.h
 test/TestFFT.o: src/dsp/FFT.h
 test/TestMathUtilities.o: src/dsp/MathUtilities.h src/dsp/nan-inf.h
 test/TestResampler.o: src/dsp/Resampler.h src/dsp/Window.h src/dsp/FFT.h
--- a/test/TestCQFrequency.cpp	Mon May 19 12:50:26 2014 +0100
+++ b/test/TestCQFrequency.cpp	Mon May 19 13:02:08 2014 +0100
@@ -42,7 +42,8 @@
 }
 
 void
-checkCQFreqColumn(int i, vector<double> column, double freq)
+checkCQFreqColumn(int i, vector<double> column,
+                  double freq, CQSpectrogram::Interpolation interp)
 {
     double maxval = 0.0;
     int maxidx = -1;
@@ -53,20 +54,24 @@
             maxidx = j;
         }
     }
+
+    int nonZeroHeight = height;
+    if (interp == CQSpectrogram::InterpolateZeros && i % 2 == 1) {
+        nonZeroHeight = height / 2;
+    }
+
     int expected = binForFrequency(freq);
     if (maxval < threshold) {
         return; // ignore these columns at start and end
-    } else {
-        if (maxidx != expected) {
-            cerr << "ERROR: In column " << i << ", maximum value for frequency "
-                 << freq << " found at index " << maxidx << endl
-                 << "(expected index " << expected << ")" << endl;
-            cerr << "column contains: ";
-            for (int j = 0; j < height; ++j) {
-                cerr << column[j] << " ";
-            }
-            cerr << endl;
+    } else if (expected < nonZeroHeight && maxidx != expected) {
+        cerr << "ERROR: In column " << i << ", maximum value for frequency "
+             << freq << " found at index " << maxidx << endl
+             << "(expected index " << expected << ")" << endl;
+        cerr << "column contains: ";
+        for (int j = 0; j < height; ++j) {
+            cerr << column[j] << " ";
         }
+        cerr << endl;
         BOOST_CHECK_EQUAL(maxidx, expected);
     }
 }
@@ -74,26 +79,37 @@
 void
 testCQFrequency(double freq)
 {
-    CQParameters params(sampleRate, cqmin, cqmax, bpo);
-    CQSpectrogram cq(params, CQSpectrogram::InterpolateLinear);
+    vector<CQSpectrogram::Interpolation> interpolationTypes;
+    interpolationTypes.push_back(CQSpectrogram::InterpolateZeros);
+    interpolationTypes.push_back(CQSpectrogram::InterpolateHold);
+    interpolationTypes.push_back(CQSpectrogram::InterpolateLinear);
 
-    BOOST_CHECK_EQUAL(cq.getBinsPerOctave(), bpo);
-    BOOST_CHECK_EQUAL(cq.getOctaves(), 2);
+    for (int k = 0; k < int(interpolationTypes.size()); ++k) {
 
-    vector<double> input;
-    for (int i = 0; i < duration; ++i) {
-        input.push_back(sin((i * 2 * M_PI * freq) / sampleRate));
-    }
-    Window<double>(HanningWindow, duration).cut(input.data());
+        CQSpectrogram::Interpolation interp = interpolationTypes[k];
 
-    CQSpectrogram::RealBlock output = cq.process(input);
-    CQSpectrogram::RealBlock rest = cq.getRemainingOutput();
-    output.insert(output.end(), rest.begin(), rest.end());
+        CQParameters params(sampleRate, cqmin, cqmax, bpo);
+        CQSpectrogram cq(params, interp);
 
-    BOOST_CHECK_EQUAL(output[0].size(), cq.getBinsPerOctave() * cq.getOctaves());
+        BOOST_CHECK_EQUAL(cq.getBinsPerOctave(), bpo);
+        BOOST_CHECK_EQUAL(cq.getOctaves(), 2);
 
-    for (int i = 0; i < int(output.size()); ++i) {
-        checkCQFreqColumn(i, output[i], freq);
+        vector<double> input;
+        for (int i = 0; i < duration; ++i) {
+            input.push_back(sin((i * 2 * M_PI * freq) / sampleRate));
+        }
+        Window<double>(HanningWindow, duration).cut(input.data());
+
+        CQSpectrogram::RealBlock output = cq.process(input);
+        CQSpectrogram::RealBlock rest = cq.getRemainingOutput();
+        output.insert(output.end(), rest.begin(), rest.end());
+
+        BOOST_CHECK_EQUAL(output[0].size(), 
+                          cq.getBinsPerOctave() * cq.getOctaves());
+
+        for (int i = 0; i < int(output.size()); ++i) {
+            checkCQFreqColumn(i, output[i], freq, interp);
+        }
     }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/TestCQTime.cpp	Mon May 19 13:02:08 2014 +0100
@@ -0,0 +1,73 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+#include "cq/CQSpectrogram.h"
+
+#include "dsp/Window.h"
+
+#include <cmath>
+#include <vector>
+#include <iostream>
+
+using std::vector;
+using std::cerr;
+using std::endl;
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MAIN
+
+#include <boost/test/unit_test.hpp>
+
+BOOST_AUTO_TEST_SUITE(TestCQTime)
+
+// Principle: Run a Dirac impulse through the CQ transform and check
+// that its output has all the peak bins aligned correctly in time.
+
+// Set up fs/2 = 50, frequency range 10 -> 40 i.e. 2 octaves, fixed
+// duration of 2 seconds
+static const double sampleRate = 100;
+static const double cqmin = 10;
+static const double cqmax = 40;
+static const double bpo = 4;
+static const int duration = sampleRate * 2;
+
+// Threshold below which to ignore a column completely
+static const double threshold = 0.08;
+
+void
+testCQTime(double t)
+{
+    vector<CQSpectrogram::Interpolation> interpolationTypes;
+    interpolationTypes.push_back(CQSpectrogram::InterpolateZeros);
+    interpolationTypes.push_back(CQSpectrogram::InterpolateHold);
+    interpolationTypes.push_back(CQSpectrogram::InterpolateLinear);
+
+    for (int k = 0; k < int(interpolationTypes.size()); ++k) {
+
+        CQParameters params(sampleRate, cqmin, cqmax, bpo);
+        CQSpectrogram cq(params, interpolationTypes[k]);
+
+        BOOST_CHECK_EQUAL(cq.getBinsPerOctave(), bpo);
+        BOOST_CHECK_EQUAL(cq.getOctaves(), 2);
+
+        //!!! generate input signal
+        vector<double> input;
+
+
+        CQSpectrogram::RealBlock output = cq.process(input);
+        CQSpectrogram::RealBlock rest = cq.getRemainingOutput();
+        output.insert(output.end(), rest.begin(), rest.end());
+
+        BOOST_CHECK_EQUAL(output[0].size(), 
+                          cq.getBinsPerOctave() * cq.getOctaves());
+
+        //!!! test output signal
+    }
+}
+
+BOOST_AUTO_TEST_CASE(time_zero) { testCQTime(0); }
+BOOST_AUTO_TEST_CASE(time_half) { testCQTime(0.5); }
+BOOST_AUTO_TEST_CASE(time_one) { testCQTime(1.0); }
+BOOST_AUTO_TEST_CASE(time_two) { testCQTime(2.0); }
+
+BOOST_AUTO_TEST_SUITE_END()
+