Mercurial > hg > constant-q-cpp
comparison vamp/CQVamp.cpp @ 110:fdd32f995b0d
First cut at a chromagram plugin as well
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 14 May 2014 14:04:34 +0100 |
parents | f5325762ff6d |
children | 2375457f2876 |
comparison
equal
deleted
inserted
replaced
109:f5325762ff6d | 110:fdd32f995b0d |
---|---|
189 desc.name = "Bins per Octave"; | 189 desc.name = "Bins per Octave"; |
190 desc.unit = "bins"; | 190 desc.unit = "bins"; |
191 desc.description = "Number of constant-Q transform bins per octave"; | 191 desc.description = "Number of constant-Q transform bins per octave"; |
192 desc.minValue = 2; | 192 desc.minValue = 2; |
193 desc.maxValue = 480; | 193 desc.maxValue = 480; |
194 desc.defaultValue = 60; | 194 desc.defaultValue = defaultBPO; |
195 desc.isQuantized = true; | 195 desc.isQuantized = true; |
196 desc.quantizeStep = 1; | 196 desc.quantizeStep = 1; |
197 list.push_back(desc); | 197 list.push_back(desc); |
198 | 198 |
199 desc.identifier = "interpolation"; | 199 desc.identifier = "interpolation"; |
300 delete m_cq; | 300 delete m_cq; |
301 m_cq = new CQSpectrogram | 301 m_cq = new CQSpectrogram |
302 (m_inputSampleRate, m_minFrequency, m_maxFrequency, m_bpo, | 302 (m_inputSampleRate, m_minFrequency, m_maxFrequency, m_bpo, |
303 m_interpolation); | 303 m_interpolation); |
304 } | 304 } |
305 m_prevFeature.clear(); | |
306 m_haveStartTime = false; | 305 m_haveStartTime = false; |
307 m_columnCount = 0; | 306 m_columnCount = 0; |
308 } | 307 } |
309 | 308 |
310 size_t | 309 size_t |
327 }; | 326 }; |
328 | 327 |
329 const char *n = names[i % 12]; | 328 const char *n = names[i % 12]; |
330 int oct = i / 12 - 1; | 329 int oct = i / 12 - 1; |
331 char buf[20]; | 330 char buf[20]; |
332 sprintf(buf, "%s%d", n, oct); | 331 sprintf(buf, "%d %s%d", i, n, oct); |
333 | 332 |
334 return buf; | 333 return buf; |
335 } | |
336 | |
337 float | |
338 CQVamp::noteFrequency(int note) const | |
339 { | |
340 return m_tuningFrequency * pow(2.0, (note - 69) / 12.0); | |
341 } | |
342 | |
343 int | |
344 CQVamp::noteNumber(float freq) const | |
345 { | |
346 return int(round(57.0 + (12.0 * log(freq / (m_tuningFrequency / 2.0)) / log(2.0)))); | |
347 } | 334 } |
348 | 335 |
349 CQVamp::OutputList | 336 CQVamp::OutputList |
350 CQVamp::getOutputDescriptors() const | 337 CQVamp::getOutputDescriptors() const |
351 { | 338 { |
362 if (m_cq) { | 349 if (m_cq) { |
363 char name[20]; | 350 char name[20]; |
364 for (int i = 0; i < (int)d.binCount; ++i) { | 351 for (int i = 0; i < (int)d.binCount; ++i) { |
365 float freq = m_cq->getBinFrequency(i); | 352 float freq = m_cq->getBinFrequency(i); |
366 sprintf(name, "%.1f Hz", freq); | 353 sprintf(name, "%.1f Hz", freq); |
367 if (fabs(noteFrequency(noteNumber(freq)) - freq) < 0.01) { | 354 int note = Pitch::getPitchForFrequency(freq, 0, m_tuningFrequency); |
368 d.binNames.push_back(name + std::string(": ") + | 355 float nearestFreq = |
369 noteName(noteNumber(freq))); | 356 Pitch::getFrequencyForPitch(note, 0, m_tuningFrequency); |
357 if (fabs(freq - nearestFreq) < 0.01) { | |
358 d.binNames.push_back(name + std::string(" ") + noteName(note)); | |
370 } else { | 359 } else { |
371 d.binNames.push_back(name); | 360 d.binNames.push_back(name); |
372 } | 361 } |
373 } | 362 } |
374 } | 363 } |
428 column[j] = cqout[i][j]; | 417 column[j] = cqout[i][j]; |
429 } | 418 } |
430 | 419 |
431 // put low frequencies at the start | 420 // put low frequencies at the start |
432 std::reverse(column.begin(), column.end()); | 421 std::reverse(column.begin(), column.end()); |
433 | |
434 m_prevFeature = column; | |
435 | 422 |
436 Feature feature; | 423 Feature feature; |
437 feature.hasTimestamp = true; | 424 feature.hasTimestamp = true; |
438 feature.timestamp = m_startTime + Vamp::RealTime::frame2RealTime | 425 feature.timestamp = m_startTime + Vamp::RealTime::frame2RealTime |
439 (m_columnCount * m_cq->getColumnHop() - m_cq->getLatency(), | 426 (m_columnCount * m_cq->getColumnHop() - m_cq->getLatency(), |