comparison dsp/rateconversion/Resampler.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 b63c22ce235b
children 6a634a9081a8
comparison
equal deleted inserted replaced
397:fd207df9432e 398:333e27d1efa1
24 #include <map> 24 #include <map>
25 #include <cassert> 25 #include <cassert>
26 26
27 using std::vector; 27 using std::vector;
28 using std::map; 28 using std::map;
29 using std::cerr;
30 using std::endl;
29 31
30 //#define DEBUG_RESAMPLER 1 32 //#define DEBUG_RESAMPLER 1
31 //#define DEBUG_RESAMPLER_VERBOSE 33 //#define DEBUG_RESAMPLER_VERBOSE 1
32 34
33 Resampler::Resampler(int sourceRate, int targetRate) : 35 Resampler::Resampler(int sourceRate, int targetRate) :
34 m_sourceRate(sourceRate), 36 m_sourceRate(sourceRate),
35 m_targetRate(targetRate) 37 m_targetRate(targetRate)
36 { 38 {
104 106
105 int inputSpacing = m_targetRate / m_gcd; 107 int inputSpacing = m_targetRate / m_gcd;
106 int outputSpacing = m_sourceRate / m_gcd; 108 int outputSpacing = m_sourceRate / m_gcd;
107 109
108 #ifdef DEBUG_RESAMPLER 110 #ifdef DEBUG_RESAMPLER
109 std::cerr << "resample " << m_sourceRate << " -> " << m_targetRate 111 cerr << "resample " << m_sourceRate << " -> " << m_targetRate
110 << ": inputSpacing " << inputSpacing << ", outputSpacing " 112 << ": inputSpacing " << inputSpacing << ", outputSpacing "
111 << outputSpacing << ": filter length " << m_filterLength 113 << outputSpacing << ": filter length " << m_filterLength
112 << std::endl; 114 << endl;
113 #endif 115 #endif
114 116
115 // Now we have a filter of (odd) length flen in which the lower 117 // Now we have a filter of (odd) length flen in which the lower
116 // sample rate corresponds to every n'th point and the higher rate 118 // sample rate corresponds to every n'th point and the higher rate
117 // to every m'th where n and m are higher and lower rates divided 119 // to every m'th where n and m are higher and lower rates divided
202 p.filter.push_back(filter[i * inputSpacing + phase]); 204 p.filter.push_back(filter[i * inputSpacing + phase]);
203 } 205 }
204 206
205 m_phaseData[phase] = p; 207 m_phaseData[phase] = p;
206 } 208 }
209
210 #ifdef DEBUG_RESAMPLER
211 int cp = 0;
212 int totDrop = 0;
213 for (int i = 0; i < inputSpacing; ++i) {
214 cerr << "phase = " << cp << ", drop = " << m_phaseData[cp].drop
215 << ", filter length = " << m_phaseData[cp].filter.size()
216 << ", next phase = " << m_phaseData[cp].nextPhase << endl;
217 totDrop += m_phaseData[cp].drop;
218 cp = m_phaseData[cp].nextPhase;
219 }
220 cerr << "total drop = " << totDrop << endl;
221 #endif
207 222
208 // The May implementation of this uses a pull model -- we ask the 223 // The May implementation of this uses a pull model -- we ask the
209 // resampler for a certain number of output samples, and it asks 224 // resampler for a certain number of output samples, and it asks
210 // its source stream for as many as it needs to calculate 225 // its source stream for as many as it needs to calculate
211 // those. This means (among other things) that the source stream 226 // those. This means (among other things) that the source stream
264 279
265 m_buffer = vector<double>(fill, 0); 280 m_buffer = vector<double>(fill, 0);
266 m_bufferOrigin = 0; 281 m_bufferOrigin = 0;
267 282
268 #ifdef DEBUG_RESAMPLER 283 #ifdef DEBUG_RESAMPLER
269 std::cerr << "initial phase " << m_phase << " (as " << (m_filterLength/2) << " % " << inputSpacing << ")" 284 cerr << "initial phase " << m_phase << " (as " << (m_filterLength/2) << " % " << inputSpacing << ")"
270 << ", latency " << m_latency << std::endl; 285 << ", latency " << m_latency << endl;
271 #endif 286 #endif
272 } 287 }
273 288
274 double 289 double
275 Resampler::reconstructOne() 290 Resampler::reconstructOne()
281 assert(n + m_bufferOrigin <= (int)m_buffer.size()); 296 assert(n + m_bufferOrigin <= (int)m_buffer.size());
282 297
283 const double *const __restrict__ buf = m_buffer.data() + m_bufferOrigin; 298 const double *const __restrict__ buf = m_buffer.data() + m_bufferOrigin;
284 const double *const __restrict__ filt = pd.filter.data(); 299 const double *const __restrict__ filt = pd.filter.data();
285 300
286 // std::cerr << "phase = " << m_phase << ", drop = " << pd.drop << ", buffer for reconstruction starts..."; 301 // cerr << "phase = " << m_phase << ", drop = " << pd.drop << ", buffer for reconstruction starts...";
287 // for (int i = 0; i < 20; ++i) { 302 // for (int i = 0; i < 20; ++i) {
288 // if (i % 5 == 0) std::cerr << "\n" << i << " "; 303 // if (i % 5 == 0) cerr << "\n" << i << " ";
289 // std::cerr << buf[i] << " "; 304 // cerr << buf[i] << " ";
290 // } 305 // }
291 // std::cerr << std::endl; 306 // cerr << endl;
292 307
293 for (int i = 0; i < n; ++i) { 308 for (int i = 0; i < n; ++i) {
294 // NB gcc can only vectorize this with -ffast-math 309 // NB gcc can only vectorize this with -ffast-math
295 v += buf[i] * filt[i]; 310 v += buf[i] * filt[i];
296 } 311 }
309 324
310 int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate)); 325 int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate));
311 int outidx = 0; 326 int outidx = 0;
312 327
313 #ifdef DEBUG_RESAMPLER 328 #ifdef DEBUG_RESAMPLER
314 std::cerr << "process: buf siz " << m_buffer.size() << " filt siz for phase " << m_phase << " " << m_phaseData[m_phase].filter.size() << std::endl; 329 cerr << "process: buf siz " << m_buffer.size() << " filt siz for phase " << m_phase << " " << m_phaseData[m_phase].filter.size() << endl;
315 #endif 330 #endif
316 331
317 double scaleFactor = (double(m_targetRate) / m_gcd) / m_peakToPole; 332 double scaleFactor = (double(m_targetRate) / m_gcd) / m_peakToPole;
318 333
319 while (outidx < maxout && 334 while (outidx < maxout &&
326 m_bufferOrigin = 0; 341 m_bufferOrigin = 0;
327 342
328 return outidx; 343 return outidx;
329 } 344 }
330 345
331 std::vector<double> 346 vector<double>
332 Resampler::process(const double *src, int n) 347 Resampler::process(const double *src, int n)
333 { 348 {
334 int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate)); 349 int maxout = int(ceil(double(n) * m_targetRate / m_sourceRate));
335 std::vector<double> out(maxout, 0.0); 350 vector<double> out(maxout, 0.0);
336 int got = process(src, out.data(), n); 351 int got = process(src, out.data(), n);
337 assert(got <= maxout); 352 assert(got <= maxout);
338 if (got < maxout) out.resize(got); 353 if (got < maxout) out.resize(got);
339 return out; 354 return out;
340 } 355 }
341 356
342 std::vector<double> 357 vector<double>
343 Resampler::resample(int sourceRate, int targetRate, const double *data, int n) 358 Resampler::resample(int sourceRate, int targetRate, const double *data, int n)
344 { 359 {
345 Resampler r(sourceRate, targetRate); 360 Resampler r(sourceRate, targetRate);
346 361
347 int latency = r.getLatency(); 362 int latency = r.getLatency();
362 377
363 // in order to return this much output to the user: 378 // in order to return this much output to the user:
364 379
365 int m = int(ceil((double(n) * targetRate) / sourceRate)); 380 int m = int(ceil((double(n) * targetRate) / sourceRate));
366 381
367 // std::cerr << "n = " << n << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", m = " << m << ", latency = " << latency << ", inputPad = " << inputPad << ", m1 = " << m1 << ", n1 = " << n1 << ", n1 - n = " << n1 - n << std::endl; 382 #ifdef DEBUG_RESAMPLER
383 cerr << "n = " << n << ", sourceRate = " << sourceRate << ", targetRate = " << targetRate << ", m = " << m << ", latency = " << latency << ", inputPad = " << inputPad << ", m1 = " << m1 << ", n1 = " << n1 << ", n1 - n = " << n1 - n << endl;
384 #endif
368 385
369 vector<double> pad(n1 - n, 0.0); 386 vector<double> pad(n1 - n, 0.0);
370 vector<double> out(m1 + 1, 0.0); 387 vector<double> out(m1 + 1, 0.0);
371 388
372 int got = r.process(data, out.data(), n); 389 int gotData = r.process(data, out.data(), n);
373 got += r.process(pad.data(), out.data() + got, pad.size()); 390 int gotPad = r.process(pad.data(), out.data() + gotData, pad.size());
374 391 int got = gotData + gotPad;
375 #ifdef DEBUG_RESAMPLER 392
376 std::cerr << "resample: " << n << " in, " << got << " out" << std::endl; 393 #ifdef DEBUG_RESAMPLER
394 cerr << "resample: " << n << " in, " << pad.size() << " padding, " << got << " out (" << gotData << " data, " << gotPad << " padding, latency = " << latency << ")" << endl;
377 #endif 395 #endif
378 #ifdef DEBUG_RESAMPLER_VERBOSE 396 #ifdef DEBUG_RESAMPLER_VERBOSE
379 std::cerr << "first 10 in:" << std::endl; 397 int printN = 50;
380 for (int i = 0; i < 10; ++i) { 398 cerr << "first " << printN << " in:" << endl;
381 std::cerr << data[i] << " "; 399 for (int i = 0; i < printN && i < n; ++i) {
382 if (i == 5) std::cerr << std::endl; 400 if (i % 5 == 0) cerr << endl << i << "... ";
383 } 401 cerr << data[i] << " ";
384 std::cerr << std::endl; 402 }
403 cerr << endl;
385 #endif 404 #endif
386 405
387 int toReturn = got - latency; 406 int toReturn = got - latency;
388 if (toReturn > m) toReturn = m; 407 if (toReturn > m) toReturn = m;
389 408
390 vector<double> sliced(out.begin() + latency, 409 vector<double> sliced(out.begin() + latency,
391 out.begin() + latency + toReturn); 410 out.begin() + latency + toReturn);
392 411
393 #ifdef DEBUG_RESAMPLER_VERBOSE 412 #ifdef DEBUG_RESAMPLER_VERBOSE
394 std::cerr << "all out (after latency compensation), length " << sliced.size() << ":"; 413 cerr << "first " << printN << " out (after latency compensation), length " << sliced.size() << ":";
395 for (int i = 0; i < sliced.size(); ++i) { 414 for (int i = 0; i < printN && i < sliced.size(); ++i) {
396 if (i % 5 == 0) std::cerr << std::endl << i << "... "; 415 if (i % 5 == 0) cerr << endl << i << "... ";
397 std::cerr << sliced[i] << " "; 416 cerr << sliced[i] << " ";
398 } 417 }
399 std::cerr << std::endl; 418 cerr << endl;
400 #endif 419 #endif
401 420
402 return sliced; 421 return sliced;
403 } 422 }
404 423