comparison CepstrumPitchTracker.cpp @ 30:2554aab152a5

Another tidy
author Chris Cannam
date Fri, 13 Jul 2012 21:35:29 +0100
parents afcd1f4e603c
children
comparison
equal deleted inserted replaced
29:afcd1f4e603c 30:2554aab152a5
43 CepstrumPitchTracker::Hypothesis::~Hypothesis() 43 CepstrumPitchTracker::Hypothesis::~Hypothesis()
44 { 44 {
45 } 45 }
46 46
47 bool 47 bool
48 CepstrumPitchTracker::Hypothesis::isWithinTolerance(Estimate s) 48 CepstrumPitchTracker::Hypothesis::isWithinTolerance(Estimate s) const
49 { 49 {
50 if (m_pending.empty()) { 50 if (m_pending.empty()) {
51 return true; 51 return true;
52 } 52 }
53 53
66 66
67 return true; 67 return true;
68 } 68 }
69 69
70 bool 70 bool
71 CepstrumPitchTracker::Hypothesis::isOutOfDateFor(Estimate s) 71 CepstrumPitchTracker::Hypothesis::isOutOfDateFor(Estimate s) const
72 { 72 {
73 if (m_pending.empty()) return false; 73 if (m_pending.empty()) return false;
74 74
75 return ((s.time - m_pending[m_pending.size()-1].time) > 75 return ((s.time - m_pending[m_pending.size()-1].time) >
76 RealTime::fromMilliseconds(40)); 76 RealTime::fromMilliseconds(40));
77 } 77 }
78 78
79 bool 79 bool
80 CepstrumPitchTracker::Hypothesis::isSatisfied() 80 CepstrumPitchTracker::Hypothesis::isSatisfied() const
81 { 81 {
82 if (m_pending.empty()) return false; 82 if (m_pending.empty()) return false;
83 83
84 double meanConfidence = 0.0; 84 double meanConfidence = 0.0;
85 for (int i = 0; i < m_pending.size(); ++i) { 85 for (int i = 0; i < m_pending.size(); ++i) {
89 89
90 int lengthRequired = 10000; 90 int lengthRequired = 10000;
91 if (meanConfidence > 0.0) { 91 if (meanConfidence > 0.0) {
92 lengthRequired = int(2.0 / meanConfidence + 0.5); 92 lengthRequired = int(2.0 / meanConfidence + 0.5);
93 } 93 }
94 std::cerr << "meanConfidence = " << meanConfidence << ", lengthRequired = " << lengthRequired << ", length = " << m_pending.size() << std::endl;
95 94
96 return (m_pending.size() > lengthRequired); 95 return (m_pending.size() > lengthRequired);
97 } 96 }
98 97
99 bool 98 bool
140 139
141 return accept; 140 return accept;
142 } 141 }
143 142
144 CepstrumPitchTracker::Hypothesis::State 143 CepstrumPitchTracker::Hypothesis::State
145 CepstrumPitchTracker::Hypothesis::getState() 144 CepstrumPitchTracker::Hypothesis::getState() const
146 { 145 {
147 return m_state; 146 return m_state;
148 } 147 }
149 148
150 CepstrumPitchTracker::Hypothesis::Estimates 149 CepstrumPitchTracker::Hypothesis::Estimates
151 CepstrumPitchTracker::Hypothesis::getAcceptedEstimates() 150 CepstrumPitchTracker::Hypothesis::getAcceptedEstimates() const
152 { 151 {
153 if (m_state == Satisfied || m_state == Expired) { 152 if (m_state == Satisfied || m_state == Expired) {
154 return m_pending; 153 return m_pending;
155 } else { 154 } else {
156 return Estimates(); 155 return Estimates();
157 } 156 }
158 } 157 }
159 158
160 double 159 double
161 CepstrumPitchTracker::Hypothesis::getMeanFrequency() 160 CepstrumPitchTracker::Hypothesis::getMeanFrequency() const
162 { 161 {
163 double acc = 0.0; 162 double acc = 0.0;
164 for (int i = 0; i < m_pending.size(); ++i) { 163 for (int i = 0; i < m_pending.size(); ++i) {
165 acc += m_pending[i].freq; 164 acc += m_pending[i].freq;
166 } 165 }
167 acc /= m_pending.size(); 166 acc /= m_pending.size();
168 return acc; 167 return acc;
169 } 168 }
170 169
171 CepstrumPitchTracker::Hypothesis::Note 170 CepstrumPitchTracker::Hypothesis::Note
172 CepstrumPitchTracker::Hypothesis::getAveragedNote() 171 CepstrumPitchTracker::Hypothesis::getAveragedNote() const
173 { 172 {
174 Note n; 173 Note n;
175 174
176 if (!(m_state == Satisfied || m_state == Expired)) { 175 if (!(m_state == Satisfied || m_state == Expired)) {
177 n.freq = 0.0; 176 n.freq = 0.0;
180 return n; 179 return n;
181 } 180 }
182 181
183 n.time = m_pending.begin()->time; 182 n.time = m_pending.begin()->time;
184 183
185 Estimates::iterator i = m_pending.end(); 184 Estimates::const_iterator i = m_pending.end();
186 --i; 185 --i;
187 n.duration = i->time - n.time; 186 n.duration = i->time - n.time;
188 187
189 // just mean frequency for now, but this isn't at all right perceptually 188 // just mean frequency for now, but this isn't at all right perceptually
190 n.freq = getMeanFrequency(); 189 n.freq = getMeanFrequency();
191 190
192 return n; 191 return n;
193 }
194
195 void
196 CepstrumPitchTracker::Hypothesis::addFeatures(FeatureSet &fs)
197 {
198 for (int i = 0; i < m_pending.size(); ++i) {
199 Feature f;
200 f.hasTimestamp = true;
201 f.timestamp = m_pending[i].time;
202 f.values.push_back(m_pending[i].freq);
203 fs[0].push_back(f);
204 }
205
206 Feature nf;
207 nf.hasTimestamp = true;
208 nf.hasDuration = true;
209 Note n = getAveragedNote();
210 nf.timestamp = n.time;
211 nf.duration = n.duration;
212 nf.values.push_back(n.freq);
213 fs[1].push_back(nf);
214 } 192 }
215 193
216 CepstrumPitchTracker::CepstrumPitchTracker(float inputSampleRate) : 194 CepstrumPitchTracker::CepstrumPitchTracker(float inputSampleRate) :
217 Plugin(inputSampleRate), 195 Plugin(inputSampleRate),
218 m_channels(0), 196 m_channels(0),
409 CepstrumPitchTracker::reset() 387 CepstrumPitchTracker::reset()
410 { 388 {
411 } 389 }
412 390
413 void 391 void
392 CepstrumPitchTracker::addFeaturesFrom(Hypothesis h, FeatureSet &fs)
393 {
394 Hypothesis::Estimates es = h.getAcceptedEstimates();
395
396 for (int i = 0; i < es.size(); ++i) {
397 Feature f;
398 f.hasTimestamp = true;
399 f.timestamp = es[i].time;
400 f.values.push_back(es[i].freq);
401 fs[0].push_back(f);
402 }
403
404 Feature nf;
405 nf.hasTimestamp = true;
406 nf.hasDuration = true;
407 Hypothesis::Note n = h.getAveragedNote();
408 nf.timestamp = n.time;
409 nf.duration = n.duration;
410 nf.values.push_back(n.freq);
411 fs[1].push_back(nf);
412 }
413
414 void
414 CepstrumPitchTracker::filter(const double *cep, double *data) 415 CepstrumPitchTracker::filter(const double *cep, double *data)
415 { 416 {
416 for (int i = 0; i < m_bins; ++i) { 417 for (int i = 0; i < m_bins; ++i) {
417 double v = 0; 418 double v = 0;
418 int n = 0; 419 int n = 0;
602 h.accept(e); //!!! must succeed as h is new, so perhaps there should be a ctor for this 603 h.accept(e); //!!! must succeed as h is new, so perhaps there should be a ctor for this
603 m_possible.push_back(h); 604 m_possible.push_back(h);
604 } 605 }
605 606
606 if (m_good.getState() == Hypothesis::Expired) { 607 if (m_good.getState() == Hypothesis::Expired) {
607 m_good.addFeatures(fs); 608 addFeaturesFrom(m_good, fs);
608 } 609 }
609 610
610 if (m_good.getState() == Hypothesis::Expired || 611 if (m_good.getState() == Hypothesis::Expired ||
611 m_good.getState() == Hypothesis::Rejected) { 612 m_good.getState() == Hypothesis::Rejected) {
612 if (candidate >= 0) { 613 if (candidate >= 0) {
635 CepstrumPitchTracker::FeatureSet 636 CepstrumPitchTracker::FeatureSet
636 CepstrumPitchTracker::getRemainingFeatures() 637 CepstrumPitchTracker::getRemainingFeatures()
637 { 638 {
638 FeatureSet fs; 639 FeatureSet fs;
639 if (m_good.getState() == Hypothesis::Satisfied) { 640 if (m_good.getState() == Hypothesis::Satisfied) {
640 m_good.addFeatures(fs); 641 addFeaturesFrom(m_good, fs);
641 } 642 }
642 return fs; 643 return fs;
643 } 644 }