Mercurial > hg > vamp-tempogram
comparison TempogramPlugin.cpp @ 19:e90a4797e579
* Attempted fixing bug which crashes sonic visualizer.
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Fri, 15 Aug 2014 12:34:07 +0100 |
parents | 89bc9e5199d7 |
children | de7213b35755 |
comparison
equal
deleted
inserted
replaced
18:89bc9e5199d7 | 19:e90a4797e579 |
---|---|
14 | 14 |
15 TempogramPlugin::TempogramPlugin(float inputSampleRate) : | 15 TempogramPlugin::TempogramPlugin(float inputSampleRate) : |
16 Plugin(inputSampleRate), | 16 Plugin(inputSampleRate), |
17 m_inputBlockSize(0), //host parameter | 17 m_inputBlockSize(0), //host parameter |
18 m_inputStepSize(0), //host parameter | 18 m_inputStepSize(0), //host parameter |
19 m_noveltyCurveMinDB(0), //set in initialise() | 19 m_noveltyCurveMinDB(pow(10,(float)-74/20)), //set in initialise() |
20 m_noveltyCurveCompressionConstant(1000), //parameter | 20 m_noveltyCurveCompressionConstant(1000), //parameter |
21 m_tempogramLog2WindowLength(10), //parameter | 21 m_tempogramLog2WindowLength(10), //parameter |
22 m_tempogramWindowLength(pow((float)2,m_tempogramLog2WindowLength)), | 22 m_tempogramWindowLength(pow((float)2,m_tempogramLog2WindowLength)), |
23 m_tempogramLog2FftLength(m_tempogramLog2WindowLength), //parameter | 23 m_tempogramLog2FftLength(m_tempogramLog2WindowLength), //parameter |
24 m_tempogramFftLength(m_tempogramWindowLength), | 24 m_tempogramFftLength(m_tempogramWindowLength), |
39 } | 39 } |
40 | 40 |
41 TempogramPlugin::~TempogramPlugin() | 41 TempogramPlugin::~TempogramPlugin() |
42 { | 42 { |
43 //delete stuff | 43 //delete stuff |
44 cleanup(); | 44 |
45 } | 45 } |
46 | 46 |
47 string | 47 string |
48 TempogramPlugin::getIdentifier() const | 48 TempogramPlugin::getIdentifier() const |
49 { | 49 { |
286 } | 286 } |
287 else if (identifier == "octDiv"){ | 287 else if (identifier == "octDiv"){ |
288 m_cyclicTempogramOctaveDivider = value; | 288 m_cyclicTempogramOctaveDivider = value; |
289 } | 289 } |
290 | 290 |
291 } | |
292 | |
293 void TempogramPlugin::updateBPMParameters(){ | |
294 | |
295 } | 291 } |
296 | 292 |
297 TempogramPlugin::ProgramList | 293 TempogramPlugin::ProgramList |
298 TempogramPlugin::getPrograms() const | 294 TempogramPlugin::getPrograms() const |
299 { | 295 { |
394 channels > getMaxChannelCount()) return false; | 390 channels > getMaxChannelCount()) return false; |
395 | 391 |
396 // Real initialisation work goes here! | 392 // Real initialisation work goes here! |
397 m_inputBlockSize = blockSize; | 393 m_inputBlockSize = blockSize; |
398 m_inputStepSize = stepSize; | 394 m_inputStepSize = stepSize; |
399 m_noveltyCurveMinDB = pow(10,(float)-74/20); | 395 |
396 m_spectrogram = SpectrogramTransposed(m_inputBlockSize/2 + 1); | |
400 | 397 |
401 if (m_tempogramFftLength < m_tempogramWindowLength){ | 398 if (m_tempogramFftLength < m_tempogramWindowLength){ |
402 m_tempogramFftLength = m_tempogramWindowLength; | 399 m_tempogramFftLength = m_tempogramWindowLength; |
403 } | 400 } |
404 if (m_tempogramMinBPM > m_tempogramMaxBPM){ | 401 if (m_tempogramMinBPM > m_tempogramMaxBPM){ |
412 | 409 |
413 if (m_tempogramMinBPM > m_cyclicTempogramMinBPM) m_cyclicTempogramMinBPM = m_tempogramMinBPM; | 410 if (m_tempogramMinBPM > m_cyclicTempogramMinBPM) m_cyclicTempogramMinBPM = m_tempogramMinBPM; |
414 float cyclicTempogramMaxBPM = 480; | 411 float cyclicTempogramMaxBPM = 480; |
415 if (m_tempogramMaxBPM < cyclicTempogramMaxBPM) cyclicTempogramMaxBPM = m_tempogramMaxBPM; | 412 if (m_tempogramMaxBPM < cyclicTempogramMaxBPM) cyclicTempogramMaxBPM = m_tempogramMaxBPM; |
416 | 413 |
417 m_spectrogram = SpectrogramTransposed(m_inputBlockSize/2 + 1); | |
418 | |
419 m_cyclicTempogramNumberOfOctaves = floor(log2(cyclicTempogramMaxBPM/m_cyclicTempogramMinBPM)); | 414 m_cyclicTempogramNumberOfOctaves = floor(log2(cyclicTempogramMaxBPM/m_cyclicTempogramMinBPM)); |
420 int numberOfBinsInFirstOctave = bpmToBin(m_cyclicTempogramMinBPM); | 415 int numberOfBinsInFirstOctave = bpmToBin(m_cyclicTempogramMinBPM); |
421 if (m_cyclicTempogramOctaveDivider < numberOfBinsInFirstOctave) m_cyclicTempogramOctaveDivider = numberOfBinsInFirstOctave; | 416 if (m_cyclicTempogramOctaveDivider > numberOfBinsInFirstOctave) m_cyclicTempogramOctaveDivider = numberOfBinsInFirstOctave; |
417 | |
418 //cout << m_cyclicTempogramOctaveDivider << endl; | |
422 | 419 |
423 return true; | 420 return true; |
424 } | |
425 | |
426 void TempogramPlugin::cleanup(){ | |
427 | |
428 } | 421 } |
429 | 422 |
430 void | 423 void |
431 TempogramPlugin::reset() | 424 TempogramPlugin::reset() |
432 { | 425 { |
433 // Clear buffers, reset stored values, etc | 426 // Clear buffers, reset stored values, etc |
427 m_spectrogram.clear(); | |
434 m_spectrogram = SpectrogramTransposed(m_inputBlockSize/2 + 1); | 428 m_spectrogram = SpectrogramTransposed(m_inputBlockSize/2 + 1); |
435 } | 429 } |
436 | 430 |
437 TempogramPlugin::FeatureSet | 431 TempogramPlugin::FeatureSet |
438 TempogramPlugin::process(const float *const *inputBuffers, Vamp::RealTime timestamp) | 432 TempogramPlugin::process(const float *const *inputBuffers, Vamp::RealTime timestamp) |
461 for (int i = 0; i < (int)ceil(m_cyclicTempogramNumberOfOctaves*m_cyclicTempogramOctaveDivider); i++){ | 455 for (int i = 0; i < (int)ceil(m_cyclicTempogramNumberOfOctaves*m_cyclicTempogramOctaveDivider); i++){ |
462 float bpm = m_cyclicTempogramMinBPM*pow(2.0f, (float)i/m_cyclicTempogramOctaveDivider); | 456 float bpm = m_cyclicTempogramMinBPM*pow(2.0f, (float)i/m_cyclicTempogramOctaveDivider); |
463 int bin = bpmToBin(bpm); | 457 int bin = bpmToBin(bpm); |
464 | 458 |
465 logBins.push_back(bin); | 459 logBins.push_back(bin); |
466 } | 460 cerr << bin << endl; |
461 } | |
462 | |
463 cerr << logBins.size() << endl; | |
467 | 464 |
468 return logBins; | 465 return logBins; |
469 } | 466 } |
470 | 467 |
471 int TempogramPlugin::bpmToBin(const float &bpm) const | 468 int TempogramPlugin::bpmToBin(const float &bpm) const |
489 hannWindow[i] = 0.0; | 486 hannWindow[i] = 0.0; |
490 } | 487 } |
491 | 488 |
492 FeatureSet featureSet; | 489 FeatureSet featureSet; |
493 | 490 |
494 //initialise m_noveltyCurve processor | 491 //initialise novelty curve processor |
495 size_t numberOfBlocks = m_spectrogram[0].size(); | 492 size_t numberOfBlocks = m_spectrogram[0].size(); |
496 NoveltyCurveProcessor nc(m_inputSampleRate, m_inputBlockSize, numberOfBlocks, m_noveltyCurveCompressionConstant); | 493 NoveltyCurveProcessor nc(m_inputSampleRate, m_inputBlockSize, numberOfBlocks, m_noveltyCurveCompressionConstant); |
497 m_noveltyCurve = nc.spectrogramToNoveltyCurve(m_spectrogram); //calculate novelty curve from magnitude data | 494 vector<float> noveltyCurve = nc.spectrogramToNoveltyCurve(m_spectrogram); //calculate novelty curve from magnitude data |
498 | 495 |
499 //push novelty curve data to featureset 1 and set timestamps | 496 //push novelty curve data to featureset 1 and set timestamps |
500 for (unsigned int i = 0; i < numberOfBlocks; i++){ | 497 for (unsigned int i = 0; i < numberOfBlocks; i++){ |
501 Feature feature; | 498 Feature noveltyCurveFeature; |
502 feature.values.push_back(m_noveltyCurve[i]); | 499 noveltyCurveFeature.values.push_back(noveltyCurve[i]); |
503 feature.hasTimestamp = false; | 500 noveltyCurveFeature.hasTimestamp = false; |
504 //feature.timestamp = ncTimestamps[i]; | 501 featureSet[1].push_back(noveltyCurveFeature); |
505 featureSet[1].push_back(feature); | |
506 } | 502 } |
507 | 503 |
508 //window function for spectrogram | 504 //window function for spectrogram |
509 WindowFunction::hanning(hannWindow, m_tempogramWindowLength); | 505 WindowFunction::hanning(hannWindow, m_tempogramWindowLength); |
510 | 506 |
511 //initialise spectrogram processor | 507 //initialise spectrogram processor |
512 SpectrogramProcessor spectrogramProcessor(m_tempogramWindowLength, m_tempogramFftLength, m_tempogramHopSize); | 508 SpectrogramProcessor spectrogramProcessor(m_tempogramWindowLength, m_tempogramFftLength, m_tempogramHopSize); |
513 //compute spectrogram from novelty curve data (i.e., tempogram) | 509 //compute spectrogram from novelty curve data (i.e., tempogram) |
514 Tempogram tempogram = spectrogramProcessor.process(&m_noveltyCurve[0], numberOfBlocks, hannWindow); | 510 Tempogram tempogram = spectrogramProcessor.process(&noveltyCurve[0], numberOfBlocks, hannWindow); |
515 delete []hannWindow; | 511 delete []hannWindow; |
516 hannWindow = 0; | 512 hannWindow = 0; |
517 | 513 |
518 int tempogramLength = tempogram.size(); | 514 int tempogramLength = tempogram.size(); |
519 | 515 |
520 //push tempogram data to featureset 0 and set timestamps. | 516 //push tempogram data to featureset 0 and set timestamps. |
521 for (int block = 0; block < tempogramLength; block++){ | 517 for (int block = 0; block < tempogramLength; block++){ |
522 Feature feature; | 518 Feature tempogramFeature; |
523 | 519 |
524 assert(tempogram[block].size() == (m_tempogramFftLength/2 + 1)); | 520 assert(tempogram[block].size() == (m_tempogramFftLength/2 + 1)); |
525 for(int k = m_tempogramMinBin; k < (int)m_tempogramMaxBin; k++){ | 521 for(int k = m_tempogramMinBin; k < (int)m_tempogramMaxBin; k++){ |
526 feature.values.push_back(tempogram[block][k]); | 522 tempogramFeature.values.push_back(tempogram[block][k]); |
527 } | 523 } |
528 feature.hasTimestamp = false; | 524 tempogramFeature.hasTimestamp = false; |
529 featureSet[0].push_back(feature); | 525 featureSet[0].push_back(tempogramFeature); |
530 } | 526 } |
531 | 527 |
532 //Calculate cyclic tempogram | 528 //Calculate cyclic tempogram |
533 vector<unsigned int> logBins = calculateTempogramNearestNeighbourLogBins(); | 529 vector<unsigned int> logBins = calculateTempogramNearestNeighbourLogBins(); |
534 Tempogram cyclicTempogram; | 530 |
535 | 531 assert(logBins.back() <= m_tempogramFftLength/2); |
532 assert(logBins.size() == m_cyclicTempogramOctaveDivider*m_cyclicTempogramNumberOfOctaves); | |
536 for (int block = 0; block < tempogramLength; block++){ | 533 for (int block = 0; block < tempogramLength; block++){ |
537 Feature feature; | 534 Feature cyclicTempogramFeature; |
538 | 535 |
539 for (int i = 0; i < m_cyclicTempogramOctaveDivider; i++){ | 536 for (int i = 0; i < m_cyclicTempogramOctaveDivider; i++){ |
540 float sum = 0; | 537 float sum = 0; |
541 for (int j = 0; j < m_cyclicTempogramNumberOfOctaves; j++){ | 538 for (int j = 0; j < m_cyclicTempogramNumberOfOctaves; j++){ |
542 sum += tempogram[block][logBins[i+j*m_cyclicTempogramOctaveDivider]]; | 539 sum += tempogram[block][logBins[i+j*m_cyclicTempogramOctaveDivider]]; |
543 } | 540 } |
544 feature.values.push_back(sum/m_cyclicTempogramNumberOfOctaves); | 541 cyclicTempogramFeature.values.push_back(sum/m_cyclicTempogramNumberOfOctaves); |
545 } | 542 } |
546 | 543 |
547 feature.hasTimestamp = false; | 544 cyclicTempogramFeature.hasTimestamp = false; |
548 | 545 featureSet[2].push_back(cyclicTempogramFeature); |
549 featureSet[2].push_back(feature); | |
550 } | 546 } |
551 | 547 |
552 return featureSet; | 548 return featureSet; |
553 } | 549 } |