comparison data/model/FFTModel.cpp @ 1576:0f62bce0f0be spectrogramparam

Further adjustments to peak picking, to try to avoid a surfeit of peaks in the higher frequencies
author Chris Cannam
date Tue, 13 Nov 2018 13:29:37 +0000
parents 054bbf17ac17
children 70e172e6cc59
comparison
equal deleted inserted replaced
1575:054bbf17ac17 1576:0f62bce0f0be
429 // size to a roughly constant pitch range (about four tones). 429 // size to a roughly constant pitch range (about four tones).
430 430
431 sv_samplerate_t sampleRate = getSampleRate(); 431 sv_samplerate_t sampleRate = getSampleRate();
432 432
433 vector<int> inrange; 433 vector<int> inrange;
434 float dist = 0.5; 434 double dist = 0.5;
435 435
436 int medianWinSize = getPeakPickWindowSize(type, sampleRate, ymin, dist); 436 int medianWinSize = getPeakPickWindowSize(type, sampleRate, ymin, dist);
437 int halfWin = medianWinSize/2; 437 int halfWin = medianWinSize/2;
438 438
439 MovingMedian<float> window(medianWinSize); 439 MovingMedian<float> window(medianWinSize);
505 return peaks; 505 return peaks;
506 } 506 }
507 507
508 int 508 int
509 FFTModel::getPeakPickWindowSize(PeakPickType type, sv_samplerate_t sampleRate, 509 FFTModel::getPeakPickWindowSize(PeakPickType type, sv_samplerate_t sampleRate,
510 int bin, float &percentile) const 510 int bin, double &dist) const
511 { 511 {
512 percentile = 0.5; 512 dist = 0.5; // dist is percentile / 100.0
513 if (type == MajorPeaks) return 10; 513 if (type == MajorPeaks) return 10;
514 if (bin == 0) return 3; 514 if (bin == 0) return 3;
515 515
516 double binfreq = (sampleRate * bin) / m_fftSize; 516 double binfreq = (sampleRate * bin) / m_fftSize;
517 double hifreq = Pitch::getFrequencyForPitch(73, 0, binfreq); 517 double hifreq = Pitch::getFrequencyForPitch(73, 0, binfreq);
518 518
519 int hibin = int(lrint((hifreq * m_fftSize) / sampleRate)); 519 int hibin = int(lrint((hifreq * m_fftSize) / sampleRate));
520 int medianWinSize = hibin - bin; 520 int medianWinSize = hibin - bin;
521
521 if (medianWinSize < 3) { 522 if (medianWinSize < 3) {
522 medianWinSize = 3; 523 medianWinSize = 3;
523 } 524 }
525
526 // We want to avoid the median window size changing too often, as
527 // it requires a reallocation. So snap to a nearby round number.
528
524 if (medianWinSize > 20) { 529 if (medianWinSize > 20) {
525 medianWinSize = (1 + medianWinSize / 10) * 10; 530 medianWinSize = (1 + medianWinSize / 10) * 10;
526 } 531 }
527 if (medianWinSize > 500) { 532 if (medianWinSize > 200) {
528 medianWinSize = 500; 533 medianWinSize = (1 + medianWinSize / 100) * 100;
529 } 534 }
530 535 if (medianWinSize > 2000) {
531 percentile = 0.5f + float(binfreq / sampleRate); 536 medianWinSize = (1 + medianWinSize / 1000) * 1000;
532 if (percentile > 0.9f) percentile = 0.9f; 537 }
538 if (medianWinSize > 20000) {
539 medianWinSize = 20000;
540 }
541
542 if (medianWinSize < 100) {
543 dist = 1.0 - (4.0 / medianWinSize);
544 } else {
545 dist = 1.0 - (8.0 / medianWinSize);
546 }
547 if (dist < 0.5) dist = 0.5;
533 548
534 return medianWinSize; 549 return medianWinSize;
535 } 550 }
536 551
537 FFTModel::PeakSet 552 FFTModel::PeakSet