Mercurial > hg > vamp-plugin-sdk
comparison examples/FixedTempoEstimator.cpp @ 215:a5a54b60e82e
* More tweaks to fixed-tempo estimator
author | cannam |
---|---|
date | Fri, 24 Oct 2008 16:10:43 +0000 |
parents | 87b131a54b0a |
children | 991d2ae87980 |
comparison
equal
deleted
inserted
replaced
214:930b51de9c28 | 215:a5a54b60e82e |
---|---|
286 | 286 |
287 if (m_n > m_dfsize) return FeatureSet(); | 287 if (m_n > m_dfsize) return FeatureSet(); |
288 | 288 |
289 float value = 0.f; | 289 float value = 0.f; |
290 | 290 |
291 bool print = (ts == RealTime::zeroTime); | |
292 | |
293 for (size_t i = 1; i < m_blockSize/2; ++i) { | 291 for (size_t i = 1; i < m_blockSize/2; ++i) { |
294 | 292 |
295 float real = inputBuffers[0][i*2]; | 293 float real = inputBuffers[0][i*2]; |
296 float imag = inputBuffers[0][i*2 + 1]; | 294 float imag = inputBuffers[0][i*2 + 1]; |
297 | 295 |
298 float sqrmag = real * real + imag * imag; | 296 float sqrmag = real * real + imag * imag; |
299 value += fabsf(sqrmag - m_priorMagnitudes[i]); | 297 value += fabsf(sqrmag - m_priorMagnitudes[i]); |
300 | |
301 if (i == 1 && ts == RealTime::zeroTime) { | |
302 cerr << "First sqrmag: " << sqrmag << ", value = " << value << endl; | |
303 } | |
304 | 298 |
305 m_priorMagnitudes[i] = sqrmag; | 299 m_priorMagnitudes[i] = sqrmag; |
306 } | 300 } |
307 | 301 |
308 m_df[m_n] = value; | 302 m_df[m_n] = value; |
367 m_r[i] += m_df[j] * m_df[j - i]; | 361 m_r[i] += m_df[j] * m_df[j - i]; |
368 } | 362 } |
369 | 363 |
370 m_r[i] /= n - i - 1; | 364 m_r[i] /= n - i - 1; |
371 } | 365 } |
372 /* | 366 |
373 for (int i = 1; i < n/2; ++i) { | 367 float related[] = { 0.5, 2, 3, 4 }; |
368 | |
369 for (int i = 1; i < n/2-1; ++i) { | |
374 | 370 |
375 float weight = 1.f - fabsf(128.f - lag2tempo(i)) * 0.005; | 371 float weight = 1.f - fabsf(128.f - lag2tempo(i)) * 0.005; |
376 if (weight < 0.f) weight = 0.f; | 372 if (weight < 0.f) weight = 0.f; |
377 weight = weight * weight; | 373 weight = weight * weight * weight; |
378 | |
379 cerr << "i = " << i << ": tempo = " << lag2tempo(i) << ", weight = " << weight << ", " << m_r[i] << " -> "; | |
380 | |
381 m_fr[i] = m_r[i] * weight; //(1 + weight / 2.f); | |
382 | |
383 cerr << m_fr[i] << endl; | |
384 } | |
385 */ | |
386 int related[] = { 2, 3, 4 }; | |
387 | |
388 int e = tempo2lag(50.f); | |
389 // int universalDiv = (n/2 - 1) / e; | |
390 // cerr << "universalDiv = " << universalDiv << endl; | |
391 | |
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 | 374 |
400 m_fr[i] = m_r[i]; | 375 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 | |
404 /* | |
405 || | |
406 !(m_fr[i] > m_fr[i-1] && | |
407 m_fr[i] >= m_fr[i+1]) | |
408 */ | |
409 // ) { | |
410 // continue; | |
411 // } | |
412 | 376 |
413 int div = 1; | 377 int div = 1; |
414 | 378 |
415 for (int j = 0; j < sizeof(related)/sizeof(related[0]); ++j) { | 379 for (int j = 0; j < int(sizeof(related)/sizeof(related[0])); ++j) { |
416 | 380 |
417 int k0 = i * related[j]; | 381 int k0 = int(i * related[j] + 0.5); |
418 | 382 |
419 if (k0 >= 0 && k0 < n/2) { | 383 if (k0 >= 0 && k0 < int(n/2)) { |
420 | 384 |
421 int kmax = 0, kmin = 0; | 385 int kmax = 0, kmin = 0; |
422 float kvmax = 0, kvmin = 0; | 386 float kvmax = 0, kvmin = 0; |
423 bool have = false; | 387 bool have = false; |
424 | 388 |
425 for (int k = k0 - 1; k <= k0 + 1; ++k) { | 389 for (int k = k0 - 1; k <= k0 + 1; ++k) { |
426 | 390 |
427 if (k < 0 || k >= n/2) continue; | 391 if (k < 0 || k >= n/2) continue; |
428 | 392 |
429 if (!have || (m_r[k] > kvmax)) { | 393 if (!have || (m_r[k] > kvmax)) { kmax = k; kvmax = m_r[k]; } |
430 kmax = k; | 394 if (!have || (m_r[k] < kvmin)) { kmin = k; kvmin = m_r[k]; } |
431 kvmax = m_r[k]; | |
432 } | |
433 | |
434 if (!have || (m_r[k] < kvmin)) { | |
435 kmin = k; | |
436 kvmin = m_r[k]; | |
437 } | |
438 | 395 |
439 have = true; | 396 have = true; |
440 } | 397 } |
441 | 398 |
442 | 399 m_fr[i] += m_r[kmax] / 5; |
443 m_fr[i] += m_r[kmax] / 4; | |
444 | |
445 // if (related[j] <= universalDiv) { | |
446 // m_fr[i] += m_fr[kmax]; //!!! | |
447 // m_fr[i] += m_r[kmax] / related[j]; | |
448 // } | |
449 | 400 |
450 if ((kmax == 0 || m_r[kmax] > m_r[kmax-1]) && | 401 if ((kmax == 0 || m_r[kmax] > m_r[kmax-1]) && |
451 (kmax == n/2-1 || m_r[kmax] > m_r[kmax+1]) && | 402 (kmax == n/2-1 || m_r[kmax] > m_r[kmax+1]) && |
452 kvmax > kvmin * 1.05) { | 403 kvmax > kvmin * 1.05) { |
453 | 404 |
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; | |
455 | |
456 m_t[i] = m_t[i] + lag2tempo(kmax) * related[j]; | 405 m_t[i] = m_t[i] + lag2tempo(kmax) * related[j]; |
457 ++div; | 406 ++div; |
458 } | 407 } |
459 } | 408 } |
460 } | 409 } |
461 | 410 |
462 m_t[i] /= div; | 411 m_t[i] /= div; |
463 | 412 |
464 if (div > 1) { | 413 // if (div > 1) { |
465 cerr << "adjusting tempo from " << lag2tempo(i) << " to " | 414 // cerr << "adjusting tempo from " << lag2tempo(i) << " to " |
466 << m_t[i] << " for fr = " << m_fr[i] << " (div = " << div << ")" << endl; | 415 // << m_t[i] << " for fr = " << m_fr[i] << " (div = " << div << ")" << endl; |
467 } | 416 // } |
468 | 417 |
469 m_fr[i] += m_fr[i] * (weight / 5); | 418 m_fr[i] += m_fr[i] * (weight / 3); |
470 } | 419 } |
471 | |
472 /* | |
473 int e = tempo2lag(60.f); | |
474 int div = (n/2 - 1) / e; | |
475 | |
476 // cerr << "e = " << e << ", n/2 = " << n/2 << ", div = " << div << endl; | |
477 if (div > 1) { | |
478 for (int j = 2; j <= div && j <= 8; j *= 2) { | |
479 for (int i = 1; i <= e; ++i) { | |
480 m_fr[i] += m_fr[i * j] * (1.f / j); | |
481 } | |
482 } | |
483 } | |
484 */ | |
485 // 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) << endl; | |
486 | |
487 | |
488 // } | |
489 | |
490 cerr << "FixedTempoEstimator::calculate done" << endl; | |
491 } | 420 } |
492 | 421 |
493 | 422 |
494 FixedTempoEstimator::FeatureSet | 423 FixedTempoEstimator::FeatureSet |
495 FixedTempoEstimator::assembleFeatures() | 424 FixedTempoEstimator::assembleFeatures() |
524 if (i == n/2-1) feature.label = ""; | 453 if (i == n/2-1) feature.label = ""; |
525 else feature.label = buffer; | 454 else feature.label = buffer; |
526 fs[ACFOutput].push_back(feature); | 455 fs[ACFOutput].push_back(feature); |
527 } | 456 } |
528 | 457 |
529 float t0 = 50.f; | 458 float t0 = 50.f; // our minimum detected tempo (could be a parameter) |
530 float t1 = 190.f; | 459 float t1 = 190.f; // our maximum detected tempo |
531 | 460 |
532 int p0 = tempo2lag(t1); | 461 int p0 = tempo2lag(t1); |
533 int p1 = tempo2lag(t0); | 462 int p1 = tempo2lag(t0); |
534 | |
535 cerr << "p0 = " << p0 << ", p1 = " << p1 << endl; | |
536 | |
537 int pc = p1 - p0 + 1; | |
538 // cerr << "pc = " << pc << endl; | |
539 | |
540 // int maxpi = 0; | |
541 // float maxp = 0.f; | |
542 | 463 |
543 std::map<float, int> candidates; | 464 std::map<float, int> candidates; |
544 | 465 |
545 for (int i = p0; i <= p1 && i < n/2-1; ++i) { | 466 for (int i = p0; i <= p1 && i < n/2-1; ++i) { |
546 | 467 |