| 31 |
31 |
|
| 32 |
32 |
using std::string;
|
| 33 |
33 |
using std::vector;
|
|
34 |
using Vamp::RealTime;
|
| 34 |
35 |
|
| 35 |
36 |
CepstrumPitchTracker::Hypothesis::Hypothesis()
|
| 36 |
37 |
{
|
| ... | ... | |
| 48 |
49 |
if (m_pending.empty()) {
|
| 49 |
50 |
return true;
|
| 50 |
51 |
}
|
|
52 |
|
|
53 |
Estimate first = m_pending[0];
|
| 51 |
54 |
Estimate last = m_pending[m_pending.size()-1];
|
|
55 |
|
|
56 |
// check we are within a relatively close tolerance of the last
|
|
57 |
// candidate
|
| 52 |
58 |
double r = s.freq / last.freq;
|
| 53 |
59 |
int cents = lrint(1200.0 * (log(r) / log(2.0)));
|
| 54 |
|
return (cents > -100 && cents < 100);
|
|
60 |
if (cents < -40 || cents > 40) return false;
|
|
61 |
|
|
62 |
// and within a wider tolerance of our starting candidate
|
|
63 |
r = s.freq / first.freq;
|
|
64 |
cents = lrint(1200.0 * (log(r) / log(2.0)));
|
|
65 |
if (cents < -80 || cents > 80) return false;
|
|
66 |
|
|
67 |
return true;
|
| 55 |
68 |
}
|
| 56 |
69 |
|
| 57 |
70 |
bool
|
| ... | ... | |
| 145 |
158 |
}
|
| 146 |
159 |
}
|
| 147 |
160 |
|
|
161 |
CepstrumPitchTracker::Hypothesis::Note
|
|
162 |
CepstrumPitchTracker::Hypothesis::getAveragedNote()
|
|
163 |
{
|
|
164 |
Note n;
|
|
165 |
|
|
166 |
if (!(m_state == Satisfied || m_state == Expired)) {
|
|
167 |
n.freq = 0.0;
|
|
168 |
n.time = RealTime::zeroTime;
|
|
169 |
n.duration = RealTime::zeroTime;
|
|
170 |
return n;
|
|
171 |
}
|
|
172 |
|
|
173 |
n.time = m_pending.begin()->time;
|
|
174 |
|
|
175 |
Estimates::iterator i = m_pending.end();
|
|
176 |
--i;
|
|
177 |
n.duration = i->time - n.time;
|
|
178 |
|
|
179 |
// just mean frequency for now, but this isn't at all right
|
|
180 |
double acc = 0.0;
|
|
181 |
for (int i = 0; i < m_pending.size(); ++i) {
|
|
182 |
acc += m_pending[i].freq;
|
|
183 |
}
|
|
184 |
acc /= m_pending.size();
|
|
185 |
n.freq = acc;
|
|
186 |
|
|
187 |
return n;
|
|
188 |
}
|
|
189 |
|
| 148 |
190 |
void
|
| 149 |
|
CepstrumPitchTracker::Hypothesis::addFeatures(FeatureList &fl)
|
|
191 |
CepstrumPitchTracker::Hypothesis::addFeatures(FeatureSet &fs)
|
| 150 |
192 |
{
|
| 151 |
193 |
for (int i = 0; i < m_pending.size(); ++i) {
|
| 152 |
194 |
Feature f;
|
| 153 |
195 |
f.hasTimestamp = true;
|
| 154 |
196 |
f.timestamp = m_pending[i].time;
|
| 155 |
197 |
f.values.push_back(m_pending[i].freq);
|
| 156 |
|
fl.push_back(f);
|
|
198 |
fs[0].push_back(f);
|
| 157 |
199 |
}
|
|
200 |
|
|
201 |
Feature nf;
|
|
202 |
nf.hasTimestamp = true;
|
|
203 |
nf.hasDuration = true;
|
|
204 |
Note n = getAveragedNote();
|
|
205 |
nf.timestamp = n.time;
|
|
206 |
nf.duration = n.duration;
|
|
207 |
nf.values.push_back(n.freq);
|
|
208 |
fs[1].push_back(nf);
|
| 158 |
209 |
}
|
| 159 |
210 |
|
| 160 |
211 |
CepstrumPitchTracker::CepstrumPitchTracker(float inputSampleRate) :
|
| ... | ... | |
| 303 |
354 |
d.hasDuration = false;
|
| 304 |
355 |
outputs.push_back(d);
|
| 305 |
356 |
|
|
357 |
d.identifier = "notes";
|
|
358 |
d.name = "Notes";
|
|
359 |
d.description = "Derived fixed-pitch note frequencies";
|
|
360 |
d.unit = "Hz";
|
|
361 |
d.hasFixedBinCount = true;
|
|
362 |
d.binCount = 1;
|
|
363 |
d.hasKnownExtents = true;
|
|
364 |
d.minValue = m_fmin;
|
|
365 |
d.maxValue = m_fmax;
|
|
366 |
d.isQuantized = false;
|
|
367 |
d.sampleType = OutputDescriptor::FixedSampleRate;
|
|
368 |
d.sampleRate = (m_inputSampleRate / m_stepSize);
|
|
369 |
d.hasDuration = true;
|
|
370 |
outputs.push_back(d);
|
|
371 |
|
| 306 |
372 |
return outputs;
|
| 307 |
373 |
}
|
| 308 |
374 |
|
| ... | ... | |
| 358 |
424 |
}
|
| 359 |
425 |
|
| 360 |
426 |
CepstrumPitchTracker::FeatureSet
|
| 361 |
|
CepstrumPitchTracker::process(const float *const *inputBuffers, Vamp::RealTime timestamp)
|
|
427 |
CepstrumPitchTracker::process(const float *const *inputBuffers, RealTime timestamp)
|
| 362 |
428 |
{
|
| 363 |
429 |
FeatureSet fs;
|
| 364 |
430 |
|
| ... | ... | |
| 466 |
532 |
}
|
| 467 |
533 |
|
| 468 |
534 |
if (m_accepted.getState() == Hypothesis::Expired) {
|
| 469 |
|
m_accepted.addFeatures(fs[0]);
|
|
535 |
m_accepted.addFeatures(fs);
|
| 470 |
536 |
}
|
| 471 |
537 |
|
| 472 |
538 |
if (m_accepted.getState() == Hypothesis::Expired ||
|
| ... | ... | |
| 503 |
569 |
{
|
| 504 |
570 |
FeatureSet fs;
|
| 505 |
571 |
if (m_accepted.getState() == Hypothesis::Satisfied) {
|
| 506 |
|
m_accepted.addFeatures(fs[0]);
|
|
572 |
m_accepted.addFeatures(fs);
|
| 507 |
573 |
}
|
| 508 |
574 |
return fs;
|
| 509 |
575 |
}
|