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