Mercurial > hg > vamp-simple-cepstrum
comparison CepstrumPitchTracker.cpp @ 11:0c95dc49163a track
Some work on accepting/rejecting peaks
author | Chris Cannam |
---|---|
date | Tue, 26 Jun 2012 16:06:00 +0100 |
parents | 960868d5f841 |
children | cb88b9954eec |
comparison
equal
deleted
inserted
replaced
10:960868d5f841 | 11:0c95dc49163a |
---|---|
41 m_histlen(1), | 41 m_histlen(1), |
42 m_vflen(3), | 42 m_vflen(3), |
43 m_binFrom(0), | 43 m_binFrom(0), |
44 m_binTo(0), | 44 m_binTo(0), |
45 m_bins(0), | 45 m_bins(0), |
46 m_history(0) | 46 m_history(0), |
47 m_prevpeak(0), | |
48 m_prevprop(0) | |
47 { | 49 { |
48 } | 50 } |
49 | 51 |
50 CepstrumPitchTracker::~CepstrumPitchTracker() | 52 CepstrumPitchTracker::~CepstrumPitchTracker() |
51 { | 53 { |
268 mean /= m_histlen; | 270 mean /= m_histlen; |
269 result[i] = mean; | 271 result[i] = mean; |
270 } | 272 } |
271 } | 273 } |
272 | 274 |
275 double | |
276 CepstrumPitchTracker::calculatePeakProportion(const double *data, double abstot, int n) | |
277 { | |
278 double aroundPeak = data[n]; | |
279 double peakProportion = 0.0; | |
280 | |
281 int i = n - 1; | |
282 while (i > 0 && data[i] <= data[i+1]) { | |
283 aroundPeak += fabs(data[i]); | |
284 --i; | |
285 } | |
286 i = n + 1; | |
287 while (i < m_bins && data[i] <= data[i-1]) { | |
288 aroundPeak += fabs(data[i]); | |
289 ++i; | |
290 } | |
291 peakProportion = aroundPeak / abstot; | |
292 | |
293 return peakProportion; | |
294 } | |
295 | |
296 bool | |
297 CepstrumPitchTracker::acceptPeak(int n, double peakProportion) | |
298 { | |
299 bool accept = false; | |
300 | |
301 if (abs(n - m_prevpeak) < 10) { //!!! should depend on bin count | |
302 accept = true; | |
303 } else if (peakProportion > m_prevprop * 2) { | |
304 accept = true; | |
305 } | |
306 | |
307 return accept; | |
308 } | |
309 | |
273 CepstrumPitchTracker::FeatureSet | 310 CepstrumPitchTracker::FeatureSet |
274 CepstrumPitchTracker::process(const float *const *inputBuffers, Vamp::RealTime timestamp) | 311 CepstrumPitchTracker::process(const float *const *inputBuffers, Vamp::RealTime timestamp) |
275 { | 312 { |
276 FeatureSet fs; | 313 FeatureSet fs; |
277 | 314 |
305 int n = m_bins; | 342 int n = m_bins; |
306 double *data = new double[n]; | 343 double *data = new double[n]; |
307 filter(rawcep, data); | 344 filter(rawcep, data); |
308 delete[] rawcep; | 345 delete[] rawcep; |
309 | 346 |
347 double abstot = 0.0; | |
348 | |
349 for (int i = 0; i < n; ++i) { | |
350 abstot += fabs(data[i]); | |
351 } | |
352 | |
310 double maxval = 0.0; | 353 double maxval = 0.0; |
311 int maxbin = 0; | 354 int maxbin = -1; |
312 double abstot = 0.0; | |
313 | 355 |
314 for (int i = 0; i < n; ++i) { | 356 for (int i = 0; i < n; ++i) { |
315 if (data[i] > maxval) { | 357 if (data[i] > maxval) { |
316 maxval = data[i]; | 358 maxval = data[i]; |
317 maxbin = i; | 359 maxbin = i; |
318 } | 360 } |
319 abstot += fabs(data[i]); | 361 } |
320 } | 362 |
321 | 363 bool accepted = false; |
322 double aroundPeak = 0.0; | 364 |
323 double peakProportion = 0.0; | 365 if (maxbin >= 0) { |
324 if (maxval > 0.0) { | 366 double pp = calculatePeakProportion(data, abstot, maxbin); |
325 aroundPeak += fabs(maxval); | 367 if (acceptPeak(maxbin, pp)) { |
326 int i = maxbin - 1; | 368 accepted = true; |
327 while (i > 0 && data[i] <= data[i+1]) { | 369 } else { |
328 aroundPeak += fabs(data[i]); | 370 // try a secondary peak |
329 --i; | 371 maxval = 0.0; |
330 } | 372 int secondbin = 0; |
331 i = maxbin + 1; | 373 for (int i = 1; i < n-1; ++i) { |
332 while (i < n && data[i] <= data[i-1]) { | 374 if (i != maxbin && |
333 aroundPeak += fabs(data[i]); | 375 data[i] > data[i-1] && |
334 ++i; | 376 data[i] > data[i+1] && |
335 } | 377 data[i] > maxval) { |
336 } | 378 maxval = data[i]; |
337 peakProportion = aroundPeak / abstot; | 379 secondbin = i; |
338 | 380 } |
381 } | |
382 double spp = calculatePeakProportion(data, abstot, secondbin); | |
383 if (acceptPeak(secondbin, spp)) { | |
384 maxbin = secondbin; | |
385 pp = spp; | |
386 accepted = true; | |
387 } | |
388 } | |
389 if (accepted) { | |
390 m_prevpeak = maxbin; | |
391 m_prevprop = pp; | |
392 } | |
393 } | |
394 | |
339 // std::cerr << "peakProportion = " << peakProportion << std::endl; | 395 // std::cerr << "peakProportion = " << peakProportion << std::endl; |
340 // std::cerr << "peak = " << m_inputSampleRate / (maxbin + m_binFrom) << std::endl; | 396 // std::cerr << "peak = " << m_inputSampleRate / (maxbin + m_binFrom) << std::endl; |
341 // std::cerr << "bins = " << m_bins << std::endl; | 397 // std::cerr << "bins = " << m_bins << std::endl; |
342 | 398 |
343 if (peakProportion >= (0.00006 * m_bins)) { | 399 // if (peakProportion >= (0.00006 * m_bins)) { |
400 if (accepted) { | |
344 Feature f; | 401 Feature f; |
345 f.hasTimestamp = true; | 402 f.hasTimestamp = true; |
346 f.timestamp = timestamp; | 403 f.timestamp = timestamp; |
347 f.values.push_back(m_inputSampleRate / (maxbin + m_binFrom)); | 404 f.values.push_back(m_inputSampleRate / (maxbin + m_binFrom)); |
348 fs[0].push_back(f); | 405 fs[0].push_back(f); |