comparison tests/TestResampler.cpp @ 397:fd207df9432e

Construct a currently-failing test on exact frequency in resampler (tracking down error in CQ)
author Chris Cannam <c.cannam@qmul.ac.uk>
date Sat, 10 May 2014 13:41:06 +0100
parents 88971211795c
children 333e27d1efa1
comparison
equal deleted inserted replaced
396:b63c22ce235b 397:fd207df9432e
148 out[i] = sin(i * M_PI / 4.0); 148 out[i] = sin(i * M_PI / 4.0);
149 } 149 }
150 testResamplerOneShot(16, 8, 2000, in, 200, out, 256); 150 testResamplerOneShot(16, 8, 2000, in, 200, out, 256);
151 } 151 }
152 152
153 double
154 measureSinFreq(const vector<double> &v, int rate, int countCycles)
155 {
156 int n = v.size();
157 int firstCrossing = -1;
158 int lastCrossing = -1;
159 int nCrossings = 0;
160 // count -ve -> +ve transitions
161 for (int i = 0; i + 1 < n; ++i) {
162 if (v[i] <= 0.0 && v[i+1] > 0.0) {
163 if (firstCrossing < 0) firstCrossing = i;
164 lastCrossing = i;
165 ++nCrossings;
166 if (nCrossings == countCycles) break;
167 }
168 }
169 int nCycles = nCrossings - 1;
170 if (nCycles <= 0) return 0.0;
171 cout << "lastCrossing = " << lastCrossing << ", firstCrossing = " << firstCrossing << ", dist = " << lastCrossing - firstCrossing << ", nCycles = " << nCycles << endl;
172 double cycle = double(lastCrossing - firstCrossing) / nCycles;
173 return rate / cycle;
174 }
175
176 void
177 testSinFrequency(int freq,
178 int sourceRate,
179 int targetRate)
180 {
181 // Resampling a sinusoid and then resampling back should give us a
182 // sinusoid of the same frequency as we started with. Let's start
183 // with a few thousand cycles of it
184
185 int nCycles = 5000;
186
187 int duration = int(nCycles * float(sourceRate) / float(freq));
188 cout << "freq = " << freq << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", duration = " << duration << endl;
189
190 vector<double> in(duration, 0);
191 for (int i = 0; i < duration; ++i) {
192 in[i] = sin(i * M_PI * 2.0 * freq / sourceRate);
193 }
194
195 vector<double> out = Resampler::resample(sourceRate, targetRate,
196 in.data(), in.size());
197
198 vector<double> back = Resampler::resample(targetRate, sourceRate,
199 out.data(), out.size());
200
201 BOOST_CHECK_EQUAL(in.size(), back.size());
202
203 double inFreq = measureSinFreq(in, sourceRate, nCycles - 2);
204 double backFreq = measureSinFreq(back, sourceRate, nCycles - 2);
205
206 cout << "inFreq = " << inFreq << ", backFreq = " << backFreq << endl;
207
208 BOOST_CHECK_SMALL(inFreq - backFreq, 1e-8);
209
210 // for (int i = 0; i < int(in.size()); ++i) {
211 // BOOST_CHECK_SMALL(in[i] - back[i], 1e-6);
212 // }
213 }
214
215 BOOST_AUTO_TEST_CASE(downUp2)
216 {
217 testSinFrequency(440, 44100, 22050);
218 }
219
220 BOOST_AUTO_TEST_CASE(downUp16)
221 {
222 testSinFrequency(440, 48000, 3000);
223 }
224
225 BOOST_AUTO_TEST_CASE(upDown2)
226 {
227 testSinFrequency(440, 44100, 88200);
228 }
229
230 BOOST_AUTO_TEST_CASE(upDown16)
231 {
232 testSinFrequency(440, 3000, 48000);
233 }
234
153 vector<double> 235 vector<double>
154 squareWave(int rate, double freq, int n) 236 squareWave(int rate, double freq, int n)
155 { 237 {
156 //!!! todo: hoist, test 238 //!!! todo: hoist, test
157 vector<double> v(n, 0.0); 239 vector<double> v(n, 0.0);