Mercurial > hg > pyin
comparison Yin.cpp @ 136:7cbf40306c10 vamp-fft-revision
Add state to YinUtil, prepare to use the Vamp FFT (but don't actually use it yet)
author | Chris Cannam |
---|---|
date | Fri, 19 Aug 2016 12:00:13 +0100 |
parents | 1b75e5fd4b99 |
children |
comparison
equal
deleted
inserted
replaced
135:2c73618b4067 | 136:7cbf40306c10 |
---|---|
29 m_frameSize(frameSize), | 29 m_frameSize(frameSize), |
30 m_inputSampleRate(inputSampleRate), | 30 m_inputSampleRate(inputSampleRate), |
31 m_thresh(thresh), | 31 m_thresh(thresh), |
32 m_threshDistr(2), | 32 m_threshDistr(2), |
33 m_yinBufferSize(frameSize/2), | 33 m_yinBufferSize(frameSize/2), |
34 m_fast(fast) | 34 m_fast(fast), |
35 m_yinUtil(new YinUtil(m_yinBufferSize)) | |
35 { | 36 { |
36 if (frameSize & (frameSize-1)) { | 37 if (frameSize & (frameSize-1)) { |
37 // throw "N must be a power of two"; | 38 // throw "N must be a power of two"; |
38 } | 39 } |
39 } | 40 } |
40 | 41 |
41 Yin::~Yin() | 42 Yin::~Yin() |
42 { | 43 { |
44 delete m_yinUtil; | |
43 } | 45 } |
44 | 46 |
45 Yin::YinOutput | 47 Yin::YinOutput |
46 Yin::process(const double *in) const { | 48 Yin::process(const double *in) const { |
47 | 49 |
48 double* yinBuffer = new double[m_yinBufferSize]; | 50 double* yinBuffer = new double[m_yinBufferSize]; |
49 | 51 |
50 // calculate aperiodicity function for all periods | 52 // calculate aperiodicity function for all periods |
51 if (m_fast) YinUtil::fastDifference(in, yinBuffer, m_yinBufferSize); | 53 if (m_fast) m_yinUtil->fastDifference(in, yinBuffer); |
52 else YinUtil::slowDifference(in, yinBuffer, m_yinBufferSize); | 54 else m_yinUtil->slowDifference(in, yinBuffer); |
53 | 55 |
54 YinUtil::cumulativeDifference(yinBuffer, m_yinBufferSize); | 56 m_yinUtil->cumulativeDifference(yinBuffer); |
55 | 57 |
56 int tau = 0; | 58 int tau = 0; |
57 tau = YinUtil::absoluteThreshold(yinBuffer, m_yinBufferSize, m_thresh); | 59 tau = m_yinUtil->absoluteThreshold(yinBuffer, m_thresh); |
58 | 60 |
59 double interpolatedTau; | 61 double interpolatedTau; |
60 double aperiodicity; | 62 double aperiodicity; |
61 double f0; | 63 double f0; |
62 | 64 |
63 if (tau!=0) | 65 if (tau!=0) |
64 { | 66 { |
65 interpolatedTau = YinUtil::parabolicInterpolation(yinBuffer, abs(tau), m_yinBufferSize); | 67 interpolatedTau = m_yinUtil->parabolicInterpolation(yinBuffer, abs(tau)); |
66 f0 = m_inputSampleRate * (1.0 / interpolatedTau); | 68 f0 = m_inputSampleRate * (1.0 / interpolatedTau); |
67 } else { | 69 } else { |
68 interpolatedTau = 0; | 70 interpolatedTau = 0; |
69 f0 = 0; | 71 f0 = 0; |
70 } | 72 } |
71 double rms = std::sqrt(YinUtil::sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize); | 73 double rms = std::sqrt(m_yinUtil->sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize); |
72 aperiodicity = yinBuffer[abs(tau)]; | 74 aperiodicity = yinBuffer[abs(tau)]; |
73 // std::cerr << aperiodicity << std::endl; | 75 // std::cerr << aperiodicity << std::endl; |
74 if (tau < 0) f0 = -f0; | 76 if (tau < 0) f0 = -f0; |
75 | 77 |
76 Yin::YinOutput yo(f0, 1-aperiodicity, rms); | 78 Yin::YinOutput yo(f0, 1-aperiodicity, rms); |
87 Yin::processProbabilisticYin(const double *in) const { | 89 Yin::processProbabilisticYin(const double *in) const { |
88 | 90 |
89 double* yinBuffer = new double[m_yinBufferSize]; | 91 double* yinBuffer = new double[m_yinBufferSize]; |
90 | 92 |
91 // calculate aperiodicity function for all periods | 93 // calculate aperiodicity function for all periods |
92 if (m_fast) YinUtil::fastDifference(in, yinBuffer, m_yinBufferSize); | 94 if (m_fast) m_yinUtil->fastDifference(in, yinBuffer); |
93 else YinUtil::slowDifference(in, yinBuffer, m_yinBufferSize); | 95 else m_yinUtil->slowDifference(in, yinBuffer); |
94 | 96 |
95 YinUtil::cumulativeDifference(yinBuffer, m_yinBufferSize); | 97 m_yinUtil->cumulativeDifference(yinBuffer); |
96 | 98 |
97 vector<double> peakProbability = YinUtil::yinProb(yinBuffer, m_threshDistr, m_yinBufferSize); | 99 vector<double> peakProbability = m_yinUtil->yinProb(yinBuffer, m_threshDistr); |
98 | 100 |
99 // calculate overall "probability" from peak probability | 101 // calculate overall "probability" from peak probability |
100 double probSum = 0; | 102 double probSum = 0; |
101 for (size_t iBin = 0; iBin < m_yinBufferSize; ++iBin) | 103 for (size_t iBin = 0; iBin < m_yinBufferSize; ++iBin) |
102 { | 104 { |
103 probSum += peakProbability[iBin]; | 105 probSum += peakProbability[iBin]; |
104 } | 106 } |
105 double rms = std::sqrt(YinUtil::sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize); | 107 double rms = std::sqrt(m_yinUtil->sumSquare(in, 0, m_yinBufferSize)/m_yinBufferSize); |
106 Yin::YinOutput yo(0,0,rms); | 108 Yin::YinOutput yo(0,0,rms); |
107 for (size_t iBuf = 0; iBuf < m_yinBufferSize; ++iBuf) | 109 for (size_t iBuf = 0; iBuf < m_yinBufferSize; ++iBuf) |
108 { | 110 { |
109 yo.salience.push_back(peakProbability[iBuf]); | 111 yo.salience.push_back(peakProbability[iBuf]); |
110 if (peakProbability[iBuf] > 0) | 112 if (peakProbability[iBuf] > 0) |
111 { | 113 { |
112 double currentF0 = | 114 double currentF0 = |
113 m_inputSampleRate * (1.0 / | 115 m_inputSampleRate * (1.0 / |
114 YinUtil::parabolicInterpolation(yinBuffer, iBuf, m_yinBufferSize)); | 116 m_yinUtil->parabolicInterpolation(yinBuffer, iBuf)); |
115 yo.freqProb.push_back(pair<double, double>(currentF0, peakProbability[iBuf])); | 117 yo.freqProb.push_back(pair<double, double>(currentF0, peakProbability[iBuf])); |
116 } | 118 } |
117 } | 119 } |
118 | 120 |
119 // std::cerr << yo.freqProb.size() << std::endl; | 121 // std::cerr << yo.freqProb.size() << std::endl; |