Mercurial > hg > pyin
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(); |