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