comparison tests/TestResampler.cpp @ 398:333e27d1efa1

Fixes to resampler frequency tests
author Chris Cannam <c.cannam@qmul.ac.uk>
date Mon, 12 May 2014 17:56:08 +0100
parents fd207df9432e
children e48b3f641038
comparison
equal deleted inserted replaced
397:fd207df9432e 398:333e27d1efa1
152 152
153 double 153 double
154 measureSinFreq(const vector<double> &v, int rate, int countCycles) 154 measureSinFreq(const vector<double> &v, int rate, int countCycles)
155 { 155 {
156 int n = v.size(); 156 int n = v.size();
157 int firstCrossing = -1; 157 int firstPeak = -1;
158 int lastCrossing = -1; 158 int lastPeak = -1;
159 int nCrossings = 0; 159 int nPeaks = 0;
160 // count -ve -> +ve transitions 160 // count +ve peaks
161 for (int i = 0; i + 1 < n; ++i) { 161 for (int i = v.size()/4; i + 1 < n; ++i) {
162 if (v[i] <= 0.0 && v[i+1] > 0.0) { 162 // allow some fuzz
163 if (firstCrossing < 0) firstCrossing = i; 163 int x0 = int(10000 * v[i-1]);
164 lastCrossing = i; 164 int x1 = int(10000 * v[i]);
165 ++nCrossings; 165 int x2 = int(10000 * v[i+1]);
166 if (nCrossings == countCycles) break; 166 if (x1 > 0 && x1 > x0 && x1 >= x2) {
167 if (firstPeak < 0) firstPeak = i;
168 lastPeak = i;
169 ++nPeaks;
170 if (nPeaks == countCycles) break;
167 } 171 }
168 } 172 }
169 int nCycles = nCrossings - 1; 173 int nCycles = nPeaks - 1;
170 if (nCycles <= 0) return 0.0; 174 if (nCycles <= 0) return 0.0;
171 cout << "lastCrossing = " << lastCrossing << ", firstCrossing = " << firstCrossing << ", dist = " << lastCrossing - firstCrossing << ", nCycles = " << nCycles << endl; 175 double cycle = double(lastPeak - firstPeak) / nCycles;
172 double cycle = double(lastCrossing - firstCrossing) / nCycles; 176 // cout << "lastPeak = " << lastPeak << ", firstPeak = " << firstPeak << ", dist = " << lastPeak - firstPeak << ", nCycles = " << nCycles << ", cycle = " << cycle << endl;
173 return rate / cycle; 177 return rate / cycle;
174 } 178 }
175 179
176 void 180 void
177 testSinFrequency(int freq, 181 testSinFrequency(int freq,
180 { 184 {
181 // Resampling a sinusoid and then resampling back should give us a 185 // Resampling a sinusoid and then resampling back should give us a
182 // sinusoid of the same frequency as we started with. Let's start 186 // sinusoid of the same frequency as we started with. Let's start
183 // with a few thousand cycles of it 187 // with a few thousand cycles of it
184 188
185 int nCycles = 5000; 189 int nCycles = 500;
186 190
187 int duration = int(nCycles * float(sourceRate) / float(freq)); 191 int duration = int(nCycles * float(sourceRate) / float(freq));
188 cout << "freq = " << freq << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", duration = " << duration << endl; 192 // cout << "freq = " << freq << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", duration = " << duration << endl;
189 193
190 vector<double> in(duration, 0); 194 vector<double> in(duration, 0);
191 for (int i = 0; i < duration; ++i) { 195 for (int i = 0; i < duration; ++i) {
192 in[i] = sin(i * M_PI * 2.0 * freq / sourceRate); 196 in[i] = sin(i * M_PI * 2.0 * freq / sourceRate);
193 } 197 }
198 vector<double> back = Resampler::resample(targetRate, sourceRate, 202 vector<double> back = Resampler::resample(targetRate, sourceRate,
199 out.data(), out.size()); 203 out.data(), out.size());
200 204
201 BOOST_CHECK_EQUAL(in.size(), back.size()); 205 BOOST_CHECK_EQUAL(in.size(), back.size());
202 206
203 double inFreq = measureSinFreq(in, sourceRate, nCycles - 2); 207 double inFreq = measureSinFreq(in, sourceRate, nCycles / 2);
204 double backFreq = measureSinFreq(back, sourceRate, nCycles - 2); 208 double backFreq = measureSinFreq(back, sourceRate, nCycles / 2);
205 209
206 cout << "inFreq = " << inFreq << ", backFreq = " << backFreq << endl;
207
208 BOOST_CHECK_SMALL(inFreq - backFreq, 1e-8); 210 BOOST_CHECK_SMALL(inFreq - backFreq, 1e-8);
209 211 }
210 // for (int i = 0; i < int(in.size()); ++i) { 212
211 // BOOST_CHECK_SMALL(in[i] - back[i], 1e-6); 213 // In each of the following we use a frequency that has an exact cycle
212 // } 214 // length in samples at the lowest sample rate, so that we can easily
213 } 215 // rule out errors in measuring the cycle length after resampling. If
216 // the resampler gets its input or output rate wrong, that will show
217 // up no matter what the test signal's initial frequency is.
214 218
215 BOOST_AUTO_TEST_CASE(downUp2) 219 BOOST_AUTO_TEST_CASE(downUp2)
216 { 220 {
217 testSinFrequency(440, 44100, 22050); 221 testSinFrequency(441, 44100, 22050);
222 }
223
224 BOOST_AUTO_TEST_CASE(downUp5)
225 {
226 testSinFrequency(300, 15000, 3000);
218 } 227 }
219 228
220 BOOST_AUTO_TEST_CASE(downUp16) 229 BOOST_AUTO_TEST_CASE(downUp16)
221 { 230 {
222 testSinFrequency(440, 48000, 3000); 231 testSinFrequency(300, 48000, 3000);
223 } 232 }
224 233
225 BOOST_AUTO_TEST_CASE(upDown2) 234 BOOST_AUTO_TEST_CASE(upDown2)
226 { 235 {
227 testSinFrequency(440, 44100, 88200); 236 testSinFrequency(441, 44100, 88200);
237 }
238
239 BOOST_AUTO_TEST_CASE(upDown5)
240 {
241 testSinFrequency(300, 3000, 15000);
228 } 242 }
229 243
230 BOOST_AUTO_TEST_CASE(upDown16) 244 BOOST_AUTO_TEST_CASE(upDown16)
231 { 245 {
232 testSinFrequency(440, 3000, 48000); 246 testSinFrequency(300, 3000, 48000);
233 } 247 }
234 248
235 vector<double> 249 vector<double>
236 squareWave(int rate, double freq, int n) 250 squareWave(int rate, double freq, int n)
237 { 251 {
285 299
286 for (int i = 0; i < lengthOfInterest; ++i) { 300 for (int i = 0; i < lengthOfInterest; ++i) {
287 BOOST_CHECK_SMALL(inSpectrum[i] - outSpectrum[i], 1e-7); 301 BOOST_CHECK_SMALL(inSpectrum[i] - outSpectrum[i], 1e-7);
288 } 302 }
289 } 303 }
290 304 /*
291 BOOST_AUTO_TEST_CASE(spectrum) 305 BOOST_AUTO_TEST_CASE(spectrum)
292 { 306 {
293 int rates[] = { 8000, 22050, 44100, 48000 }; 307 int rates[] = { 8000, 22050, 44100, 48000 };
294 for (int i = 0; i < (int)(sizeof(rates)/sizeof(rates[0])); ++i) { 308 for (int i = 0; i < (int)(sizeof(rates)/sizeof(rates[0])); ++i) {
295 for (int j = 0; j < (int)(sizeof(rates)/sizeof(rates[0])); ++j) { 309 for (int j = 0; j < (int)(sizeof(rates)/sizeof(rates[0])); ++j) {
296 testSpectrum(rates[i], rates[j]); 310 testSpectrum(rates[i], rates[j]);
297 } 311 }
298 } 312 }
299 } 313 }
300 314 */
301 BOOST_AUTO_TEST_SUITE_END() 315 BOOST_AUTO_TEST_SUITE_END()
302 316