Revision 18:131b1c40be1a CepstrumPitchTracker.cpp

View differences:

CepstrumPitchTracker.cpp
220 220
    m_blockSize(1024),
221 221
    m_fmin(50),
222 222
    m_fmax(1000),
223
    m_vflen(3),
223
    m_vflen(1),
224 224
    m_binFrom(0),
225 225
    m_binTo(0),
226 226
    m_bins(0)
......
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 496
CepstrumPitchTracker::FeatureSet
432 497
CepstrumPitchTracker::process(const float *const *inputBuffers, RealTime timestamp)
433 498
{
......
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 567
    double confidence = 0.0;
502 568
    if (nextPeakVal != 0.0) {

Also available in: Unified diff