Mercurial > hg > svcore
diff data/model/FFTModel.cpp @ 500:83eae5239db6
* Permit viewing (though not editing) colour 3d plot layer data in
the spreadsheet data viewer dialog
* Add somewhat simplistic RDF export for layers
* Fix display of peak frequencies in spectrum layer
* Fix (I hope) sizing of plugin parameter dialog
author | Chris Cannam |
---|---|
date | Tue, 02 Dec 2008 17:17:25 +0000 |
parents | 115f60df1e4d |
children | 6066bde1c126 |
line wrap: on
line diff
--- a/data/model/FFTModel.cpp Fri Nov 28 15:45:20 2008 +0000 +++ b/data/model/FFTModel.cpp Tue Dec 02 17:17:25 2008 +0000 @@ -170,10 +170,13 @@ size_t h = getHeight(); float magnitudes[h]; + if (m_server->getMagnitudesAt(x << m_xshift, magnitudes)) { + for (size_t y = 0; y < h; ++y) { - result.push_back(magnitudes[h]); + result.push_back(magnitudes[y]); } + } else { for (size_t i = 0; i < h; ++i) result.push_back(0.f); } @@ -259,6 +262,10 @@ getColumn(x, values); + float mean = 0.f; + for (int i =0; i < values.size(); ++i) mean += values[i]; + if (values.size() >0) mean /= values.size(); + // For peak picking we use a moving median window, picking the // highest value within each continuous region of values that // exceed the median. For pitch adaptivity, we adjust the window @@ -269,6 +276,7 @@ std::deque<float> window; std::vector<size_t> inrange; float dist = 0.5; + size_t medianWinSize = getPeakPickWindowSize(type, sampleRate, ymin, dist); size_t halfWin = medianWinSize/2; @@ -280,6 +288,8 @@ if (ymax + halfWin < values.size()) binmax = ymax + halfWin; else binmax = values.size()-1; + size_t prevcentre = 0; + for (size_t bin = binmin; bin <= binmax; ++bin) { float value = values[bin]; @@ -290,7 +300,11 @@ medianWinSize = getPeakPickWindowSize(type, sampleRate, bin, dist); halfWin = medianWinSize/2; - while (window.size() > medianWinSize) window.pop_front(); + while (window.size() > medianWinSize) { + window.pop_front(); + } + + size_t actualSize = window.size(); if (type == MajorPitchAdaptivePeaks) { if (ymax + halfWin < values.size()) binmax = ymax + halfWin; @@ -301,25 +315,37 @@ std::sort(sorted.begin(), sorted.end()); float median = sorted[int(sorted.size() * dist)]; - if (value > median) { - inrange.push_back(bin); - } + size_t centrebin = 0; + if (bin > actualSize/2) centrebin = bin - actualSize/2; + + while (centrebin > prevcentre || bin == binmin) { - if (value <= median || bin+1 == values.size()) { - size_t peakbin = 0; - float peakval = 0.f; - if (!inrange.empty()) { - for (size_t i = 0; i < inrange.size(); ++i) { - if (i == 0 || values[inrange[i]] > peakval) { - peakval = values[inrange[i]]; - peakbin = inrange[i]; + if (centrebin > prevcentre) ++prevcentre; + + float centre = values[prevcentre]; + + if (centre > median) { + inrange.push_back(centrebin); + } + + if (centre <= median || centrebin+1 == values.size()) { + if (!inrange.empty()) { + size_t peakbin = 0; + float peakval = 0.f; + for (size_t i = 0; i < inrange.size(); ++i) { + if (i == 0 || values[inrange[i]] > peakval) { + peakval = values[inrange[i]]; + peakbin = inrange[i]; + } + } + inrange.clear(); + if (peakbin >= ymin && peakbin <= ymax) { + peaks.insert(peakbin); } } - inrange.clear(); - if (peakbin >= ymin && peakbin <= ymax) { - peaks.insert(peakbin); - } } + + if (bin == binmin) break; } }