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
37 #include "PluginAdapter.h"
39 //#define DEBUG_PLUGIN_ADAPTER 1
44 class PluginAdapterBase::Impl
47 Impl(PluginAdapterBase *);
50 const VampPluginDescriptor *getDescriptor();
53 PluginAdapterBase *m_base;
55 static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc,
56 float inputSampleRate);
58 static void vampCleanup(VampPluginHandle handle);
60 static int vampInitialise(VampPluginHandle handle, unsigned int channels,
61 unsigned int stepSize, unsigned int blockSize);
63 static void vampReset(VampPluginHandle handle);
65 static float vampGetParameter(VampPluginHandle handle, int param);
66 static void vampSetParameter(VampPluginHandle handle, int param, float value);
68 static unsigned int vampGetCurrentProgram(VampPluginHandle handle);
69 static void vampSelectProgram(VampPluginHandle handle, unsigned int program);
71 static unsigned int vampGetPreferredStepSize(VampPluginHandle handle);
72 static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle);
73 static unsigned int vampGetMinChannelCount(VampPluginHandle handle);
74 static unsigned int vampGetMaxChannelCount(VampPluginHandle handle);
76 static unsigned int vampGetOutputCount(VampPluginHandle handle);
78 static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle,
81 static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
83 static VampFeatureList *vampProcess(VampPluginHandle handle,
84 const float *const *inputBuffers,
88 static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle);
90 static void vampReleaseFeatureSet(VampFeatureList *fs);
92 void cleanup(Plugin *plugin);
93 void checkOutputMap(Plugin *plugin);
94 unsigned int getOutputCount(Plugin *plugin);
95 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
97 VampFeatureList *process(Plugin *plugin,
98 const float *const *inputBuffers,
100 VampFeatureList *getRemainingFeatures(Plugin *plugin);
101 VampFeatureList *convertFeatures(Plugin *plugin,
102 const Plugin::FeatureSet &features);
104 // maps both plugins and descriptors to adapters
105 typedef std::map<const void *, Impl *> AdapterMap;
106 static AdapterMap *m_adapterMap;
107 static Impl *lookupAdapter(VampPluginHandle);
110 VampPluginDescriptor m_descriptor;
111 Plugin::ParameterList m_parameters;
112 Plugin::ProgramList m_programs;
114 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap;
115 OutputMap m_pluginOutputs;
117 std::map<Plugin *, VampFeatureList *> m_fs;
118 std::map<Plugin *, std::vector<size_t> > m_fsizes;
119 std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes;
120 void resizeFS(Plugin *plugin, int n);
121 void resizeFL(Plugin *plugin, int n, size_t sz);
122 void resizeFV(Plugin *plugin, int n, int j, size_t sz);
125 PluginAdapterBase::PluginAdapterBase()
127 m_impl = new Impl(this);
130 PluginAdapterBase::~PluginAdapterBase()
135 const VampPluginDescriptor *
136 PluginAdapterBase::getDescriptor()
138 return m_impl->getDescriptor();
141 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) :
145 #ifdef DEBUG_PLUGIN_ADAPTER
146 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl;
150 const VampPluginDescriptor *
151 PluginAdapterBase::Impl::getDescriptor()
153 #ifdef DEBUG_PLUGIN_ADAPTER
154 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl;
157 if (m_populated) return &m_descriptor;
159 Plugin *plugin = m_base->createPlugin(48000);
161 if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
162 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
163 << "Plugin object API version "
164 << plugin->getVampApiVersion()
165 << " does not match actual API version "
166 << VAMP_API_VERSION << std::endl;
171 m_parameters = plugin->getParameterDescriptors();
172 m_programs = plugin->getPrograms();
174 m_descriptor.vampApiVersion = plugin->getVampApiVersion();
175 m_descriptor.identifier = strdup(plugin->getIdentifier().c_str());
176 m_descriptor.name = strdup(plugin->getName().c_str());
177 m_descriptor.description = strdup(plugin->getDescription().c_str());
178 m_descriptor.maker = strdup(plugin->getMaker().c_str());
179 m_descriptor.pluginVersion = plugin->getPluginVersion();
180 m_descriptor.copyright = strdup(plugin->getCopyright().c_str());
182 m_descriptor.parameterCount = m_parameters.size();
183 m_descriptor.parameters = (const VampParameterDescriptor **)
184 malloc(m_parameters.size() * sizeof(VampParameterDescriptor));
188 for (i = 0; i < m_parameters.size(); ++i) {
189 VampParameterDescriptor *desc = (VampParameterDescriptor *)
190 malloc(sizeof(VampParameterDescriptor));
191 desc->identifier = strdup(m_parameters[i].identifier.c_str());
192 desc->name = strdup(m_parameters[i].name.c_str());
193 desc->description = strdup(m_parameters[i].description.c_str());
194 desc->unit = strdup(m_parameters[i].unit.c_str());
195 desc->minValue = m_parameters[i].minValue;
196 desc->maxValue = m_parameters[i].maxValue;
197 desc->defaultValue = m_parameters[i].defaultValue;
198 desc->isQuantized = m_parameters[i].isQuantized;
199 desc->quantizeStep = m_parameters[i].quantizeStep;
200 desc->valueNames = 0;
201 if (desc->isQuantized && !m_parameters[i].valueNames.empty()) {
202 desc->valueNames = (const char **)
203 malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *));
204 for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) {
205 desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str());
207 desc->valueNames[m_parameters[i].valueNames.size()] = 0;
209 m_descriptor.parameters[i] = desc;
212 m_descriptor.programCount = m_programs.size();
213 m_descriptor.programs = (const char **)
214 malloc(m_programs.size() * sizeof(const char *));
216 for (i = 0; i < m_programs.size(); ++i) {
217 m_descriptor.programs[i] = strdup(m_programs[i].c_str());
220 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
221 m_descriptor.inputDomain = vampFrequencyDomain;
223 m_descriptor.inputDomain = vampTimeDomain;
226 m_descriptor.instantiate = vampInstantiate;
227 m_descriptor.cleanup = vampCleanup;
228 m_descriptor.initialise = vampInitialise;
229 m_descriptor.reset = vampReset;
230 m_descriptor.getParameter = vampGetParameter;
231 m_descriptor.setParameter = vampSetParameter;
232 m_descriptor.getCurrentProgram = vampGetCurrentProgram;
233 m_descriptor.selectProgram = vampSelectProgram;
234 m_descriptor.getPreferredStepSize = vampGetPreferredStepSize;
235 m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize;
236 m_descriptor.getMinChannelCount = vampGetMinChannelCount;
237 m_descriptor.getMaxChannelCount = vampGetMaxChannelCount;
238 m_descriptor.getOutputCount = vampGetOutputCount;
239 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor;
240 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
241 m_descriptor.process = vampProcess;
242 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
243 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
246 m_adapterMap = new AdapterMap;
248 (*m_adapterMap)[&m_descriptor] = this;
253 return &m_descriptor;
256 PluginAdapterBase::Impl::~Impl()
258 #ifdef DEBUG_PLUGIN_ADAPTER
259 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl;
262 if (!m_populated) return;
264 free((void *)m_descriptor.identifier);
265 free((void *)m_descriptor.name);
266 free((void *)m_descriptor.description);
267 free((void *)m_descriptor.maker);
268 free((void *)m_descriptor.copyright);
270 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) {
271 const VampParameterDescriptor *desc = m_descriptor.parameters[i];
272 free((void *)desc->identifier);
273 free((void *)desc->name);
274 free((void *)desc->description);
275 free((void *)desc->unit);
276 if (desc->valueNames) {
277 for (unsigned int j = 0; desc->valueNames[j]; ++j) {
278 free((void *)desc->valueNames[j]);
280 free((void *)desc->valueNames);
283 free((void *)m_descriptor.parameters);
285 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
286 free((void *)m_descriptor.programs[i]);
288 free((void *)m_descriptor.programs);
292 m_adapterMap->erase(&m_descriptor);
294 if (m_adapterMap->empty()) {
301 PluginAdapterBase::Impl *
302 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle)
304 #ifdef DEBUG_PLUGIN_ADAPTER
305 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl;
308 if (!m_adapterMap) return 0;
309 AdapterMap::const_iterator i = m_adapterMap->find(handle);
310 if (i == m_adapterMap->end()) return 0;
315 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc,
316 float inputSampleRate)
318 #ifdef DEBUG_PLUGIN_ADAPTER
319 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl;
323 m_adapterMap = new AdapterMap();
326 if (m_adapterMap->find(desc) == m_adapterMap->end()) {
327 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl;
331 Impl *adapter = (*m_adapterMap)[desc];
332 if (desc != &adapter->m_descriptor) return 0;
334 Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate);
336 (*m_adapterMap)[plugin] = adapter;
339 #ifdef DEBUG_PLUGIN_ADAPTER
340 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl;
347 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle)
349 #ifdef DEBUG_PLUGIN_ADAPTER
350 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl;
353 Impl *adapter = lookupAdapter(handle);
355 delete ((Plugin *)handle);
358 adapter->cleanup(((Plugin *)handle));
362 PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle,
363 unsigned int channels,
364 unsigned int stepSize,
365 unsigned int blockSize)
367 #ifdef DEBUG_PLUGIN_ADAPTER
368 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl;
371 bool result = ((Plugin *)handle)->initialise
372 (channels, stepSize, blockSize);
373 return result ? 1 : 0;
377 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle)
379 #ifdef DEBUG_PLUGIN_ADAPTER
380 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl;
383 ((Plugin *)handle)->reset();
387 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle,
390 #ifdef DEBUG_PLUGIN_ADAPTER
391 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl;
394 Impl *adapter = lookupAdapter(handle);
395 if (!adapter) return 0.0;
396 Plugin::ParameterList &list = adapter->m_parameters;
397 return ((Plugin *)handle)->getParameter(list[param].identifier);
401 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle,
402 int param, float value)
404 #ifdef DEBUG_PLUGIN_ADAPTER
405 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl;
408 Impl *adapter = lookupAdapter(handle);
409 if (!adapter) return;
410 Plugin::ParameterList &list = adapter->m_parameters;
411 ((Plugin *)handle)->setParameter(list[param].identifier, value);
415 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle)
417 #ifdef DEBUG_PLUGIN_ADAPTER
418 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl;
421 Impl *adapter = lookupAdapter(handle);
422 if (!adapter) return 0;
423 Plugin::ProgramList &list = adapter->m_programs;
424 std::string program = ((Plugin *)handle)->getCurrentProgram();
425 for (unsigned int i = 0; i < list.size(); ++i) {
426 if (list[i] == program) return i;
432 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle,
433 unsigned int program)
435 #ifdef DEBUG_PLUGIN_ADAPTER
436 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl;
439 Impl *adapter = lookupAdapter(handle);
440 if (!adapter) return;
441 Plugin::ProgramList &list = adapter->m_programs;
442 ((Plugin *)handle)->selectProgram(list[program]);
446 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle)
448 #ifdef DEBUG_PLUGIN_ADAPTER
449 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl;
452 return ((Plugin *)handle)->getPreferredStepSize();
456 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle)
458 #ifdef DEBUG_PLUGIN_ADAPTER
459 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl;
462 return ((Plugin *)handle)->getPreferredBlockSize();
466 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle)
468 #ifdef DEBUG_PLUGIN_ADAPTER
469 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl;
472 return ((Plugin *)handle)->getMinChannelCount();
476 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle)
478 #ifdef DEBUG_PLUGIN_ADAPTER
479 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl;
482 return ((Plugin *)handle)->getMaxChannelCount();
486 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle)
488 #ifdef DEBUG_PLUGIN_ADAPTER
489 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl;
492 Impl *adapter = lookupAdapter(handle);
494 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl;
496 if (!adapter) return 0;
497 return adapter->getOutputCount((Plugin *)handle);
500 VampOutputDescriptor *
501 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle,
504 #ifdef DEBUG_PLUGIN_ADAPTER
505 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl;
508 Impl *adapter = lookupAdapter(handle);
510 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl;
512 if (!adapter) return 0;
513 return adapter->getOutputDescriptor((Plugin *)handle, i);
517 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
519 #ifdef DEBUG_PLUGIN_ADAPTER
520 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl;
523 if (desc->identifier) free((void *)desc->identifier);
524 if (desc->name) free((void *)desc->name);
525 if (desc->description) free((void *)desc->description);
526 if (desc->unit) free((void *)desc->unit);
527 if (desc->hasFixedBinCount && desc->binNames) {
528 for (unsigned int i = 0; i < desc->binCount; ++i) {
529 if (desc->binNames[i]) {
530 free((void *)desc->binNames[i]);
534 if (desc->binNames) free((void *)desc->binNames);
539 PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle,
540 const float *const *inputBuffers,
544 #ifdef DEBUG_PLUGIN_ADAPTER
545 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl;
548 Impl *adapter = lookupAdapter(handle);
549 if (!adapter) return 0;
550 return adapter->process((Plugin *)handle,
551 inputBuffers, sec, nsec);
555 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
557 #ifdef DEBUG_PLUGIN_ADAPTER
558 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl;
561 Impl *adapter = lookupAdapter(handle);
562 if (!adapter) return 0;
563 return adapter->getRemainingFeatures((Plugin *)handle);
567 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
569 #ifdef DEBUG_PLUGIN_ADAPTER
570 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
575 PluginAdapterBase::Impl::cleanup(Plugin *plugin)
577 if (m_fs.find(plugin) != m_fs.end()) {
578 size_t outputCount = 0;
579 if (m_pluginOutputs[plugin]) {
580 outputCount = m_pluginOutputs[plugin]->size();
582 VampFeatureList *list = m_fs[plugin];
583 for (unsigned int i = 0; i < outputCount; ++i) {
584 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
585 if (list[i].features[j].label) {
586 free(list[i].features[j].label);
588 if (list[i].features[j].values) {
589 free(list[i].features[j].values);
592 if (list[i].features) free(list[i].features);
595 m_fsizes.erase(plugin);
596 m_fvsizes.erase(plugin);
599 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
600 delete m_pluginOutputs[plugin];
601 m_pluginOutputs.erase(plugin);
605 m_adapterMap->erase(plugin);
607 if (m_adapterMap->empty()) {
613 delete ((Plugin *)plugin);
617 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin)
619 if (m_pluginOutputs.find(plugin) == m_pluginOutputs.end() ||
620 !m_pluginOutputs[plugin]) {
621 m_pluginOutputs[plugin] = new Plugin::OutputList
622 (plugin->getOutputDescriptors());
623 // std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl;
628 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin)
630 checkOutputMap(plugin);
631 return m_pluginOutputs[plugin]->size();
634 VampOutputDescriptor *
635 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin,
638 checkOutputMap(plugin);
639 Plugin::OutputDescriptor &od =
640 (*m_pluginOutputs[plugin])[i];
642 VampOutputDescriptor *desc = (VampOutputDescriptor *)
643 malloc(sizeof(VampOutputDescriptor));
645 desc->identifier = strdup(od.identifier.c_str());
646 desc->name = strdup(od.name.c_str());
647 desc->description = strdup(od.description.c_str());
648 desc->unit = strdup(od.unit.c_str());
649 desc->hasFixedBinCount = od.hasFixedBinCount;
650 desc->binCount = od.binCount;
652 if (od.hasFixedBinCount && od.binCount > 0) {
653 desc->binNames = (const char **)
654 malloc(od.binCount * sizeof(const char *));
656 for (unsigned int i = 0; i < od.binCount; ++i) {
657 if (i < od.binNames.size()) {
658 desc->binNames[i] = strdup(od.binNames[i].c_str());
660 desc->binNames[i] = 0;
667 desc->hasKnownExtents = od.hasKnownExtents;
668 desc->minValue = od.minValue;
669 desc->maxValue = od.maxValue;
670 desc->isQuantized = od.isQuantized;
671 desc->quantizeStep = od.quantizeStep;
673 switch (od.sampleType) {
674 case Plugin::OutputDescriptor::OneSamplePerStep:
675 desc->sampleType = vampOneSamplePerStep; break;
676 case Plugin::OutputDescriptor::FixedSampleRate:
677 desc->sampleType = vampFixedSampleRate; break;
678 case Plugin::OutputDescriptor::VariableSampleRate:
679 desc->sampleType = vampVariableSampleRate; break;
682 desc->sampleRate = od.sampleRate;
688 PluginAdapterBase::Impl::process(Plugin *plugin,
689 const float *const *inputBuffers,
692 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl;
693 RealTime rt(sec, nsec);
694 checkOutputMap(plugin);
695 return convertFeatures(plugin, plugin->process(inputBuffers, rt));
699 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin)
701 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl;
702 checkOutputMap(plugin);
703 return convertFeatures(plugin, plugin->getRemainingFeatures());
707 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
708 const Plugin::FeatureSet &features)
713 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
715 resizeFS(plugin, outputCount);
716 VampFeatureList *fs = m_fs[plugin];
718 for (Plugin::FeatureSet::const_iterator fi = features.begin();
719 fi != features.end(); ++fi) {
723 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl;
725 if (n >= int(outputCount)) {
726 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl;
731 for (int i = lastN + 1; i < n; ++i) {
732 fs[i].featureCount = 0;
736 const Plugin::FeatureList &fl = fi->second;
738 size_t sz = fl.size();
739 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
740 fs[n].featureCount = sz;
742 for (size_t j = 0; j < sz; ++j) {
744 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl;
746 VampFeature *feature = &fs[n].features[j];
748 feature->hasTimestamp = fl[j].hasTimestamp;
749 feature->sec = fl[j].timestamp.sec;
750 feature->nsec = fl[j].timestamp.nsec;
751 feature->valueCount = fl[j].values.size();
753 if (feature->label) free(feature->label);
755 if (fl[j].label.empty()) {
758 feature->label = strdup(fl[j].label.c_str());
761 if (feature->valueCount > m_fvsizes[plugin][n][j]) {
762 resizeFV(plugin, n, j, feature->valueCount);
765 for (unsigned int k = 0; k < feature->valueCount; ++k) {
766 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl;
767 feature->values[k] = fl[j].values[k];
774 if (lastN == -1) return 0;
776 if (int(outputCount) > lastN + 1) {
777 for (int i = lastN + 1; i < int(outputCount); ++i) {
778 fs[i].featureCount = 0;
786 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
788 // std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
790 int i = m_fsizes[plugin].size();
793 // std::cerr << "resizing from " << i << std::endl;
795 m_fs[plugin] = (VampFeatureList *)realloc
796 (m_fs[plugin], n * sizeof(VampFeatureList));
799 m_fs[plugin][i].featureCount = 0;
800 m_fs[plugin][i].features = 0;
801 m_fsizes[plugin].push_back(0);
802 m_fvsizes[plugin].push_back(std::vector<size_t>());
808 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
810 // std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
811 // << sz << ")" << std::endl;
813 size_t i = m_fsizes[plugin][n];
816 // std::cerr << "resizing from " << i << std::endl;
818 m_fs[plugin][n].features = (VampFeature *)realloc
819 (m_fs[plugin][n].features, sz * sizeof(VampFeature));
821 while (m_fsizes[plugin][n] < sz) {
822 m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0;
823 m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0;
824 m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0;
825 m_fvsizes[plugin][n].push_back(0);
826 m_fsizes[plugin][n]++;
831 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
833 // std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
834 // << j << ", " << sz << ")" << std::endl;
836 size_t i = m_fvsizes[plugin][n][j];
839 // std::cerr << "resizing from " << i << std::endl;
841 m_fs[plugin][n].features[j].values = (float *)realloc
842 (m_fs[plugin][n].features[j].values, sz * sizeof(float));
844 m_fvsizes[plugin][n][j] = sz;
847 PluginAdapterBase::Impl::AdapterMap *
848 PluginAdapterBase::Impl::m_adapterMap = 0;