annotate Yin.cpp @ 0:99bac62ee2da

added PYIN sources, should be compileable
author matthiasm
date Wed, 27 Nov 2013 11:59:49 +0000
parents
children 5945b8905d1f
rev   line source
matthiasm@0 1 #include "Yin.h"
matthiasm@0 2
matthiasm@0 3 #include "vamp-sdk/FFT.h"
matthiasm@0 4 #include "MeanFilter.h"
matthiasm@0 5 #include "YinUtil.h"
matthiasm@0 6
matthiasm@0 7 #include <vector>
matthiasm@0 8 #include <cstdlib>
matthiasm@0 9 #include <cstdio>
matthiasm@0 10 #include <cmath>
matthiasm@0 11 #include <complex>
matthiasm@0 12
matthiasm@0 13 using std::vector;
matthiasm@0 14
matthiasm@0 15 Yin::Yin(size_t frameSize, size_t inputSampleRate, double thresh) :
matthiasm@0 16 m_frameSize(frameSize),
matthiasm@0 17 m_inputSampleRate(inputSampleRate),
matthiasm@0 18 m_thresh(thresh),
matthiasm@0 19 m_threshDistr(2),
matthiasm@0 20 m_yinBufferSize(frameSize/2)
matthiasm@0 21 {
matthiasm@0 22 if (frameSize & (frameSize-1)) {
matthiasm@0 23 throw "N must be a power of two";
matthiasm@0 24 }
matthiasm@0 25 }
matthiasm@0 26
matthiasm@0 27 Yin::~Yin()
matthiasm@0 28 {
matthiasm@0 29 }
matthiasm@0 30
matthiasm@0 31 Yin::YinOutput
matthiasm@0 32 Yin::process(const double *in) const {
matthiasm@0 33
matthiasm@0 34 double* yinBuffer = new double[m_yinBufferSize];
matthiasm@0 35
matthiasm@0 36 // calculate aperiodicity function for all periods
matthiasm@0 37 YinUtil::fastDifference(in, yinBuffer, m_yinBufferSize);
matthiasm@0 38 YinUtil::cumulativeDifference(yinBuffer, m_yinBufferSize);
matthiasm@0 39
matthiasm@0 40 int tau = 0;
matthiasm@0 41 tau = YinUtil::absoluteThreshold(yinBuffer, m_yinBufferSize, m_thresh);
matthiasm@0 42
matthiasm@0 43 double interpolatedTau;
matthiasm@0 44 double aperiodicity;
matthiasm@0 45 double f0;
matthiasm@0 46
matthiasm@0 47 if (tau!=0)
matthiasm@0 48 {
matthiasm@0 49 interpolatedTau = YinUtil::parabolicInterpolation(yinBuffer, abs(tau), m_yinBufferSize);
matthiasm@0 50 f0 = m_inputSampleRate * (1.0 / interpolatedTau);
matthiasm@0 51 } else {
matthiasm@0 52 interpolatedTau = 0;
matthiasm@0 53 f0 = 0;
matthiasm@0 54 }
matthiasm@0 55 double rms = std::sqrt(YinUtil::sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize);
matthiasm@0 56 aperiodicity = yinBuffer[abs(tau)];
matthiasm@0 57 // std::cerr << aperiodicity << std::endl;
matthiasm@0 58 if (tau < 0) f0 = -f0;
matthiasm@0 59
matthiasm@0 60 Yin::YinOutput yo(f0, 1-aperiodicity, rms);
matthiasm@0 61 for (size_t iBuf = 0; iBuf < m_yinBufferSize; ++iBuf)
matthiasm@0 62 {
matthiasm@0 63 yo.salience.push_back(yinBuffer[iBuf] < 1 ? 1-yinBuffer[iBuf] : 0); // why are the values sometimes < 0 if I don't check?
matthiasm@0 64 }
matthiasm@0 65
matthiasm@0 66 delete [] yinBuffer;
matthiasm@0 67 return yo;
matthiasm@0 68 }
matthiasm@0 69
matthiasm@0 70 Yin::YinOutput
matthiasm@0 71 Yin::processProbabilisticYin(const double *in) const {
matthiasm@0 72
matthiasm@0 73 double* yinBuffer = new double[m_yinBufferSize];
matthiasm@0 74
matthiasm@0 75 // calculate aperiodicity function for all periods
matthiasm@0 76 YinUtil::fastDifference(in, yinBuffer, m_yinBufferSize);
matthiasm@0 77 YinUtil::cumulativeDifference(yinBuffer, m_yinBufferSize);
matthiasm@0 78
matthiasm@0 79 vector<double> peakProbability = YinUtil::yinProb(yinBuffer, m_threshDistr, m_yinBufferSize);
matthiasm@0 80
matthiasm@0 81 // calculate overall "probability" from peak probability
matthiasm@0 82 double probSum = 0;
matthiasm@0 83 for (size_t iBin = 0; iBin < m_yinBufferSize; ++iBin)
matthiasm@0 84 {
matthiasm@0 85 probSum += peakProbability[iBin];
matthiasm@0 86 }
matthiasm@0 87
matthiasm@0 88 Yin::YinOutput yo(0,0,0);
matthiasm@0 89 for (size_t iBuf = 0; iBuf < m_yinBufferSize; ++iBuf)
matthiasm@0 90 {
matthiasm@0 91 yo.salience.push_back(peakProbability[iBuf]);
matthiasm@0 92 if (peakProbability[iBuf] > 0)
matthiasm@0 93 {
matthiasm@0 94 double currentF0 =
matthiasm@0 95 m_inputSampleRate * (1.0 /
matthiasm@0 96 YinUtil::parabolicInterpolation(yinBuffer, iBuf, m_yinBufferSize));
matthiasm@0 97 yo.freqProb.push_back(pair<double, double>(currentF0, peakProbability[iBuf]));
matthiasm@0 98 }
matthiasm@0 99 }
matthiasm@0 100
matthiasm@0 101 // std::cerr << yo.freqProb.size() << std::endl;
matthiasm@0 102
matthiasm@0 103 delete [] yinBuffer;
matthiasm@0 104 return yo;
matthiasm@0 105 }
matthiasm@0 106
matthiasm@0 107
matthiasm@0 108 int
matthiasm@0 109 Yin::setThreshold(double parameter)
matthiasm@0 110 {
matthiasm@0 111 m_thresh = static_cast<float>(parameter);
matthiasm@0 112 return 0;
matthiasm@0 113 }
matthiasm@0 114
matthiasm@0 115 int
matthiasm@0 116 Yin::setThresholdDistr(float parameter)
matthiasm@0 117 {
matthiasm@0 118 m_threshDistr = static_cast<size_t>(parameter);
matthiasm@0 119 return 0;
matthiasm@0 120 }
matthiasm@0 121
matthiasm@0 122 int
matthiasm@0 123 Yin::setFrameSize(size_t parameter)
matthiasm@0 124 {
matthiasm@0 125 m_frameSize = parameter;
matthiasm@0 126 m_yinBufferSize = m_frameSize/2;
matthiasm@0 127 return 0;
matthiasm@0 128 }
matthiasm@0 129
matthiasm@0 130 // int
matthiasm@0 131 // Yin::setRemoveUnvoiced(bool parameter)
matthiasm@0 132 // {
matthiasm@0 133 // m_removeUnvoiced = parameter;
matthiasm@0 134 // return 0;
matthiasm@0 135 // }