Mercurial > hg > vamp-plugin-sdk
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); |
