annotate vamp/CQVamp.cpp @ 35:75d528478feb

Add Vamp plugin for testing with
author Chris Cannam <c.cannam@qmul.ac.uk>
date Wed, 06 Nov 2013 14:30:42 +0000
parents
children cb072f01435b
rev   line source
c@35 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
c@35 2
c@35 3 #include "CQVamp.h"
c@35 4
c@35 5 #include "../cpp-qm-dsp/ConstantQ.h"
c@35 6
c@35 7 using std::string;
c@35 8 using std::vector;
c@35 9 using std::cerr;
c@35 10 using std::endl;
c@35 11
c@35 12 CQVamp::CQVamp(float inputSampleRate) :
c@35 13 Vamp::Plugin(inputSampleRate),
c@35 14 m_cq(0),
c@35 15 m_maxFrequency(inputSampleRate/2),
c@35 16 m_minFrequency(46),
c@35 17 m_bpo(24)
c@35 18 {
c@35 19 }
c@35 20
c@35 21 CQVamp::~CQVamp()
c@35 22 {
c@35 23 delete m_cq;
c@35 24 }
c@35 25
c@35 26 string
c@35 27 CQVamp::getIdentifier() const
c@35 28 {
c@35 29 return "cqvamp";
c@35 30 }
c@35 31
c@35 32 string
c@35 33 CQVamp::getName() const
c@35 34 {
c@35 35 return "Constant-Q Spectrogram";
c@35 36 }
c@35 37
c@35 38 string
c@35 39 CQVamp::getDescription() const
c@35 40 {
c@35 41 return "Extract a spectrogram with constant ratio of centre frequency to resolution from the input audio";
c@35 42 }
c@35 43
c@35 44 string
c@35 45 CQVamp::getMaker() const
c@35 46 {
c@35 47 return "Queen Mary, University of London";
c@35 48 }
c@35 49
c@35 50 int
c@35 51 CQVamp::getPluginVersion() const
c@35 52 {
c@35 53 return 1;
c@35 54 }
c@35 55
c@35 56 string
c@35 57 CQVamp::getCopyright() const
c@35 58 {
c@35 59 return "Plugin by Chris Cannam. Method by Christian Schörkhuber and Anssi Klapuri. Copyright (c) 2013 QMUL";
c@35 60 }
c@35 61
c@35 62 CQVamp::ParameterList
c@35 63 CQVamp::getParameterDescriptors() const
c@35 64 {
c@35 65 ParameterList list;
c@35 66
c@35 67 ParameterDescriptor desc;
c@35 68 desc.identifier = "minfreq";
c@35 69 desc.name = "Minimum Frequency";
c@35 70 desc.unit = "Hz";
c@35 71 desc.description = "Hint for the lowest frequency to be included in the constant-Q transform. The actual frequency range will be an integral number of octaves ending at the highest frequency specified";
c@35 72 desc.minValue = 10;
c@35 73 desc.maxValue = m_inputSampleRate/2;
c@35 74 desc.defaultValue = 46;
c@35 75 desc.isQuantized = false;
c@35 76 list.push_back(desc);
c@35 77
c@35 78 desc.identifier = "maxfreq";
c@35 79 desc.name = "Maximum Frequency";
c@35 80 desc.unit = "Hz";
c@35 81 desc.description = "Highest frequency to be included in the constant-Q transform";
c@35 82 desc.minValue = 10;
c@35 83 desc.maxValue = m_inputSampleRate/2;
c@35 84 desc.defaultValue = m_inputSampleRate/2;
c@35 85 desc.isQuantized = false;
c@35 86 list.push_back(desc);
c@35 87
c@35 88 desc.identifier = "bpo";
c@35 89 desc.name = "Bins per Octave";
c@35 90 desc.unit = "bins";
c@35 91 desc.description = "Number of constant-Q transform bins per octave";
c@35 92 desc.minValue = 2;
c@35 93 desc.maxValue = 480;
c@35 94 desc.defaultValue = 24;
c@35 95 desc.isQuantized = true;
c@35 96 desc.quantizeStep = 1;
c@35 97 list.push_back(desc);
c@35 98
c@35 99 return list;
c@35 100 }
c@35 101
c@35 102 float
c@35 103 CQVamp::getParameter(std::string param) const
c@35 104 {
c@35 105 if (param == "minfreq") {
c@35 106 return m_minFrequency;
c@35 107 }
c@35 108 if (param == "maxfreq") {
c@35 109 return m_maxFrequency;
c@35 110 }
c@35 111 if (param == "bpo") {
c@35 112 return m_bpo;
c@35 113 }
c@35 114 std::cerr << "WARNING: CQVamp::getParameter: unknown parameter \""
c@35 115 << param << "\"" << std::endl;
c@35 116 return 0.0;
c@35 117 }
c@35 118
c@35 119 void
c@35 120 CQVamp::setParameter(std::string param, float value)
c@35 121 {
c@35 122 if (param == "minfreq") {
c@35 123 m_minFrequency = value;
c@35 124 } else if (param == "maxfreq") {
c@35 125 m_maxFrequency = value;
c@35 126 } else if (param == "bpo") {
c@35 127 m_bpo = lrintf(value);
c@35 128 } else {
c@35 129 std::cerr << "WARNING: CQVamp::setParameter: unknown parameter \""
c@35 130 << param << "\"" << std::endl;
c@35 131 }
c@35 132 }
c@35 133
c@35 134 bool
c@35 135 CQVamp::initialise(size_t channels, size_t stepSize, size_t blockSize)
c@35 136 {
c@35 137 if (m_cq) {
c@35 138 delete m_cq;
c@35 139 m_cq = 0;
c@35 140 }
c@35 141
c@35 142 if (channels < getMinChannelCount() ||
c@35 143 channels > getMaxChannelCount()) return false;
c@35 144
c@35 145 m_stepSize = stepSize;
c@35 146 m_blockSize = blockSize;
c@35 147
c@35 148 m_cq = new ConstantQ
c@35 149 (m_inputSampleRate, m_minFrequency, m_maxFrequency, m_bpo);
c@35 150
c@35 151 return true;
c@35 152 }
c@35 153
c@35 154 void
c@35 155 CQVamp::reset()
c@35 156 {
c@35 157 if (m_cq) {
c@35 158 delete m_cq;
c@35 159 m_cq = new ConstantQ
c@35 160 (m_inputSampleRate, m_minFrequency, m_maxFrequency, m_bpo);
c@35 161 }
c@35 162 }
c@35 163
c@35 164 size_t
c@35 165 CQVamp::getPreferredStepSize() const
c@35 166 {
c@35 167 return 0;
c@35 168 }
c@35 169
c@35 170 size_t
c@35 171 CQVamp::getPreferredBlockSize() const
c@35 172 {
c@35 173 return 0;
c@35 174 }
c@35 175
c@35 176 CQVamp::OutputList
c@35 177 CQVamp::getOutputDescriptors() const
c@35 178 {
c@35 179 OutputList list;
c@35 180
c@35 181 OutputDescriptor d;
c@35 182 d.identifier = "constantq";
c@35 183 d.name = "Constant-Q Spectrogram";
c@35 184 d.unit = "";
c@35 185 d.description = "Output of constant-Q transform, as a single vector per process block";
c@35 186 d.hasFixedBinCount = true;
c@35 187 d.binCount = (m_cq ? m_cq->getTotalBins() : (9 * 24));
c@35 188 d.hasKnownExtents = false;
c@35 189 d.isQuantized = false;
c@35 190 d.sampleType = OutputDescriptor::FixedSampleRate;
c@35 191 d.sampleRate = m_inputSampleRate / (m_cq ? m_cq->getColumnHop() : 256);
c@35 192 list.push_back(d);
c@35 193
c@35 194 return list;
c@35 195 }
c@35 196
c@35 197 CQVamp::FeatureSet
c@35 198 CQVamp::process(const float *const *inputBuffers,
c@35 199 Vamp::RealTime /* timestamp */)
c@35 200 {
c@35 201 if (!m_cq) {
c@35 202 cerr << "ERROR: CQVamp::process: "
c@35 203 << "Plugin has not been initialised"
c@35 204 << endl;
c@35 205 return FeatureSet();
c@35 206 }
c@35 207
c@35 208 vector<double> data;
c@35 209 for (int i = 0; i < m_blockSize; ++i) data.push_back(inputBuffers[0][i]);
c@35 210
c@35 211 vector<vector<double> > cqout = m_cq->process(data);
c@35 212
c@35 213 FeatureSet returnFeatures;
c@35 214
c@35 215 for (int i = 0; i < cqout.size(); ++i) {
c@35 216
c@35 217 vector<float> column(m_cq->getTotalBins(), 0.f);
c@35 218 for (int j = 0; j < cqout[i].size(); ++j) {
c@35 219 column[j] = cqout[i][j];
c@35 220 }
c@35 221
c@35 222 Feature feature;
c@35 223 feature.hasTimestamp = false;
c@35 224 feature.values = column;
c@35 225 feature.label = "";
c@35 226 returnFeatures[0].push_back(feature);
c@35 227 }
c@35 228
c@35 229 return returnFeatures;
c@35 230 }
c@35 231
c@35 232 CQVamp::FeatureSet
c@35 233 CQVamp::getRemainingFeatures()
c@35 234 {
c@35 235 return FeatureSet();
c@35 236 }
c@35 237