Mercurial > hg > vamp-simple-cepstrum
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; |