diff dsp/rateconversion/TestResampler.cpp @ 143:a4aa37f7af28

Some fixes, and start on spectrum test
author Chris Cannam
date Tue, 15 Oct 2013 18:27:19 +0100
parents f8fc21365a8c
children b21e97d570be
line wrap: on
line diff
--- a/dsp/rateconversion/TestResampler.cpp	Mon Oct 14 16:20:00 2013 +0100
+++ b/dsp/rateconversion/TestResampler.cpp	Tue Oct 15 18:27:19 2013 +0100
@@ -2,6 +2,9 @@
 
 #include "Resampler.h"
 
+#include "qm-dsp/base/Window.h"
+#include "qm-dsp/dsp/transforms/FFT.h"
+
 #include <iostream>
 
 #include <cmath>
@@ -147,5 +150,68 @@
     testResamplerOneShot(16, 8, 2000, in, 200, out, 256);
 }
 
+vector<double>
+squareWave(int rate, int freq, int n)
+{
+    //!!! todo: hoist, test
+    vector<double> v(n, 0.0);
+    for (int h = 0; h < (rate/4)/freq; ++h) {
+	double m = h * 2 + 1;
+	double scale = 1 / m;
+	for (int i = 0; i < n; ++i) {
+	    v[i] += scale * sin(i * 2 * M_PI * freq / rate);
+	}
+    }
+    return v;
+}
+
+void
+testSpectrum(int inrate, int outrate)
+{
+    // One second of a square wave
+    int freq = 500;
+
+    std::cerr << "inrate = " << inrate << ", outrate = " << outrate << ", freq * outrate / inrate = " << (double(freq) * double(outrate)) / double(inrate) << std::endl;
+
+    std::cerr << "making square wave... ";
+    vector<double> square =
+	squareWave(inrate, freq, inrate);
+    std::cerr << "done" << std::endl;
+
+    vector<double> maybeSquare = 
+	Resampler::resample(inrate, outrate, square.data(), square.size());
+
+    BOOST_CHECK_EQUAL(maybeSquare.size(), outrate);
+
+    Window<double>(HanningWindow, inrate).cut(square.data());
+    Window<double>(HanningWindow, outrate).cut(maybeSquare.data());
+
+    // forward magnitude with size inrate, outrate
+
+    vector<double> inSpectrum(inrate, 0.0);
+    FFTReal(inrate).forwardMagnitude(square.data(), inSpectrum.data());
+
+    vector<double> outSpectrum(outrate, 0.0);
+    FFTReal(outrate).forwardMagnitude(maybeSquare.data(), outSpectrum.data());
+
+    // Don't compare bins any higher than 99% of Nyquist freq of lower sr
+    int lengthOfInterest = (inrate < outrate ? inrate : outrate) / 2;
+    lengthOfInterest = lengthOfInterest - (lengthOfInterest / 100);
+
+    for (int i = 0; i < lengthOfInterest; ++i) {
+	BOOST_CHECK_SMALL(inSpectrum[i] - outSpectrum[i], 1e-7);
+    }
+}
+
+BOOST_AUTO_TEST_CASE(spectrum)
+{
+    int rates[] = { 8000, 22050, 44100, 48000 };
+    for (int i = 0; i < sizeof(rates)/sizeof(rates[0]); ++i) {
+	for (int j = 0; j < sizeof(rates)/sizeof(rates[0]); ++j) {
+	    testSpectrum(rates[i], rates[j]);
+	}
+    }
+}
+
 BOOST_AUTO_TEST_SUITE_END()