Chris@58: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ Chris@58: Chris@58: /* Chris@58: Sonic Visualiser Chris@58: An audio file viewer and annotation editor. Chris@58: Centre for Digital Music, Queen Mary, University of London. Chris@58: This file copyright 2006 Chris Cannam. Chris@58: Chris@58: This program is free software; you can redistribute it and/or Chris@58: modify it under the terms of the GNU General Public License as Chris@58: published by the Free Software Foundation; either version 2 of the Chris@58: License, or (at your option) any later version. See the file Chris@58: COPYING included with this distribution for more information. Chris@58: */ Chris@58: Chris@58: #ifndef _FEATURE_EXTRACTION_PLUGIN_ADAPTER_H_ Chris@58: #define _FEATURE_EXTRACTION_PLUGIN_ADAPTER_H_ Chris@58: Chris@58: #include "api/svp.h" Chris@58: #include "FeatureExtractionPlugin.h" Chris@58: Chris@58: #include Chris@58: Chris@58: template Chris@58: class FeatureExtractionPluginAdapter Chris@58: { Chris@58: public: Chris@58: FeatureExtractionPluginAdapter() { Chris@58: Chris@58: Plugin plugin(48000); Chris@58: Chris@58: m_parameters = plugin.getParameterDescriptors(); Chris@58: m_programs = plugin.getPrograms(); Chris@58: Chris@58: m_descriptor.name = strdup(plugin.getName().c_str()); Chris@58: m_descriptor.description = strdup(plugin.getDescription().c_str()); Chris@58: m_descriptor.maker = strdup(plugin.getMaker().c_str()); Chris@58: m_descriptor.pluginVersion = plugin.getPluginVersion(); Chris@58: m_descriptor.copyright = strdup(plugin.getCopyright().c_str()); Chris@58: Chris@58: m_descriptor.parameterCount = m_parameters.size(); Chris@58: m_descriptor.parameters = (const SVPParameterDescriptor **) Chris@58: malloc(m_parameters.size() * sizeof(SVPParameterDescriptor)); Chris@58: Chris@58: for (unsigned int i = 0; i < m_parameters.size(); ++i) { Chris@58: SVPParameterDescriptor *desc = (SVPParameterDescriptor *) Chris@58: malloc(sizeof(SVPParameterDescriptor)); Chris@58: desc->name = strdup(m_parameters[i].name.c_str()); Chris@58: desc->description = strdup(m_parameters[i].description.c_str()); Chris@58: desc->unit = strdup(m_parameters[i].unit.c_str()); Chris@58: desc->minValue = m_parameters[i].minValue; Chris@58: desc->maxValue = m_parameters[i].maxValue; Chris@58: desc->defaultValue = m_parameters[i].defaultValue; Chris@58: desc->isQuantized = m_parameters[i].isQuantized; Chris@58: desc->quantizeStep = m_parameters[i].quantizeStep; Chris@58: m_descriptor.parameters[i] = desc; Chris@58: } Chris@58: Chris@58: m_descriptor.programCount = m_programs.size(); Chris@58: m_descriptor.programs = (const char **) Chris@58: malloc(m_programs.size() * sizeof(const char *)); Chris@58: Chris@58: for (unsigned int i = 0; i < m_programs.size(); ++i) { Chris@58: m_descriptor.programs[i] = strdup(m_programs[i].c_str()); Chris@58: } Chris@58: Chris@58: m_descriptor.instantiate = svpInstantiate; Chris@58: m_descriptor.cleanup = svpCleanup; Chris@58: m_descriptor.initialise = svpInitialise; Chris@58: m_descriptor.reset = svpReset; Chris@58: m_descriptor.getParameter = svpGetParameter; Chris@58: m_descriptor.setParameter = svpSetParameter; Chris@58: m_descriptor.getCurrentProgram = svpGetCurrentProgram; Chris@58: m_descriptor.selectProgram = svpSelectProgram; Chris@58: m_descriptor.getPreferredStepSize = svpGetPreferredStepSize; Chris@58: m_descriptor.getPreferredBlockSize = svpGetPreferredBlockSize; Chris@58: m_descriptor.getMinChannelCount = svpGetMinChannelCount; Chris@58: m_descriptor.getMaxChannelCount = svpGetMaxChannelCount; Chris@58: m_descriptor.getOutputCount = svpGetOutputCount; Chris@58: m_descriptor.getOutputDescriptor = svpGetOutputDescriptor; Chris@58: m_descriptor.releaseOutputDescriptor = svpReleaseOutputDescriptor; Chris@58: m_descriptor.process = svpProcess; Chris@58: m_descriptor.getRemainingFeatures = svpGetRemainingFeatures; Chris@58: m_descriptor.releaseFeatureSet = svpReleaseFeatureSet; Chris@58: Chris@58: m_adapterMap[&m_descriptor] = this; Chris@58: } Chris@58: Chris@58: virtual ~FeatureExtractionPluginAdapter() { Chris@58: Chris@58: free((void *)m_descriptor.name); Chris@58: free((void *)m_descriptor.description); Chris@58: free((void *)m_descriptor.maker); Chris@58: free((void *)m_descriptor.copyright); Chris@58: Chris@58: for (unsigned int i = 0; i < m_descriptor.parameterCount; ++i) { Chris@58: const SVPParameterDescriptor *desc = m_descriptor.parameters[i]; Chris@58: free((void *)desc->name); Chris@58: free((void *)desc->description); Chris@58: free((void *)desc->unit); Chris@58: } Chris@58: free((void *)m_descriptor.parameters); Chris@58: Chris@58: for (unsigned int i = 0; i < m_descriptor.programCount; ++i) { Chris@58: free((void *)m_descriptor.programs[i]); Chris@58: } Chris@58: free((void *)m_descriptor.programs); Chris@58: Chris@58: m_adapterMap.erase(&m_descriptor); Chris@58: } Chris@58: Chris@58: const SVPPluginDescriptor *getDescriptor() const { Chris@58: return &m_descriptor; Chris@58: } Chris@58: Chris@58: protected: Chris@58: static SVPPluginHandle svpInstantiate(const SVPPluginDescriptor *desc, Chris@58: float inputSampleRate) { Chris@58: if (m_adapterMap.find(desc) == m_adapterMap.end()) return 0; Chris@58: FeatureExtractionPluginAdapter *adapter = m_adapterMap[desc]; Chris@58: if (desc != &adapter->m_descriptor) return 0; Chris@58: Plugin *plugin = new Plugin(inputSampleRate); Chris@58: m_adapterMap[plugin] = adapter; Chris@58: return plugin; Chris@58: } Chris@58: Chris@58: static void svpCleanup(SVPPluginHandle handle) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) { Chris@58: delete ((Plugin *)handle); Chris@58: return; Chris@58: } Chris@58: m_adapterMap[handle]->cleanup(((Plugin *)handle)); Chris@58: } Chris@58: Chris@58: static int svpInitialise(SVPPluginHandle handle, unsigned int channels, Chris@58: unsigned int stepSize, unsigned int blockSize) { Chris@58: bool result = ((Plugin *)handle)->initialise(channels, Chris@58: stepSize, blockSize); Chris@58: return result ? 1 : 0; Chris@58: } Chris@58: Chris@58: static void svpReset(SVPPluginHandle handle) { Chris@58: ((Plugin *)handle)->reset(); Chris@58: } Chris@58: Chris@58: static float svpGetParameter(SVPPluginHandle handle, int param) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return 0.0; Chris@58: FeatureExtractionPlugin::ParameterList &list = Chris@58: m_adapterMap[handle]->m_parameters; Chris@58: return ((Plugin *)handle)->getParameter(list[param].name); Chris@58: } Chris@58: Chris@58: static void svpSetParameter(SVPPluginHandle handle, int param, float value) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return; Chris@58: FeatureExtractionPlugin::ParameterList &list = Chris@58: m_adapterMap[handle]->m_parameters; Chris@58: ((Plugin *)handle)->setParameter(list[param].name, value); Chris@58: } Chris@58: Chris@58: static unsigned int svpGetCurrentProgram(SVPPluginHandle handle) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return 0; Chris@58: FeatureExtractionPlugin::ProgramList &list = Chris@58: m_adapterMap[handle]->m_programs; Chris@58: std::string program = ((Plugin *)handle)->getCurrentProgram(); Chris@58: for (unsigned int i = 0; i < list.size(); ++i) { Chris@58: if (list[i] == program) return i; Chris@58: } Chris@58: return 0; Chris@58: } Chris@58: Chris@58: static void svpSelectProgram(SVPPluginHandle handle, unsigned int program) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return; Chris@58: FeatureExtractionPlugin::ProgramList &list = Chris@58: m_adapterMap[handle]->m_programs; Chris@58: ((Plugin *)handle)->selectProgram(list[program]); Chris@58: } Chris@58: Chris@58: static unsigned int svpGetPreferredStepSize(SVPPluginHandle handle) { Chris@58: return ((Plugin *)handle)->getPreferredStepSize(); Chris@58: } Chris@58: Chris@58: static unsigned int svpGetPreferredBlockSize(SVPPluginHandle handle) { Chris@58: return ((Plugin *)handle)->getPreferredBlockSize(); Chris@58: } Chris@58: Chris@58: static unsigned int svpGetMinChannelCount(SVPPluginHandle handle) { Chris@58: return ((Plugin *)handle)->getMinChannelCount(); Chris@58: } Chris@58: Chris@58: static unsigned int svpGetMaxChannelCount(SVPPluginHandle handle) { Chris@58: return ((Plugin *)handle)->getMaxChannelCount(); Chris@58: } Chris@58: Chris@58: static unsigned int svpGetOutputCount(SVPPluginHandle handle) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return 0; Chris@58: return m_adapterMap[handle]->getOutputCount((Plugin *)handle); Chris@58: } Chris@58: Chris@58: static SVPOutputDescriptor *svpGetOutputDescriptor(SVPPluginHandle handle, Chris@58: unsigned int i) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return 0; Chris@58: return m_adapterMap[handle]->getOutputDescriptor((Plugin *)handle, i); Chris@58: } Chris@58: Chris@58: static void svpReleaseOutputDescriptor(SVPOutputDescriptor *desc) { Chris@58: if (desc->name) free((void *)desc->name); Chris@58: if (desc->description) free((void *)desc->description); Chris@58: if (desc->unit) free((void *)desc->unit); Chris@58: for (unsigned int i = 0; i < desc->valueCount; ++i) { Chris@58: free((void *)desc->valueNames[i]); Chris@58: } Chris@58: if (desc->valueNames) free((void *)desc->valueNames); Chris@58: free((void *)desc); Chris@58: } Chris@58: Chris@58: static SVPFeatureList **svpProcess(SVPPluginHandle handle, Chris@58: float **inputBuffers, Chris@58: int sec, Chris@58: int nsec) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return 0; Chris@58: return m_adapterMap[handle]->process((Plugin *)handle, Chris@58: inputBuffers, sec, nsec); Chris@58: } Chris@58: Chris@58: static SVPFeatureList **svpGetRemainingFeatures(SVPPluginHandle handle) { Chris@58: if (m_adapterMap.find(handle) == m_adapterMap.end()) return 0; Chris@58: return m_adapterMap[handle]->getRemainingFeatures((Plugin *)handle); Chris@58: } Chris@58: Chris@58: static void svpReleaseFeatureSet(SVPFeatureList **fs) { Chris@58: if (!fs) return; Chris@58: for (unsigned int i = 0; fs[i]; ++i) { Chris@58: for (unsigned int j = 0; j < fs[i]->featureCount; ++j) { Chris@58: SVPFeature *feature = &fs[i]->features[j]; Chris@58: if (feature->values) free((void *)feature->values); Chris@58: if (feature->label) free((void *)feature->label); Chris@58: free((void *)feature); Chris@58: } Chris@58: if (fs[i]->features) free((void *)fs[i]->features); Chris@58: free((void *)fs[i]); Chris@58: } Chris@58: free((void *)fs); Chris@58: } Chris@58: Chris@58: void cleanup(Plugin *plugin) { Chris@58: if (m_pluginOutputs.find(plugin) != m_pluginOutputs.end()) { Chris@58: delete m_pluginOutputs[plugin]; Chris@58: m_pluginOutputs.erase(plugin); Chris@58: } Chris@58: m_adapterMap.erase(plugin); Chris@58: delete ((Plugin *)plugin); Chris@58: } Chris@58: Chris@58: void checkOutputMap(Plugin *plugin) { Chris@58: if (!m_pluginOutputs[plugin]) { Chris@58: m_pluginOutputs[plugin] = new FeatureExtractionPlugin::OutputList Chris@58: (plugin->getOutputDescriptors()); Chris@58: } Chris@58: } Chris@58: Chris@58: unsigned int getOutputCount(Plugin *plugin) { Chris@58: checkOutputMap(plugin); Chris@58: return m_pluginOutputs[plugin]->size(); Chris@58: } Chris@58: Chris@58: SVPOutputDescriptor *getOutputDescriptor(Plugin *plugin, Chris@58: unsigned int i) { Chris@58: Chris@58: checkOutputMap(plugin); Chris@58: FeatureExtractionPlugin::OutputDescriptor &od = Chris@58: (*m_pluginOutputs[plugin])[i]; Chris@58: Chris@58: SVPOutputDescriptor *desc = (SVPOutputDescriptor *) Chris@58: malloc(sizeof(SVPOutputDescriptor)); Chris@58: Chris@58: desc->name = strdup(od.name.c_str()); Chris@58: desc->description = strdup(od.description.c_str()); Chris@58: desc->unit = strdup(od.unit.c_str()); Chris@58: desc->hasFixedValueCount = od.hasFixedValueCount; Chris@58: desc->valueCount = od.valueCount; Chris@58: Chris@58: desc->valueNames = (const char **) Chris@58: malloc(od.valueCount * sizeof(const char *)); Chris@58: Chris@58: for (unsigned int i = 0; i < od.valueCount; ++i) { Chris@58: desc->valueNames[i] = strdup(od.valueNames[i].c_str()); Chris@58: } Chris@58: Chris@58: desc->hasKnownExtents = od.hasKnownExtents; Chris@58: desc->minValue = od.minValue; Chris@58: desc->maxValue = od.maxValue; Chris@58: desc->isQuantized = od.isQuantized; Chris@58: desc->quantizeStep = od.quantizeStep; Chris@58: Chris@58: switch (od.sampleType) { Chris@58: case FeatureExtractionPlugin::OutputDescriptor::OneSamplePerStep: Chris@58: desc->sampleType = svpOneSamplePerStep; break; Chris@58: case FeatureExtractionPlugin::OutputDescriptor::FixedSampleRate: Chris@58: desc->sampleType = svpFixedSampleRate; break; Chris@58: case FeatureExtractionPlugin::OutputDescriptor::VariableSampleRate: Chris@58: desc->sampleType = svpVariableSampleRate; break; Chris@58: } Chris@58: Chris@58: desc->sampleRate = od.sampleRate; Chris@58: Chris@58: return desc; Chris@58: } Chris@58: Chris@58: SVPFeatureList **process(Plugin *plugin, Chris@58: float **inputBuffers, Chris@58: int sec, int nsec) { Chris@58: RealTime rt(sec, nsec); Chris@58: return convertFeatures(plugin->process(inputBuffers, rt)); Chris@58: } Chris@58: Chris@58: SVPFeatureList **getRemainingFeatures(Plugin *plugin) { Chris@58: return convertFeatures(plugin->getRemainingFeatures()); Chris@58: } Chris@58: Chris@58: SVPFeatureList **convertFeatures(const FeatureExtractionPlugin::FeatureSet &features) { Chris@58: Chris@58: unsigned int n = 0; Chris@58: if (features.begin() != features.end()) { Chris@58: FeatureExtractionPlugin::FeatureSet::const_iterator i = features.end(); Chris@58: --i; Chris@58: n = i->first + 1; Chris@58: } Chris@58: Chris@58: if (!n) return 0; Chris@58: Chris@58: SVPFeatureList **fs = (SVPFeatureList **) Chris@58: malloc((n + 1) * sizeof(SVPFeatureList *)); Chris@58: Chris@58: for (unsigned int i = 0; i < n; ++i) { Chris@58: fs[i] = (SVPFeatureList *)malloc(sizeof(SVPFeatureList)); Chris@58: if (features.find(i) == features.end()) { Chris@58: fs[i]->featureCount = 0; Chris@58: fs[i]->features = 0; Chris@58: } else { Chris@58: FeatureExtractionPlugin::FeatureSet::const_iterator fi = Chris@58: features.find(i); Chris@58: const FeatureExtractionPlugin::FeatureList &fl = fi->second; Chris@58: fs[i]->featureCount = fl.size(); Chris@58: fs[i]->features = (SVPFeature *)malloc(fl.size() * Chris@58: sizeof(SVPFeature)); Chris@58: for (unsigned int j = 0; j < fl.size(); ++j) { Chris@58: fs[i]->features[j].hasTimestamp = fl[j].hasTimestamp; Chris@58: fs[i]->features[j].sec = fl[j].timestamp.sec; Chris@58: fs[i]->features[j].nsec = fl[j].timestamp.nsec; Chris@58: fs[i]->features[j].valueCount = fl[j].values.size(); Chris@58: fs[i]->features[j].values = (float *)malloc Chris@58: (fs[i]->features[j].valueCount * sizeof(float)); Chris@58: for (unsigned int k = 0; k < fs[i]->features[j].valueCount; ++k) { Chris@58: fs[i]->features[j].values[k] = fl[j].values[k]; Chris@58: } Chris@58: fs[i]->features[j].label = strdup(fl[j].label.c_str()); Chris@58: } Chris@58: } Chris@58: } Chris@58: Chris@58: fs[n] = 0; Chris@58: Chris@58: return fs; Chris@58: } Chris@58: Chris@58: typedef std::map AdapterMap; Chris@58: static AdapterMap m_adapterMap; Chris@58: Chris@58: SVPPluginDescriptor m_descriptor; Chris@58: FeatureExtractionPlugin::ParameterList m_parameters; Chris@58: FeatureExtractionPlugin::ProgramList m_programs; Chris@58: Chris@58: typedef std::map OutputMap; Chris@58: OutputMap m_pluginOutputs; Chris@58: Chris@58: typedef std::map FeatureBufferMap; Chris@58: FeatureBufferMap m_pluginFeatures; Chris@58: }; Chris@58: Chris@58: template Chris@58: typename FeatureExtractionPluginAdapter::AdapterMap Chris@58: FeatureExtractionPluginAdapter::m_adapterMap; Chris@58: Chris@58: #endif Chris@58: