1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
6 An API for audio analysis and feature extraction plugins.
8 Centre for Digital Music, Queen Mary, University of London.
9 Copyright 2006 Chris Cannam.
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:
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
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.
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
39 #include "PluginAdapter.h"
41 //#define DEBUG_PLUGIN_ADAPTER 1
46 class PluginAdapterBase::Impl
49 Impl(PluginAdapterBase *);
52 const VampPluginDescriptor *getDescriptor();
55 PluginAdapterBase *m_base;
57 static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc,
58 float inputSampleRate);
60 static void vampCleanup(VampPluginHandle handle);
62 static int vampInitialise(VampPluginHandle handle, unsigned int channels,
63 unsigned int stepSize, unsigned int blockSize);
65 static void vampReset(VampPluginHandle handle);
67 static float vampGetParameter(VampPluginHandle handle, int param);
68 static void vampSetParameter(VampPluginHandle handle, int param, float value);
70 static unsigned int vampGetCurrentProgram(VampPluginHandle handle);
71 static void vampSelectProgram(VampPluginHandle handle, unsigned int program);
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);
78 static unsigned int vampGetOutputCount(VampPluginHandle handle);
80 static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle,
83 static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
85 static VampFeatureList *vampProcess(VampPluginHandle handle,
86 const float *const *inputBuffers,
90 static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle);
92 static void vampReleaseFeatureSet(VampFeatureList *fs);
94 void cleanup(Plugin *plugin);
95 void checkOutputMap(Plugin *plugin);
96 unsigned int getOutputCount(Plugin *plugin);
97 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
99 VampFeatureList *process(Plugin *plugin,
100 const float *const *inputBuffers,
102 VampFeatureList *getRemainingFeatures(Plugin *plugin);
103 VampFeatureList *convertFeatures(Plugin *plugin,
104 const Plugin::FeatureSet &features);
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);
112 VampPluginDescriptor m_descriptor;
113 Plugin::ParameterList m_parameters;
114 Plugin::ProgramList m_programs;
116 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap;
117 OutputMap m_pluginOutputs;
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);
127 PluginAdapterBase::PluginAdapterBase()
129 m_impl = new Impl(this);
132 PluginAdapterBase::~PluginAdapterBase()
137 const VampPluginDescriptor *
138 PluginAdapterBase::getDescriptor()
140 return m_impl->getDescriptor();
143 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) :
147 #ifdef DEBUG_PLUGIN_ADAPTER
148 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl;
152 const VampPluginDescriptor *
153 PluginAdapterBase::Impl::getDescriptor()
155 #ifdef DEBUG_PLUGIN_ADAPTER
156 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl;
159 if (m_populated) return &m_descriptor;
161 Plugin *plugin = m_base->createPlugin(48000);
163 if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
164 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
165 << "Plugin object API version "
166 << plugin->getVampApiVersion()
167 << " does not match actual API version "
168 << VAMP_API_VERSION << std::endl;
173 m_parameters = plugin->getParameterDescriptors();
174 m_programs = plugin->getPrograms();
176 m_descriptor.vampApiVersion = plugin->getVampApiVersion();
177 m_descriptor.identifier = strdup(plugin->getIdentifier().c_str());
178 m_descriptor.name = strdup(plugin->getName().c_str());
179 m_descriptor.description = strdup(plugin->getDescription().c_str());
180 m_descriptor.maker = strdup(plugin->getMaker().c_str());
181 m_descriptor.pluginVersion = plugin->getPluginVersion();
182 m_descriptor.copyright = strdup(plugin->getCopyright().c_str());
184 m_descriptor.parameterCount = m_parameters.size();
185 m_descriptor.parameters = (const VampParameterDescriptor **)
186 malloc(m_parameters.size() * sizeof(VampParameterDescriptor));
190 for (i = 0; i < m_parameters.size(); ++i) {
191 VampParameterDescriptor *desc = (VampParameterDescriptor *)
192 malloc(sizeof(VampParameterDescriptor));
193 desc->identifier = strdup(m_parameters[i].identifier.c_str());
194 desc->name = strdup(m_parameters[i].name.c_str());
195 desc->description = strdup(m_parameters[i].description.c_str());
196 desc->unit = strdup(m_parameters[i].unit.c_str());
197 desc->minValue = m_parameters[i].minValue;
198 desc->maxValue = m_parameters[i].maxValue;
199 desc->defaultValue = m_parameters[i].defaultValue;
200 desc->isQuantized = m_parameters[i].isQuantized;
201 desc->quantizeStep = m_parameters[i].quantizeStep;
202 desc->valueNames = 0;
203 if (desc->isQuantized && !m_parameters[i].valueNames.empty()) {
204 desc->valueNames = (const char **)
205 malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *));
206 for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) {
207 desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str());
209 desc->valueNames[m_parameters[i].valueNames.size()] = 0;
211 m_descriptor.parameters[i] = desc;
214 m_descriptor.programCount = m_programs.size();
215 m_descriptor.programs = (const char **)
216 malloc(m_programs.size() * sizeof(const char *));
218 for (i = 0; i < m_programs.size(); ++i) {
219 m_descriptor.programs[i] = strdup(m_programs[i].c_str());
222 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
223 m_descriptor.inputDomain = vampFrequencyDomain;
225 m_descriptor.inputDomain = vampTimeDomain;
228 m_descriptor.instantiate = vampInstantiate;
229 m_descriptor.cleanup = vampCleanup;
230 m_descriptor.initialise = vampInitialise;
231 m_descriptor.reset = vampReset;
232 m_descriptor.getParameter = vampGetParameter;
233 m_descriptor.setParameter = vampSetParameter;
234 m_descriptor.getCurrentProgram = vampGetCurrentProgram;
235 m_descriptor.selectProgram = vampSelectProgram;
236 m_descriptor.getPreferredStepSize = vampGetPreferredStepSize;
237 m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize;
238 m_descriptor.getMinChannelCount = vampGetMinChannelCount;
239 m_descriptor.getMaxChannelCount = vampGetMaxChannelCount;
240 m_descriptor.getOutputCount = vampGetOutputCount;
241 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor;
242 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
243 m_descriptor.process = vampProcess;
244 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
245 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
248 m_adapterMap = new AdapterMap;
250 (*m_adapterMap)[&m_descriptor] = this;
255 return &m_descriptor;
258 PluginAdapterBase::Impl::~Impl()
260 #ifdef DEBUG_PLUGIN_ADAPTER
261 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl;
264 if (!m_populated) return;
266 free((void *)m_descriptor.identifier);
267 free((void *)m_descriptor.name);
268 free((void *)m_descriptor.description);
269 free((void *)m_descriptor.maker);
270 free((void *)m_descriptor.copyright);
272 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) {
273 const VampParameterDescriptor *desc = m_descriptor.parameters[i];
274 free((void *)desc->identifier);
275 free((void *)desc->name);
276 free((void *)desc->description);
277 free((void *)desc->unit);
278 if (desc->valueNames) {
279 for (unsigned int j = 0; desc->valueNames[j]; ++j) {
280 free((void *)desc->valueNames[j]);
282 free((void *)desc->valueNames);
285 free((void *)m_descriptor.parameters);
287 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
288 free((void *)m_descriptor.programs[i]);
290 free((void *)m_descriptor.programs);
294 m_adapterMap->erase(&m_descriptor);
296 if (m_adapterMap->empty()) {
303 PluginAdapterBase::Impl *
304 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle)
306 #ifdef DEBUG_PLUGIN_ADAPTER
307 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl;
310 if (!m_adapterMap) return 0;
311 AdapterMap::const_iterator i = m_adapterMap->find(handle);
312 if (i == m_adapterMap->end()) return 0;
317 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc,
318 float inputSampleRate)
320 #ifdef DEBUG_PLUGIN_ADAPTER
321 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl;
325 m_adapterMap = new AdapterMap();
328 if (m_adapterMap->find(desc) == m_adapterMap->end()) {
329 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl;
333 Impl *adapter = (*m_adapterMap)[desc];
334 if (desc != &adapter->m_descriptor) return 0;
336 Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate);
338 (*m_adapterMap)[plugin] = adapter;
341 #ifdef DEBUG_PLUGIN_ADAPTER
342 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl;
349 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle)
351 #ifdef DEBUG_PLUGIN_ADAPTER
352 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl;
355 Impl *adapter = lookupAdapter(handle);
357 delete ((Plugin *)handle);
360 adapter->cleanup(((Plugin *)handle));
364 PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle,
365 unsigned int channels,
366 unsigned int stepSize,
367 unsigned int blockSize)
369 #ifdef DEBUG_PLUGIN_ADAPTER
370 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl;
373 bool result = ((Plugin *)handle)->initialise
374 (channels, stepSize, blockSize);
375 return result ? 1 : 0;
379 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle)
381 #ifdef DEBUG_PLUGIN_ADAPTER
382 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl;
385 ((Plugin *)handle)->reset();
389 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle,
392 #ifdef DEBUG_PLUGIN_ADAPTER
393 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl;
396 Impl *adapter = lookupAdapter(handle);
397 if (!adapter) return 0.0;
398 Plugin::ParameterList &list = adapter->m_parameters;
399 return ((Plugin *)handle)->getParameter(list[param].identifier);
403 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle,
404 int param, float value)
406 #ifdef DEBUG_PLUGIN_ADAPTER
407 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl;
410 Impl *adapter = lookupAdapter(handle);
411 if (!adapter) return;
412 Plugin::ParameterList &list = adapter->m_parameters;
413 ((Plugin *)handle)->setParameter(list[param].identifier, value);
417 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle)
419 #ifdef DEBUG_PLUGIN_ADAPTER
420 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl;
423 Impl *adapter = lookupAdapter(handle);
424 if (!adapter) return 0;
425 Plugin::ProgramList &list = adapter->m_programs;
426 std::string program = ((Plugin *)handle)->getCurrentProgram();
427 for (unsigned int i = 0; i < list.size(); ++i) {
428 if (list[i] == program) return i;
434 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle,
435 unsigned int program)
437 #ifdef DEBUG_PLUGIN_ADAPTER
438 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl;
441 Impl *adapter = lookupAdapter(handle);
442 if (!adapter) return;
443 Plugin::ProgramList &list = adapter->m_programs;
444 ((Plugin *)handle)->selectProgram(list[program]);
448 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle)
450 #ifdef DEBUG_PLUGIN_ADAPTER
451 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl;
454 return ((Plugin *)handle)->getPreferredStepSize();
458 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle)
460 #ifdef DEBUG_PLUGIN_ADAPTER
461 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl;
464 return ((Plugin *)handle)->getPreferredBlockSize();
468 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle)
470 #ifdef DEBUG_PLUGIN_ADAPTER
471 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl;
474 return ((Plugin *)handle)->getMinChannelCount();
478 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle)
480 #ifdef DEBUG_PLUGIN_ADAPTER
481 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl;
484 return ((Plugin *)handle)->getMaxChannelCount();
488 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle)
490 #ifdef DEBUG_PLUGIN_ADAPTER
491 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl;
494 Impl *adapter = lookupAdapter(handle);
496 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl;
498 if (!adapter) return 0;
499 return adapter->getOutputCount((Plugin *)handle);
502 VampOutputDescriptor *
503 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle,
506 #ifdef DEBUG_PLUGIN_ADAPTER
507 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl;
510 Impl *adapter = lookupAdapter(handle);
512 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl;
514 if (!adapter) return 0;
515 return adapter->getOutputDescriptor((Plugin *)handle, i);
519 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
521 #ifdef DEBUG_PLUGIN_ADAPTER
522 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl;
525 if (desc->identifier) free((void *)desc->identifier);
526 if (desc->name) free((void *)desc->name);
527 if (desc->description) free((void *)desc->description);
528 if (desc->unit) free((void *)desc->unit);
529 if (desc->hasFixedBinCount && desc->binNames) {
530 for (unsigned int i = 0; i < desc->binCount; ++i) {
531 if (desc->binNames[i]) {
532 free((void *)desc->binNames[i]);
536 if (desc->binNames) free((void *)desc->binNames);
541 PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle,
542 const float *const *inputBuffers,
546 #ifdef DEBUG_PLUGIN_ADAPTER
547 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl;
550 Impl *adapter = lookupAdapter(handle);
551 if (!adapter) return 0;
552 return adapter->process((Plugin *)handle,
553 inputBuffers, sec, nsec);
557 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
559 #ifdef DEBUG_PLUGIN_ADAPTER
560 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl;
563 Impl *adapter = lookupAdapter(handle);
564 if (!adapter) return 0;
565 return adapter->getRemainingFeatures((Plugin *)handle);
569 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
571 #ifdef DEBUG_PLUGIN_ADAPTER
572 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
577 PluginAdapterBase::Impl::cleanup(Plugin *plugin)
579 if (m_fs.find(plugin) != m_fs.end()) {
580 size_t outputCount = 0;
581 if (m_pluginOutputs[plugin]) {
582 outputCount = m_pluginOutputs[plugin]->size();
584 VampFeatureList *list = m_fs[plugin];
585 for (unsigned int i = 0; i < outputCount; ++i) {
586 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
587 if (list[i].features[j].label) {
588 free(list[i].features[j].label);
590 if (list[i].features[j].values) {
591 free(list[i].features[j].values);
594 if (list[i].features) free(list[i].features);
597 m_fsizes.erase(plugin);
598 m_fvsizes.erase(plugin);
601 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
602 delete m_pluginOutputs[plugin];
603 m_pluginOutputs.erase(plugin);
607 m_adapterMap->erase(plugin);
609 if (m_adapterMap->empty()) {
615 delete ((Plugin *)plugin);
619 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin)
621 if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() ||
622 !m_pluginOutputs[plugin]) {
623 m_pluginOutputs[plugin] = new Plugin::OutputList
624 (plugin->getOutputDescriptors());
625 // std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl;
630 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin)
632 checkOutputMap(plugin);
633 return m_pluginOutputs[plugin]->size();
636 VampOutputDescriptor *
637 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin,
640 checkOutputMap(plugin);
641 Plugin::OutputDescriptor &od =
642 (*m_pluginOutputs[plugin])[i];
644 VampOutputDescriptor *desc = (VampOutputDescriptor *)
645 malloc(sizeof(VampOutputDescriptor));
647 desc->identifier = strdup(od.identifier.c_str());
648 desc->name = strdup(od.name.c_str());
649 desc->description = strdup(od.description.c_str());
650 desc->unit = strdup(od.unit.c_str());
651 desc->hasFixedBinCount = od.hasFixedBinCount;
652 desc->binCount = od.binCount;
654 if (od.hasFixedBinCount && od.binCount > 0) {
655 desc->binNames = (const char **)
656 malloc(od.binCount * sizeof(const char *));
658 for (unsigned int i = 0; i < od.binCount; ++i) {
659 if (i < od.binNames.size()) {
660 desc->binNames[i] = strdup(od.binNames[i].c_str());
662 desc->binNames[i] = 0;
669 desc->hasKnownExtents = od.hasKnownExtents;
670 desc->minValue = od.minValue;
671 desc->maxValue = od.maxValue;
672 desc->isQuantized = od.isQuantized;
673 desc->quantizeStep = od.quantizeStep;
675 switch (od.sampleType) {
676 case Plugin::OutputDescriptor::OneSamplePerStep:
677 desc->sampleType = vampOneSamplePerStep; break;
678 case Plugin::OutputDescriptor::FixedSampleRate:
679 desc->sampleType = vampFixedSampleRate; break;
680 case Plugin::OutputDescriptor::VariableSampleRate:
681 desc->sampleType = vampVariableSampleRate; break;
684 desc->sampleRate = od.sampleRate;
690 PluginAdapterBase::Impl::process(Plugin *plugin,
691 const float *const *inputBuffers,
694 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl;
695 RealTime rt(sec, nsec);
696 checkOutputMap(plugin);
697 return convertFeatures(plugin, plugin->process(inputBuffers, rt));
701 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin)
703 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl;
704 checkOutputMap(plugin);
705 return convertFeatures(plugin, plugin->getRemainingFeatures());
709 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
710 const Plugin::FeatureSet &features)
715 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
717 resizeFS(plugin, outputCount);
718 VampFeatureList *fs = m_fs[plugin];
720 for (Plugin::FeatureSet::const_iterator fi = features.begin();
721 fi != features.end(); ++fi) {
725 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl;
727 if (n >= int(outputCount)) {
728 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl;
733 for (int i = lastN + 1; i < n; ++i) {
734 fs[i].featureCount = 0;
738 const Plugin::FeatureList &fl = fi->second;
740 size_t sz = fl.size();
741 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
742 fs[n].featureCount = sz;
744 for (size_t j = 0; j < sz; ++j) {
746 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl;
748 VampFeature *feature = &fs[n].features[j];
750 feature->hasTimestamp = fl[j].hasTimestamp;
751 feature->sec = fl[j].timestamp.sec;
752 feature->nsec = fl[j].timestamp.nsec;
753 feature->valueCount = fl[j].values.size();
755 if (feature->label) free(feature->label);
757 if (fl[j].label.empty()) {
760 feature->label = strdup(fl[j].label.c_str());
763 if (feature->valueCount > m_fvsizes[plugin][n][j]) {
764 resizeFV(plugin, n, j, feature->valueCount);
767 for (unsigned int k = 0; k < feature->valueCount; ++k) {
768 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl;
769 feature->values[k] = fl[j].values[k];
776 if (lastN == -1) return 0;
778 if (int(outputCount) > lastN + 1) {
779 for (int i = lastN + 1; i < int(outputCount); ++i) {
780 fs[i].featureCount = 0;
788 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
790 // std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
792 int i = m_fsizes[plugin].size();
795 // std::cerr << "resizing from " << i << std::endl;
797 m_fs[plugin] = (VampFeatureList *)realloc
798 (m_fs[plugin], n * sizeof(VampFeatureList));
801 m_fs[plugin][i].featureCount = 0;
802 m_fs[plugin][i].features = 0;
803 m_fsizes[plugin].push_back(0);
804 m_fvsizes[plugin].push_back(std::vector<size_t>());
810 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
812 // std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
813 // << sz << ")" << std::endl;
815 size_t i = m_fsizes[plugin][n];
818 // std::cerr << "resizing from " << i << std::endl;
820 m_fs[plugin][n].features = (VampFeature *)realloc
821 (m_fs[plugin][n].features, sz * sizeof(VampFeature));
823 while (m_fsizes[plugin][n] < sz) {
824 m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0;
825 m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0;
826 m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0;
827 m_fvsizes[plugin][n].push_back(0);
828 m_fsizes[plugin][n]++;
833 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
835 // std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
836 // << j << ", " << sz << ")" << std::endl;
838 size_t i = m_fvsizes[plugin][n][j];
841 // std::cerr << "resizing from " << i << std::endl;
843 m_fs[plugin][n].features[j].values = (float *)realloc
844 (m_fs[plugin][n].features[j].values, sz * sizeof(float));
846 m_fvsizes[plugin][n][j] = sz;
849 PluginAdapterBase::Impl::AdapterMap *
850 PluginAdapterBase::Impl::m_adapterMap = 0;