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