comparison dsp/tempotracking/TempoTrackV2.cpp @ 281:33e03341d541

* Make it possible to retrieve beat spectral difference function from bar detector * Avoid crashes when bar detector is run with very short input
author Chris Cannam <c.cannam@qmul.ac.uk>
date Fri, 27 Feb 2009 10:23:08 +0000
parents 9c403afdd9e9
children d241e7701c0c
comparison
equal deleted inserted replaced
280:9c403afdd9e9 281:33e03341d541
113 // matrix to store output of comb filter bank, increment column of matrix at each frame 113 // matrix to store output of comb filter bank, increment column of matrix at each frame
114 d_mat_t rcfmat; 114 d_mat_t rcfmat;
115 int col_counter = -1; 115 int col_counter = -1;
116 116
117 // main loop for beat period calculation 117 // main loop for beat period calculation
118 for (uint i=0; i<(df.size()-winlen); i+=step) 118 for (uint i=0; i+winlen<df.size(); i+=step)
119 { 119 {
120 // get dfframe 120 // get dfframe
121 d_vec_t dfframe(winlen); 121 d_vec_t dfframe(winlen);
122 for (uint k=0; k<winlen; k++) 122 for (uint k=0; k<winlen; k++)
123 { 123 {
246 } 246 }
247 } 247 }
248 248
249 249
250 uint T = delta.size(); 250 uint T = delta.size();
251
252 if (T < 2) return; // can't do anything at all meaningful
253
251 uint Q = delta[0].size(); 254 uint Q = delta[0].size();
252 255
253 // initialize first column of delta 256 // initialize first column of delta
254 for (uint j=0; j<Q; j++) 257 for (uint j=0; j<Q; j++)
255 { 258 {
390 393
391 void 394 void
392 TempoTrackV2::calculateBeats(const d_vec_t &df, const d_vec_t &beat_period, 395 TempoTrackV2::calculateBeats(const d_vec_t &df, const d_vec_t &beat_period,
393 d_vec_t &beats) 396 d_vec_t &beats)
394 { 397 {
398 if (df.empty() || beat_period.empty()) return;
399
395 d_vec_t cumscore(df.size()); // store cumulative score 400 d_vec_t cumscore(df.size()); // store cumulative score
396 i_vec_t backlink(df.size()); // backlink (stores best beat locations at each time instant) 401 i_vec_t backlink(df.size()); // backlink (stores best beat locations at each time instant)
397 d_vec_t localscore(df.size()); // localscore, for now this is the same as the detection function 402 d_vec_t localscore(df.size()); // localscore, for now this is the same as the detection function
398 403
399 for (uint i=0; i<df.size(); i++) 404 for (uint i=0; i<df.size(); i++)
446 { 451 {
447 tmp_vec.push_back(cumscore[i]); 452 tmp_vec.push_back(cumscore[i]);
448 } 453 }
449 454
450 int startpoint = get_max_ind(tmp_vec) + cumscore.size() - beat_period[beat_period.size()-1] ; 455 int startpoint = get_max_ind(tmp_vec) + cumscore.size() - beat_period[beat_period.size()-1] ;
456
457 // can happen if no results obtained earlier (e.g. input too short)
458 if (startpoint >= backlink.size()) startpoint = backlink.size()-1;
451 459
452 // USE BACKLINK TO GET EACH NEW BEAT (TOWARDS THE BEGINNING OF THE FILE) 460 // USE BACKLINK TO GET EACH NEW BEAT (TOWARDS THE BEGINNING OF THE FILE)
453 // BACKTRACKING FROM THE END TO THE BEGINNING.. MAKING SURE NOT TO GO BEFORE SAMPLE 0 461 // BACKTRACKING FROM THE END TO THE BEGINNING.. MAKING SURE NOT TO GO BEFORE SAMPLE 0
454 i_vec_t ibeats; 462 i_vec_t ibeats;
455 ibeats.push_back(startpoint); 463 ibeats.push_back(startpoint);
456 std::cerr << "startpoint = " << startpoint << std::endl; 464 std::cerr << "startpoint = " << startpoint << std::endl;
457 while (backlink[ibeats.back()] > 0) 465 while (backlink[ibeats.back()] > 0)
458 { 466 {
459 std::cerr << "backlink[" << ibeats.back() << "] = " << backlink[ibeats.back()] << std::endl; 467 std::cerr << "backlink[" << ibeats.back() << "] = " << backlink[ibeats.back()] << std::endl;
460 ibeats.push_back(backlink[ibeats.back()]); 468 int b = ibeats.back();
469 if (backlink[b] == b) break; // shouldn't happen... haha
470 ibeats.push_back(backlink[b]);
461 } 471 }
462 472
463 // REVERSE SEQUENCE OF IBEATS AND STORE AS BEATS 473 // REVERSE SEQUENCE OF IBEATS AND STORE AS BEATS
464 for (uint i=0; i<ibeats.size(); i++) 474 for (uint i=0; i<ibeats.size(); i++)
465 { 475 {