comparison examples/FixedTempoEstimator.cpp @ 209:0f6616ef0e18

* More tweaks (still incomplete)
author cannam
date Thu, 16 Oct 2008 16:26:00 +0000
parents df55003e8968
children 87b131a54b0a
comparison
equal deleted inserted replaced
208:df55003e8968 209:0f6616ef0e18
123 channels > getMaxChannelCount()) return false; 123 channels > getMaxChannelCount()) return false;
124 124
125 m_stepSize = stepSize; 125 m_stepSize = stepSize;
126 m_blockSize = blockSize; 126 m_blockSize = blockSize;
127 127
128 float dfLengthSecs = 8.f; 128 float dfLengthSecs = 10.f;
129 m_dfsize = (dfLengthSecs * m_inputSampleRate) / m_stepSize; 129 m_dfsize = (dfLengthSecs * m_inputSampleRate) / m_stepSize;
130 130
131 m_priorMagnitudes = new float[m_blockSize/2]; 131 m_priorMagnitudes = new float[m_blockSize/2];
132 m_df = new float[m_dfsize]; 132 m_df = new float[m_dfsize];
133 133
296 float imag = inputBuffers[0][i*2 + 1]; 296 float imag = inputBuffers[0][i*2 + 1];
297 297
298 float sqrmag = real * real + imag * imag; 298 float sqrmag = real * real + imag * imag;
299 value += fabsf(sqrmag - m_priorMagnitudes[i]); 299 value += fabsf(sqrmag - m_priorMagnitudes[i]);
300 300
301 // if (i == 1 && ts == RealTime::zeroTime) { 301 if (i == 1 && ts == RealTime::zeroTime) {
302 // cerr << "First sqrmag: " << sqrmag << ", value = " << value << endl; 302 cerr << "First sqrmag: " << sqrmag << ", value = " << value << endl;
303 // } 303 }
304 304
305 m_priorMagnitudes[i] = sqrmag; 305 m_priorMagnitudes[i] = sqrmag;
306 } 306 }
307 307
308 m_df[m_n] = value; 308 m_df[m_n] = value;
342 if (m_r) { 342 if (m_r) {
343 cerr << "FixedTempoEstimator::calculate: calculation already happened?" << endl; 343 cerr << "FixedTempoEstimator::calculate: calculation already happened?" << endl;
344 return; 344 return;
345 } 345 }
346 346
347 if (m_n < m_dfsize / 6) { 347 if (m_n < m_dfsize / 9) {
348 cerr << "FixedTempoEstimator::calculate: Not enough data to go on (have " << m_n << ", want at least " << m_dfsize/4 << ")" << endl; 348 cerr << "FixedTempoEstimator::calculate: Not enough data to go on (have " << m_n << ", want at least " << m_dfsize/4 << ")" << endl;
349 return; // not enough data (perhaps we should return the duration of the input as the "estimated" beat length?) 349 return; // not enough data (perhaps we should return the duration of the input as the "estimated" beat length?)
350 } 350 }
351 351
352 int n = m_n; 352 int n = m_n;
367 m_r[i] += m_df[j] * m_df[j - i]; 367 m_r[i] += m_df[j] * m_df[j - i];
368 } 368 }
369 369
370 m_r[i] /= n - i - 1; 370 m_r[i] /= n - i - 1;
371 } 371 }
372 372 /*
373 for (int i = 1; i < n/2; ++i) { 373 for (int i = 1; i < n/2; ++i) {
374 374
375 float weight = 1.f - fabsf(128.f - lag2tempo(i)) * 0.005; 375 float weight = 1.f - fabsf(128.f - lag2tempo(i)) * 0.005;
376 if (weight < 0.f) weight = 0.f; 376 if (weight < 0.f) weight = 0.f;
377 weight = weight * weight; 377 weight = weight * weight;
378 378
379 cerr << "i = " << i << ": tempo = " << lag2tempo(i) << ", weight = " << weight << endl; 379 cerr << "i = " << i << ": tempo = " << lag2tempo(i) << ", weight = " << weight << ", " << m_r[i] << " -> ";
380 380
381 m_fr[i] = m_r[i] * (1 + weight / 3.f); 381 m_fr[i] = m_r[i] * weight; //(1 + weight / 2.f);
382 } 382
383 383 cerr << m_fr[i] << endl;
384 int related[4] = { 2, 3, 4 }; 384 }
385 385 */
386 int e = tempo2lag(60.f); 386 int related[] = { 2, 3, 4 };
387 int universalDiv = (n/2 - 1) / e; 387
388 cerr << "universalDiv = " << universalDiv << endl; 388 int e = tempo2lag(50.f);
389 389 // int universalDiv = (n/2 - 1) / e;
390 for (int i = 0; i < n/2; ++i) { 390 // cerr << "universalDiv = " << universalDiv << endl;
391 391
392 if (i == 0 || i == n/2 - 1 392 for (int i = 1; i < n/2-1; ++i) {
393
394 float weight = 1.f - fabsf(128.f - lag2tempo(i)) * 0.005;
395 if (weight < 0.f) weight = 0.f;
396 weight = weight * weight;
397
398 // cerr << "i = " << i << ": tempo = " << lag2tempo(i) << ", weight = " << weight << ", " << m_r[i] << " -> ";
399
400 m_fr[i] = m_r[i];
401 // m_fr[i] = m_r[i] * weight; //(1 + weight / 2.f);
402
403 // if (i == 0 || i == n/2 - 1
393 /* 404 /*
394 || 405 ||
395 !(m_fr[i] > m_fr[i-1] && 406 !(m_fr[i] > m_fr[i-1] &&
396 m_fr[i] >= m_fr[i+1]) 407 m_fr[i] >= m_fr[i+1])
397 */ 408 */
398 ) { 409 // ) {
399 continue; 410 // continue;
400 } 411 // }
401 412
402 int div = 1; 413 int div = 1;
403 414
404 for (int j = 0; j < sizeof(related)/sizeof(related[0]); ++j) { 415 for (int j = 0; j < sizeof(related)/sizeof(related[0]); ++j) {
405 416
406 int k0 = i * related[j]; 417 int k0 = i * related[j];
407 418
408 if (k0 > 1 && k0 < n/2 - 2) { 419 if (k0 >= 0 && k0 < n/2) {
409 420
410 int kmax = 0, kmin = 0; 421 int kmax = 0, kmin = 0;
411 float kvmax = 0, kvmin = 0; 422 float kvmax = 0, kvmin = 0;
412 423 bool have = false;
413 for (int k = k0 - 2; k <= k0 + 2; ++k) { 424
414 425 for (int k = k0 - 1; k <= k0 + 1; ++k) {
415 if (k == k0 - 2 || m_r[k] > kvmax) { 426
427 if (k < 0 || k >= n/2) continue;
428
429 if (!have || (m_r[k] > kvmax)) {
416 kmax = k; 430 kmax = k;
417 kvmax = m_r[k]; 431 kvmax = m_r[k];
418 } 432 }
419 433
420 if (k == k0 - 2 || m_r[k] < kvmin) { 434 if (!have || (m_r[k] < kvmin)) {
421 kmin = k; 435 kmin = k;
422 kvmin = m_r[k]; 436 kvmin = m_r[k];
423 } 437 }
438
439 have = true;
424 } 440 }
425 441
426 if (related[j] <= universalDiv) { 442
427 // m_fr[i] += m_fr[kmax]; //!!! 443 m_fr[i] += m_r[kmax] / 4;
428 m_fr[i] += m_r[kmax] / related[j]; 444
429 } 445 // if (related[j] <= universalDiv) {
430 446 // m_fr[i] += m_fr[kmax]; //!!!
431 if (m_r[kmax] > m_r[kmax-1] && 447 // m_fr[i] += m_r[kmax] / related[j];
432 m_r[kmax] > m_r[kmax+1] && 448 // }
449
450 if ((kmax == 0 || m_r[kmax] > m_r[kmax-1]) &&
451 (kmax == n/2-1 || m_r[kmax] > m_r[kmax+1]) &&
433 kvmax > kvmin * 1.05) { 452 kvmax > kvmin * 1.05) {
434 453
435 // cerr << "peak at " << i << " (val " << m_r[i] << ", tempo " << lag2tempo(i) << ") has sympathetic peak at " << kmax << " (val " << m_r[kmax] << " for relative tempo " << lag2tempo(kmax) * related[j] << ")" << endl; 454 // cerr << "peak at " << i << " (val " << m_r[i] << ", tempo " << lag2tempo(i) << ") has sympathetic peak at " << kmax << " (val " << m_r[kmax] << " for relative tempo " << lag2tempo(kmax) * related[j] << ")" << endl;
436 455
437 m_t[i] = m_t[i] + lag2tempo(kmax) * related[j]; 456 m_t[i] = m_t[i] + lag2tempo(kmax) * related[j];
438 ++div; 457 ++div;
439 } 458 }
440 } 459 }
441 } 460 }
442 461
443 m_t[i] /= div; 462 m_t[i] /= div;
444 463
445 // if (div > 1) { 464 if (div > 1) {
446 // cerr << "adjusting tempo from " << lag2tempo(i) << " to " 465 cerr << "adjusting tempo from " << lag2tempo(i) << " to "
447 // << m_t[i] << endl; 466 << m_t[i] << " for fr = " << m_fr[i] << " (div = " << div << ")" << endl;
448 // } 467 }
468
469 m_fr[i] += m_fr[i] * (weight / 5);
449 } 470 }
450 471
451 /* 472 /*
452 int e = tempo2lag(60.f); 473 int e = tempo2lag(60.f);
453 int div = (n/2 - 1) / e; 474 int div = (n/2 - 1) / e;
503 if (i == n/2-1) feature.label = ""; 524 if (i == n/2-1) feature.label = "";
504 else feature.label = buffer; 525 else feature.label = buffer;
505 fs[ACFOutput].push_back(feature); 526 fs[ACFOutput].push_back(feature);
506 } 527 }
507 528
508 float t0 = 60.f; 529 float t0 = 50.f;
509 float t1 = 180.f; 530 float t1 = 190.f;
510 531
511 int p0 = tempo2lag(t1); 532 int p0 = tempo2lag(t1);
512 int p1 = tempo2lag(t0); 533 int p1 = tempo2lag(t0);
513 534
514 cerr << "p0 = " << p0 << ", p1 = " << p1 << endl; 535 cerr << "p0 = " << p0 << ", p1 = " << p1 << endl;
521 542
522 std::map<float, int> candidates; 543 std::map<float, int> candidates;
523 544
524 for (int i = p0; i <= p1 && i < n/2-1; ++i) { 545 for (int i = p0; i <= p1 && i < n/2-1; ++i) {
525 546
526 candidates[m_fr[i]] = i; 547 if (m_fr[i] > m_fr[i-1] &&
548 m_fr[i] > m_fr[i+1]) {
549 candidates[m_fr[i]] = i;
550 }
527 551
528 feature.timestamp = m_start + 552 feature.timestamp = m_start +
529 RealTime::frame2RealTime(i * m_stepSize, m_inputSampleRate); 553 RealTime::frame2RealTime(i * m_stepSize, m_inputSampleRate);
530 feature.values[0] = m_fr[i]; 554 feature.values[0] = m_fr[i];
531 sprintf(buffer, "%.1f bpm", lag2tempo(i)); 555 sprintf(buffer, "%.1f bpm", lag2tempo(i));