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(),