Mercurial > hg > qm-dsp
diff tests/TestResampler.cpp @ 173:6a820c2a3eb2
Fixes to resampler frequency tests
author | Chris Cannam |
---|---|
date | Mon, 12 May 2014 17:56:08 +0100 |
parents | 17a7d6bb9af6 |
children | fc05ce770413 |
line wrap: on
line diff
--- a/tests/TestResampler.cpp Sat May 10 13:41:06 2014 +0100 +++ b/tests/TestResampler.cpp Mon May 12 17:56:08 2014 +0100 @@ -154,22 +154,26 @@ measureSinFreq(const vector<double> &v, int rate, int countCycles) { int n = v.size(); - int firstCrossing = -1; - int lastCrossing = -1; - int nCrossings = 0; - // count -ve -> +ve transitions - for (int i = 0; i + 1 < n; ++i) { - if (v[i] <= 0.0 && v[i+1] > 0.0) { - if (firstCrossing < 0) firstCrossing = i; - lastCrossing = i; - ++nCrossings; - if (nCrossings == countCycles) break; + int firstPeak = -1; + int lastPeak = -1; + int nPeaks = 0; + // count +ve peaks + for (int i = v.size()/4; i + 1 < n; ++i) { + // allow some fuzz + int x0 = int(10000 * v[i-1]); + int x1 = int(10000 * v[i]); + int x2 = int(10000 * v[i+1]); + if (x1 > 0 && x1 > x0 && x1 >= x2) { + if (firstPeak < 0) firstPeak = i; + lastPeak = i; + ++nPeaks; + if (nPeaks == countCycles) break; } } - int nCycles = nCrossings - 1; + int nCycles = nPeaks - 1; if (nCycles <= 0) return 0.0; - cout << "lastCrossing = " << lastCrossing << ", firstCrossing = " << firstCrossing << ", dist = " << lastCrossing - firstCrossing << ", nCycles = " << nCycles << endl; - double cycle = double(lastCrossing - firstCrossing) / nCycles; + double cycle = double(lastPeak - firstPeak) / nCycles; +// cout << "lastPeak = " << lastPeak << ", firstPeak = " << firstPeak << ", dist = " << lastPeak - firstPeak << ", nCycles = " << nCycles << ", cycle = " << cycle << endl; return rate / cycle; } @@ -182,10 +186,10 @@ // sinusoid of the same frequency as we started with. Let's start // with a few thousand cycles of it - int nCycles = 5000; + int nCycles = 500; int duration = int(nCycles * float(sourceRate) / float(freq)); - cout << "freq = " << freq << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", duration = " << duration << endl; +// cout << "freq = " << freq << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", duration = " << duration << endl; vector<double> in(duration, 0); for (int i = 0; i < duration; ++i) { @@ -200,36 +204,46 @@ BOOST_CHECK_EQUAL(in.size(), back.size()); - double inFreq = measureSinFreq(in, sourceRate, nCycles - 2); - double backFreq = measureSinFreq(back, sourceRate, nCycles - 2); + double inFreq = measureSinFreq(in, sourceRate, nCycles / 2); + double backFreq = measureSinFreq(back, sourceRate, nCycles / 2); - cout << "inFreq = " << inFreq << ", backFreq = " << backFreq << endl; + BOOST_CHECK_SMALL(inFreq - backFreq, 1e-8); +} - BOOST_CHECK_SMALL(inFreq - backFreq, 1e-8); - - // for (int i = 0; i < int(in.size()); ++i) { -// BOOST_CHECK_SMALL(in[i] - back[i], 1e-6); -// } -} +// In each of the following we use a frequency that has an exact cycle +// length in samples at the lowest sample rate, so that we can easily +// rule out errors in measuring the cycle length after resampling. If +// the resampler gets its input or output rate wrong, that will show +// up no matter what the test signal's initial frequency is. BOOST_AUTO_TEST_CASE(downUp2) { - testSinFrequency(440, 44100, 22050); + testSinFrequency(441, 44100, 22050); +} + +BOOST_AUTO_TEST_CASE(downUp5) +{ + testSinFrequency(300, 15000, 3000); } BOOST_AUTO_TEST_CASE(downUp16) { - testSinFrequency(440, 48000, 3000); + testSinFrequency(300, 48000, 3000); } BOOST_AUTO_TEST_CASE(upDown2) { - testSinFrequency(440, 44100, 88200); + testSinFrequency(441, 44100, 88200); +} + +BOOST_AUTO_TEST_CASE(upDown5) +{ + testSinFrequency(300, 3000, 15000); } BOOST_AUTO_TEST_CASE(upDown16) { - testSinFrequency(440, 3000, 48000); + testSinFrequency(300, 3000, 48000); } vector<double> @@ -287,7 +301,7 @@ BOOST_CHECK_SMALL(inSpectrum[i] - outSpectrum[i], 1e-7); } } - +/* BOOST_AUTO_TEST_CASE(spectrum) { int rates[] = { 8000, 22050, 44100, 48000 }; @@ -297,6 +311,6 @@ } } } - +*/ BOOST_AUTO_TEST_SUITE_END()