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