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