comparison data/model/FFTModel.cpp @ 1573:f04038819c26 spectrogramparam

Introduce & make use of faster MovingMedian class (now with resize capability)
author Chris Cannam
date Thu, 08 Nov 2018 15:02:30 +0000
parents 5fe24e4af12c
children 054bbf17ac17
comparison
equal deleted inserted replaced
1572:c36ffc195988 1573:f04038819c26
18 18
19 #include "base/Profiler.h" 19 #include "base/Profiler.h"
20 #include "base/Pitch.h" 20 #include "base/Pitch.h"
21 #include "base/HitCount.h" 21 #include "base/HitCount.h"
22 #include "base/Debug.h" 22 #include "base/Debug.h"
23 #include "base/MovingMedian.h"
23 24
24 #include <algorithm> 25 #include <algorithm>
25 26
26 #include <cassert> 27 #include <cassert>
27 #include <deque> 28 #include <deque>
427 // exceed the median. For pitch adaptivity, we adjust the window 428 // exceed the median. For pitch adaptivity, we adjust the window
428 // size to a roughly constant pitch range (about four tones). 429 // size to a roughly constant pitch range (about four tones).
429 430
430 sv_samplerate_t sampleRate = getSampleRate(); 431 sv_samplerate_t sampleRate = getSampleRate();
431 432
432 deque<float> window;
433 vector<int> inrange; 433 vector<int> inrange;
434 float dist = 0.5; 434 float 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
439 MovingMedian<float> window(medianWinSize);
438 440
439 int binmin; 441 int binmin;
440 if (ymin > halfWin) binmin = ymin - halfWin; 442 if (ymin > halfWin) binmin = ymin - halfWin;
441 else binmin = 0; 443 else binmin = 0;
442 444
448 450
449 for (int bin = binmin; bin <= binmax; ++bin) { 451 for (int bin = binmin; bin <= binmax; ++bin) {
450 452
451 float value = values[bin]; 453 float value = values[bin];
452 454
453 window.push_back(value);
454
455 // so-called median will actually be the dist*100'th percentile 455 // so-called median will actually be the dist*100'th percentile
456 medianWinSize = getPeakPickWindowSize(type, sampleRate, bin, dist); 456 medianWinSize = getPeakPickWindowSize(type, sampleRate, bin, dist);
457
458 halfWin = medianWinSize/2; 457 halfWin = medianWinSize/2;
459 458
460 while ((int)window.size() > medianWinSize) { 459 int actualSize = std::min(medianWinSize, bin - binmin + 1);
461 window.pop_front(); 460 window.resize(actualSize);
462 } 461 window.setPercentile(dist * 100.0);
463 462 window.push(value);
464 int actualSize = int(window.size());
465 463
466 if (type == MajorPitchAdaptivePeaks) { 464 if (type == MajorPitchAdaptivePeaks) {
467 if (ymax + halfWin < nv) binmax = ymax + halfWin; 465 if (ymax + halfWin < nv) binmax = ymax + halfWin;
468 else binmax = nv - 1; 466 else binmax = nv - 1;
469 } 467 }
470 468
471 vector<float> sorted(window.begin(), window.end()); 469 float median = window.get();
472 sort(sorted.begin(), sorted.end());
473 float median = sorted[int(float(sorted.size()) * dist)];
474 470
475 int centrebin = 0; 471 int centrebin = 0;
476 if (bin > actualSize/2) centrebin = bin - actualSize/2; 472 if (bin > actualSize/2) centrebin = bin - actualSize/2;
477 473
478 while (centrebin > prevcentre || bin == binmin) { 474 while (centrebin > prevcentre || bin == binmin) {