comparison examples/FixedTempoEstimator.cpp @ 204:4275327f9c79

* More tweaks to fixed-tempo estimator
author cannam
date Tue, 14 Oct 2008 17:26:26 +0000
parents e100112ecc06
children fa8afbb7221b
comparison
equal deleted inserted replaced
203:4e90c48a7460 204:4275327f9c79
52 m_blockSize(0), 52 m_blockSize(0),
53 m_priorMagnitudes(0), 53 m_priorMagnitudes(0),
54 m_df(0), 54 m_df(0),
55 m_r(0), 55 m_r(0),
56 m_fr(0), 56 m_fr(0),
57 m_t(0),
57 m_n(0) 58 m_n(0)
58 { 59 {
59 } 60 }
60 61
61 FixedTempoEstimator::~FixedTempoEstimator() 62 FixedTempoEstimator::~FixedTempoEstimator()
62 { 63 {
63 delete[] m_priorMagnitudes; 64 delete[] m_priorMagnitudes;
64 delete[] m_df; 65 delete[] m_df;
65 delete[] m_r; 66 delete[] m_r;
66 delete[] m_fr; 67 delete[] m_fr;
68 delete[] m_t;
67 } 69 }
68 70
69 string 71 string
70 FixedTempoEstimator::getIdentifier() const 72 FixedTempoEstimator::getIdentifier() const
71 { 73 {
160 delete[] m_r; 162 delete[] m_r;
161 m_r = 0; 163 m_r = 0;
162 164
163 delete[] m_fr; 165 delete[] m_fr;
164 m_fr = 0; 166 m_fr = 0;
167
168 delete[] m_t;
169 m_t = 0;
165 170
166 m_n = 0; 171 m_n = 0;
167 172
168 m_start = RealTime::zeroTime; 173 m_start = RealTime::zeroTime;
169 m_lasttime = RealTime::zeroTime; 174 m_lasttime = RealTime::zeroTime;
337 342
338 int n = m_n; 343 int n = m_n;
339 344
340 m_r = new float[n/2]; 345 m_r = new float[n/2];
341 m_fr = new float[n/2]; 346 m_fr = new float[n/2];
347 m_t = new float[n/2];
342 348
343 for (int i = 0; i < n/2; ++i) { 349 for (int i = 0; i < n/2; ++i) {
344 m_r[i] = 0.f; 350 m_r[i] = 0.f;
345 m_fr[i] = 0.f; 351 m_fr[i] = 0.f;
352 m_t[i] = 0.f;
346 } 353 }
347 354
348 for (int i = 0; i < n/2; ++i) { 355 for (int i = 0; i < n/2; ++i) {
349 356
350 for (int j = i; j < n-1; ++j) { 357 for (int j = i; j < n-1; ++j) {
354 m_r[i] /= n - i - 1; 361 m_r[i] /= n - i - 1;
355 } 362 }
356 363
357 for (int i = 1; i < n/2; ++i) { 364 for (int i = 1; i < n/2; ++i) {
358 365
359 m_fr[i] = m_r[i]; 366 float weight = 1.f - fabsf(128.f - lag2tempo(i)) * 0.005;
367 if (weight < 0.f) weight = 0.f;
368 weight = weight * weight;
369 std::cerr << "i = " << i << ": tempo = " << lag2tempo(i) << ", weight = " << weight << std::endl;
370
371 // m_fr[i] = m_r[i];
372 m_fr[i] = 0;
373
374 m_fr[i] = m_r[i] * (1 + weight/20.f);
375 }
376
377 float related[4] = { 1.5, 0.66666667, 0.5 };
378
379 for (int i = 1; i < n/2 - 1; ++i) {
380
381 if (!(m_fr[i] > m_fr[i-1] &&
382 m_fr[i] >= m_fr[i+1])) {
383 continue;
384 }
385
386 m_t[i] = lag2tempo(i);
360 387
361 int div = 1; 388 int div = 1;
362 389
363 int j = i; 390 for (int j = 0; j < sizeof(related)/sizeof(related[0]); ++j) {
391
392 int k0 = i / related[j];
393
394 if (k0 > 1 && k0 < n/2 - 2) {
395
396 for (int k = k0 - 1; k <= k0 + 1; ++k) {
397
398 if (m_r[k] > m_r[k-1] &&
399 m_r[k] >= m_r[k+1]) {
400
401 std::cerr << "peak at " << i << " (val " << m_r[i] << ", tempo " << lag2tempo(i) << ") has sympathetic peak at " << k << " (val " << m_r[k] << " for relative tempo " << lag2tempo(k) / related[j] << ")" << std::endl;
402
403 m_t[i] = m_t[i] + lag2tempo(k) / related[j];
404 ++div;
405 }
406 }
407 }
408 }
409
410 m_t[i] /= div;
411
412 if (div > 1) {
413 std::cerr << "adjusting tempo from " << lag2tempo(i) << " to "
414 << m_t[i] << std::endl;
415 }
416 }
417 /*
418 for (int i = 1; i < n/2; ++i) {
419
420 // int div = 1;
421 int j = i * 2;
364 422
365 while (j < n/2) { 423 while (j < n/2) {
366 m_fr[i] += m_r[j]; 424 m_fr[i] += m_fr[j] * 0.1;
367 j *= 2; 425 j *= 2;
368 ++div; 426 // ++div;
369 } 427 }
370 /* 428
371 for (int j = 1; j <= (n/2 - 1)/i; ++j) { 429 // m_fr[i] /= div;
372 m_fr[i] += m_r[i * j]; 430 }
373 ++div; 431
374 } 432 // std::cerr << "i = " << i << ", (n/2 - 1)/i = " << (n/2 - 1)/i << ", sum = " << m_fr[i] << ", div = " << div << ", val = " << m_fr[i] / div << ", t = " << lag2tempo(i) << std::endl;
433
434
435 // }
375 */ 436 */
376 // std::cerr << "i = " << i << ", (n/2 - 1)/i = " << (n/2 - 1)/i << ", sum = " << m_fr[i] << ", div = " << div << ", val = " << m_fr[i] / div << ", t = " << lag2tempo(i) << std::endl;
377
378
379 // m_fr[i] /= 1 + (n/2 - 1)/i;
380 m_fr[i] /= div;
381 }
382
383 std::cerr << "FixedTempoEstimator::calculate done" << std::endl; 437 std::cerr << "FixedTempoEstimator::calculate done" << std::endl;
384 } 438 }
385 439
386 440
387 FixedTempoEstimator::FeatureSet 441 FixedTempoEstimator::FeatureSet
468 feature.duration = m_lasttime - m_start; 522 feature.duration = m_lasttime - m_start;
469 523
470 std::map<float, int>::const_iterator ci = candidates.end(); 524 std::map<float, int>::const_iterator ci = candidates.end();
471 --ci; 525 --ci;
472 int maxpi = ci->second; 526 int maxpi = ci->second;
473 527
474 feature.values[0] = lag2tempo(maxpi); 528 if (m_t[maxpi] > 0) {
475 529 feature.values[0] = m_t[maxpi];
476 sprintf(buffer, "%.1f bpm", lag2tempo(maxpi)); 530 } else {
531 // shouldn't happen -- it would imply that this high value was not a peak!
532 feature.values[0] = lag2tempo(maxpi);
533 std::cerr << "WARNING: No stored tempo for index " << maxpi << std::endl;
534 }
535
536 sprintf(buffer, "%.1f bpm", feature.values[0]);
477 feature.label = buffer; 537 feature.label = buffer;
478 538
479 fs[TempoOutput].push_back(feature); 539 fs[TempoOutput].push_back(feature);
480 540
481 feature.values.clear(); 541 feature.values.clear();
482 feature.label = ""; 542 feature.label = "";
483 543
484 while (feature.values.size() < 8) { 544 while (feature.values.size() < 8) {
485 feature.values.push_back(lag2tempo(ci->second)); 545 feature.values.push_back(lag2tempo(ci->second)); //!!!??? use m_t?
486 if (ci == candidates.begin()) break; 546 if (ci == candidates.begin()) break;
487 --ci; 547 --ci;
488 } 548 }
489 549
490 fs[CandidatesOutput].push_back(feature); 550 fs[CandidatesOutput].push_back(feature);