comparison PYIN.cpp @ 91:854d9403c5be

note separation based on RMS
author matthiasm
date Wed, 07 Jan 2015 16:30:16 +0000
parents b087967c4417
children 2687ba2cafae
comparison
equal deleted inserted replaced
90:b087967c4417 91:854d9403c5be
44 m_oSmoothedPitchTrack(0), 44 m_oSmoothedPitchTrack(0),
45 m_oNotes(0), 45 m_oNotes(0),
46 m_threshDistr(2.0f), 46 m_threshDistr(2.0f),
47 m_outputUnvoiced(0.0f), 47 m_outputUnvoiced(0.0f),
48 m_pitchProb(0), 48 m_pitchProb(0),
49 m_timestamp(0) 49 m_timestamp(0),
50 m_level(0)
50 { 51 {
51 } 52 }
52 53
53 PYIN::~PYIN() 54 PYIN::~PYIN()
54 { 55 {
342 m_yin.setThresholdDistr(m_threshDistr); 343 m_yin.setThresholdDistr(m_threshDistr);
343 m_yin.setFrameSize(m_blockSize); 344 m_yin.setFrameSize(m_blockSize);
344 345
345 m_pitchProb.clear(); 346 m_pitchProb.clear();
346 m_timestamp.clear(); 347 m_timestamp.clear();
348 m_level.clear();
347 /* 349 /*
348 std::cerr << "PYIN::reset" 350 std::cerr << "PYIN::reset"
349 << ", blockSize = " << m_blockSize 351 << ", blockSize = " << m_blockSize
350 << std::endl; 352 << std::endl;
351 */ 353 */
360 double *dInputBuffers = new double[m_blockSize]; 362 double *dInputBuffers = new double[m_blockSize];
361 for (size_t i = 0; i < m_blockSize; ++i) dInputBuffers[i] = inputBuffers[0][i]; 363 for (size_t i = 0; i < m_blockSize; ++i) dInputBuffers[i] = inputBuffers[0][i];
362 364
363 Yin::YinOutput yo = m_yin.processProbabilisticYin(dInputBuffers); 365 Yin::YinOutput yo = m_yin.processProbabilisticYin(dInputBuffers);
364 delete [] dInputBuffers; 366 delete [] dInputBuffers;
367
368 m_level.push_back(yo.rms);
365 369
366 // First, get the things out of the way that we don't want to output 370 // First, get the things out of the way that we don't want to output
367 // immediately, but instead save for later. 371 // immediately, but instead save for later.
368 vector<pair<double, double> > tempPitchProb; 372 vector<pair<double, double> > tempPitchProb;
369 for (size_t iCandidate = 0; iCandidate < yo.freqProb.size(); ++iCandidate) 373 for (size_t iCandidate = 0; iCandidate < yo.freqProb.size(); ++iCandidate)
468 size_t nFrame = m_pitchProb.size(); 472 size_t nFrame = m_pitchProb.size();
469 473
470 std::vector<float> notePitchTrack; // collects pitches for one note at a time 474 std::vector<float> notePitchTrack; // collects pitches for one note at a time
471 for (size_t iFrame = 0; iFrame < nFrame; ++iFrame) 475 for (size_t iFrame = 0; iFrame < nFrame; ++iFrame)
472 { 476 {
473 isVoiced = mnOut[iFrame].noteState < 3 && smoothedPitch[iFrame].size() > 0; 477 isVoiced = mnOut[iFrame].noteState < 3
478 && smoothedPitch[iFrame].size() > 0
479 && (iFrame == nFrame-1
480 || ((m_level[iFrame+1]/m_level[iFrame]) < 1.25));
481 // std::cerr << m_level[iFrame]/m_level[iFrame-1] << std::endl;
474 if (isVoiced && iFrame != nFrame-1) 482 if (isVoiced && iFrame != nFrame-1)
475 { 483 {
476 if (oldIsVoiced == 0) // beginning of a note 484 if (oldIsVoiced == 0) // beginning of a note
477 { 485 {
478 onsetFrame = iFrame; 486 onsetFrame = iFrame;
479 notePitchTrack.clear(); 487 notePitchTrack.clear();
480 } 488 }
481 float pitch = smoothedPitch[iFrame][0].first; 489 float pitch = smoothedPitch[iFrame][0].first;
482 notePitchTrack.push_back(pitch); // add to the note's pitch track 490 notePitchTrack.push_back(pitch); // add to the note's pitch track
483 } else { // not currently voiced 491 } else { // not currently voiced
484 if (oldIsVoiced == 1 && notePitchTrack.size() > 17) // end of note 492 if (oldIsVoiced == 1 && notePitchTrack.size() > 14) // end of note
485 { 493 {
486 std::sort(notePitchTrack.begin(), notePitchTrack.end()); 494 std::sort(notePitchTrack.begin(), notePitchTrack.end());
487 float medianPitch = notePitchTrack[notePitchTrack.size()/2]; 495 float medianPitch = notePitchTrack[notePitchTrack.size()/2];
488 float medianFreq = std::pow(2,(medianPitch - 69) / 12) * 440; 496 float medianFreq = std::pow(2,(medianPitch - 69) / 12) * 440;
489 f.values.clear(); 497 f.values.clear();