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 "vamp-sdk/PluginAdapter.h"
42 #if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 2 )
43 #error Unexpected version of Vamp SDK header included
47 //#define DEBUG_PLUGIN_ADAPTER 1
49 _VAMP_SDK_PLUGSPACE_BEGIN(PluginAdapter.cpp)
53 class PluginAdapterBase::Impl
56 Impl(PluginAdapterBase *);
59 const VampPluginDescriptor *getDescriptor();
62 PluginAdapterBase *m_base;
64 static VampPluginHandle vampInstantiate(const VampPluginDescriptor *desc,
65 float inputSampleRate);
67 static void vampCleanup(VampPluginHandle handle);
69 static int vampInitialise(VampPluginHandle handle, unsigned int channels,
70 unsigned int stepSize, unsigned int blockSize);
72 static void vampReset(VampPluginHandle handle);
74 static float vampGetParameter(VampPluginHandle handle, int param);
75 static void vampSetParameter(VampPluginHandle handle, int param, float value);
77 static unsigned int vampGetCurrentProgram(VampPluginHandle handle);
78 static void vampSelectProgram(VampPluginHandle handle, unsigned int program);
80 static unsigned int vampGetPreferredStepSize(VampPluginHandle handle);
81 static unsigned int vampGetPreferredBlockSize(VampPluginHandle handle);
82 static unsigned int vampGetMinChannelCount(VampPluginHandle handle);
83 static unsigned int vampGetMaxChannelCount(VampPluginHandle handle);
85 static unsigned int vampGetOutputCount(VampPluginHandle handle);
87 static VampOutputDescriptor *vampGetOutputDescriptor(VampPluginHandle handle,
90 static void vampReleaseOutputDescriptor(VampOutputDescriptor *desc);
92 static VampFeatureList *vampProcess(VampPluginHandle handle,
93 const float *const *inputBuffers,
97 static VampFeatureList *vampGetRemainingFeatures(VampPluginHandle handle);
99 static void vampReleaseFeatureSet(VampFeatureList *fs);
101 void checkOutputMap(Plugin *plugin);
102 void markOutputsChanged(Plugin *plugin);
104 void cleanup(Plugin *plugin);
105 unsigned int getOutputCount(Plugin *plugin);
106 VampOutputDescriptor *getOutputDescriptor(Plugin *plugin,
108 VampFeatureList *process(Plugin *plugin,
109 const float *const *inputBuffers,
111 VampFeatureList *getRemainingFeatures(Plugin *plugin);
112 VampFeatureList *convertFeatures(Plugin *plugin,
113 const Plugin::FeatureSet &features);
115 // maps both plugins and descriptors to adapters
116 typedef std::map<const void *, Impl *> AdapterMap;
117 static AdapterMap *m_adapterMap;
118 static Impl *lookupAdapter(VampPluginHandle);
121 VampPluginDescriptor m_descriptor;
122 Plugin::ParameterList m_parameters;
123 Plugin::ProgramList m_programs;
125 typedef std::map<Plugin *, Plugin::OutputList *> OutputMap;
126 OutputMap m_pluginOutputs;
128 std::map<Plugin *, VampFeatureList *> m_fs;
129 std::map<Plugin *, std::vector<size_t> > m_fsizes;
130 std::map<Plugin *, std::vector<std::vector<size_t> > > m_fvsizes;
131 void resizeFS(Plugin *plugin, int n);
132 void resizeFL(Plugin *plugin, int n, size_t sz);
133 void resizeFV(Plugin *plugin, int n, int j, size_t sz);
136 PluginAdapterBase::PluginAdapterBase()
138 m_impl = new Impl(this);
141 PluginAdapterBase::~PluginAdapterBase()
146 const VampPluginDescriptor *
147 PluginAdapterBase::getDescriptor()
149 return m_impl->getDescriptor();
152 PluginAdapterBase::Impl::Impl(PluginAdapterBase *base) :
156 #ifdef DEBUG_PLUGIN_ADAPTER
157 std::cerr << "PluginAdapterBase::Impl[" << this << "]::Impl" << std::endl;
161 const VampPluginDescriptor *
162 PluginAdapterBase::Impl::getDescriptor()
164 #ifdef DEBUG_PLUGIN_ADAPTER
165 std::cerr << "PluginAdapterBase::Impl[" << this << "]::getDescriptor" << std::endl;
168 if (m_populated) return &m_descriptor;
170 Plugin *plugin = m_base->createPlugin(48000);
173 std::cerr << "PluginAdapterBase::Impl::getDescriptor: Failed to create plugin" << std::endl;
177 if (plugin->getVampApiVersion() != VAMP_API_VERSION) {
178 std::cerr << "Vamp::PluginAdapterBase::Impl::getDescriptor: ERROR: "
179 << "API version " << plugin->getVampApiVersion()
180 << " for\nplugin \"" << plugin->getIdentifier() << "\" "
181 << "differs from version "
182 << VAMP_API_VERSION << " for adapter.\n"
183 << "This plugin is probably linked against a different version of the Vamp SDK\n"
184 << "from the version it was compiled with. It will need to be re-linked correctly\n"
185 << "before it can be used." << std::endl;
190 m_parameters = plugin->getParameterDescriptors();
191 m_programs = plugin->getPrograms();
193 m_descriptor.vampApiVersion = plugin->getVampApiVersion();
194 m_descriptor.identifier = strdup(plugin->getIdentifier().c_str());
195 m_descriptor.name = strdup(plugin->getName().c_str());
196 m_descriptor.description = strdup(plugin->getDescription().c_str());
197 m_descriptor.maker = strdup(plugin->getMaker().c_str());
198 m_descriptor.pluginVersion = plugin->getPluginVersion();
199 m_descriptor.copyright = strdup(plugin->getCopyright().c_str());
201 m_descriptor.parameterCount = m_parameters.size();
202 m_descriptor.parameters = (const VampParameterDescriptor **)
203 malloc(m_parameters.size() * sizeof(VampParameterDescriptor));
207 for (i = 0; i < m_parameters.size(); ++i) {
208 VampParameterDescriptor *desc = (VampParameterDescriptor *)
209 malloc(sizeof(VampParameterDescriptor));
210 desc->identifier = strdup(m_parameters[i].identifier.c_str());
211 desc->name = strdup(m_parameters[i].name.c_str());
212 desc->description = strdup(m_parameters[i].description.c_str());
213 desc->unit = strdup(m_parameters[i].unit.c_str());
214 desc->minValue = m_parameters[i].minValue;
215 desc->maxValue = m_parameters[i].maxValue;
216 desc->defaultValue = m_parameters[i].defaultValue;
217 desc->isQuantized = m_parameters[i].isQuantized;
218 desc->quantizeStep = m_parameters[i].quantizeStep;
219 desc->valueNames = 0;
220 if (desc->isQuantized && !m_parameters[i].valueNames.empty()) {
221 desc->valueNames = (const char **)
222 malloc((m_parameters[i].valueNames.size()+1) * sizeof(char *));
223 for (unsigned int j = 0; j < m_parameters[i].valueNames.size(); ++j) {
224 desc->valueNames[j] = strdup(m_parameters[i].valueNames[j].c_str());
226 desc->valueNames[m_parameters[i].valueNames.size()] = 0;
228 m_descriptor.parameters[i] = desc;
231 m_descriptor.programCount = m_programs.size();
232 m_descriptor.programs = (const char **)
233 malloc(m_programs.size() * sizeof(const char *));
235 for (i = 0; i < m_programs.size(); ++i) {
236 m_descriptor.programs[i] = strdup(m_programs[i].c_str());
239 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
240 m_descriptor.inputDomain = vampFrequencyDomain;
242 m_descriptor.inputDomain = vampTimeDomain;
245 m_descriptor.instantiate = vampInstantiate;
246 m_descriptor.cleanup = vampCleanup;
247 m_descriptor.initialise = vampInitialise;
248 m_descriptor.reset = vampReset;
249 m_descriptor.getParameter = vampGetParameter;
250 m_descriptor.setParameter = vampSetParameter;
251 m_descriptor.getCurrentProgram = vampGetCurrentProgram;
252 m_descriptor.selectProgram = vampSelectProgram;
253 m_descriptor.getPreferredStepSize = vampGetPreferredStepSize;
254 m_descriptor.getPreferredBlockSize = vampGetPreferredBlockSize;
255 m_descriptor.getMinChannelCount = vampGetMinChannelCount;
256 m_descriptor.getMaxChannelCount = vampGetMaxChannelCount;
257 m_descriptor.getOutputCount = vampGetOutputCount;
258 m_descriptor.getOutputDescriptor = vampGetOutputDescriptor;
259 m_descriptor.releaseOutputDescriptor = vampReleaseOutputDescriptor;
260 m_descriptor.process = vampProcess;
261 m_descriptor.getRemainingFeatures = vampGetRemainingFeatures;
262 m_descriptor.releaseFeatureSet = vampReleaseFeatureSet;
265 m_adapterMap = new AdapterMap;
267 (*m_adapterMap)[&m_descriptor] = this;
272 return &m_descriptor;
275 PluginAdapterBase::Impl::~Impl()
277 #ifdef DEBUG_PLUGIN_ADAPTER
278 std::cerr << "PluginAdapterBase::Impl[" << this << "]::~Impl" << std::endl;
281 if (!m_populated) return;
283 free((void *)m_descriptor.identifier);
284 free((void *)m_descriptor.name);
285 free((void *)m_descriptor.description);
286 free((void *)m_descriptor.maker);
287 free((void *)m_descriptor.copyright);
289 for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) {
290 const VampParameterDescriptor *desc = m_descriptor.parameters[i];
291 free((void *)desc->identifier);
292 free((void *)desc->name);
293 free((void *)desc->description);
294 free((void *)desc->unit);
295 if (desc->valueNames) {
296 for (unsigned int j = 0; desc->valueNames[j]; ++j) {
297 free((void *)desc->valueNames[j]);
299 free((void *)desc->valueNames);
302 free((void *)m_descriptor.parameters);
304 for (unsigned int i = 0; i < m_descriptor.programCount; ++i) {
305 free((void *)m_descriptor.programs[i]);
307 free((void *)m_descriptor.programs);
311 m_adapterMap->erase(&m_descriptor);
313 if (m_adapterMap->empty()) {
320 PluginAdapterBase::Impl *
321 PluginAdapterBase::Impl::lookupAdapter(VampPluginHandle handle)
323 #ifdef DEBUG_PLUGIN_ADAPTER
324 std::cerr << "PluginAdapterBase::Impl::lookupAdapter(" << handle << ")" << std::endl;
327 if (!m_adapterMap) return 0;
328 AdapterMap::const_iterator i = m_adapterMap->find(handle);
329 if (i == m_adapterMap->end()) return 0;
334 PluginAdapterBase::Impl::vampInstantiate(const VampPluginDescriptor *desc,
335 float inputSampleRate)
337 #ifdef DEBUG_PLUGIN_ADAPTER
338 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << ")" << std::endl;
342 m_adapterMap = new AdapterMap();
345 if (m_adapterMap->find(desc) == m_adapterMap->end()) {
346 std::cerr << "WARNING: PluginAdapterBase::Impl::vampInstantiate: Descriptor " << desc << " not in adapter map" << std::endl;
350 Impl *adapter = (*m_adapterMap)[desc];
351 if (desc != &adapter->m_descriptor) return 0;
353 Plugin *plugin = adapter->m_base->createPlugin(inputSampleRate);
355 (*m_adapterMap)[plugin] = adapter;
358 #ifdef DEBUG_PLUGIN_ADAPTER
359 std::cerr << "PluginAdapterBase::Impl::vampInstantiate(" << desc << "): returning handle " << plugin << std::endl;
366 PluginAdapterBase::Impl::vampCleanup(VampPluginHandle handle)
368 #ifdef DEBUG_PLUGIN_ADAPTER
369 std::cerr << "PluginAdapterBase::Impl::vampCleanup(" << handle << ")" << std::endl;
372 Impl *adapter = lookupAdapter(handle);
374 delete ((Plugin *)handle);
377 adapter->cleanup(((Plugin *)handle));
381 PluginAdapterBase::Impl::vampInitialise(VampPluginHandle handle,
382 unsigned int channels,
383 unsigned int stepSize,
384 unsigned int blockSize)
386 #ifdef DEBUG_PLUGIN_ADAPTER
387 std::cerr << "PluginAdapterBase::Impl::vampInitialise(" << handle << ", " << channels << ", " << stepSize << ", " << blockSize << ")" << std::endl;
390 Impl *adapter = lookupAdapter(handle);
391 if (!adapter) return 0;
392 bool result = ((Plugin *)handle)->initialise(channels, stepSize, blockSize);
393 adapter->markOutputsChanged((Plugin *)handle);
394 return result ? 1 : 0;
398 PluginAdapterBase::Impl::vampReset(VampPluginHandle handle)
400 #ifdef DEBUG_PLUGIN_ADAPTER
401 std::cerr << "PluginAdapterBase::Impl::vampReset(" << handle << ")" << std::endl;
404 ((Plugin *)handle)->reset();
408 PluginAdapterBase::Impl::vampGetParameter(VampPluginHandle handle,
411 #ifdef DEBUG_PLUGIN_ADAPTER
412 std::cerr << "PluginAdapterBase::Impl::vampGetParameter(" << handle << ", " << param << ")" << std::endl;
415 Impl *adapter = lookupAdapter(handle);
416 if (!adapter) return 0.0;
417 Plugin::ParameterList &list = adapter->m_parameters;
418 return ((Plugin *)handle)->getParameter(list[param].identifier);
422 PluginAdapterBase::Impl::vampSetParameter(VampPluginHandle handle,
423 int param, float value)
425 #ifdef DEBUG_PLUGIN_ADAPTER
426 std::cerr << "PluginAdapterBase::Impl::vampSetParameter(" << handle << ", " << param << ", " << value << ")" << std::endl;
429 Impl *adapter = lookupAdapter(handle);
430 if (!adapter) return;
431 Plugin::ParameterList &list = adapter->m_parameters;
432 ((Plugin *)handle)->setParameter(list[param].identifier, value);
433 adapter->markOutputsChanged((Plugin *)handle);
437 PluginAdapterBase::Impl::vampGetCurrentProgram(VampPluginHandle handle)
439 #ifdef DEBUG_PLUGIN_ADAPTER
440 std::cerr << "PluginAdapterBase::Impl::vampGetCurrentProgram(" << handle << ")" << std::endl;
443 Impl *adapter = lookupAdapter(handle);
444 if (!adapter) return 0;
445 Plugin::ProgramList &list = adapter->m_programs;
446 std::string program = ((Plugin *)handle)->getCurrentProgram();
447 for (unsigned int i = 0; i < list.size(); ++i) {
448 if (list[i] == program) return i;
454 PluginAdapterBase::Impl::vampSelectProgram(VampPluginHandle handle,
455 unsigned int program)
457 #ifdef DEBUG_PLUGIN_ADAPTER
458 std::cerr << "PluginAdapterBase::Impl::vampSelectProgram(" << handle << ", " << program << ")" << std::endl;
461 Impl *adapter = lookupAdapter(handle);
462 if (!adapter) return;
464 Plugin::ProgramList &list = adapter->m_programs;
465 ((Plugin *)handle)->selectProgram(list[program]);
467 adapter->markOutputsChanged((Plugin *)handle);
471 PluginAdapterBase::Impl::vampGetPreferredStepSize(VampPluginHandle handle)
473 #ifdef DEBUG_PLUGIN_ADAPTER
474 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredStepSize(" << handle << ")" << std::endl;
477 return ((Plugin *)handle)->getPreferredStepSize();
481 PluginAdapterBase::Impl::vampGetPreferredBlockSize(VampPluginHandle handle)
483 #ifdef DEBUG_PLUGIN_ADAPTER
484 std::cerr << "PluginAdapterBase::Impl::vampGetPreferredBlockSize(" << handle << ")" << std::endl;
487 return ((Plugin *)handle)->getPreferredBlockSize();
491 PluginAdapterBase::Impl::vampGetMinChannelCount(VampPluginHandle handle)
493 #ifdef DEBUG_PLUGIN_ADAPTER
494 std::cerr << "PluginAdapterBase::Impl::vampGetMinChannelCount(" << handle << ")" << std::endl;
497 return ((Plugin *)handle)->getMinChannelCount();
501 PluginAdapterBase::Impl::vampGetMaxChannelCount(VampPluginHandle handle)
503 #ifdef DEBUG_PLUGIN_ADAPTER
504 std::cerr << "PluginAdapterBase::Impl::vampGetMaxChannelCount(" << handle << ")" << std::endl;
507 return ((Plugin *)handle)->getMaxChannelCount();
511 PluginAdapterBase::Impl::vampGetOutputCount(VampPluginHandle handle)
513 #ifdef DEBUG_PLUGIN_ADAPTER
514 std::cerr << "PluginAdapterBase::Impl::vampGetOutputCount(" << handle << ")" << std::endl;
517 Impl *adapter = lookupAdapter(handle);
519 // std::cerr << "vampGetOutputCount: handle " << handle << " -> adapter "<< adapter << std::endl;
521 if (!adapter) return 0;
522 return adapter->getOutputCount((Plugin *)handle);
525 VampOutputDescriptor *
526 PluginAdapterBase::Impl::vampGetOutputDescriptor(VampPluginHandle handle,
529 #ifdef DEBUG_PLUGIN_ADAPTER
530 std::cerr << "PluginAdapterBase::Impl::vampGetOutputDescriptor(" << handle << ", " << i << ")" << std::endl;
533 Impl *adapter = lookupAdapter(handle);
535 // std::cerr << "vampGetOutputDescriptor: handle " << handle << " -> adapter "<< adapter << std::endl;
537 if (!adapter) return 0;
538 return adapter->getOutputDescriptor((Plugin *)handle, i);
542 PluginAdapterBase::Impl::vampReleaseOutputDescriptor(VampOutputDescriptor *desc)
544 #ifdef DEBUG_PLUGIN_ADAPTER
545 std::cerr << "PluginAdapterBase::Impl::vampReleaseOutputDescriptor(" << desc << ")" << std::endl;
548 if (desc->identifier) free((void *)desc->identifier);
549 if (desc->name) free((void *)desc->name);
550 if (desc->description) free((void *)desc->description);
551 if (desc->unit) free((void *)desc->unit);
552 if (desc->hasFixedBinCount && desc->binNames) {
553 for (unsigned int i = 0; i < desc->binCount; ++i) {
554 if (desc->binNames[i]) {
555 free((void *)desc->binNames[i]);
559 if (desc->binNames) free((void *)desc->binNames);
564 PluginAdapterBase::Impl::vampProcess(VampPluginHandle handle,
565 const float *const *inputBuffers,
569 #ifdef DEBUG_PLUGIN_ADAPTER
570 std::cerr << "PluginAdapterBase::Impl::vampProcess(" << handle << ", " << sec << ", " << nsec << ")" << std::endl;
573 Impl *adapter = lookupAdapter(handle);
574 if (!adapter) return 0;
575 return adapter->process((Plugin *)handle, inputBuffers, sec, nsec);
579 PluginAdapterBase::Impl::vampGetRemainingFeatures(VampPluginHandle handle)
581 #ifdef DEBUG_PLUGIN_ADAPTER
582 std::cerr << "PluginAdapterBase::Impl::vampGetRemainingFeatures(" << handle << ")" << std::endl;
585 Impl *adapter = lookupAdapter(handle);
586 if (!adapter) return 0;
587 return adapter->getRemainingFeatures((Plugin *)handle);
591 PluginAdapterBase::Impl::vampReleaseFeatureSet(VampFeatureList *)
593 #ifdef DEBUG_PLUGIN_ADAPTER
594 std::cerr << "PluginAdapterBase::Impl::vampReleaseFeatureSet" << std::endl;
599 PluginAdapterBase::Impl::cleanup(Plugin *plugin)
601 if (m_fs.find(plugin) != m_fs.end()) {
602 size_t outputCount = 0;
603 if (m_pluginOutputs[plugin]) {
604 outputCount = m_pluginOutputs[plugin]->size();
606 VampFeatureList *list = m_fs[plugin];
607 for (unsigned int i = 0; i < outputCount; ++i) {
608 for (unsigned int j = 0; j < m_fsizes[plugin][i]; ++j) {
609 if (list[i].features[j].v1.label) {
610 free(list[i].features[j].v1.label);
612 if (list[i].features[j].v1.values) {
613 free(list[i].features[j].v1.values);
616 if (list[i].features) free(list[i].features);
619 m_fsizes.erase(plugin);
620 m_fvsizes.erase(plugin);
623 if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) {
624 delete m_pluginOutputs[plugin];
625 m_pluginOutputs.erase(plugin);
629 m_adapterMap->erase(plugin);
631 if (m_adapterMap->empty()) {
637 delete ((Plugin *)plugin);
641 PluginAdapterBase::Impl::checkOutputMap(Plugin *plugin)
643 OutputMap::iterator i = m_pluginOutputs.find(plugin);
645 if (i == m_pluginOutputs.end() || !i->second) {
647 m_pluginOutputs[plugin] = new Plugin::OutputList
648 (plugin->getOutputDescriptors());
650 // std::cerr << "PluginAdapterBase::Impl::checkOutputMap: Have " << m_pluginOutputs[plugin]->size() << " outputs for plugin " << plugin->getIdentifier() << std::endl;
655 PluginAdapterBase::Impl::markOutputsChanged(Plugin *plugin)
657 OutputMap::iterator i = m_pluginOutputs.find(plugin);
659 // std::cerr << "PluginAdapterBase::Impl::markOutputsChanged" << std::endl;
661 if (i != m_pluginOutputs.end()) {
663 Plugin::OutputList *list = i->second;
664 m_pluginOutputs.erase(i);
670 PluginAdapterBase::Impl::getOutputCount(Plugin *plugin)
672 checkOutputMap(plugin);
674 return m_pluginOutputs[plugin]->size();
677 VampOutputDescriptor *
678 PluginAdapterBase::Impl::getOutputDescriptor(Plugin *plugin,
681 checkOutputMap(plugin);
683 Plugin::OutputDescriptor &od =
684 (*m_pluginOutputs[plugin])[i];
686 VampOutputDescriptor *desc = (VampOutputDescriptor *)
687 malloc(sizeof(VampOutputDescriptor));
689 desc->identifier = strdup(od.identifier.c_str());
690 desc->name = strdup(od.name.c_str());
691 desc->description = strdup(od.description.c_str());
692 desc->unit = strdup(od.unit.c_str());
693 desc->hasFixedBinCount = od.hasFixedBinCount;
694 desc->binCount = od.binCount;
696 if (od.hasFixedBinCount && od.binCount > 0
697 // We would like to do "&& !od.binNames.empty()" here -- but we
698 // can't, because it will crash older versions of the host adapter
699 // which try to copy the names across whenever the bin count is
700 // non-zero, regardless of whether they exist or not
702 desc->binNames = (const char **)
703 malloc(od.binCount * sizeof(const char *));
705 for (unsigned int i = 0; i < od.binCount; ++i) {
706 if (i < od.binNames.size()) {
707 desc->binNames[i] = strdup(od.binNames[i].c_str());
709 desc->binNames[i] = 0;
716 desc->hasKnownExtents = od.hasKnownExtents;
717 desc->minValue = od.minValue;
718 desc->maxValue = od.maxValue;
719 desc->isQuantized = od.isQuantized;
720 desc->quantizeStep = od.quantizeStep;
722 switch (od.sampleType) {
723 case Plugin::OutputDescriptor::OneSamplePerStep:
724 desc->sampleType = vampOneSamplePerStep; break;
725 case Plugin::OutputDescriptor::FixedSampleRate:
726 desc->sampleType = vampFixedSampleRate; break;
727 case Plugin::OutputDescriptor::VariableSampleRate:
728 desc->sampleType = vampVariableSampleRate; break;
731 desc->sampleRate = od.sampleRate;
732 desc->hasDuration = od.hasDuration;
738 PluginAdapterBase::Impl::process(Plugin *plugin,
739 const float *const *inputBuffers,
742 // std::cerr << "PluginAdapterBase::Impl::process" << std::endl;
743 RealTime rt(sec, nsec);
744 checkOutputMap(plugin);
745 return convertFeatures(plugin, plugin->process(inputBuffers, rt));
749 PluginAdapterBase::Impl::getRemainingFeatures(Plugin *plugin)
751 // std::cerr << "PluginAdapterBase::Impl::getRemainingFeatures" << std::endl;
752 checkOutputMap(plugin);
753 return convertFeatures(plugin, plugin->getRemainingFeatures());
757 PluginAdapterBase::Impl::convertFeatures(Plugin *plugin,
758 const Plugin::FeatureSet &features)
763 if (m_pluginOutputs[plugin]) outputCount = m_pluginOutputs[plugin]->size();
765 resizeFS(plugin, outputCount);
766 VampFeatureList *fs = m_fs[plugin];
768 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: sizeof(Feature) == " << sizeof(Plugin::Feature) << ", sizeof(VampFeature) == " << sizeof(VampFeature) << ", sizeof(VampFeatureList) == " << sizeof(VampFeatureList) << std::endl;
770 for (Plugin::FeatureSet::const_iterator fi = features.begin();
771 fi != features.end(); ++fi) {
775 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: n = " << n << std::endl;
777 if (n >= int(outputCount)) {
778 std::cerr << "WARNING: PluginAdapterBase::Impl::convertFeatures: Too many outputs from plugin (" << n+1 << ", only should be " << outputCount << ")" << std::endl;
783 for (int i = lastN + 1; i < n; ++i) {
784 fs[i].featureCount = 0;
788 const Plugin::FeatureList &fl = fi->second;
790 size_t sz = fl.size();
791 if (sz > m_fsizes[plugin][n]) resizeFL(plugin, n, sz);
792 fs[n].featureCount = sz;
794 for (size_t j = 0; j < sz; ++j) {
796 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: j = " << j << std::endl;
798 VampFeature *feature = &fs[n].features[j].v1;
800 feature->hasTimestamp = fl[j].hasTimestamp;
801 feature->sec = fl[j].timestamp.sec;
802 feature->nsec = fl[j].timestamp.nsec;
803 feature->valueCount = fl[j].values.size();
805 VampFeatureV2 *v2 = &fs[n].features[j + sz].v2;
807 v2->hasDuration = fl[j].hasDuration;
808 v2->durationSec = fl[j].duration.sec;
809 v2->durationNsec = fl[j].duration.nsec;
811 if (feature->label) free(feature->label);
813 if (fl[j].label.empty()) {
816 feature->label = strdup(fl[j].label.c_str());
819 if (feature->valueCount > m_fvsizes[plugin][n][j]) {
820 resizeFV(plugin, n, j, feature->valueCount);
823 for (unsigned int k = 0; k < feature->valueCount; ++k) {
824 // std::cerr << "PluginAdapterBase::Impl::convertFeatures: k = " << k << std::endl;
825 feature->values[k] = fl[j].values[k];
832 if (lastN == -1) return 0;
834 if (int(outputCount) > lastN + 1) {
835 for (int i = lastN + 1; i < int(outputCount); ++i) {
836 fs[i].featureCount = 0;
840 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: have " << outputCount << " outputs" << std::endl;
841 // for (int i = 0; i < outputCount; ++i) {
842 // std::cerr << "PluginAdapter(v2)::convertFeatures: NOTE: output " << i << " has " << fs[i].featureCount << " features" << std::endl;
850 PluginAdapterBase::Impl::resizeFS(Plugin *plugin, int n)
852 // std::cerr << "PluginAdapterBase::Impl::resizeFS(" << plugin << ", " << n << ")" << std::endl;
854 int i = m_fsizes[plugin].size();
857 // std::cerr << "resizing from " << i << std::endl;
859 m_fs[plugin] = (VampFeatureList *)realloc
860 (m_fs[plugin], n * sizeof(VampFeatureList));
863 m_fs[plugin][i].featureCount = 0;
864 m_fs[plugin][i].features = 0;
865 m_fsizes[plugin].push_back(0);
866 m_fvsizes[plugin].push_back(std::vector<size_t>());
872 PluginAdapterBase::Impl::resizeFL(Plugin *plugin, int n, size_t sz)
874 // std::cerr << "PluginAdapterBase::Impl::resizeFL(" << plugin << ", " << n << ", "
875 // << sz << ")" << std::endl;
877 size_t i = m_fsizes[plugin][n];
880 // std::cerr << "resizing from " << i << std::endl;
882 m_fs[plugin][n].features = (VampFeatureUnion *)realloc
883 (m_fs[plugin][n].features, 2 * sz * sizeof(VampFeatureUnion));
885 while (m_fsizes[plugin][n] < sz) {
886 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.hasTimestamp = 0;
887 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.valueCount = 0;
888 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.values = 0;
889 m_fs[plugin][n].features[m_fsizes[plugin][n]].v1.label = 0;
890 m_fs[plugin][n].features[m_fsizes[plugin][n] + sz].v2.hasDuration = 0;
891 m_fvsizes[plugin][n].push_back(0);
892 m_fsizes[plugin][n]++;
897 PluginAdapterBase::Impl::resizeFV(Plugin *plugin, int n, int j, size_t sz)
899 // std::cerr << "PluginAdapterBase::Impl::resizeFV(" << plugin << ", " << n << ", "
900 // << j << ", " << sz << ")" << std::endl;
902 size_t i = m_fvsizes[plugin][n][j];
905 // std::cerr << "resizing from " << i << std::endl;
907 m_fs[plugin][n].features[j].v1.values = (float *)realloc
908 (m_fs[plugin][n].features[j].v1.values, sz * sizeof(float));
910 m_fvsizes[plugin][n][j] = sz;
913 PluginAdapterBase::Impl::AdapterMap *
914 PluginAdapterBase::Impl::m_adapterMap = 0;
918 _VAMP_SDK_PLUGSPACE_END(PluginAdapter.cpp)