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 }