comparison sdk/PluginAdapter.cpp @ 0:6479539d1b32

* Importing first cut of Sonic Visualiser's Vamp plugin format SDK
author cannam
date Fri, 31 Mar 2006 14:21:51 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:6479539d1b32
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Vamp
5
6 An API for audio analysis and feature extraction plugins.
7
8 Centre for Digital Music, Queen Mary, University of London.
9 Copyright 2006 Chris Cannam.
10
11 Permission is hereby granted, free of charge, to any person
12 obtaining a copy of this software and associated documentation
13 files (the "Software"), to deal in the Software without
14 restriction, including without limitation the rights to use, copy,
15 modify, merge, publish, distribute, sublicense, and/or sell copies
16 of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 Except as contained in this notice, the names of the Centre for
31 Digital Music; Queen Mary, University of London; and Chris Cannam
32 shall not be used in advertising or otherwise to promote the sale,
33 use or other dealings in this Software without prior written
34 authorization.
35 */
36
37 #include "PluginAdapter.h"
38
39 namespace Vamp {
40
41 PluginAdapterBase::PluginAdapterBase() :
42 m_populated(false)
43 {
44 }
45
46 const VampPluginDescriptor *
47 PluginAdapterBase::getDescriptor()
48 {
49 if (m_populated) return &m_descriptor;
50
51 Plugin *plugin = createPlugin(48000);
52
53 m_parameters = plugin->getParameterDescriptors();
54 m_programs = plugin->getPrograms();
55
56 m_descriptor.name = strdup(plugin->getName().c_str());
57 m_descriptor.description = strdup(plugin->getDescription().c_str());
58 m_descriptor.maker = strdup(plugin->getMaker().c_str());
59 m_descriptor.pluginVersion = plugin->getPluginVersion();
60 m_descriptor.copyright = strdup(plugin->getCopyright().c_str());
61
62 m_descriptor.parameterCount = m_parameters.size();
63 m_descriptor.parameters = (const VampParameterDescriptor **)
64 malloc(m_parameters.size() * sizeof(VampParameterDescriptor));
65
66 for (unsigned int i = 0; i < m_parameters.size(); ++i) {
67 VampParameterDescriptor *desc = (VampParameterDescriptor *)
68 malloc(sizeof(VampParameterDescriptor));
69 desc->name = strdup(m_parameters[i].name.c_str());
70 desc->description = strdup(m_parameters[i].description.c_str());
71 desc->unit = strdup(m_parameters[i].unit.c_str());
72 desc->minValue = m_parameters[i].minValue;
73 desc->maxValue = m_parameters[i].maxValue;
74 desc->defaultValue = m_parameters[i].defaultValue;
75 desc->isQuantized = m_parameters[i].isQuantized;
76 desc->quantizeStep = m_parameters[i].quantizeStep;
77 m_descriptor.parameters[i] = desc;
78 }
79
80 m_descriptor.programCount = m_programs.size();
81 m_descriptor.programs = (const char **)
82 malloc(m_programs.size() * sizeof(const char *));
83
84 for (unsigned int i = 0; i < m_programs.size(); ++i) {
85 m_descriptor.programs[i] = strdup(m_programs[i].c_str());
86 }
87
88 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
89 m_descriptor.inputDomain = vampFrequencyDomain;
90 } else {
91 m_descriptor.inputDomain = vampTimeDomain;
92 }
93
94 m_descriptor.instantiate = vampInstantiate;
95 m_descriptor.cleanup = vampCleanup;
96 m_descriptor.initialise = vampInitialise;
97 m_descriptor.reset = vampReset;
98 m_descriptor.getParameter = vampGetParameter;
99 m_descriptor.setParameter = vampSetParameter;
100 m_descriptor.getCurrentProgram = vampGetCurrentProgram;
101 m_descriptor.selectProgram = vampSelectProgram;
102 m_descriptor.getPreferredStepSize = vampGetPreferredStepSize;
103 m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize;
104 m_descriptor.getMinChannelCount = vampGetMinChannelCount;
105 m_descriptor.getMaxChannelCount = vampGetMaxChannelCount;
106 m_descriptor.getOutputCount = vampGetOutputCount;
107 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor;
108 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
109 m_descriptor.process = vampProcess;
110 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
111 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
112
113 m_adapterMap[&m_descriptor] = this;
114
115 delete plugin;
116
117 m_populated = true;
118 return &m_descriptor;
119 }
120
121 PluginAdapterBase::~PluginAdapterBase()
122 {
123 if (!m_populated) return;
124
125 free((void *)m_descriptor.name);
126 free((void *)m_descriptor.description);
127 free((void *)m_descriptor.maker);
128 free((void *)m_descriptor.copyright);
129
130 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) {
131 const VampParameterDescriptor *desc = m_descriptor.parameters[i];
132 free((void *)desc->name);
133 free((void *)desc->description);
134 free((void *)desc->unit);
135 }
136 free((void *)m_descriptor.parameters);
137
138 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
139 free((void *)m_descriptor.programs[i]);
140 }
141 free((void *)m_descriptor.programs);
142
143 m_adapterMap.erase(&m_descriptor);
144 }
145
146 PluginAdapterBase *
147 PluginAdapterBase::lookupAdapter(VampPluginHandle handle)
148 {
149 AdapterMap::const_iterator i = m_adapterMap.find(handle);
150 if (i == m_adapterMap.end()) return 0;
151 return i->second;
152 }
153
154 VampPluginHandle
155 PluginAdapterBase::vampInstantiate(const VampPluginDescriptor *desc,
156 float inputSampleRate)
157 {
158 if (m_adapterMap.find(desc) == m_adapterMap.end()) return 0;
159 PluginAdapterBase *adapter = m_adapterMap[desc];
160 if (desc != &adapter->m_descriptor) return 0;
161
162 Plugin *plugin = adapter->createPlugin(inputSampleRate);
163 if (plugin) {
164 m_adapterMap[plugin] = adapter;
165 }
166
167 return plugin;
168 }
169
170 void
171 PluginAdapterBase::vampCleanup(VampPluginHandle handle)
172 {
173 PluginAdapterBase *adapter = lookupAdapter(handle);
174 if (!adapter) {
175 delete ((Plugin *)handle);
176 return;
177 }
178 adapter->cleanup(((Plugin *)handle));
179 }
180
181 int
182 PluginAdapterBase::vampInitialise(VampPluginHandle handle,
183 unsigned int channels,
184 unsigned int stepSize,
185 unsigned int blockSize)
186 {
187 bool result = ((Plugin *)handle)->initialise
188 (channels, stepSize, blockSize);
189 return result ? 1 : 0;
190 }
191
192 void
193 PluginAdapterBase::vampReset(VampPluginHandle handle)
194 {
195 ((Plugin *)handle)->reset();
196 }
197
198 float
199 PluginAdapterBase::vampGetParameter(VampPluginHandle handle,
200 int param)
201 {
202 PluginAdapterBase *adapter = lookupAdapter(handle);
203 if (!adapter) return 0.0;
204 Plugin::ParameterList &list = adapter->m_parameters;
205 return ((Plugin *)handle)->getParameter(list[param].name);
206 }
207
208 void
209 PluginAdapterBase::vampSetParameter(VampPluginHandle handle,
210 int param, float value)
211 {
212 PluginAdapterBase *adapter = lookupAdapter(handle);
213 if (!adapter) return;
214 Plugin::ParameterList &list = adapter->m_parameters;
215 ((Plugin *)handle)->setParameter(list[param].name, value);
216 }
217
218 unsigned int
219 PluginAdapterBase::vampGetCurrentProgram(VampPluginHandle handle)
220 {
221 PluginAdapterBase *adapter = lookupAdapter(handle);
222 if (!adapter) return 0;
223 Plugin::ProgramList &list = adapter->m_programs;
224 std::string program = ((Plugin *)handle)->getCurrentProgram();
225 for (unsigned int i = 0; i < list.size(); ++i) {
226 if (list[i] == program) return i;
227 }
228 return 0;
229 }
230
231 void
232 PluginAdapterBase::vampSelectProgram(VampPluginHandle handle,
233 unsigned int program)
234 {
235 PluginAdapterBase *adapter = lookupAdapter(handle);
236 if (!adapter) return;
237 Plugin::ProgramList &list = adapter->m_programs;
238 ((Plugin *)handle)->selectProgram(list[program]);
239 }
240
241 unsigned int
242 PluginAdapterBase::vampGetPreferredStepSize(VampPluginHandle handle)
243 {
244 return ((Plugin *)handle)->getPreferredStepSize();
245 }
246
247 unsigned int
248 PluginAdapterBase::vampGetPreferredBlockSize(VampPluginHandle handle)
249 {
250 return ((Plugin *)handle)->getPreferredBlockSize();
251 }
252
253 unsigned int
254 PluginAdapterBase::vampGetMinChannelCount(VampPluginHandle handle)
255 {
256 return ((Plugin *)handle)->getMinChannelCount();
257 }
258
259 unsigned int
260 PluginAdapterBase::vampGetMaxChannelCount(VampPluginHandle handle)
261 {
262 return ((Plugin *)handle)->getMaxChannelCount();
263 }
264
265 unsigned int
266 PluginAdapterBase::vampGetOutputCount(VampPluginHandle handle)
267 {
268 PluginAdapterBase *adapter = lookupAdapter(handle);
269 if (!adapter) return 0;
270 return adapter->getOutputCount((Plugin *)handle);
271 }
272
273 VampOutputDescriptor *
274 PluginAdapterBase::vampGetOutputDescriptor(VampPluginHandle handle,
275 unsigned int i)
276 {
277 PluginAdapterBase *adapter = lookupAdapter(handle);
278 if (!adapter) return 0;
279 return adapter->getOutputDescriptor((Plugin *)handle, i);
280 }
281
282 void
283 PluginAdapterBase::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
284 {
285 if (desc->name) free((void *)desc->name);
286 if (desc->description) free((void *)desc->description);
287 if (desc->unit) free((void *)desc->unit);
288 for (unsigned int i = 0; i < desc->valueCount; ++i) {
289 free((void *)desc->valueNames[i]);
290 }
291 if (desc->valueNames) free((void *)desc->valueNames);
292 free((void *)desc);
293 }
294
295 VampFeatureList **
296 PluginAdapterBase::vampProcess(VampPluginHandle handle,
297 float **inputBuffers,
298 int sec,
299 int nsec)
300 {
301 PluginAdapterBase *adapter = lookupAdapter(handle);
302 if (!adapter) return 0;
303 return adapter->process((Plugin *)handle,
304 inputBuffers, sec, nsec);
305 }
306
307 VampFeatureList **
308 PluginAdapterBase::vampGetRemainingFeatures(VampPluginHandle handle)
309 {
310 PluginAdapterBase *adapter = lookupAdapter(handle);
311 if (!adapter) return 0;
312 return adapter->getRemainingFeatures((Plugin *)handle);
313 }
314
315 void
316 PluginAdapterBase::vampReleaseFeatureSet(VampFeatureList **fs)
317 {
318 if (!fs) return;
319 for (unsigned int i = 0; fs[i]; ++i) {
320 for (unsigned int j = 0; j < fs[i]->featureCount; ++j) {
321 VampFeature *feature = &fs[i]->features[j];
322 if (feature->values) free((void *)feature->values);
323 if (feature->label) free((void *)feature->label);
324 free((void *)feature);
325 }
326 if (fs[i]->features) free((void *)fs[i]->features);
327 free((void *)fs[i]);
328 }
329 free((void *)fs);
330 }
331
332 void
333 PluginAdapterBase::cleanup(Plugin *plugin)
334 {
335 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
336 delete m_pluginOutputs[plugin];
337 m_pluginOutputs.erase(plugin);
338 }
339 m_adapterMap.erase(plugin);
340 delete ((Plugin *)plugin);
341 }
342
343 void
344 PluginAdapterBase::checkOutputMap(Plugin *plugin)
345 {
346 if (!m_pluginOutputs[plugin]) {
347 m_pluginOutputs[plugin] = new Plugin::OutputList
348 (plugin->getOutputDescriptors());
349 }
350 }
351
352 unsigned int
353 PluginAdapterBase::getOutputCount(Plugin *plugin)
354 {
355 checkOutputMap(plugin);
356 return m_pluginOutputs[plugin]->size();
357 }
358
359 VampOutputDescriptor *
360 PluginAdapterBase::getOutputDescriptor(Plugin *plugin,
361 unsigned int i)
362 {
363 checkOutputMap(plugin);
364 Plugin::OutputDescriptor &od =
365 (*m_pluginOutputs[plugin])[i];
366
367 VampOutputDescriptor *desc = (VampOutputDescriptor *)
368 malloc(sizeof(VampOutputDescriptor));
369
370 desc->name = strdup(od.name.c_str());
371 desc->description = strdup(od.description.c_str());
372 desc->unit = strdup(od.unit.c_str());
373 desc->hasFixedValueCount = od.hasFixedValueCount;
374 desc->valueCount = od.valueCount;
375
376 desc->valueNames = (const char **)
377 malloc(od.valueCount * sizeof(const char *));
378
379 for (unsigned int i = 0; i < od.valueCount; ++i) {
380 if (i < od.valueNames.size()) {
381 desc->valueNames[i] = strdup(od.valueNames[i].c_str());
382 } else {
383 desc->valueNames[i] = 0;
384 }
385 }
386
387 desc->hasKnownExtents = od.hasKnownExtents;
388 desc->minValue = od.minValue;
389 desc->maxValue = od.maxValue;
390 desc->isQuantized = od.isQuantized;
391 desc->quantizeStep = od.quantizeStep;
392
393 switch (od.sampleType) {
394 case Plugin::OutputDescriptor::OneSamplePerStep:
395 desc->sampleType = vampOneSamplePerStep; break;
396 case Plugin::OutputDescriptor::FixedSampleRate:
397 desc->sampleType = vampFixedSampleRate; break;
398 case Plugin::OutputDescriptor::VariableSampleRate:
399 desc->sampleType = vampVariableSampleRate; break;
400 }
401
402 desc->sampleRate = od.sampleRate;
403
404 return desc;
405 }
406
407 VampFeatureList **
408 PluginAdapterBase::process(Plugin *plugin,
409 float **inputBuffers,
410 int sec, int nsec)
411 {
412 RealTime rt(sec, nsec);
413 return convertFeatures(plugin->process(inputBuffers, rt));
414 }
415
416 VampFeatureList **
417 PluginAdapterBase::getRemainingFeatures(Plugin *plugin)
418 {
419 return convertFeatures(plugin->getRemainingFeatures());
420 }
421
422 VampFeatureList **
423 PluginAdapterBase::convertFeatures(const Plugin::FeatureSet &features)
424 {
425 unsigned int n = 0;
426 if (features.begin() != features.end()) {
427 Plugin::FeatureSet::const_iterator i = features.end();
428 --i;
429 n = i->first + 1;
430 }
431
432 if (!n) return 0;
433
434 VampFeatureList **fs = (VampFeatureList **)
435 malloc((n + 1) * sizeof(VampFeatureList *));
436
437 for (unsigned int i = 0; i < n; ++i) {
438 fs[i] = (VampFeatureList *)malloc(sizeof(VampFeatureList));
439 if (features.find(i) == features.end()) {
440 fs[i]->featureCount = 0;
441 fs[i]->features = 0;
442 } else {
443 Plugin::FeatureSet::const_iterator fi =
444 features.find(i);
445 const Plugin::FeatureList &fl = fi->second;
446 fs[i]->featureCount = fl.size();
447 fs[i]->features = (VampFeature *)malloc(fl.size() *
448 sizeof(VampFeature));
449 for (unsigned int j = 0; j < fl.size(); ++j) {
450 fs[i]->features[j].hasTimestamp = fl[j].hasTimestamp;
451 fs[i]->features[j].sec = fl[j].timestamp.sec;
452 fs[i]->features[j].nsec = fl[j].timestamp.nsec;
453 fs[i]->features[j].valueCount = fl[j].values.size();
454 fs[i]->features[j].values = (float *)malloc
455 (fs[i]->features[j].valueCount * sizeof(float));
456 for (unsigned int k = 0; k < fs[i]->features[j].valueCount; ++k) {
457 fs[i]->features[j].values[k] = fl[j].values[k];
458 }
459 fs[i]->features[j].label = strdup(fl[j].label.c_str());
460 }
461 }
462 }
463
464 fs[n] = 0;
465
466 return fs;
467 }
468
469 PluginAdapterBase::AdapterMap
470 PluginAdapterBase::m_adapterMap;
471
472 }
473