Mercurial > hg > vamp-plugin-sdk
comparison src/vamp-sdk/PluginAdapter.cpp @ 227:6b30e064cab7 distinct-libraries
* more moving
author | cannam |
---|---|
date | Thu, 06 Nov 2008 14:13:12 +0000 |
parents | src/PluginAdapter.cpp@14029eb08472 |
children | 5ee166dccfff |
comparison
equal
deleted
inserted
replaced
226:14029eb08472 | 227:6b30e064cab7 |
---|---|
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 AUTHORS 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 #include <cstring> | |
40 #include <cstdlib> | |
41 | |
42 //#define DEBUG_PLUGIN_ADAPTER 1 | |
43 | |
44 namespace Vamp { | |
45 | |
46 class PluginAdapterBase::Impl | |
47 { | |
48 public: | |
49 Impl(PluginAdapterBase *); | |
50 ~Impl(); | |
51 | |
52 const VampPluginDescriptor *getDescriptor(); | |
53 | |
54 protected: | |
55 PluginAdapterBase *m_base; | |
56 | |
57 static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc, | |
58 float inputSampleRate); | |
59 | |
60 static void vampCleanup(VampPluginHandle handle); | |
61 | |
62 static int vampInitialise(VampPluginHandle handle, unsigned int channels, | |
63 unsigned int stepSize, unsigned int blockSize); | |
64 | |
65 static void vampReset(VampPluginHandle handle); | |
66 | |
67 static float vampGetParameter(VampPluginHandle handle, int param); | |
68 static void vampSetParameter(VampPluginHandle handle, int param, float value); | |
69 | |
70 static unsigned int vampGetCurrentProgram(VampPluginHandle handle); | |
71 static void vampSelectProgram(VampPluginHandle handle, unsigned int program); | |
72 | |
73 static unsigned int vampGetPreferredStepSize(VampPluginHandle handle); | |
74 static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle); | |
75 static unsigned int vampGetMinChannelCount(VampPluginHandle handle); | |
76 static unsigned int vampGetMaxChannelCount(VampPluginHandle handle); | |
77 | |
78 static unsigned int vampGetOutputCount(VampPluginHandle handle); | |
79 | |
80 static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle, | |
81 unsigned int i); | |
82 | |
83 static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc); | |
84 | |
85 static VampFeatureList *vampProcess(VampPluginHandle handle, | |
86 const float *const *inputBuffers, | |
87 int sec, | |
88 int nsec); | |
89 | |
90 static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle); | |
91 | |
92 static void vampReleaseFeatureSet(VampFeatureList *fs); | |
93 | |
94 void cleanup(Plugin *plugin); | |
95 void checkOutputMap(Plugin *plugin); | |
96 unsigned int getOutputCount(Plugin *plugin); | |
97 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin, | |
98 unsigned int i); | |
99 VampFeatureList *process(Plugin *plugin, | |
100 const float *const *inputBuffers, | |
101 int sec, int nsec); | |
102 VampFeatureList *getRemainingFeatures(Plugin *plugin); | |
103 VampFeatureList *convertFeatures(Plugin *plugin, | |
104 const Plugin::FeatureSet &features); | |
105 | |
106 // maps both plugins and descriptors to adapters | |
107 typedef std::map<const void *, Impl *> AdapterMap; | |
108 static AdapterMap *m_adapterMap; | |
109 static Impl *lookupAdapter(VampPluginHandle); | |
110 | |
111 bool m_populated; | |
112 VampPluginDescriptor m_descriptor; | |
113 Plugin::ParameterList m_parameters; | |
114 Plugin::ProgramList m_programs; | |
115 | |
116 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap; | |
117 OutputMap m_pluginOutputs; | |
118 | |
119 std::map<Plugin *, VampFeatureList *> m_fs; | |
120 std::map<Plugin *, std::vector<size_t> > m_fsizes; | |
121 std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes; | |
122 void resizeFS(Plugin *plugin, int n); | |
123 void resizeFL(Plugin *plugin, int n, size_t sz); | |
124 void resizeFV(Plugin *plugin, int n, int j, size_t sz); | |
125 }; | |
126 | |
127 PluginAdapterBase::PluginAdapterBase() | |
128 { | |
129 m_impl = new Impl(this); | |
130 } | |
131 | |
132 PluginAdapterBase::~PluginAdapterBase() | |
133 { | |
134 delete m_impl; | |
135 } | |
136 | |
137 const VampPluginDescriptor * | |
138 PluginAdapterBase::getDescriptor() | |
139 { | |
140 return m_impl->getDescriptor(); | |
141 } | |
142 | |
143 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) : | |
144 m_base(base), | |
145 m_populated(false) | |
146 { | |
147 #ifdef DEBUG_PLUGIN_ADAPTER | |
148 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl; | |
149 #endif | |
150 } | |
151 | |
152 const VampPluginDescriptor * | |
153 PluginAdapterBase::Impl::getDescriptor() | |
154 { | |
155 #ifdef DEBUG_PLUGIN_ADAPTER | |
156 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl; | |
157 #endif | |
158 | |
159 if (m_populated) return &m_descriptor; | |
160 | |
161 Plugin *plugin = m_base->createPlugin(48000); | |
162 | |
163 if (plugin->getVampApiVersion() != VAMP_API_VERSION) { | |
164 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: " | |
165 << "API version " << plugin->getVampApiVersion() | |
166 << " for\nplugin \"" << plugin->getIdentifier() << "\" " | |
167 << "differs from version " | |
168 << VAMP_API_VERSION << " for adapter.\n" | |
169 << "This plugin is probably linked against a different version of the Vamp SDK\n" | |
170 << "from the version it was compiled with. It will need to be re-linked correctly\n" | |
171 << "before it can be used." << std::endl; | |
172 delete plugin; | |
173 return 0; | |
174 } | |
175 | |
176 m_parameters = plugin->getParameterDescriptors(); | |
177 m_programs = plugin->getPrograms(); | |
178 | |
179 m_descriptor.vampApiVersion = plugin->getVampApiVersion(); | |
180 m_descriptor.identifier = strdup(plugin->getIdentifier().c_str()); | |
181 m_descriptor.name = strdup(plugin->getName().c_str()); | |
182 m_descriptor.description = strdup(plugin->getDescription().c_str()); | |
183 m_descriptor.maker = strdup(plugin->getMaker().c_str()); | |
184 m_descriptor.pluginVersion = plugin->getPluginVersion(); | |
185 m_descriptor.copyright = strdup(plugin->getCopyright().c_str()); | |
186 | |
187 m_descriptor.parameterCount = m_parameters.size(); | |
188 m_descriptor.parameters = (const VampParameterDescriptor **) | |
189 malloc(m_parameters.size() * sizeof(VampParameterDescriptor)); | |
190 | |
191 unsigned int i; | |
192 | |
193 for (i = 0; i < m_parameters.size(); ++i) { | |
194 VampParameterDescriptor *desc = (VampParameterDescriptor *) | |
195 malloc(sizeof(VampParameterDescriptor)); | |
196 desc->identifier = strdup(m_parameters[i].identifier.c_str()); | |
197 desc->name = strdup(m_parameters[i].name.c_str()); | |
198 desc->description = strdup(m_parameters[i].description.c_str()); | |
199 desc->unit = strdup(m_parameters[i].unit.c_str()); | |
200 desc->minValue = m_parameters[i].minValue; | |
201 desc->maxValue = m_parameters[i].maxValue; | |
202 desc->defaultValue = m_parameters[i].defaultValue; | |
203 desc->isQuantized = m_parameters[i].isQuantized; | |
204 desc->quantizeStep = m_parameters[i].quantizeStep; | |
205 desc->valueNames = 0; | |
206 if (desc->isQuantized && !m_parameters[i].valueNames.empty()) { | |
207 desc->valueNames = (const char **) | |
208 malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *)); | |
209 for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) { | |
210 desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str()); | |
211 } | |
212 desc->valueNames[m_parameters[i].valueNames.size()] = 0; | |
213 } | |
214 m_descriptor.parameters[i] = desc; | |
215 } | |
216 | |
217 m_descriptor.programCount = m_programs.size(); | |
218 m_descriptor.programs = (const char **) | |
219 malloc(m_programs.size() * sizeof(const char *)); | |
220 | |
221 for (i = 0; i < m_programs.size(); ++i) { | |
222 m_descriptor.programs[i] = strdup(m_programs[i].c_str()); | |
223 } | |
224 | |
225 if (plugin->getInputDomain() == Plugin::FrequencyDomain) { | |
226 m_descriptor.inputDomain = vampFrequencyDomain; | |
227 } else { | |
228 m_descriptor.inputDomain = vampTimeDomain; | |
229 } | |
230 | |
231 m_descriptor.instantiate = vampInstantiate; | |
232 m_descriptor.cleanup = vampCleanup; | |
233 m_descriptor.initialise = vampInitialise; | |
234 m_descriptor.reset = vampReset; | |
235 m_descriptor.getParameter = vampGetParameter; | |
236 m_descriptor.setParameter = vampSetParameter; | |
237 m_descriptor.getCurrentProgram = vampGetCurrentProgram; | |
238 m_descriptor.selectProgram = vampSelectProgram; | |
239 m_descriptor.getPreferredStepSize = vampGetPreferredStepSize; | |
240 m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize; | |
241 m_descriptor.getMinChannelCount = vampGetMinChannelCount; | |
242 m_descriptor.getMaxChannelCount = vampGetMaxChannelCount; | |
243 m_descriptor.getOutputCount = vampGetOutputCount; | |
244 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor; | |
245 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor; | |
246 m_descriptor.process = vampProcess; | |
247 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures; | |
248 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet; | |
249 | |
250 if (!m_adapterMap) { | |
251 m_adapterMap = new AdapterMap; | |
252 } | |
253 (*m_adapterMap)[&m_descriptor] = this; | |
254 | |
255 delete plugin; | |
256 | |
257 m_populated = true; | |
258 return &m_descriptor; | |
259 } | |
260 | |
261 PluginAdapterBase::Impl::~Impl() | |
262 { | |
263 #ifdef DEBUG_PLUGIN_ADAPTER | |
264 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl; | |
265 #endif | |
266 | |
267 if (!m_populated) return; | |
268 | |
269 free((void *)m_descriptor.identifier); | |
270 free((void *)m_descriptor.name); | |
271 free((void *)m_descriptor.description); | |
272 free((void *)m_descriptor.maker); | |
273 free((void *)m_descriptor.copyright); | |
274 | |
275 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) { | |
276 const VampParameterDescriptor *desc = m_descriptor.parameters[i]; | |
277 free((void *)desc->identifier); | |
278 free((void *)desc->name); | |
279 free((void *)desc->description); | |
280 free((void *)desc->unit); | |
281 if (desc->valueNames) { | |
282 for (unsigned int j = 0; desc->valueNames[j]; ++j) { | |
283 free((void *)desc->valueNames[j]); | |
284 } | |
285 free((void *)desc->valueNames); | |
286 } | |
287 } | |
288 free((void *)m_descriptor.parameters); | |
289 | |
290 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { | |
291 free((void *)m_descriptor.programs[i]); | |
292 } | |
293 free((void *)m_descriptor.programs); | |
294 | |
295 if (m_adapterMap) { | |
296 | |
297 m_adapterMap->erase(&m_descriptor); | |
298 | |
299 if (m_adapterMap->empty()) { | |
300 delete m_adapterMap; | |
301 m_adapterMap = 0; | |
302 } | |
303 } | |
304 } | |
305 | |
306 PluginAdapterBase::Impl * | |
307 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle) | |
308 { | |
309 #ifdef DEBUG_PLUGIN_ADAPTER | |
310 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl; | |
311 #endif | |
312 | |
313 if (!m_adapterMap) return 0; | |
314 AdapterMap::const_iterator i = m_adapterMap->find(handle); | |
315 if (i == m_adapterMap->end()) return 0; | |
316 return i->second; | |
317 } | |
318 | |
319 VampPluginHandle | |
320 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc, | |
321 float inputSampleRate) | |
322 { | |
323 #ifdef DEBUG_PLUGIN_ADAPTER | |
324 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl; | |
325 #endif | |
326 | |
327 if (!m_adapterMap) { | |
328 m_adapterMap = new AdapterMap(); | |
329 } | |
330 | |
331 if (m_adapterMap->find(desc) == m_adapterMap->end()) { | |
332 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl; | |
333 return 0; | |
334 } | |
335 | |
336 Impl *adapter = (*m_adapterMap)[desc]; | |
337 if (desc != &adapter->m_descriptor) return 0; | |
338 | |
339 Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate); | |
340 if (plugin) { | |
341 (*m_adapterMap)[plugin] = adapter; | |
342 } | |
343 | |
344 #ifdef DEBUG_PLUGIN_ADAPTER | |
345 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl; | |
346 #endif | |
347 | |
348 return plugin; | |
349 } | |
350 | |
351 void | |
352 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle) | |
353 { | |
354 #ifdef DEBUG_PLUGIN_ADAPTER | |
355 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl; | |
356 #endif | |
357 | |
358 Impl *adapter = lookupAdapter(handle); | |
359 if (!adapter) { | |
360 delete ((Plugin *)handle); | |
361 return; | |
362 } | |
363 adapter->cleanup(((Plugin *)handle)); | |
364 } | |
365 | |
366 int | |
367 PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle, | |
368 unsigned int channels, | |
369 unsigned int stepSize, | |
370 unsigned int blockSize) | |
371 { | |
372 #ifdef DEBUG_PLUGIN_ADAPTER | |
373 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl; | |
374 #endif | |
375 | |
376 bool result = ((Plugin *)handle)->initialise | |
377 (channels, stepSize, blockSize); | |
378 return result ? 1 : 0; | |
379 } | |
380 | |
381 void | |
382 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle) | |
383 { | |
384 #ifdef DEBUG_PLUGIN_ADAPTER | |
385 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl; | |
386 #endif | |
387 | |
388 ((Plugin *)handle)->reset(); | |
389 } | |
390 | |
391 float | |
392 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle, | |
393 int param) | |
394 { | |
395 #ifdef DEBUG_PLUGIN_ADAPTER | |
396 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl; | |
397 #endif | |
398 | |
399 Impl *adapter = lookupAdapter(handle); | |
400 if (!adapter) return 0.0; | |
401 Plugin::ParameterList &list = adapter->m_parameters; | |
402 return ((Plugin *)handle)->getParameter(list[param].identifier); | |
403 } | |
404 | |
405 void | |
406 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle, | |
407 int param, float value) | |
408 { | |
409 #ifdef DEBUG_PLUGIN_ADAPTER | |
410 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl; | |
411 #endif | |
412 | |
413 Impl *adapter = lookupAdapter(handle); | |
414 if (!adapter) return; | |
415 Plugin::ParameterList &list = adapter->m_parameters; | |
416 ((Plugin *)handle)->setParameter(list[param].identifier, value); | |
417 } | |
418 | |
419 unsigned int | |
420 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle) | |
421 { | |
422 #ifdef DEBUG_PLUGIN_ADAPTER | |
423 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl; | |
424 #endif | |
425 | |
426 Impl *adapter = lookupAdapter(handle); | |
427 if (!adapter) return 0; | |
428 Plugin::ProgramList &list = adapter->m_programs; | |
429 std::string program = ((Plugin *)handle)->getCurrentProgram(); | |
430 for (unsigned int i = 0; i < list.size(); ++i) { | |
431 if (list[i] == program) return i; | |
432 } | |
433 return 0; | |
434 } | |
435 | |
436 void | |
437 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle, | |
438 unsigned int program) | |
439 { | |
440 #ifdef DEBUG_PLUGIN_ADAPTER | |
441 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl; | |
442 #endif | |
443 | |
444 Impl *adapter = lookupAdapter(handle); | |
445 if (!adapter) return; | |
446 Plugin::ProgramList &list = adapter->m_programs; | |
447 ((Plugin *)handle)->selectProgram(list[program]); | |
448 } | |
449 | |
450 unsigned int | |
451 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle) | |
452 { | |
453 #ifdef DEBUG_PLUGIN_ADAPTER | |
454 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl; | |
455 #endif | |
456 | |
457 return ((Plugin *)handle)->getPreferredStepSize(); | |
458 } | |
459 | |
460 unsigned int | |
461 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle) | |
462 { | |
463 #ifdef DEBUG_PLUGIN_ADAPTER | |
464 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl; | |
465 #endif | |
466 | |
467 return ((Plugin *)handle)->getPreferredBlockSize(); | |
468 } | |
469 | |
470 unsigned int | |
471 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle) | |
472 { | |
473 #ifdef DEBUG_PLUGIN_ADAPTER | |
474 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl; | |
475 #endif | |
476 | |
477 return ((Plugin *)handle)->getMinChannelCount(); | |
478 } | |
479 | |
480 unsigned int | |
481 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle) | |
482 { | |
483 #ifdef DEBUG_PLUGIN_ADAPTER | |
484 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl; | |
485 #endif | |
486 | |
487 return ((Plugin *)handle)->getMaxChannelCount(); | |
488 } | |
489 | |
490 unsigned int | |
491 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle) | |
492 { | |
493 #ifdef DEBUG_PLUGIN_ADAPTER | |
494 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl; | |
495 #endif | |
496 | |
497 Impl *adapter = lookupAdapter(handle); | |
498 | |
499 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl; | |
500 | |
501 if (!adapter) return 0; | |
502 return adapter->getOutputCount((Plugin *)handle); | |
503 } | |
504 | |
505 VampOutputDescriptor * | |
506 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle, | |
507 unsigned int i) | |
508 { | |
509 #ifdef DEBUG_PLUGIN_ADAPTER | |
510 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl; | |
511 #endif | |
512 | |
513 Impl *adapter = lookupAdapter(handle); | |
514 | |
515 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl; | |
516 | |
517 if (!adapter) return 0; | |
518 return adapter->getOutputDescriptor((Plugin *)handle, i); | |
519 } | |
520 | |
521 void | |
522 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc) | |
523 { | |
524 #ifdef DEBUG_PLUGIN_ADAPTER | |
525 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl; | |
526 #endif | |
527 | |
528 if (desc->identifier) free((void *)desc->identifier); | |
529 if (desc->name) free((void *)desc->name); | |
530 if (desc->description) free((void *)desc->description); | |
531 if (desc->unit) free((void *)desc->unit); | |
532 if (desc->hasFixedBinCount && desc->binNames) { | |
533 for (unsigned int i = 0; i < desc->binCount; ++i) { | |
534 if (desc->binNames[i]) { | |
535 free((void *)desc->binNames[i]); | |
536 } | |
537 } | |
538 } | |
539 if (desc->binNames) free((void *)desc->binNames); | |
540 free((void *)desc); | |
541 } | |
542 | |
543 VampFeatureList * | |
544 PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle, | |
545 const float *const *inputBuffers, | |
546 int sec, | |
547 int nsec) | |
548 { | |
549 #ifdef DEBUG_PLUGIN_ADAPTER | |
550 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl; | |
551 #endif | |
552 | |
553 Impl *adapter = lookupAdapter(handle); | |
554 if (!adapter) return 0; | |
555 return adapter->process((Plugin *)handle, | |
556 inputBuffers, sec, nsec); | |
557 } | |
558 | |
559 VampFeatureList * | |
560 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle) | |
561 { | |
562 #ifdef DEBUG_PLUGIN_ADAPTER | |
563 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl; | |
564 #endif | |
565 | |
566 Impl *adapter = lookupAdapter(handle); | |
567 if (!adapter) return 0; | |
568 return adapter->getRemainingFeatures((Plugin *)handle); | |
569 } | |
570 | |
571 void | |
572 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs) | |
573 { | |
574 #ifdef DEBUG_PLUGIN_ADAPTER | |
575 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl; | |
576 #endif | |
577 } | |
578 | |
579 void | |
580 PluginAdapterBase::Impl::cleanup(Plugin *plugin) | |
581 { | |
582 if (m_fs.find(plugin) != m_fs.end()) { | |
583 size_t outputCount = 0; | |
584 if (m_pluginOutputs[plugin]) { | |
585 outputCount = m_pluginOutputs[plugin]->size(); | |
586 } | |
587 VampFeatureList *list = m_fs[plugin]; | |
588 for (unsigned int i = 0; i < outputCount; ++i) { | |
589 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) { | |
590 if (list[i].features[j].v1.label) { | |
591 free(list[i].features[j].v1.label); | |
592 } | |
593 if (list[i].features[j].v1.values) { | |
594 free(list[i].features[j].v1.values); | |
595 } | |
596 } | |
597 if (list[i].features) free(list[i].features); | |
598 } | |
599 m_fs.erase(plugin); | |
600 m_fsizes.erase(plugin); | |
601 m_fvsizes.erase(plugin); | |
602 } | |
603 | |
604 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { | |
605 delete m_pluginOutputs[plugin]; | |
606 m_pluginOutputs.erase(plugin); | |
607 } | |
608 | |
609 if (m_adapterMap) { | |
610 m_adapterMap->erase(plugin); | |
611 | |
612 if (m_adapterMap->empty()) { | |
613 delete m_adapterMap; | |
614 m_adapterMap = 0; | |
615 } | |
616 } | |
617 | |
618 delete ((Plugin *)plugin); | |
619 } | |
620 | |
621 void | |
622 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin) | |
623 { | |
624 if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() || | |
625 !m_pluginOutputs[plugin]) { | |
626 m_pluginOutputs[plugin] = new Plugin::OutputList | |
627 (plugin->getOutputDescriptors()); | |
628 // std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl; | |
629 } | |
630 } | |
631 | |
632 unsigned int | |
633 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin) | |
634 { | |
635 checkOutputMap(plugin); | |
636 return m_pluginOutputs[plugin]->size(); | |
637 } | |
638 | |
639 VampOutputDescriptor * | |
640 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin, | |
641 unsigned int i) | |
642 { | |
643 checkOutputMap(plugin); | |
644 Plugin::OutputDescriptor &od = | |
645 (*m_pluginOutputs[plugin])[i]; | |
646 | |
647 VampOutputDescriptor *desc = (VampOutputDescriptor *) | |
648 malloc(sizeof(VampOutputDescriptor)); | |
649 | |
650 desc->identifier = strdup(od.identifier.c_str()); | |
651 desc->name = strdup(od.name.c_str()); | |
652 desc->description = strdup(od.description.c_str()); | |
653 desc->unit = strdup(od.unit.c_str()); | |
654 desc->hasFixedBinCount = od.hasFixedBinCount; | |
655 desc->binCount = od.binCount; | |
656 | |
657 if (od.hasFixedBinCount && od.binCount > 0) { | |
658 desc->binNames = (const char **) | |
659 malloc(od.binCount * sizeof(const char *)); | |
660 | |
661 for (unsigned int i = 0; i < od.binCount; ++i) { | |
662 if (i < od.binNames.size()) { | |
663 desc->binNames[i] = strdup(od.binNames[i].c_str()); | |
664 } else { | |
665 desc->binNames[i] = 0; | |
666 } | |
667 } | |
668 } else { | |
669 desc->binNames = 0; | |
670 } | |
671 | |
672 desc->hasKnownExtents = od.hasKnownExtents; | |
673 desc->minValue = od.minValue; | |
674 desc->maxValue = od.maxValue; | |
675 desc->isQuantized = od.isQuantized; | |
676 desc->quantizeStep = od.quantizeStep; | |
677 | |
678 switch (od.sampleType) { | |
679 case Plugin::OutputDescriptor::OneSamplePerStep: | |
680 desc->sampleType = vampOneSamplePerStep; break; | |
681 case Plugin::OutputDescriptor::FixedSampleRate: | |
682 desc->sampleType = vampFixedSampleRate; break; | |
683 case Plugin::OutputDescriptor::VariableSampleRate: | |
684 desc->sampleType = vampVariableSampleRate; break; | |
685 } | |
686 | |
687 desc->sampleRate = od.sampleRate; | |
688 desc->hasDuration = od.hasDuration; | |
689 | |
690 return desc; | |
691 } | |
692 | |
693 VampFeatureList * | |
694 PluginAdapterBase::Impl::process(Plugin *plugin, | |
695 const float *const *inputBuffers, | |
696 int sec, int nsec) | |
697 { | |
698 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl; | |
699 RealTime rt(sec, nsec); | |
700 checkOutputMap(plugin); | |
701 return convertFeatures(plugin, plugin->process(inputBuffers, rt)); | |
702 } | |
703 | |
704 VampFeatureList * | |
705 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin) | |
706 { | |
707 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl; | |
708 checkOutputMap(plugin); | |
709 return convertFeatures(plugin, plugin->getRemainingFeatures()); | |
710 } | |
711 | |
712 VampFeatureList * | |
713 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin, | |
714 const Plugin::FeatureSet &features) | |
715 { | |
716 int lastN = -1; | |
717 | |
718 int outputCount = 0; | |
719 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size(); | |
720 | |
721 resizeFS(plugin, outputCount); | |
722 VampFeatureList *fs = m_fs[plugin]; | |
723 | |
724 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: sizeof(Feature) == " << sizeof(Plugin::Feature) << ", sizeof(VampFeature) == " << sizeof(VampFeature) << ", sizeof(VampFeatureList) == " << sizeof(VampFeatureList) << std::endl; | |
725 | |
726 for (Plugin::FeatureSet::const_iterator fi = features.begin(); | |
727 fi != features.end(); ++fi) { | |
728 | |
729 int n = fi->first; | |
730 | |
731 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl; | |
732 | |
733 if (n >= int(outputCount)) { | |
734 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl; | |
735 continue; | |
736 } | |
737 | |
738 if (n > lastN + 1) { | |
739 for (int i = lastN + 1; i < n; ++i) { | |
740 fs[i].featureCount = 0; | |
741 } | |
742 } | |
743 | |
744 const Plugin::FeatureList &fl = fi->second; | |
745 | |
746 size_t sz = fl.size(); | |
747 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz); | |
748 fs[n].featureCount = sz; | |
749 | |
750 for (size_t j = 0; j < sz; ++j) { | |
751 | |
752 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl; | |
753 | |
754 VampFeature *feature = &fs[n].features[j].v1; | |
755 | |
756 feature->hasTimestamp = fl[j].hasTimestamp; | |
757 feature->sec = fl[j].timestamp.sec; | |
758 feature->nsec = fl[j].timestamp.nsec; | |
759 feature->valueCount = fl[j].values.size(); | |
760 | |
761 VampFeatureV2 *v2 = &fs[n].features[j + sz].v2; | |
762 | |
763 v2->hasDuration = fl[j].hasDuration; | |
764 v2->durationSec = fl[j].duration.sec; | |
765 v2->durationNsec = fl[j].duration.nsec; | |
766 | |
767 if (feature->label) free(feature->label); | |
768 | |
769 if (fl[j].label.empty()) { | |
770 feature->label = 0; | |
771 } else { | |
772 feature->label = strdup(fl[j].label.c_str()); | |
773 } | |
774 | |
775 if (feature->valueCount > m_fvsizes[plugin][n][j]) { | |
776 resizeFV(plugin, n, j, feature->valueCount); | |
777 } | |
778 | |
779 for (unsigned int k = 0; k < feature->valueCount; ++k) { | |
780 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl; | |
781 feature->values[k] = fl[j].values[k]; | |
782 } | |
783 } | |
784 | |
785 lastN = n; | |
786 } | |
787 | |
788 if (lastN == -1) return 0; | |
789 | |
790 if (int(outputCount) > lastN + 1) { | |
791 for (int i = lastN + 1; i < int(outputCount); ++i) { | |
792 fs[i].featureCount = 0; | |
793 } | |
794 } | |
795 | |
796 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: have " << outputCount << " outputs" << std::endl; | |
797 // for (int i = 0; i < outputCount; ++i) { | |
798 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: output " << i << " has " << fs[i].featureCount << " features" << std::endl; | |
799 // } | |
800 | |
801 | |
802 return fs; | |
803 } | |
804 | |
805 void | |
806 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n) | |
807 { | |
808 // std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl; | |
809 | |
810 int i = m_fsizes[plugin].size(); | |
811 if (i >= n) return; | |
812 | |
813 // std::cerr << "resizing from " << i << std::endl; | |
814 | |
815 m_fs[plugin] = (VampFeatureList *)realloc | |
816 (m_fs[plugin], n * sizeof(VampFeatureList)); | |
817 | |
818 while (i < n) { | |
819 m_fs[plugin][i].featureCount = 0; | |
820 m_fs[plugin][i].features = 0; | |
821 m_fsizes[plugin].push_back(0); | |
822 m_fvsizes[plugin].push_back(std::vector<size_t>()); | |
823 i++; | |
824 } | |
825 } | |
826 | |
827 void | |
828 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz) | |
829 { | |
830 // std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", " | |
831 // << sz << ")" << std::endl; | |
832 | |
833 size_t i = m_fsizes[plugin][n]; | |
834 if (i >= sz) return; | |
835 | |
836 // std::cerr << "resizing from " << i << std::endl; | |
837 | |
838 m_fs[plugin][n].features = (VampFeatureUnion *)realloc | |
839 (m_fs[plugin][n].features, 2 * sz * sizeof(VampFeatureUnion)); | |
840 | |
841 while (m_fsizes[plugin][n] < sz) { | |
842 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.hasTimestamp = 0; | |
843 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.valueCount = 0; | |
844 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.values = 0; | |
845 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.label = 0; | |
846 m_fs[plugin][n].features[m_fsizes[plugin][n] + sz].v2.hasDuration = 0; | |
847 m_fvsizes[plugin][n].push_back(0); | |
848 m_fsizes[plugin][n]++; | |
849 } | |
850 } | |
851 | |
852 void | |
853 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz) | |
854 { | |
855 // std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", " | |
856 // << j << ", " << sz << ")" << std::endl; | |
857 | |
858 size_t i = m_fvsizes[plugin][n][j]; | |
859 if (i >= sz) return; | |
860 | |
861 // std::cerr << "resizing from " << i << std::endl; | |
862 | |
863 m_fs[plugin][n].features[j].v1.values = (float *)realloc | |
864 (m_fs[plugin][n].features[j].v1.values, sz * sizeof(float)); | |
865 | |
866 m_fvsizes[plugin][n][j] = sz; | |
867 } | |
868 | |
869 PluginAdapterBase::Impl::AdapterMap * | |
870 PluginAdapterBase::Impl::m_adapterMap = 0; | |
871 | |
872 } | |
873 |