Mercurial > hg > nnls-chroma
comparison NNLSBase.cpp @ 80:026a5c0ee2c2 matthiasm-plugin
bins per semitone can now be chosen in chromamethods.h
author | Matthias Mauch <mail@matthiasmauch.net> |
---|---|
date | Thu, 11 Nov 2010 15:11:05 +0900 |
parents | ba930176df5b |
children | 4270f3039ab0 |
comparison
equal
deleted
inserted
replaced
78:d52884de7d79 | 80:026a5c0ee2c2 |
---|---|
32 Plugin(inputSampleRate), | 32 Plugin(inputSampleRate), |
33 m_logSpectrum(0), | 33 m_logSpectrum(0), |
34 m_blockSize(0), | 34 m_blockSize(0), |
35 m_stepSize(0), | 35 m_stepSize(0), |
36 m_lengthOfNoteIndex(0), | 36 m_lengthOfNoteIndex(0), |
37 m_meanTuning0(0), | 37 m_meanTunings(0), |
38 m_meanTuning1(0), | 38 m_localTunings(0), |
39 m_meanTuning2(0), | |
40 m_localTuning0(0), | |
41 m_localTuning1(0), | |
42 m_localTuning2(0), | |
43 m_whitening(1.0), | 39 m_whitening(1.0), |
44 m_preset(0.0), | 40 m_preset(0.0), |
45 m_localTuning(0), | 41 m_localTuning(0), |
46 m_kernelValue(0), | 42 m_kernelValue(0), |
47 m_kernelFftIndex(0), | 43 m_kernelFftIndex(0), |
52 m_chordnames(0), | 48 m_chordnames(0), |
53 m_doNormalizeChroma(0), | 49 m_doNormalizeChroma(0), |
54 m_rollon(0), | 50 m_rollon(0), |
55 m_s(0.7), | 51 m_s(0.7), |
56 m_useNNLS(1), | 52 m_useNNLS(1), |
57 m_useHMM(1) | 53 m_useHMM(1), |
54 sinvalues(0), | |
55 cosvalues(0) | |
58 { | 56 { |
59 if (debug_on) cerr << "--> NNLSBase" << endl; | 57 if (debug_on) cerr << "--> NNLSBase" << endl; |
60 | 58 |
61 // make the *note* dictionary matrix | 59 // make the *note* dictionary matrix |
62 m_dict = new float[nNote * 84]; | 60 m_dict = new float[nNote * 84]; |
350 { | 348 { |
351 if (debug_on) { | 349 if (debug_on) { |
352 cerr << "--> initialise"; | 350 cerr << "--> initialise"; |
353 } | 351 } |
354 | 352 |
353 // make things for tuning estimation | |
354 for (int iBPS = 0; iBPS < nBPS; ++iBPS) { | |
355 sinvalues.push_back(sin(2*M_PI*(iBPS*1.0/nBPS))); | |
356 cosvalues.push_back(cos(2*M_PI*(iBPS*1.0/nBPS))); | |
357 } | |
358 | |
359 | |
360 // make hamming window of length 1/2 octave | |
355 int hamwinlength = nBPS * 6 + 1; | 361 int hamwinlength = nBPS * 6 + 1; |
356 float hamwinsum = 0; | 362 float hamwinsum = 0; |
357 for (int i = 0; i < hamwinlength; ++i) { | 363 for (int i = 0; i < hamwinlength; ++i) { |
358 hw.push_back(0.54 - 0.46 * cos((2*M_PI*i)/(hamwinlength-1))); | 364 hw.push_back(0.54 - 0.46 * cos((2*M_PI*i)/(hamwinlength-1))); |
359 hamwinsum += 0.54 - 0.46 * cos((2*M_PI*i)/(hamwinlength-1)); | 365 hamwinsum += 0.54 - 0.46 * cos((2*M_PI*i)/(hamwinlength-1)); |
360 } | 366 } |
361 for (int i = 0; i < hamwinlength; ++i) hw[i] = hw[i] / hamwinsum; | 367 for (int i = 0; i < hamwinlength; ++i) hw[i] = hw[i] / hamwinsum; |
368 | |
369 | |
370 // initialise the tuning | |
371 for (int iBPS = 0; iBPS < nBPS; ++iBPS) { | |
372 m_meanTunings.push_back(0); | |
373 m_localTunings.push_back(0); | |
374 } | |
362 | 375 |
363 if (channels < getMinChannelCount() || | 376 if (channels < getMinChannelCount() || |
364 channels > getMaxChannelCount()) return false; | 377 channels > getMaxChannelCount()) return false; |
365 m_blockSize = blockSize; | 378 m_blockSize = blockSize; |
366 m_stepSize = stepSize; | 379 m_stepSize = stepSize; |
409 | 422 |
410 // Clear buffers, reset stored values, etc | 423 // Clear buffers, reset stored values, etc |
411 m_frameCount = 0; | 424 m_frameCount = 0; |
412 // m_dictID = 0; | 425 // m_dictID = 0; |
413 m_logSpectrum.clear(); | 426 m_logSpectrum.clear(); |
414 m_meanTuning0 = 0; | 427 for (int iBPS = 0; iBPS < nBPS; ++iBPS) { |
415 m_meanTuning1 = 0; | 428 m_meanTunings[iBPS] = 0; |
416 m_meanTuning2 = 0; | 429 m_localTunings[iBPS] = 0; |
417 m_localTuning0 = 0; | 430 } |
418 m_localTuning1 = 0; | |
419 m_localTuning2 = 0; | |
420 m_localTuning.clear(); | 431 m_localTuning.clear(); |
421 } | 432 } |
422 | 433 |
423 void | 434 void |
424 NNLSBase::baseProcess(const float *const *inputBuffers, Vamp::RealTime timestamp) | 435 NNLSBase::baseProcess(const float *const *inputBuffers, Vamp::RealTime timestamp) |
471 // cerr << endl; | 482 // cerr << endl; |
472 | 483 |
473 | 484 |
474 float one_over_N = 1.0/m_frameCount; | 485 float one_over_N = 1.0/m_frameCount; |
475 // update means of complex tuning variables | 486 // update means of complex tuning variables |
476 m_meanTuning0 *= float(m_frameCount-1)*one_over_N; | 487 for (int iBPS = 0; iBPS < nBPS; ++iBPS) m_meanTunings[iBPS] *= float(m_frameCount-1)*one_over_N; |
477 m_meanTuning1 *= float(m_frameCount-1)*one_over_N; | 488 |
478 m_meanTuning2 *= float(m_frameCount-1)*one_over_N; | 489 for (int iTone = 0; iTone < round(nNote*0.62/nBPS)*nBPS+1; iTone = iTone + nBPS) { |
479 | 490 for (int iBPS = 0; iBPS < nBPS; ++iBPS) m_meanTunings[iBPS] += nm[iTone + iBPS]*one_over_N; |
480 for (int iTone = 0; iTone < 160; iTone = iTone + 3) { | |
481 m_meanTuning0 += nm[iTone + 0]*one_over_N; | |
482 m_meanTuning1 += nm[iTone + 1]*one_over_N; | |
483 m_meanTuning2 += nm[iTone + 2]*one_over_N; | |
484 float ratioOld = 0.997; | 491 float ratioOld = 0.997; |
485 m_localTuning0 *= ratioOld; m_localTuning0 += nm[iTone + 0] * (1 - ratioOld); | 492 for (int iBPS = 0; iBPS < nBPS; ++iBPS) { |
486 m_localTuning1 *= ratioOld; m_localTuning1 += nm[iTone + 1] * (1 - ratioOld); | 493 m_localTunings[iBPS] *= ratioOld; |
487 m_localTuning2 *= ratioOld; m_localTuning2 += nm[iTone + 2] * (1 - ratioOld); | 494 m_localTunings[iBPS] += nm[iTone + iBPS] * (1 - ratioOld); |
488 } | 495 } |
489 | 496 } |
490 // if (m_tuneLocal) { | 497 // if (m_tuneLocal) { |
491 // local tuning | 498 // local tuning |
492 float localTuningImag = sinvalue * m_localTuning1 - sinvalue * m_localTuning2; | 499 // float localTuningImag = sinvalue * m_localTunings[1] - sinvalue * m_localTunings[2]; |
493 float localTuningReal = m_localTuning0 + cosvalue * m_localTuning1 + cosvalue * m_localTuning2; | 500 // float localTuningReal = m_localTunings[0] + cosvalue * m_localTunings[1] + cosvalue * m_localTunings[2]; |
501 | |
502 float localTuningImag = 0; | |
503 float localTuningReal = 0; | |
504 for (int iBPS = 0; iBPS < nBPS; ++iBPS) { | |
505 localTuningReal += m_localTunings[iBPS] * cosvalues[iBPS]; | |
506 localTuningImag += m_localTunings[iBPS] * sinvalues[iBPS]; | |
507 } | |
508 | |
494 float normalisedtuning = atan2(localTuningImag, localTuningReal)/(2*M_PI); | 509 float normalisedtuning = atan2(localTuningImag, localTuningReal)/(2*M_PI); |
495 m_localTuning.push_back(normalisedtuning); | 510 m_localTuning.push_back(normalisedtuning); |
496 | 511 |
497 Feature f1; // logfreqspec | 512 Feature f1; // logfreqspec |
498 f1.hasTimestamp = true; | 513 f1.hasTimestamp = true; |
521 // | 536 // |
522 /** Calculate Tuning | 537 /** Calculate Tuning |
523 calculate tuning from (using the angle of the complex number defined by the | 538 calculate tuning from (using the angle of the complex number defined by the |
524 cumulative mean real and imag values) | 539 cumulative mean real and imag values) |
525 **/ | 540 **/ |
526 float meanTuningImag = sinvalue * m_meanTuning1 - sinvalue * m_meanTuning2; | 541 float meanTuningImag = sinvalue * m_meanTunings[1] - sinvalue * m_meanTunings[2]; |
527 float meanTuningReal = m_meanTuning0 + cosvalue * m_meanTuning1 + cosvalue * m_meanTuning2; | 542 float meanTuningReal = m_meanTunings[0] + cosvalue * m_meanTunings[1] + cosvalue * m_meanTunings[2]; |
528 float cumulativetuning = 440 * pow(2,atan2(meanTuningImag, meanTuningReal)/(24*M_PI)); | 543 float cumulativetuning = 440 * pow(2,atan2(meanTuningImag, meanTuningReal)/(24*M_PI)); |
529 float normalisedtuning = atan2(meanTuningImag, meanTuningReal)/(2*M_PI); | 544 float normalisedtuning = atan2(meanTuningImag, meanTuningReal)/(2*M_PI); |
530 int intShift = floor(normalisedtuning * 3); | 545 int intShift = floor(normalisedtuning * 3); |
531 float intFactor = normalisedtuning * 3 - intShift; // intFactor is a really bad name for this | 546 float floatShift = normalisedtuning * 3 - intShift; // floatShift is a really bad name for this |
532 | 547 |
533 char buffer0 [50]; | 548 char buffer0 [50]; |
534 | 549 |
535 sprintf(buffer0, "estimated tuning: %0.1f Hz", cumulativetuning); | 550 sprintf(buffer0, "estimated tuning: %0.1f Hz", cumulativetuning); |
536 | 551 |
562 f2.timestamp = f1.timestamp; | 577 f2.timestamp = f1.timestamp; |
563 f2.values.push_back(0.0); f2.values.push_back(0.0); // set lower edge to zero | 578 f2.values.push_back(0.0); f2.values.push_back(0.0); // set lower edge to zero |
564 | 579 |
565 if (m_tuneLocal == 1.0) { | 580 if (m_tuneLocal == 1.0) { |
566 intShift = floor(m_localTuning[count] * 3); | 581 intShift = floor(m_localTuning[count] * 3); |
567 intFactor = m_localTuning[count] * 3 - intShift; // intFactor is a really bad name for this | 582 floatShift = m_localTuning[count] * 3 - intShift; // floatShift is a really bad name for this |
568 } | 583 } |
569 | 584 |
570 // cerr << intShift << " " << intFactor << endl; | 585 // cerr << intShift << " " << floatShift << endl; |
571 | 586 |
572 for (unsigned k = 2; k < f1.values.size() - 3; ++k) { // interpolate all inner bins | 587 for (unsigned k = 2; k < f1.values.size() - 3; ++k) { // interpolate all inner bins |
573 tempValue = f1.values[k + intShift] * (1-intFactor) + f1.values[k+intShift+1] * intFactor; | 588 tempValue = f1.values[k + intShift] * (1-floatShift) + f1.values[k+intShift+1] * floatShift; |
574 f2.values.push_back(tempValue); | 589 f2.values.push_back(tempValue); |
575 } | 590 } |
576 | 591 |
577 f2.values.push_back(0.0); f2.values.push_back(0.0); f2.values.push_back(0.0); // upper edge | 592 f2.values.push_back(0.0); f2.values.push_back(0.0); f2.values.push_back(0.0); // upper edge |
578 vector<float> runningmean = SpecialConvolution(f2.values,hw); | 593 vector<float> runningmean = SpecialConvolution(f2.values,hw); |