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); |