comparison CepstrumPitchTracker.cpp @ 25:a15d8c89a36e

Clumsily cut-n-paste interpolation into pitch tracker as well
author Chris Cannam
date Thu, 05 Jul 2012 21:54:50 +0100
parents a949c0278d7d
children 44bb93cae288
comparison
equal deleted inserted replaced
24:0a3c1ecff644 25:a15d8c89a36e
218 m_channels(0), 218 m_channels(0),
219 m_stepSize(256), 219 m_stepSize(256),
220 m_blockSize(1024), 220 m_blockSize(1024),
221 m_fmin(50), 221 m_fmin(50),
222 m_fmax(1000), 222 m_fmax(1000),
223 m_vflen(3), 223 m_vflen(1),
224 m_binFrom(0), 224 m_binFrom(0),
225 m_binTo(0), 225 m_binTo(0),
226 m_bins(0) 226 m_bins(0)
227 { 227 {
228 } 228 }
426 } 426 }
427 data[i] = v / n; 427 data[i] = v / n;
428 } 428 }
429 } 429 }
430 430
431 double
432 CepstrumPitchTracker::cubicInterpolate(const double y[4], double x)
433 {
434 double a0 = y[3] - y[2] - y[0] + y[1];
435 double a1 = y[0] - y[1] - a0;
436 double a2 = y[2] - y[0];
437 double a3 = y[1];
438 return
439 a0 * x * x * x +
440 a1 * x * x +
441 a2 * x +
442 a3;
443 }
444
445 double
446 CepstrumPitchTracker::findInterpolatedPeak(const double *in, int maxbin)
447 {
448 if (maxbin < 2 || maxbin > m_bins - 3) {
449 return maxbin;
450 }
451
452 double maxval = 0.0;
453 double maxidx = maxbin;
454
455 const int divisions = 10;
456 double y[4];
457
458 y[0] = in[maxbin-1];
459 y[1] = in[maxbin];
460 y[2] = in[maxbin+1];
461 y[3] = in[maxbin+2];
462 for (int i = 0; i < divisions; ++i) {
463 double probe = double(i) / double(divisions);
464 double value = cubicInterpolate(y, probe);
465 if (value > maxval) {
466 maxval = value;
467 maxidx = maxbin + probe;
468 }
469 }
470
471 y[3] = y[2];
472 y[2] = y[1];
473 y[1] = y[0];
474 y[0] = in[maxbin-2];
475 for (int i = 0; i < divisions; ++i) {
476 double probe = double(i) / double(divisions);
477 double value = cubicInterpolate(y, probe);
478 if (value > maxval) {
479 maxval = value;
480 maxidx = maxbin - 1 + probe;
481 }
482 }
483
484 /*
485 std::cerr << "centre = " << maxbin << ": ["
486 << in[maxbin-2] << ","
487 << in[maxbin-1] << ","
488 << in[maxbin] << ","
489 << in[maxbin+1] << ","
490 << in[maxbin+2] << "] -> " << maxidx << std::endl;
491 */
492
493 return maxidx;
494 }
495
431 CepstrumPitchTracker::FeatureSet 496 CepstrumPitchTracker::FeatureSet
432 CepstrumPitchTracker::process(const float *const *inputBuffers, RealTime timestamp) 497 CepstrumPitchTracker::process(const float *const *inputBuffers, RealTime timestamp)
433 { 498 {
434 FeatureSet fs; 499 FeatureSet fs;
435 500
494 data[i] > nextPeakVal) { 559 data[i] > nextPeakVal) {
495 nextPeakVal = data[i]; 560 nextPeakVal = data[i];
496 } 561 }
497 } 562 }
498 563
499 double peakfreq = m_inputSampleRate / (maxbin + m_binFrom); 564 double cimax = findInterpolatedPeak(data, maxbin);
565 double peakfreq = m_inputSampleRate / (cimax + m_binFrom);
500 566
501 double confidence = 0.0; 567 double confidence = 0.0;
502 if (nextPeakVal != 0.0) { 568 if (nextPeakVal != 0.0) {
503 confidence = ((maxval / nextPeakVal) - 1.0) / 4.0; 569 confidence = ((maxval / nextPeakVal) - 1.0) / 4.0;
504 if (confidence > 1.0) confidence = 1.0; 570 if (confidence > 1.0) confidence = 1.0;