Mercurial > hg > constant-q-cpp
diff vamp/CQChromaVamp.cpp @ 170:b96b0addbca7
Pull out chroma class into library
author | Chris Cannam <c.cannam@qmul.ac.uk> |
---|---|
date | Wed, 04 Feb 2015 15:09:06 +0000 |
parents | 8a1d240ac542 |
children | a12642e36167 |
line wrap: on
line diff
--- a/vamp/CQChromaVamp.cpp Wed Jan 14 18:00:34 2015 +0000 +++ b/vamp/CQChromaVamp.cpp Wed Feb 04 15:09:06 2015 +0000 @@ -31,12 +31,9 @@ #include "CQChromaVamp.h" -#include "cq/CQSpectrogram.h" - -#include "Pitch.h" +#include "cq/Chromagram.h" #include <algorithm> -#include <cstdio> using std::string; using std::vector; @@ -54,9 +51,7 @@ m_octaveCount(defaultOctaveCount), m_tuningFrequency(defaultTuningFrequency), m_bpo(defaultBPO), - m_cq(0), - m_maxFrequency(0), - m_minFrequency(0), + m_chroma(0), m_haveStartTime(false), m_columnCount(0) { @@ -64,7 +59,7 @@ CQChromaVamp::~CQChromaVamp() { - delete m_cq; + delete m_chroma; } string @@ -196,9 +191,9 @@ bool CQChromaVamp::initialise(size_t channels, size_t stepSize, size_t blockSize) { - if (m_cq) { - delete m_cq; - m_cq = 0; + if (m_chroma) { + delete m_chroma; + m_chroma = 0; } if (channels < getMinChannelCount() || @@ -207,30 +202,9 @@ m_stepSize = stepSize; m_blockSize = blockSize; - int highestOctave = m_lowestOctave + m_octaveCount - 1; - - int midiPitchLimit = (1 + highestOctave) * 12 + 12; // C just beyond top - double midiPitchLimitFreq = - Pitch::getFrequencyForPitch(midiPitchLimit, 0, m_tuningFrequency); - - // Max frequency is frequency of the MIDI pitch just beyond the - // top octave range (midiPitchLimit) minus one bin, then minus - // floor(bins per semitone / 2) - int bps = m_bpo / 12; - m_maxFrequency = midiPitchLimitFreq / pow(2, (1.0 + floor(bps/2)) / m_bpo); - - // Min frequency is frequency of midiPitchLimit lowered by the - // appropriate number of octaves. - m_minFrequency = midiPitchLimitFreq / pow(2, m_octaveCount + 1); - -// cerr << "lowest octave: " << m_lowestOctave << ", highest octave: " -// << highestOctave << ", limit midi pitch: " << midiPitchLimit -// << ", min freq " << m_minFrequency << ", max freq " << m_maxFrequency -// << endl; - reset(); - if (!m_cq || !m_cq->isValid()) { + if (!m_chroma || !m_chroma->isValid()) { cerr << "CQVamp::initialise: Constant-Q parameters not valid! Not initialising" << endl; return false; } @@ -241,9 +215,14 @@ void CQChromaVamp::reset() { - delete m_cq; - CQParameters p(m_inputSampleRate, m_minFrequency, m_maxFrequency, m_bpo); - m_cq = new CQSpectrogram(p, CQSpectrogram::InterpolateLinear); + delete m_chroma; + Chromagram::Parameters p(m_inputSampleRate); + p.lowestOctave = m_lowestOctave; + p.octaves = m_octaveCount; + p.bpo = m_bpo; + p.tuningFrequency = m_tuningFrequency; + + m_chroma = new Chromagram(p); m_haveStartTime = false; m_startTime = Vamp::RealTime::zeroTime; @@ -265,10 +244,6 @@ CQChromaVamp::OutputList CQChromaVamp::getOutputDescriptors() const { - static const char *names[] = { - "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" - }; - OutputList list; OutputDescriptor d; @@ -279,26 +254,16 @@ d.hasFixedBinCount = true; d.binCount = m_bpo; - if (m_cq) { - char name[20]; + if (m_chroma) { for (int i = 0; i < (int)d.binCount; ++i) { - float freq = m_cq->getBinFrequency(d.binCount - i - 1); - int note = Pitch::getPitchForFrequency(freq, 0, m_tuningFrequency); - float nearestFreq = - Pitch::getFrequencyForPitch(note, 0, m_tuningFrequency); - sprintf(name, "%d", i); - if (fabs(freq - nearestFreq) < 0.01) { - d.binNames.push_back(name + std::string(" ") + names[note % 12]); - } else { - d.binNames.push_back(name); - } + d.binNames.push_back(m_chroma->getBinName(i)); } } d.hasKnownExtents = false; d.isQuantized = false; d.sampleType = OutputDescriptor::FixedSampleRate; - d.sampleRate = m_inputSampleRate / (m_cq ? m_cq->getColumnHop() : 256); + d.sampleRate = m_inputSampleRate / (m_chroma ? m_chroma->getColumnHop() : 256); list.push_back(d); return list; @@ -308,7 +273,7 @@ CQChromaVamp::process(const float *const *inputBuffers, Vamp::RealTime timestamp) { - if (!m_cq) { + if (!m_chroma) { cerr << "ERROR: CQChromaVamp::process: " << "Plugin has not been initialised" << endl; @@ -323,40 +288,32 @@ vector<double> data; for (int i = 0; i < m_blockSize; ++i) data.push_back(inputBuffers[0][i]); - vector<vector<double> > cqout = m_cq->process(data); - return convertToFeatures(cqout); + vector<vector<double> > chromaout = m_chroma->process(data); + return convertToFeatures(chromaout); } CQChromaVamp::FeatureSet CQChromaVamp::getRemainingFeatures() { - vector<vector<double> > cqout = m_cq->getRemainingOutput(); - return convertToFeatures(cqout); + vector<vector<double> > chromaout = m_chroma->getRemainingOutput(); + return convertToFeatures(chromaout); } CQChromaVamp::FeatureSet -CQChromaVamp::convertToFeatures(const vector<vector<double> > &cqout) +CQChromaVamp::convertToFeatures(const vector<vector<double> > &chromaout) { FeatureSet returnFeatures; - int width = cqout.size(); + int width = chromaout.size(); for (int i = 0; i < width; ++i) { - vector<float> column(m_bpo, 0.f); - - // fold and invert to put low frequencies at the start - - int thisHeight = cqout[i].size(); - - for (int j = 0; j < thisHeight; ++j) { - column[m_bpo - (j % m_bpo) - 1] += cqout[i][j]; - } + vector<float> column(chromaout[i].begin(), chromaout[i].end()); Feature feature; feature.hasTimestamp = true; feature.timestamp = m_startTime + Vamp::RealTime::frame2RealTime - (m_columnCount * m_cq->getColumnHop() - m_cq->getLatency(), + (m_columnCount * m_chroma->getColumnHop() - m_chroma->getLatency(), m_inputSampleRate); feature.values = column; feature.label = "";