Mercurial > hg > vamp-plugin-sdk
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 |