comparison Yin.cpp @ 0:99bac62ee2da

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