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"
44 //#define DEBUG_PLUGIN_ADAPTER 1
49 class PluginAdapterBase::Impl
52 Impl(PluginAdapterBase *);
55 const VampPluginDescriptor *getDescriptor();
58 PluginAdapterBase *m_base;
60 static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc,
61 float inputSampleRate);
63 static void vampCleanup(VampPluginHandle handle);
65 static int vampInitialise(VampPluginHandle handle, unsigned int channels,
66 unsigned int stepSize, unsigned int blockSize);
68 static void vampReset(VampPluginHandle handle);
70 static float vampGetParameter(VampPluginHandle handle, int param);
71 static void vampSetParameter(VampPluginHandle handle, int param, float value);
73 static unsigned int vampGetCurrentProgram(VampPluginHandle handle);
74 static void vampSelectProgram(VampPluginHandle handle, unsigned int program);
76 static unsigned int vampGetPreferredStepSize(VampPluginHandle handle);
77 static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle);
78 static unsigned int vampGetMinChannelCount(VampPluginHandle handle);
79 static unsigned int vampGetMaxChannelCount(VampPluginHandle handle);
81 static unsigned int vampGetOutputCount(VampPluginHandle handle);
83 static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle,
86 static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
88 static VampFeatureList *vampProcess(VampPluginHandle handle,
89 const float *const *inputBuffers,
93 static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle);
95 static void vampReleaseFeatureSet(VampFeatureList *fs);
97 void cleanup(Plugin *plugin);
98 void checkOutputMap(Plugin *plugin);
99 unsigned int getOutputCount(Plugin *plugin);
100 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
102 VampFeatureList *process(Plugin *plugin,
103 const float *const *inputBuffers,
105 VampFeatureList *getRemainingFeatures(Plugin *plugin);
106 VampFeatureList *convertFeatures(Plugin *plugin,
107 const Plugin::FeatureSet &features);
109 // maps both plugins and descriptors to adapters
110 typedef std::map<const void *, Impl *> AdapterMap;
111 static AdapterMap *m_adapterMap;
112 static Impl *lookupAdapter(VampPluginHandle);
115 VampPluginDescriptor m_descriptor;
116 Plugin::ParameterList m_parameters;
117 Plugin::ProgramList m_programs;
119 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap;
120 OutputMap m_pluginOutputs;
122 std::map<Plugin *, VampFeatureList *> m_fs;
123 std::map<Plugin *, std::vector<size_t> > m_fsizes;
124 std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes;
125 void resizeFS(Plugin *plugin, int n);
126 void resizeFL(Plugin *plugin, int n, size_t sz);
127 void resizeFV(Plugin *plugin, int n, int j, size_t sz);
130 PluginAdapterBase::PluginAdapterBase()
132 m_impl = new Impl(this);
135 PluginAdapterBase::~PluginAdapterBase()
140 const VampPluginDescriptor *
141 PluginAdapterBase::getDescriptor()
143 return m_impl->getDescriptor();
146 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) :
150 #ifdef DEBUG_PLUGIN_ADAPTER
151 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl;
155 const VampPluginDescriptor *
156 PluginAdapterBase::Impl::getDescriptor()
158 #ifdef DEBUG_PLUGIN_ADAPTER
159 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl;
162 if (m_populated) return &m_descriptor;
164 Plugin *plugin = m_base->createPlugin(48000);
166 if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
167 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
168 << "Plugin object API version "
169 << plugin->getVampApiVersion()
170 << " does not match actual API version "
171 << VAMP_API_VERSION << std::endl;
176 m_parameters = plugin->getParameterDescriptors();
177 m_programs = plugin->getPrograms();
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());
187 m_descriptor.parameterCount = m_parameters.size();
188 m_descriptor.parameters = (const VampParameterDescriptor **)
189 malloc(m_parameters.size() * sizeof(VampParameterDescriptor));
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());
212 desc->valueNames[m_parameters[i].valueNames.size()] = 0;
214 m_descriptor.parameters[i] = desc;
217 m_descriptor.programCount = m_programs.size();
218 m_descriptor.programs = (const char **)
219 malloc(m_programs.size() * sizeof(const char *));
221 for (i = 0; i < m_programs.size(); ++i) {
222 m_descriptor.programs[i] = strdup(m_programs[i].c_str());
225 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
226 m_descriptor.inputDomain = vampFrequencyDomain;
228 m_descriptor.inputDomain = vampTimeDomain;
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;
251 m_adapterMap = new AdapterMap;
253 (*m_adapterMap)[&m_descriptor] = this;
258 return &m_descriptor;
261 PluginAdapterBase::Impl::~Impl()
263 #ifdef DEBUG_PLUGIN_ADAPTER
264 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl;
267 if (!m_populated) return;
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);
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]);
285 free((void *)desc->valueNames);
288 free((void *)m_descriptor.parameters);
290 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
291 free((void *)m_descriptor.programs[i]);
293 free((void *)m_descriptor.programs);
297 m_adapterMap->erase(&m_descriptor);
299 if (m_adapterMap->empty()) {
306 PluginAdapterBase::Impl *
307 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle)
309 #ifdef DEBUG_PLUGIN_ADAPTER
310 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl;
313 if (!m_adapterMap) return 0;
314 AdapterMap::const_iterator i = m_adapterMap->find(handle);
315 if (i == m_adapterMap->end()) return 0;
320 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc,
321 float inputSampleRate)
323 #ifdef DEBUG_PLUGIN_ADAPTER
324 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl;
328 m_adapterMap = new AdapterMap();
331 if (m_adapterMap->find(desc) == m_adapterMap->end()) {
332 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl;
336 Impl *adapter = (*m_adapterMap)[desc];
337 if (desc != &adapter->m_descriptor) return 0;
339 Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate);
341 (*m_adapterMap)[plugin] = adapter;
344 #ifdef DEBUG_PLUGIN_ADAPTER
345 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl;
352 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle)
354 #ifdef DEBUG_PLUGIN_ADAPTER
355 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl;
358 Impl *adapter = lookupAdapter(handle);
360 delete ((Plugin *)handle);
363 adapter->cleanup(((Plugin *)handle));
367 PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle,
368 unsigned int channels,
369 unsigned int stepSize,
370 unsigned int blockSize)
372 #ifdef DEBUG_PLUGIN_ADAPTER
373 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl;
376 bool result = ((Plugin *)handle)->initialise
377 (channels, stepSize, blockSize);
378 return result ? 1 : 0;
382 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle)
384 #ifdef DEBUG_PLUGIN_ADAPTER
385 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl;
388 ((Plugin *)handle)->reset();
392 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle,
395 #ifdef DEBUG_PLUGIN_ADAPTER
396 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl;
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);
406 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle,
407 int param, float value)
409 #ifdef DEBUG_PLUGIN_ADAPTER
410 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl;
413 Impl *adapter = lookupAdapter(handle);
414 if (!adapter) return;
415 Plugin::ParameterList &list = adapter->m_parameters;
416 ((Plugin *)handle)->setParameter(list[param].identifier, value);
420 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle)
422 #ifdef DEBUG_PLUGIN_ADAPTER
423 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl;
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;
437 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle,
438 unsigned int program)
440 #ifdef DEBUG_PLUGIN_ADAPTER
441 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl;
444 Impl *adapter = lookupAdapter(handle);
445 if (!adapter) return;
446 Plugin::ProgramList &list = adapter->m_programs;
447 ((Plugin *)handle)->selectProgram(list[program]);
451 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle)
453 #ifdef DEBUG_PLUGIN_ADAPTER
454 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl;
457 return ((Plugin *)handle)->getPreferredStepSize();
461 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle)
463 #ifdef DEBUG_PLUGIN_ADAPTER
464 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl;
467 return ((Plugin *)handle)->getPreferredBlockSize();
471 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle)
473 #ifdef DEBUG_PLUGIN_ADAPTER
474 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl;
477 return ((Plugin *)handle)->getMinChannelCount();
481 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle)
483 #ifdef DEBUG_PLUGIN_ADAPTER
484 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl;
487 return ((Plugin *)handle)->getMaxChannelCount();
491 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle)
493 #ifdef DEBUG_PLUGIN_ADAPTER
494 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl;
497 Impl *adapter = lookupAdapter(handle);
499 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl;
501 if (!adapter) return 0;
502 return adapter->getOutputCount((Plugin *)handle);
505 VampOutputDescriptor *
506 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle,
509 #ifdef DEBUG_PLUGIN_ADAPTER
510 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl;
513 Impl *adapter = lookupAdapter(handle);
515 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl;
517 if (!adapter) return 0;
518 return adapter->getOutputDescriptor((Plugin *)handle, i);
522 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
524 #ifdef DEBUG_PLUGIN_ADAPTER
525 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl;
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]);
539 if (desc->binNames) free((void *)desc->binNames);
544 PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle,
545 const float *const *inputBuffers,
549 #ifdef DEBUG_PLUGIN_ADAPTER
550 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl;
553 Impl *adapter = lookupAdapter(handle);
554 if (!adapter) return 0;
555 return adapter->process((Plugin *)handle,
556 inputBuffers, sec, nsec);
560 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
562 #ifdef DEBUG_PLUGIN_ADAPTER
563 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl;
566 Impl *adapter = lookupAdapter(handle);
567 if (!adapter) return 0;
568 return adapter->getRemainingFeatures((Plugin *)handle);
572 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *fs)
574 #ifdef DEBUG_PLUGIN_ADAPTER
575 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
580 PluginAdapterBase::Impl::cleanup(Plugin *plugin)
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();
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].label) {
591 free(list[i].features[j].label);
593 if (list[i].features[j].values) {
594 free(list[i].features[j].values);
597 if (list[i].features) free(list[i].features);
600 m_fsizes.erase(plugin);
601 m_fvsizes.erase(plugin);
604 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
605 delete m_pluginOutputs[plugin];
606 m_pluginOutputs.erase(plugin);
610 m_adapterMap->erase(plugin);
612 if (m_adapterMap->empty()) {
618 delete ((Plugin *)plugin);
622 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin)
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;
633 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin)
635 checkOutputMap(plugin);
636 return m_pluginOutputs[plugin]->size();
639 VampOutputDescriptor *
640 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin,
643 checkOutputMap(plugin);
644 Plugin::OutputDescriptor &od =
645 (*m_pluginOutputs[plugin])[i];
647 VampOutputDescriptor *desc = (VampOutputDescriptor *)
648 malloc(sizeof(VampOutputDescriptor));
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;
657 if (od.hasFixedBinCount && od.binCount > 0) {
658 desc->binNames = (const char **)
659 malloc(od.binCount * sizeof(const char *));
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());
665 desc->binNames[i] = 0;
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;
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;
687 desc->sampleRate = od.sampleRate;
693 PluginAdapterBase::Impl::process(Plugin *plugin,
694 const float *const *inputBuffers,
697 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl;
698 RealTime rt(sec, nsec);
699 checkOutputMap(plugin);
700 return convertFeatures(plugin, plugin->process(inputBuffers, rt));
704 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin)
706 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl;
707 checkOutputMap(plugin);
708 return convertFeatures(plugin, plugin->getRemainingFeatures());
712 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
713 const Plugin::FeatureSet &features)
718 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
720 resizeFS(plugin, outputCount);
721 VampFeatureList *fs = m_fs[plugin];
723 for (Plugin::FeatureSet::const_iterator fi = features.begin();
724 fi != features.end(); ++fi) {
728 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl;
730 if (n >= int(outputCount)) {
731 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl;
736 for (int i = lastN + 1; i < n; ++i) {
737 fs[i].featureCount = 0;
741 const Plugin::FeatureList &fl = fi->second;
743 size_t sz = fl.size();
744 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
745 fs[n].featureCount = sz;
747 for (size_t j = 0; j < sz; ++j) {
749 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl;
751 VampFeature *feature = &fs[n].features[j];
753 feature->hasTimestamp = fl[j].hasTimestamp;
754 feature->sec = fl[j].timestamp.sec;
755 feature->nsec = fl[j].timestamp.nsec;
756 feature->valueCount = fl[j].values.size();
758 if (feature->label) free(feature->label);
760 if (fl[j].label.empty()) {
763 feature->label = strdup(fl[j].label.c_str());
766 if (feature->valueCount > m_fvsizes[plugin][n][j]) {
767 resizeFV(plugin, n, j, feature->valueCount);
770 for (unsigned int k = 0; k < feature->valueCount; ++k) {
771 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl;
772 feature->values[k] = fl[j].values[k];
779 if (lastN == -1) return 0;
781 if (int(outputCount) > lastN + 1) {
782 for (int i = lastN + 1; i < int(outputCount); ++i) {
783 fs[i].featureCount = 0;
791 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
793 // std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
795 int i = m_fsizes[plugin].size();
798 // std::cerr << "resizing from " << i << std::endl;
800 m_fs[plugin] = (VampFeatureList *)realloc
801 (m_fs[plugin], n * sizeof(VampFeatureList));
804 m_fs[plugin][i].featureCount = 0;
805 m_fs[plugin][i].features = 0;
806 m_fsizes[plugin].push_back(0);
807 m_fvsizes[plugin].push_back(std::vector<size_t>());
813 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
815 // std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
816 // << sz << ")" << std::endl;
818 size_t i = m_fsizes[plugin][n];
821 // std::cerr << "resizing from " << i << std::endl;
823 m_fs[plugin][n].features = (VampFeature *)realloc
824 (m_fs[plugin][n].features, sz * sizeof(VampFeature));
826 while (m_fsizes[plugin][n] < sz) {
827 m_fs[plugin][n].features[m_fsizes[plugin][n]].valueCount = 0;
828 m_fs[plugin][n].features[m_fsizes[plugin][n]].values = 0;
829 m_fs[plugin][n].features[m_fsizes[plugin][n]].label = 0;
830 m_fvsizes[plugin][n].push_back(0);
831 m_fsizes[plugin][n]++;
836 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
838 // std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
839 // << j << ", " << sz << ")" << std::endl;
841 size_t i = m_fvsizes[plugin][n][j];
844 // std::cerr << "resizing from " << i << std::endl;
846 m_fs[plugin][n].features[j].values = (float *)realloc
847 (m_fs[plugin][n].features[j].values, sz * sizeof(float));
849 m_fvsizes[plugin][n][j] = sz;
852 PluginAdapterBase::Impl::AdapterMap *
853 PluginAdapterBase::Impl::m_adapterMap = 0;