Mercurial > hg > qm-vamp-plugins
comparison plugins/BeatTrack.cpp @ 87:790e051896a9
* Update, and add tempo return features for new-style tracker
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Mon, 09 Feb 2009 16:06:06 +0000 |
parents | e377296d01b2 |
children | d47b22cf47bc |
comparison
equal
deleted
inserted
replaced
86:e377296d01b2 | 87:790e051896a9 |
---|---|
368 ttParams.WinT.post = 8; | 368 ttParams.WinT.post = 8; |
369 ttParams.WinT.pre = 7; | 369 ttParams.WinT.pre = 7; |
370 | 370 |
371 TempoTrack tempoTracker(ttParams); | 371 TempoTrack tempoTracker(ttParams); |
372 | 372 |
373 vector<double> tempos; | 373 vector<double> tempi; |
374 vector<int> beats = tempoTracker.process(m_d->dfOutput, &tempos); | 374 vector<int> beats = tempoTracker.process(m_d->dfOutput, &tempi); |
375 | 375 |
376 FeatureSet returnFeatures; | 376 FeatureSet returnFeatures; |
377 | 377 |
378 char label[100]; | 378 char label[100]; |
379 | 379 |
408 returnFeatures[0].push_back(feature); // beats are output 0 | 408 returnFeatures[0].push_back(feature); // beats are output 0 |
409 } | 409 } |
410 | 410 |
411 double prevTempo = 0.0; | 411 double prevTempo = 0.0; |
412 | 412 |
413 for (size_t i = 0; i < tempos.size(); ++i) { | 413 for (size_t i = 0; i < tempi.size(); ++i) { |
414 | 414 |
415 size_t frame = i * m_d->dfConfig.stepSize * ttParams.lagLength; | 415 size_t frame = i * m_d->dfConfig.stepSize * ttParams.lagLength; |
416 | 416 |
417 // std::cerr << "unit " << i << ", step size " << m_d->dfConfig.stepSize << ", hop " << ttParams.lagLength << ", frame = " << frame << std::endl; | 417 // std::cerr << "unit " << i << ", step size " << m_d->dfConfig.stepSize << ", hop " << ttParams.lagLength << ", frame = " << frame << std::endl; |
418 | 418 |
419 if (tempos[i] > 1 && int(tempos[i] * 100) != int(prevTempo * 100)) { | 419 if (tempi[i] > 1 && int(tempi[i] * 100) != int(prevTempo * 100)) { |
420 Feature feature; | 420 Feature feature; |
421 feature.hasTimestamp = true; | 421 feature.hasTimestamp = true; |
422 feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime | 422 feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime |
423 (frame, lrintf(m_inputSampleRate)); | 423 (frame, lrintf(m_inputSampleRate)); |
424 feature.values.push_back(tempos[i]); | 424 feature.values.push_back(tempi[i]); |
425 sprintf(label, "%.2f bpm", tempos[i]); | 425 sprintf(label, "%.2f bpm", tempi[i]); |
426 feature.label = label; | 426 feature.label = label; |
427 returnFeatures[2].push_back(feature); // tempo is output 2 | 427 returnFeatures[2].push_back(feature); // tempo is output 2 |
428 prevTempo = tempi[i]; | |
428 } | 429 } |
429 } | 430 } |
430 | 431 |
431 return returnFeatures; | 432 return returnFeatures; |
432 } | 433 } |
434 BeatTracker::FeatureSet | 435 BeatTracker::FeatureSet |
435 BeatTracker::beatTrackNew() | 436 BeatTracker::beatTrackNew() |
436 { | 437 { |
437 vector<double> df; | 438 vector<double> df; |
438 vector<double> beatPeriod; | 439 vector<double> beatPeriod; |
440 vector<double> tempi; | |
439 | 441 |
440 for (size_t i = 2; i < m_d->dfOutput.size(); ++i) { // discard first two elts | 442 for (size_t i = 2; i < m_d->dfOutput.size(); ++i) { // discard first two elts |
441 df.push_back(m_d->dfOutput[i]); | 443 df.push_back(m_d->dfOutput[i]); |
442 beatPeriod.push_back(0.0); | 444 beatPeriod.push_back(0.0); |
443 } | 445 } |
444 if (df.empty()) return FeatureSet(); | 446 if (df.empty()) return FeatureSet(); |
445 | 447 |
446 TempoTrackV2 tt; | 448 TempoTrackV2 tt; |
447 | 449 |
448 tt.calculateBeatPeriod(df, beatPeriod); | 450 tt.calculateBeatPeriod(df, beatPeriod, tempi); |
449 | 451 |
450 vector<double> beats; | 452 vector<double> beats; |
451 tt.calculateBeats(df, beatPeriod, beats); | 453 tt.calculateBeats(df, beatPeriod, beats); |
452 | 454 |
453 FeatureSet returnFeatures; | 455 FeatureSet returnFeatures; |
454 | 456 |
455 char label[100]; | 457 char label[100]; |
456 | 458 |
457 for (size_t i = 0; i < beats.size(); ++i) { | 459 for (size_t i = 0; i < beats.size(); ++i) { |
458 | 460 |
459 // beats are returned in reverse order? | 461 size_t frame = beats[i] * m_d->dfConfig.stepSize; |
460 | |
461 size_t index = beats.size() - i - 1; | |
462 | |
463 size_t frame = beats[index] * m_d->dfConfig.stepSize; | |
464 | 462 |
465 Feature feature; | 463 Feature feature; |
466 feature.hasTimestamp = true; | 464 feature.hasTimestamp = true; |
467 feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime | 465 feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime |
468 (frame, lrintf(m_inputSampleRate)); | 466 (frame, lrintf(m_inputSampleRate)); |
469 | 467 |
470 float bpm = 0.0; | 468 float bpm = 0.0; |
471 int frameIncrement = 0; | 469 int frameIncrement = 0; |
472 | 470 |
473 if (index > 0) { | 471 if (i+1 < beats.size()) { |
474 | 472 |
475 frameIncrement = (beats[index - 1] - beats[index]) * m_d->dfConfig.stepSize; | 473 frameIncrement = (beats[i+1] - beats[i]) * m_d->dfConfig.stepSize; |
476 | 474 |
477 // one beat is frameIncrement frames, so there are | 475 // one beat is frameIncrement frames, so there are |
478 // samplerate/frameIncrement bps, so | 476 // samplerate/frameIncrement bps, so |
479 // 60*samplerate/frameIncrement bpm | 477 // 60*samplerate/frameIncrement bpm |
480 | 478 |
487 } | 485 } |
488 | 486 |
489 returnFeatures[0].push_back(feature); // beats are output 0 | 487 returnFeatures[0].push_back(feature); // beats are output 0 |
490 } | 488 } |
491 | 489 |
490 double prevTempo = 0.0; | |
491 | |
492 for (size_t i = 0; i < tempi.size(); ++i) { | |
493 | |
494 size_t frame = i * m_d->dfConfig.stepSize; | |
495 | |
496 if (tempi[i] > 1 && int(tempi[i] * 100) != int(prevTempo * 100)) { | |
497 Feature feature; | |
498 feature.hasTimestamp = true; | |
499 feature.timestamp = m_d->origin + Vamp::RealTime::frame2RealTime | |
500 (frame, lrintf(m_inputSampleRate)); | |
501 feature.values.push_back(tempi[i]); | |
502 sprintf(label, "%.2f bpm", tempi[i]); | |
503 feature.label = label; | |
504 returnFeatures[2].push_back(feature); // tempo is output 2 | |
505 prevTempo = tempi[i]; | |
506 } | |
507 } | |
508 | |
492 return returnFeatures; | 509 return returnFeatures; |
493 } | 510 } |
494 | 511 |