cannam@1
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
cannam@1
|
2
|
cannam@1
|
3 /*
|
cannam@1
|
4 Vamp
|
cannam@1
|
5
|
cannam@1
|
6 An API for audio analysis and feature extraction plugins.
|
cannam@1
|
7
|
cannam@1
|
8 Centre for Digital Music, Queen Mary, University of London.
|
cannam@1
|
9 Copyright 2006 Chris Cannam.
|
cannam@1
|
10
|
cannam@1
|
11 Permission is hereby granted, free of charge, to any person
|
cannam@1
|
12 obtaining a copy of this software and associated documentation
|
cannam@1
|
13 files (the "Software"), to deal in the Software without
|
cannam@1
|
14 restriction, including without limitation the rights to use, copy,
|
cannam@1
|
15 modify, merge, publish, distribute, sublicense, and/or sell copies
|
cannam@1
|
16 of the Software, and to permit persons to whom the Software is
|
cannam@1
|
17 furnished to do so, subject to the following conditions:
|
cannam@1
|
18
|
cannam@1
|
19 The above copyright notice and this permission notice shall be
|
cannam@1
|
20 included in all copies or substantial portions of the Software.
|
cannam@1
|
21
|
cannam@1
|
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
cannam@1
|
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
cannam@1
|
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
cannam@6
|
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
cannam@1
|
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
cannam@1
|
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
cannam@1
|
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
cannam@1
|
29
|
cannam@1
|
30 Except as contained in this notice, the names of the Centre for
|
cannam@1
|
31 Digital Music; Queen Mary, University of London; and Chris Cannam
|
cannam@1
|
32 shall not be used in advertising or otherwise to promote the sale,
|
cannam@1
|
33 use or other dealings in this Software without prior written
|
cannam@1
|
34 authorization.
|
cannam@1
|
35 */
|
cannam@1
|
36
|
cannam@1
|
37 #include "PluginHostAdapter.h"
|
cannam@1
|
38
|
cannam@1
|
39 namespace Vamp
|
cannam@1
|
40 {
|
cannam@1
|
41
|
cannam@1
|
42 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
|
cannam@1
|
43 float inputSampleRate) :
|
cannam@1
|
44 Plugin(inputSampleRate),
|
cannam@1
|
45 m_descriptor(descriptor)
|
cannam@1
|
46 {
|
cannam@1
|
47 std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
|
cannam@1
|
48 m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
|
cannam@1
|
49 }
|
cannam@1
|
50
|
cannam@1
|
51 PluginHostAdapter::~PluginHostAdapter()
|
cannam@1
|
52 {
|
cannam@1
|
53 if (m_handle) m_descriptor->cleanup(m_handle);
|
cannam@1
|
54 }
|
cannam@1
|
55
|
cannam@1
|
56 bool
|
cannam@1
|
57 PluginHostAdapter::initialise(size_t channels,
|
cannam@1
|
58 size_t stepSize,
|
cannam@1
|
59 size_t blockSize)
|
cannam@1
|
60 {
|
cannam@1
|
61 if (!m_handle) return false;
|
cannam@1
|
62 return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
|
cannam@1
|
63 true : false;
|
cannam@1
|
64 }
|
cannam@1
|
65
|
cannam@1
|
66 void
|
cannam@1
|
67 PluginHostAdapter::reset()
|
cannam@1
|
68 {
|
cannam@1
|
69 if (!m_handle) return;
|
cannam@1
|
70 m_descriptor->reset(m_handle);
|
cannam@1
|
71 }
|
cannam@1
|
72
|
cannam@1
|
73 PluginHostAdapter::InputDomain
|
cannam@1
|
74 PluginHostAdapter::getInputDomain() const
|
cannam@1
|
75 {
|
cannam@1
|
76 if (m_descriptor->inputDomain == vampFrequencyDomain) {
|
cannam@1
|
77 return FrequencyDomain;
|
cannam@1
|
78 } else {
|
cannam@1
|
79 return TimeDomain;
|
cannam@1
|
80 }
|
cannam@1
|
81 }
|
cannam@1
|
82
|
cannam@1
|
83 std::string
|
cannam@1
|
84 PluginHostAdapter::getName() const
|
cannam@1
|
85 {
|
cannam@1
|
86 return m_descriptor->name;
|
cannam@1
|
87 }
|
cannam@1
|
88
|
cannam@1
|
89 std::string
|
cannam@1
|
90 PluginHostAdapter::getDescription() const
|
cannam@1
|
91 {
|
cannam@1
|
92 return m_descriptor->description;
|
cannam@1
|
93 }
|
cannam@1
|
94
|
cannam@1
|
95 std::string
|
cannam@1
|
96 PluginHostAdapter::getMaker() const
|
cannam@1
|
97 {
|
cannam@1
|
98 return m_descriptor->maker;
|
cannam@1
|
99 }
|
cannam@1
|
100
|
cannam@1
|
101 int
|
cannam@1
|
102 PluginHostAdapter::getPluginVersion() const
|
cannam@1
|
103 {
|
cannam@1
|
104 return m_descriptor->pluginVersion;
|
cannam@1
|
105 }
|
cannam@1
|
106
|
cannam@1
|
107 std::string
|
cannam@1
|
108 PluginHostAdapter::getCopyright() const
|
cannam@1
|
109 {
|
cannam@1
|
110 return m_descriptor->copyright;
|
cannam@1
|
111 }
|
cannam@1
|
112
|
cannam@1
|
113 PluginHostAdapter::ParameterList
|
cannam@1
|
114 PluginHostAdapter::getParameterDescriptors() const
|
cannam@1
|
115 {
|
cannam@1
|
116 ParameterList list;
|
cannam@1
|
117 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
cannam@1
|
118 const VampParameterDescriptor *spd = m_descriptor->parameters[i];
|
cannam@1
|
119 ParameterDescriptor pd;
|
cannam@1
|
120 pd.name = spd->name;
|
cannam@1
|
121 pd.description = spd->description;
|
cannam@1
|
122 pd.unit = spd->unit;
|
cannam@1
|
123 pd.minValue = spd->minValue;
|
cannam@1
|
124 pd.maxValue = spd->maxValue;
|
cannam@1
|
125 pd.defaultValue = spd->defaultValue;
|
cannam@1
|
126 pd.isQuantized = spd->isQuantized;
|
cannam@1
|
127 pd.quantizeStep = spd->quantizeStep;
|
cannam@9
|
128 if (pd.isQuantized && spd->valueNames) {
|
cannam@9
|
129 for (unsigned int j = 0; spd->valueNames[j]; ++j) {
|
cannam@9
|
130 pd.valueNames.push_back(spd->valueNames[j]);
|
cannam@9
|
131 }
|
cannam@9
|
132 }
|
cannam@1
|
133 list.push_back(pd);
|
cannam@1
|
134 }
|
cannam@1
|
135 return list;
|
cannam@1
|
136 }
|
cannam@1
|
137
|
cannam@1
|
138 float
|
cannam@1
|
139 PluginHostAdapter::getParameter(std::string param) const
|
cannam@1
|
140 {
|
cannam@1
|
141 if (!m_handle) return 0.0;
|
cannam@1
|
142
|
cannam@1
|
143 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
cannam@1
|
144 if (param == m_descriptor->parameters[i]->name) {
|
cannam@1
|
145 return m_descriptor->getParameter(m_handle, i);
|
cannam@1
|
146 }
|
cannam@1
|
147 }
|
cannam@1
|
148
|
cannam@1
|
149 return 0.0;
|
cannam@1
|
150 }
|
cannam@1
|
151
|
cannam@1
|
152 void
|
cannam@1
|
153 PluginHostAdapter::setParameter(std::string param,
|
cannam@1
|
154 float value)
|
cannam@1
|
155 {
|
cannam@1
|
156 if (!m_handle) return;
|
cannam@1
|
157
|
cannam@1
|
158 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
cannam@1
|
159 if (param == m_descriptor->parameters[i]->name) {
|
cannam@1
|
160 m_descriptor->setParameter(m_handle, i, value);
|
cannam@1
|
161 return;
|
cannam@1
|
162 }
|
cannam@1
|
163 }
|
cannam@1
|
164 }
|
cannam@1
|
165
|
cannam@1
|
166 PluginHostAdapter::ProgramList
|
cannam@1
|
167 PluginHostAdapter::getPrograms() const
|
cannam@1
|
168 {
|
cannam@1
|
169 ProgramList list;
|
cannam@1
|
170
|
cannam@1
|
171 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
|
cannam@1
|
172 list.push_back(m_descriptor->programs[i]);
|
cannam@1
|
173 }
|
cannam@1
|
174
|
cannam@1
|
175 return list;
|
cannam@1
|
176 }
|
cannam@1
|
177
|
cannam@1
|
178 std::string
|
cannam@1
|
179 PluginHostAdapter::getCurrentProgram() const
|
cannam@1
|
180 {
|
cannam@1
|
181 if (!m_handle) return "";
|
cannam@1
|
182
|
cannam@1
|
183 int pn = m_descriptor->getCurrentProgram(m_handle);
|
cannam@1
|
184 return m_descriptor->programs[pn];
|
cannam@1
|
185 }
|
cannam@1
|
186
|
cannam@1
|
187 void
|
cannam@1
|
188 PluginHostAdapter::selectProgram(std::string program)
|
cannam@1
|
189 {
|
cannam@1
|
190 if (!m_handle) return;
|
cannam@1
|
191
|
cannam@1
|
192 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
|
cannam@1
|
193 if (program == m_descriptor->programs[i]) {
|
cannam@1
|
194 m_descriptor->selectProgram(m_handle, i);
|
cannam@1
|
195 return;
|
cannam@1
|
196 }
|
cannam@1
|
197 }
|
cannam@1
|
198 }
|
cannam@1
|
199
|
cannam@1
|
200 size_t
|
cannam@1
|
201 PluginHostAdapter::getPreferredStepSize() const
|
cannam@1
|
202 {
|
cannam@1
|
203 if (!m_handle) return 0;
|
cannam@1
|
204 return m_descriptor->getPreferredStepSize(m_handle);
|
cannam@1
|
205 }
|
cannam@1
|
206
|
cannam@1
|
207 size_t
|
cannam@1
|
208 PluginHostAdapter::getPreferredBlockSize() const
|
cannam@1
|
209 {
|
cannam@1
|
210 if (!m_handle) return 0;
|
cannam@1
|
211 return m_descriptor->getPreferredBlockSize(m_handle);
|
cannam@1
|
212 }
|
cannam@1
|
213
|
cannam@1
|
214 PluginHostAdapter::OutputList
|
cannam@1
|
215 PluginHostAdapter::getOutputDescriptors() const
|
cannam@1
|
216 {
|
cannam@1
|
217 OutputList list;
|
cannam@1
|
218 if (!m_handle) return list;
|
cannam@1
|
219
|
cannam@1
|
220 unsigned int count = m_descriptor->getOutputCount(m_handle);
|
cannam@1
|
221
|
cannam@1
|
222 for (unsigned int i = 0; i < count; ++i) {
|
cannam@1
|
223 VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
|
cannam@1
|
224 OutputDescriptor d;
|
cannam@1
|
225 d.name = sd->name;
|
cannam@1
|
226 d.description = sd->description;
|
cannam@1
|
227 d.unit = sd->unit;
|
cannam@9
|
228 d.hasFixedBinCount = sd->hasFixedBinCount;
|
cannam@9
|
229 d.binCount = sd->binCount;
|
cannam@9
|
230 if (d.hasFixedBinCount) {
|
cannam@9
|
231 for (unsigned int j = 0; j < sd->binCount; ++j) {
|
cannam@9
|
232 d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
|
cannam@9
|
233 }
|
cannam@1
|
234 }
|
cannam@1
|
235 d.hasKnownExtents = sd->hasKnownExtents;
|
cannam@1
|
236 d.minValue = sd->minValue;
|
cannam@1
|
237 d.maxValue = sd->maxValue;
|
cannam@1
|
238 d.isQuantized = sd->isQuantized;
|
cannam@1
|
239 d.quantizeStep = sd->quantizeStep;
|
cannam@1
|
240
|
cannam@1
|
241 switch (sd->sampleType) {
|
cannam@1
|
242 case vampOneSamplePerStep:
|
cannam@1
|
243 d.sampleType = OutputDescriptor::OneSamplePerStep; break;
|
cannam@1
|
244 case vampFixedSampleRate:
|
cannam@1
|
245 d.sampleType = OutputDescriptor::FixedSampleRate; break;
|
cannam@1
|
246 case vampVariableSampleRate:
|
cannam@1
|
247 d.sampleType = OutputDescriptor::VariableSampleRate; break;
|
cannam@1
|
248 }
|
cannam@1
|
249
|
cannam@1
|
250 d.sampleRate = sd->sampleRate;
|
cannam@1
|
251
|
cannam@1
|
252 list.push_back(d);
|
cannam@1
|
253
|
cannam@1
|
254 m_descriptor->releaseOutputDescriptor(sd);
|
cannam@1
|
255 }
|
cannam@1
|
256
|
cannam@1
|
257 return list;
|
cannam@1
|
258 }
|
cannam@1
|
259
|
cannam@1
|
260 PluginHostAdapter::FeatureSet
|
cannam@1
|
261 PluginHostAdapter::process(float **inputBuffers,
|
cannam@1
|
262 RealTime timestamp)
|
cannam@1
|
263 {
|
cannam@1
|
264 FeatureSet fs;
|
cannam@1
|
265 if (!m_handle) return fs;
|
cannam@1
|
266
|
cannam@1
|
267 int sec = timestamp.sec;
|
cannam@1
|
268 int nsec = timestamp.nsec;
|
cannam@1
|
269
|
cannam@1
|
270 VampFeatureList **features = m_descriptor->process(m_handle,
|
cannam@1
|
271 inputBuffers,
|
cannam@1
|
272 sec, nsec);
|
cannam@1
|
273
|
cannam@1
|
274 convertFeatures(features, fs);
|
cannam@1
|
275 m_descriptor->releaseFeatureSet(features);
|
cannam@1
|
276 return fs;
|
cannam@1
|
277 }
|
cannam@1
|
278
|
cannam@1
|
279 PluginHostAdapter::FeatureSet
|
cannam@1
|
280 PluginHostAdapter::getRemainingFeatures()
|
cannam@1
|
281 {
|
cannam@1
|
282 FeatureSet fs;
|
cannam@1
|
283 if (!m_handle) return fs;
|
cannam@1
|
284
|
cannam@1
|
285 VampFeatureList **features = m_descriptor->getRemainingFeatures(m_handle);
|
cannam@1
|
286
|
cannam@1
|
287 convertFeatures(features, fs);
|
cannam@1
|
288 m_descriptor->releaseFeatureSet(features);
|
cannam@1
|
289 return fs;
|
cannam@1
|
290 }
|
cannam@1
|
291
|
cannam@1
|
292 void
|
cannam@1
|
293 PluginHostAdapter::convertFeatures(VampFeatureList **features,
|
cannam@1
|
294 FeatureSet &fs)
|
cannam@1
|
295 {
|
cannam@7
|
296 if (!features) return;
|
cannam@7
|
297
|
cannam@1
|
298 for (unsigned int i = 0; features[i]; ++i) {
|
cannam@1
|
299
|
cannam@1
|
300 VampFeatureList &list = *features[i];
|
cannam@1
|
301
|
cannam@1
|
302 if (list.featureCount > 0) {
|
cannam@1
|
303
|
cannam@1
|
304 for (unsigned int j = 0; j < list.featureCount; ++j) {
|
cannam@1
|
305
|
cannam@1
|
306 Feature feature;
|
cannam@1
|
307 feature.hasTimestamp = list.features[j].hasTimestamp;
|
cannam@1
|
308 feature.timestamp = RealTime(list.features[j].sec,
|
cannam@1
|
309 list.features[j].nsec);
|
cannam@1
|
310
|
cannam@1
|
311 for (unsigned int k = 0; k < list.features[j].valueCount; ++k) {
|
cannam@1
|
312 feature.values.push_back(list.features[j].values[k]);
|
cannam@1
|
313 }
|
cannam@7
|
314
|
cannam@7
|
315 if (list.features[j].label) {
|
cannam@7
|
316 feature.label = list.features[j].label;
|
cannam@7
|
317 }
|
cannam@1
|
318
|
cannam@1
|
319 fs[i].push_back(feature);
|
cannam@1
|
320 }
|
cannam@1
|
321 }
|
cannam@1
|
322 }
|
cannam@1
|
323 }
|
cannam@1
|
324
|
cannam@1
|
325 }
|