Mercurial > hg > svcore
comparison data/model/FFTModel.cpp @ 551:408e56d30f58
* Re-enable peak frequencies display in spectrogram
author | Chris Cannam |
---|---|
date | Thu, 05 Feb 2009 17:33:21 +0000 |
parents | 55ad231c9db7 |
children | d7f3dfe6f9a4 |
comparison
equal
deleted
inserted
replaced
550:107d3f3705c9 | 551:408e56d30f58 |
---|---|
239 } | 239 } |
240 | 240 |
241 FFTModel::PeakLocationSet | 241 FFTModel::PeakLocationSet |
242 FFTModel::getPeaks(PeakPickType type, size_t x, size_t ymin, size_t ymax) | 242 FFTModel::getPeaks(PeakPickType type, size_t x, size_t ymin, size_t ymax) |
243 { | 243 { |
244 Profiler profiler("FFTModel::getPeaks"); | |
245 | |
244 FFTModel::PeakLocationSet peaks; | 246 FFTModel::PeakLocationSet peaks; |
245 if (!isOK()) return peaks; | 247 if (!isOK()) return peaks; |
246 | 248 |
247 if (ymax == 0 || ymax > getHeight() - 1) { | 249 if (ymax == 0 || ymax > getHeight() - 1) { |
248 ymax = getHeight() - 1; | 250 ymax = getHeight() - 1; |
249 } | 251 } |
250 | 252 |
251 Column values; | |
252 | |
253 if (type == AllPeaks) { | 253 if (type == AllPeaks) { |
254 for (size_t y = ymin; y <= ymax; ++y) { | 254 int minbin = ymin; |
255 values.push_back(getMagnitudeAt(x, y)); | 255 if (minbin > 0) minbin = minbin - 1; |
256 } | 256 int maxbin = ymax; |
257 size_t i = 0; | 257 if (maxbin < getHeight() - 1) maxbin = maxbin + 1; |
258 const int n = maxbin - minbin + 1; | |
259 float values[n]; | |
260 getMagnitudesAt(x, values, minbin, maxbin - minbin + 1); | |
258 for (size_t bin = ymin; bin <= ymax; ++bin) { | 261 for (size_t bin = ymin; bin <= ymax; ++bin) { |
259 if ((i == 0 || values[i] > values[i-1]) && | 262 if (bin == minbin || bin == maxbin) continue; |
260 (i == values.size()-1 || values[i] >= values[i+1])) { | 263 if (values[bin - minbin] > values[bin - minbin - 1] && |
264 values[bin - minbin] > values[bin - minbin + 1]) { | |
261 peaks.insert(bin); | 265 peaks.insert(bin); |
262 } | 266 } |
263 ++i; | |
264 } | 267 } |
265 return peaks; | 268 return peaks; |
266 } | 269 } |
267 | 270 |
268 values = getColumn(x); | 271 Column values = getColumn(x); |
269 | 272 |
270 float mean = 0.f; | 273 float mean = 0.f; |
271 for (int i =0; i < values.size(); ++i) mean += values[i]; | 274 for (int i = 0; i < values.size(); ++i) mean += values[i]; |
272 if (values.size() >0) mean /= values.size(); | 275 if (values.size() >0) mean /= values.size(); |
273 | 276 |
274 // For peak picking we use a moving median window, picking the | 277 // For peak picking we use a moving median window, picking the |
275 // highest value within each continuous region of values that | 278 // highest value within each continuous region of values that |
276 // exceed the median. For pitch adaptivity, we adjust the window | 279 // exceed the median. For pitch adaptivity, we adjust the window |
380 | 383 |
381 FFTModel::PeakSet | 384 FFTModel::PeakSet |
382 FFTModel::getPeakFrequencies(PeakPickType type, size_t x, | 385 FFTModel::getPeakFrequencies(PeakPickType type, size_t x, |
383 size_t ymin, size_t ymax) | 386 size_t ymin, size_t ymax) |
384 { | 387 { |
388 Profiler profiler("FFTModel::getPeakFrequencies"); | |
389 | |
385 PeakSet peaks; | 390 PeakSet peaks; |
386 if (!isOK()) return peaks; | 391 if (!isOK()) return peaks; |
387 PeakLocationSet locations = getPeaks(type, x, ymin, ymax); | 392 PeakLocationSet locations = getPeaks(type, x, ymin, ymax); |
388 | 393 |
389 size_t sampleRate = getSampleRate(); | 394 size_t sampleRate = getSampleRate(); |