Revision 66:7ad142c710c6
| AgentFeeder.cpp | ||
|---|---|---|
| 76 | 76 |
} |
| 77 | 77 |
|
| 78 | 78 |
if (!swallowed) {
|
| 79 |
NoteHypothesis h; |
|
| 79 |
NoteHypothesis h(m_slack);
|
|
| 80 | 80 |
if (h.accept(e)) {
|
| 81 | 81 |
newCandidates.push_back(h); |
| 82 | 82 |
} |
| AgentFeeder.h | ||
|---|---|---|
| 49 | 49 |
class AgentFeeder |
| 50 | 50 |
{
|
| 51 | 51 |
public: |
| 52 |
AgentFeeder() : m_haveCurrent(false) { }
|
|
| 52 |
AgentFeeder(float slack) : |
|
| 53 |
m_slack(slack), |
|
| 54 |
m_current(slack), |
|
| 55 |
m_haveCurrent(false) |
|
| 56 |
{ }
|
|
| 53 | 57 |
|
| 54 | 58 |
void feed(NoteHypothesis::Estimate); |
| 55 | 59 |
void finish(); |
| ... | ... | |
| 63 | 67 |
Hypotheses reap(Hypotheses); |
| 64 | 68 |
|
| 65 | 69 |
private: |
| 70 |
float m_slack; |
|
| 66 | 71 |
Hypotheses m_candidates; |
| 67 | 72 |
NoteHypothesis m_current; |
| 68 | 73 |
bool m_haveCurrent; |
| CepstralPitchTracker.cpp | ||
|---|---|---|
| 50 | 50 |
m_fmin(50), |
| 51 | 51 |
m_fmax(900), |
| 52 | 52 |
m_vflen(1), |
| 53 |
m_slack(40), |
|
| 54 |
m_sensitivity(10), |
|
| 55 |
m_threshold(0.1), |
|
| 53 | 56 |
m_binFrom(0), |
| 54 | 57 |
m_binTo(0), |
| 55 | 58 |
m_bins(0), |
| ... | ... | |
| 92 | 95 |
{
|
| 93 | 96 |
// Increment this each time you release a version that behaves |
| 94 | 97 |
// differently from the previous one |
| 95 |
return 1;
|
|
| 98 |
return 2;
|
|
| 96 | 99 |
} |
| 97 | 100 |
|
| 98 | 101 |
string |
| ... | ... | |
| 135 | 138 |
CepstralPitchTracker::getParameterDescriptors() const |
| 136 | 139 |
{
|
| 137 | 140 |
ParameterList list; |
| 141 |
|
|
| 142 |
ParameterDescriptor d; |
|
| 143 |
d.identifier = "sensitivity"; |
|
| 144 |
d.name = "Sensitivity"; |
|
| 145 |
d.description = "Sensitivity of the voicing detector"; |
|
| 146 |
d.unit = ""; |
|
| 147 |
d.minValue = 0; |
|
| 148 |
d.maxValue = 100; |
|
| 149 |
d.defaultValue = 10; |
|
| 150 |
d.isQuantized = true; |
|
| 151 |
d.quantizeStep = 1; |
|
| 152 |
list.push_back(d); |
|
| 153 |
|
|
| 154 |
d.identifier = "slack"; |
|
| 155 |
d.name = "Slack"; |
|
| 156 |
d.description = "Maximum permissible length of voicing gap for a continuous note"; |
|
| 157 |
d.unit = "ms"; |
|
| 158 |
d.minValue = 0; |
|
| 159 |
d.maxValue = 200; |
|
| 160 |
d.defaultValue = 40; |
|
| 161 |
d.isQuantized = true; |
|
| 162 |
d.quantizeStep = 1; |
|
| 163 |
list.push_back(d); |
|
| 164 |
|
|
| 165 |
d.identifier = "threshold"; |
|
| 166 |
d.name = "Silence threshold"; |
|
| 167 |
d.description = "Threshold for silence detection"; |
|
| 168 |
d.unit = ""; //!!! todo: convert this threshold to a meaningful unit! |
|
| 169 |
d.minValue = 0; |
|
| 170 |
d.maxValue = 0.5; |
|
| 171 |
d.defaultValue = 0.1; |
|
| 172 |
d.isQuantized = false; |
|
| 173 |
list.push_back(d); |
|
| 174 |
|
|
| 138 | 175 |
return list; |
| 139 | 176 |
} |
| 140 | 177 |
|
| 141 | 178 |
float |
| 142 | 179 |
CepstralPitchTracker::getParameter(string identifier) const |
| 143 | 180 |
{
|
| 181 |
if (identifier == "sensitivity") return m_sensitivity; |
|
| 182 |
else if (identifier == "slack") return m_slack; |
|
| 183 |
else if (identifier == "threshold") return m_threshold; |
|
| 144 | 184 |
return 0.f; |
| 145 | 185 |
} |
| 146 | 186 |
|
| 147 | 187 |
void |
| 148 | 188 |
CepstralPitchTracker::setParameter(string identifier, float value) |
| 149 | 189 |
{
|
| 190 |
if (identifier == "sensitivity") m_sensitivity = value; |
|
| 191 |
else if (identifier == "slack") m_slack = value; |
|
| 192 |
else if (identifier == "threshold") m_threshold = value; |
|
| 150 | 193 |
} |
| 151 | 194 |
|
| 152 | 195 |
CepstralPitchTracker::ProgramList |
| ... | ... | |
| 204 | 247 |
d.hasDuration = true; |
| 205 | 248 |
outputs.push_back(d); |
| 206 | 249 |
|
| 250 |
d.identifier = "raw"; |
|
| 251 |
d.name = "Raw frequencies"; |
|
| 252 |
d.description = "Raw peak frequencies from cepstrum, including unvoiced segments"; |
|
| 253 |
d.unit = "Hz"; |
|
| 254 |
d.hasFixedBinCount = true; |
|
| 255 |
d.binCount = 1; |
|
| 256 |
d.hasKnownExtents = true; |
|
| 257 |
d.minValue = m_fmin; |
|
| 258 |
d.maxValue = m_fmax; |
|
| 259 |
d.isQuantized = false; |
|
| 260 |
d.sampleType = OutputDescriptor::OneSamplePerStep; |
|
| 261 |
d.hasDuration = false; |
|
| 262 |
outputs.push_back(d); |
|
| 263 |
|
|
| 207 | 264 |
return outputs; |
| 208 | 265 |
} |
| 209 | 266 |
|
| ... | ... | |
| 243 | 300 |
CepstralPitchTracker::reset() |
| 244 | 301 |
{
|
| 245 | 302 |
delete m_feeder; |
| 246 |
m_feeder = new AgentFeeder(); |
|
| 303 |
m_feeder = new AgentFeeder(m_slack);
|
|
| 247 | 304 |
m_nAccepted = 0; |
| 248 | 305 |
} |
| 249 | 306 |
|
| ... | ... | |
| 327 | 384 |
double cimax = pi.findPeakLocation(data, m_bins, maxbin); |
| 328 | 385 |
double peakfreq = m_inputSampleRate / (cimax + m_binFrom); |
| 329 | 386 |
|
| 387 |
FeatureSet fs; |
|
| 388 |
Feature rawf; |
|
| 389 |
rawf.hasTimestamp = false; |
|
| 390 |
rawf.hasDuration = false; |
|
| 391 |
rawf.values.push_back(peakfreq); |
|
| 392 |
fs[2].push_back(rawf); |
|
| 393 |
|
|
| 330 | 394 |
double confidence = 0.0; |
| 331 |
double threshold = 0.1; // for magmean |
|
| 332 | 395 |
|
| 333 | 396 |
if (nextPeakVal != 0.0) {
|
| 334 |
confidence = (maxval - nextPeakVal) * 10.0;
|
|
| 335 |
if (magmean < threshold) confidence = 0.0; |
|
| 397 |
confidence = (maxval - nextPeakVal) * m_sensitivity;
|
|
| 398 |
if (magmean < m_threshold) confidence = 0.0;
|
|
| 336 | 399 |
} |
| 337 | 400 |
|
| 338 | 401 |
delete[] data; |
| ... | ... | |
| 344 | 407 |
|
| 345 | 408 |
m_feeder->feed(e); |
| 346 | 409 |
|
| 347 |
FeatureSet fs; |
|
| 348 | 410 |
addNewFeatures(fs); |
| 349 | 411 |
return fs; |
| 350 | 412 |
} |
| CepstralPitchTracker.h | ||
|---|---|---|
| 76 | 76 |
float m_fmax; |
| 77 | 77 |
int m_vflen; |
| 78 | 78 |
|
| 79 |
float m_slack; |
|
| 80 |
float m_sensitivity; |
|
| 81 |
float m_threshold; |
|
| 82 |
|
|
| 79 | 83 |
int m_binFrom; |
| 80 | 84 |
int m_binTo; |
| 81 | 85 |
int m_bins; // count of "interesting" bins, those returned in m_cepOutput |
| Makefile.inc | ||
|---|---|---|
| 73 | 73 |
|
| 74 | 74 |
# DO NOT DELETE |
| 75 | 75 |
|
| 76 |
AgentFeeder.o: AgentFeeder.h NoteHypothesis.h |
|
| 76 | 77 |
CepstralPitchTracker.o: CepstralPitchTracker.h NoteHypothesis.h Cepstrum.h |
| 77 |
CepstralPitchTracker.o: MeanFilter.h PeakInterpolator.h |
|
| 78 |
libmain.o: CepstralPitchTracker.h NoteHypothesis.h |
|
| 78 |
CepstralPitchTracker.o: MeanFilter.h PeakInterpolator.h AgentFeeder.h |
|
| 79 | 79 |
NoteHypothesis.o: NoteHypothesis.h |
| 80 | 80 |
PeakInterpolator.o: PeakInterpolator.h |
| 81 |
libmain.o: CepstralPitchTracker.h NoteHypothesis.h |
|
| 82 |
test/TestAgentFeeder.o: AgentFeeder.h NoteHypothesis.h |
|
| 81 | 83 |
test/TestCepstrum.o: Cepstrum.h |
| 82 | 84 |
test/TestMeanFilter.o: MeanFilter.h |
| 83 | 85 |
test/TestNoteHypothesis.o: NoteHypothesis.h |
| 84 | 86 |
test/TestPeakInterpolator.o: PeakInterpolator.h |
| 87 |
AgentFeeder.o: NoteHypothesis.h |
|
| 85 | 88 |
CepstralPitchTracker.o: NoteHypothesis.h |
| NoteHypothesis.cpp | ||
|---|---|---|
| 28 | 28 |
|
| 29 | 29 |
using Vamp::RealTime; |
| 30 | 30 |
|
| 31 |
NoteHypothesis::NoteHypothesis() |
|
| 31 |
NoteHypothesis::NoteHypothesis(float slack) : |
|
| 32 |
m_state(New), |
|
| 33 |
m_slack(slack) |
|
| 32 | 34 |
{
|
| 33 |
m_state = New; |
|
| 34 | 35 |
} |
| 35 | 36 |
|
| 36 | 37 |
NoteHypothesis::~NoteHypothesis() |
| ... | ... | |
| 65 | 66 |
{
|
| 66 | 67 |
if (m_pending.empty()) return false; |
| 67 | 68 |
return ((s.time - m_pending[m_pending.size()-1].time) > |
| 68 |
RealTime::fromMilliseconds(40));
|
|
| 69 |
RealTime::fromMilliseconds(m_slack));
|
|
| 69 | 70 |
} |
| 70 | 71 |
|
| 71 | 72 |
bool |
| NoteHypothesis.h | ||
|---|---|---|
| 57 | 57 |
}; |
| 58 | 58 |
|
| 59 | 59 |
/** |
| 60 |
* Construct an empty hypothesis. This will be in New state and |
|
| 61 |
* will provisionally accept any estimate. |
|
| 60 |
* Construct an empty hypothesis. The given slack (in |
|
| 61 |
* milliseconds) determines how long the hypothesis is prepared to |
|
| 62 |
* tolerate unacceptable estimates in between accepted estimates |
|
| 63 |
* before it becomes rejected. A reasonable default is 40ms. |
|
| 64 |
* |
|
| 65 |
* This hypothesis will be in New state and will provisionally |
|
| 66 |
* accept any estimate. |
|
| 62 | 67 |
*/ |
| 63 |
NoteHypothesis(); |
|
| 68 |
NoteHypothesis(float slack);
|
|
| 64 | 69 |
|
| 65 | 70 |
/** |
| 66 | 71 |
* Destroy the hypothesis |
| ... | ... | |
| 134 | 139 |
|
| 135 | 140 |
State m_state; |
| 136 | 141 |
Estimates m_pending; |
| 142 |
float m_slack; |
|
| 137 | 143 |
}; |
| 138 | 144 |
|
| 139 | 145 |
#endif |
| test/TestAgentFeeder.cpp | ||
|---|---|---|
| 35 | 35 |
|
| 36 | 36 |
typedef NoteHypothesis::Estimate Est; |
| 37 | 37 |
|
| 38 |
#define DEFAULT_SLACK_MS 40 |
|
| 39 |
|
|
| 38 | 40 |
BOOST_AUTO_TEST_SUITE(TestAgentFeeder) |
| 39 | 41 |
|
| 40 | 42 |
BOOST_AUTO_TEST_CASE(feederEmpty) |
| 41 | 43 |
{
|
| 42 |
AgentFeeder f; |
|
| 44 |
AgentFeeder f(DEFAULT_SLACK_MS);
|
|
| 43 | 45 |
f.finish(); |
| 44 | 46 |
AgentFeeder::Hypotheses accepted = f.getAcceptedHypotheses(); |
| 45 | 47 |
BOOST_CHECK(accepted.empty()); |
| ... | ... | |
| 52 | 54 |
Est e20(low, ms(20), 1); |
| 53 | 55 |
Est e30(low, ms(30), 1); |
| 54 | 56 |
|
| 55 |
AgentFeeder f; |
|
| 57 |
AgentFeeder f(DEFAULT_SLACK_MS);
|
|
| 56 | 58 |
f.feed(e0); |
| 57 | 59 |
f.feed(e10); |
| 58 | 60 |
f.feed(e20); |
| ... | ... | |
| 76 | 78 |
Est f20(high, ms(2020), 1); |
| 77 | 79 |
Est f30(high, ms(2030), 1); |
| 78 | 80 |
|
| 79 |
AgentFeeder f; |
|
| 81 |
AgentFeeder f(DEFAULT_SLACK_MS);
|
|
| 80 | 82 |
f.feed(e0); |
| 81 | 83 |
f.feed(e10); |
| 82 | 84 |
f.feed(e20); |
| ... | ... | |
| 118 | 120 |
Est f43(high, ms(43), 1); |
| 119 | 121 |
Est f44(high, ms(44), 1); |
| 120 | 122 |
|
| 121 |
AgentFeeder f; |
|
| 123 |
AgentFeeder f(DEFAULT_SLACK_MS);
|
|
| 122 | 124 |
f.feed(e0); |
| 123 | 125 |
f.feed(e10); |
| 124 | 126 |
f.feed(e20); |
| ... | ... | |
| 171 | 173 |
Est f70(high, ms(70), 1); |
| 172 | 174 |
Est f80(high, ms(80), 1); |
| 173 | 175 |
|
| 174 |
AgentFeeder f; |
|
| 176 |
AgentFeeder f(DEFAULT_SLACK_MS);
|
|
| 175 | 177 |
f.feed(e0); |
| 176 | 178 |
f.feed(e10); |
| 177 | 179 |
f.feed(e20); |
| ... | ... | |
| 225 | 227 |
Est f40(high, ms(40), 1); |
| 226 | 228 |
Est f50(high, ms(50), 1); |
| 227 | 229 |
|
| 228 |
AgentFeeder f; |
|
| 230 |
AgentFeeder f(DEFAULT_SLACK_MS);
|
|
| 229 | 231 |
|
| 230 | 232 |
f.feed(e0); |
| 231 | 233 |
f.feed(e10); |
| test/TestNoteHypothesis.cpp | ||
|---|---|---|
| 49 | 49 |
|
| 50 | 50 |
using Vamp::RealTime; |
| 51 | 51 |
|
| 52 |
#define DEFAULT_SLACK_MS 40 |
|
| 53 |
|
|
| 52 | 54 |
BOOST_AUTO_TEST_SUITE(TestNoteHypothesis) |
| 53 | 55 |
|
| 54 | 56 |
BOOST_AUTO_TEST_CASE(emptyAccept) |
| 55 | 57 |
{
|
| 56 | 58 |
// An empty hypothesis should accept any estimate with a |
| 57 | 59 |
// non-negligible confidence, and enter provisional state |
| 58 |
NoteHypothesis h; |
|
| 60 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 59 | 61 |
NoteHypothesis::Estimate e; // default estimate has confidence 1 |
| 60 | 62 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New); |
| 61 | 63 |
BOOST_CHECK(h.accept(e)); |
| ... | ... | |
| 66 | 68 |
{
|
| 67 | 69 |
// A hypothesis should reject any estimate that has a negligible |
| 68 | 70 |
// confidence |
| 69 |
NoteHypothesis h; |
|
| 71 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 70 | 72 |
NoteHypothesis::Estimate e; |
| 71 | 73 |
e.confidence = 0; |
| 72 | 74 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New); |
| ... | ... | |
| 78 | 80 |
{
|
| 79 | 81 |
// But if we're already in process we don't go to rejected state, |
| 80 | 82 |
// we just ignore this hypothesis |
| 81 |
NoteHypothesis h; |
|
| 83 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 82 | 84 |
NoteHypothesis::Estimate e; |
| 83 | 85 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New); |
| 84 | 86 |
BOOST_CHECK(h.accept(e)); |
| ... | ... | |
| 92 | 94 |
{
|
| 93 | 95 |
// Having accepted a first estimate, a hypothesis should reject a |
| 94 | 96 |
// second (and enter rejected state) if there is too long a gap |
| 95 |
// between them for them to belong to a single note |
|
| 96 |
NoteHypothesis h; |
|
| 97 |
// between them for them to belong to a single note. Test this |
|
| 98 |
// with more than one slack parameter, since that's what |
|
| 99 |
// determines how long the gap can be. |
|
| 100 |
|
|
| 101 |
{
|
|
| 102 |
NoteHypothesis h(40); |
|
| 97 | 103 |
NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1); |
| 98 | 104 |
NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(50), 1); |
| 99 | 105 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New); |
| ... | ... | |
| 101 | 107 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional); |
| 102 | 108 |
BOOST_CHECK(!h.accept(e2)); |
| 103 | 109 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Rejected); |
| 110 |
} |
|
| 111 |
{
|
|
| 112 |
NoteHypothesis h(100); |
|
| 113 |
NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1); |
|
| 114 |
NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(50), 1); |
|
| 115 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::New); |
|
| 116 |
BOOST_CHECK(h.accept(e1)); |
|
| 117 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional); |
|
| 118 |
BOOST_CHECK(h.accept(e2)); |
|
| 119 |
BOOST_CHECK_EQUAL(h.getState(), NoteHypothesis::Provisional); |
|
| 120 |
} |
|
| 104 | 121 |
} |
| 105 | 122 |
|
| 106 | 123 |
BOOST_AUTO_TEST_CASE(simpleSatisfy) |
| ... | ... | |
| 108 | 125 |
// A hypothesis should enter satisfied state after accepting three |
| 109 | 126 |
// consistent estimates, and then remain satisfied while accepting |
| 110 | 127 |
// further consistent estimates |
| 111 |
NoteHypothesis h; |
|
| 128 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 112 | 129 |
NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1); |
| 113 | 130 |
NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(10), 1); |
| 114 | 131 |
NoteHypothesis::Estimate e3(500, RealTime::fromMilliseconds(20), 1); |
| ... | ... | |
| 130 | 147 |
// offered an estimate that follows too long a gap, should enter |
| 131 | 148 |
// expired state rather than rejected state (showing that it has a |
| 132 | 149 |
// valid note but that the note has apparently finished) |
| 133 |
NoteHypothesis h; |
|
| 150 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 134 | 151 |
NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1); |
| 135 | 152 |
NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(10), 1); |
| 136 | 153 |
NoteHypothesis::Estimate e3(500, RealTime::fromMilliseconds(20), 1); |
| ... | ... | |
| 156 | 173 |
{
|
| 157 | 174 |
// A wildly different frequency occurring in the middle of a |
| 158 | 175 |
// provisionally accepted note should be ignored |
| 159 |
NoteHypothesis h; |
|
| 176 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 160 | 177 |
NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1); |
| 161 | 178 |
NoteHypothesis::Estimate e2(1000, RealTime::fromMilliseconds(10), 1); |
| 162 | 179 |
NoteHypothesis::Estimate e3(500, RealTime::fromMilliseconds(20), 1); |
| ... | ... | |
| 176 | 193 |
{
|
| 177 | 194 |
// A wildly different frequency occurring in the middle of a |
| 178 | 195 |
// satisfied note should be ignored |
| 179 |
NoteHypothesis h; |
|
| 196 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 180 | 197 |
NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 1); |
| 181 | 198 |
NoteHypothesis::Estimate e2(500, RealTime::fromMilliseconds(10), 1); |
| 182 | 199 |
NoteHypothesis::Estimate e3(500, RealTime::fromMilliseconds(20), 1); |
| ... | ... | |
| 199 | 216 |
{
|
| 200 | 217 |
// Behaviour with slightly varying frequencies should be as for |
| 201 | 218 |
// that with fixed frequency |
| 202 |
NoteHypothesis h; |
|
| 219 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 203 | 220 |
NoteHypothesis::Estimate e1(500, RealTime::fromMilliseconds(0), 0.5); |
| 204 | 221 |
NoteHypothesis::Estimate e2(502, RealTime::fromMilliseconds(10), 0.5); |
| 205 | 222 |
NoteHypothesis::Estimate e3(504, RealTime::fromMilliseconds(20), 0.5); |
| ... | ... | |
| 225 | 242 |
{
|
| 226 | 243 |
// But there's a limit: outside a certain range we should reject |
| 227 | 244 |
//!!! (but what is this range? is it part of the spec?) |
| 228 |
NoteHypothesis h; |
|
| 245 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 229 | 246 |
NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(0), 1); |
| 230 | 247 |
NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(10), 1); |
| 231 | 248 |
NoteHypothesis::Estimate e3(444, RealTime::fromMilliseconds(20), 1); |
| ... | ... | |
| 244 | 261 |
BOOST_AUTO_TEST_CASE(acceptedEstimates) |
| 245 | 262 |
{
|
| 246 | 263 |
// Check that getAcceptedEstimates() returns the right result |
| 247 |
NoteHypothesis h; |
|
| 264 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 248 | 265 |
NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(0), 1); |
| 249 | 266 |
NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(10), 1); |
| 250 | 267 |
NoteHypothesis::Estimate e3(444, RealTime::fromMilliseconds(20), 1); |
| ... | ... | |
| 276 | 293 |
BOOST_AUTO_TEST_CASE(meanFrequency) |
| 277 | 294 |
{
|
| 278 | 295 |
// Check that the mean frequency is the mean of the frequencies |
| 279 |
NoteHypothesis h; |
|
| 296 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 280 | 297 |
NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(0), 1); |
| 281 | 298 |
NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(10), 1); |
| 282 | 299 |
NoteHypothesis::Estimate e3(444, RealTime::fromMilliseconds(20), 1); |
| ... | ... | |
| 289 | 306 |
BOOST_AUTO_TEST_CASE(averagedNote) |
| 290 | 307 |
{
|
| 291 | 308 |
// Check that getAveragedNote returns something sane |
| 292 |
NoteHypothesis h; |
|
| 309 |
NoteHypothesis h(DEFAULT_SLACK_MS);
|
|
| 293 | 310 |
NoteHypothesis::Estimate e1(440, RealTime::fromMilliseconds(10), 1); |
| 294 | 311 |
NoteHypothesis::Estimate e2(448, RealTime::fromMilliseconds(20), 1); |
| 295 | 312 |
NoteHypothesis::Estimate e3(444, RealTime::fromMilliseconds(30), 1); |
Also available in: Unified diff