cannam@1: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ cannam@1: cannam@1: /* cannam@1: Vamp cannam@1: cannam@1: An API for audio analysis and feature extraction plugins. cannam@1: cannam@1: Centre for Digital Music, Queen Mary, University of London. cannam@1: Copyright 2006 Chris Cannam. cannam@1: cannam@1: Permission is hereby granted, free of charge, to any person cannam@1: obtaining a copy of this software and associated documentation cannam@1: files (the "Software"), to deal in the Software without cannam@1: restriction, including without limitation the rights to use, copy, cannam@1: modify, merge, publish, distribute, sublicense, and/or sell copies cannam@1: of the Software, and to permit persons to whom the Software is cannam@1: furnished to do so, subject to the following conditions: cannam@1: cannam@1: The above copyright notice and this permission notice shall be cannam@1: included in all copies or substantial portions of the Software. cannam@1: cannam@1: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, cannam@1: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF cannam@1: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND cannam@1: NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR cannam@1: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF cannam@1: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION cannam@1: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. cannam@1: cannam@1: Except as contained in this notice, the names of the Centre for cannam@1: Digital Music; Queen Mary, University of London; and Chris Cannam cannam@1: shall not be used in advertising or otherwise to promote the sale, cannam@1: use or other dealings in this Software without prior written cannam@1: authorization. cannam@1: */ cannam@1: cannam@1: #include "PluginHostAdapter.h" cannam@1: cannam@1: namespace Vamp cannam@1: { cannam@1: cannam@1: PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor, cannam@1: float inputSampleRate) : cannam@1: Plugin(inputSampleRate), cannam@1: m_descriptor(descriptor) cannam@1: { cannam@1: std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl; cannam@1: m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate); cannam@1: } cannam@1: cannam@1: PluginHostAdapter::~PluginHostAdapter() cannam@1: { cannam@1: if (m_handle) m_descriptor->cleanup(m_handle); cannam@1: } cannam@1: cannam@1: bool cannam@1: PluginHostAdapter::initialise(size_t channels, cannam@1: size_t stepSize, cannam@1: size_t blockSize) cannam@1: { cannam@1: if (!m_handle) return false; cannam@1: return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ? cannam@1: true : false; cannam@1: } cannam@1: cannam@1: void cannam@1: PluginHostAdapter::reset() cannam@1: { cannam@1: if (!m_handle) return; cannam@1: m_descriptor->reset(m_handle); cannam@1: } cannam@1: cannam@1: PluginHostAdapter::InputDomain cannam@1: PluginHostAdapter::getInputDomain() const cannam@1: { cannam@1: if (m_descriptor->inputDomain == vampFrequencyDomain) { cannam@1: return FrequencyDomain; cannam@1: } else { cannam@1: return TimeDomain; cannam@1: } cannam@1: } cannam@1: cannam@1: std::string cannam@1: PluginHostAdapter::getName() const cannam@1: { cannam@1: return m_descriptor->name; cannam@1: } cannam@1: cannam@1: std::string cannam@1: PluginHostAdapter::getDescription() const cannam@1: { cannam@1: return m_descriptor->description; cannam@1: } cannam@1: cannam@1: std::string cannam@1: PluginHostAdapter::getMaker() const cannam@1: { cannam@1: return m_descriptor->maker; cannam@1: } cannam@1: cannam@1: int cannam@1: PluginHostAdapter::getPluginVersion() const cannam@1: { cannam@1: return m_descriptor->pluginVersion; cannam@1: } cannam@1: cannam@1: std::string cannam@1: PluginHostAdapter::getCopyright() const cannam@1: { cannam@1: return m_descriptor->copyright; cannam@1: } cannam@1: cannam@1: PluginHostAdapter::ParameterList cannam@1: PluginHostAdapter::getParameterDescriptors() const cannam@1: { cannam@1: ParameterList list; cannam@1: for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { cannam@1: const VampParameterDescriptor *spd = m_descriptor->parameters[i]; cannam@1: ParameterDescriptor pd; cannam@1: pd.name = spd->name; cannam@1: pd.description = spd->description; cannam@1: pd.unit = spd->unit; cannam@1: pd.minValue = spd->minValue; cannam@1: pd.maxValue = spd->maxValue; cannam@1: pd.defaultValue = spd->defaultValue; cannam@1: pd.isQuantized = spd->isQuantized; cannam@1: pd.quantizeStep = spd->quantizeStep; cannam@1: list.push_back(pd); cannam@1: } cannam@1: return list; cannam@1: } cannam@1: cannam@1: float cannam@1: PluginHostAdapter::getParameter(std::string param) const cannam@1: { cannam@1: if (!m_handle) return 0.0; cannam@1: cannam@1: for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { cannam@1: if (param == m_descriptor->parameters[i]->name) { cannam@1: return m_descriptor->getParameter(m_handle, i); cannam@1: } cannam@1: } cannam@1: cannam@1: return 0.0; cannam@1: } cannam@1: cannam@1: void cannam@1: PluginHostAdapter::setParameter(std::string param, cannam@1: float value) cannam@1: { cannam@1: if (!m_handle) return; cannam@1: cannam@1: for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) { cannam@1: if (param == m_descriptor->parameters[i]->name) { cannam@1: m_descriptor->setParameter(m_handle, i, value); cannam@1: return; cannam@1: } cannam@1: } cannam@1: } cannam@1: cannam@1: PluginHostAdapter::ProgramList cannam@1: PluginHostAdapter::getPrograms() const cannam@1: { cannam@1: ProgramList list; cannam@1: cannam@1: for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { cannam@1: list.push_back(m_descriptor->programs[i]); cannam@1: } cannam@1: cannam@1: return list; cannam@1: } cannam@1: cannam@1: std::string cannam@1: PluginHostAdapter::getCurrentProgram() const cannam@1: { cannam@1: if (!m_handle) return ""; cannam@1: cannam@1: int pn = m_descriptor->getCurrentProgram(m_handle); cannam@1: return m_descriptor->programs[pn]; cannam@1: } cannam@1: cannam@1: void cannam@1: PluginHostAdapter::selectProgram(std::string program) cannam@1: { cannam@1: if (!m_handle) return; cannam@1: cannam@1: for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { cannam@1: if (program == m_descriptor->programs[i]) { cannam@1: m_descriptor->selectProgram(m_handle, i); cannam@1: return; cannam@1: } cannam@1: } cannam@1: } cannam@1: cannam@1: size_t cannam@1: PluginHostAdapter::getPreferredStepSize() const cannam@1: { cannam@1: if (!m_handle) return 0; cannam@1: return m_descriptor->getPreferredStepSize(m_handle); cannam@1: } cannam@1: cannam@1: size_t cannam@1: PluginHostAdapter::getPreferredBlockSize() const cannam@1: { cannam@1: if (!m_handle) return 0; cannam@1: return m_descriptor->getPreferredBlockSize(m_handle); cannam@1: } cannam@1: cannam@1: PluginHostAdapter::OutputList cannam@1: PluginHostAdapter::getOutputDescriptors() const cannam@1: { cannam@1: OutputList list; cannam@1: if (!m_handle) return list; cannam@1: cannam@1: unsigned int count = m_descriptor->getOutputCount(m_handle); cannam@1: cannam@1: for (unsigned int i = 0; i < count; ++i) { cannam@1: VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i); cannam@1: OutputDescriptor d; cannam@1: d.name = sd->name; cannam@1: d.description = sd->description; cannam@1: d.unit = sd->unit; cannam@1: d.hasFixedValueCount = sd->hasFixedValueCount; cannam@1: d.valueCount = sd->valueCount; cannam@1: for (unsigned int j = 0; j < sd->valueCount; ++j) { cannam@1: d.valueNames.push_back(sd->valueNames[i] ? sd->valueNames[i] : ""); cannam@1: } cannam@1: d.hasKnownExtents = sd->hasKnownExtents; cannam@1: d.minValue = sd->minValue; cannam@1: d.maxValue = sd->maxValue; cannam@1: d.isQuantized = sd->isQuantized; cannam@1: d.quantizeStep = sd->quantizeStep; cannam@1: cannam@1: switch (sd->sampleType) { cannam@1: case vampOneSamplePerStep: cannam@1: d.sampleType = OutputDescriptor::OneSamplePerStep; break; cannam@1: case vampFixedSampleRate: cannam@1: d.sampleType = OutputDescriptor::FixedSampleRate; break; cannam@1: case vampVariableSampleRate: cannam@1: d.sampleType = OutputDescriptor::VariableSampleRate; break; cannam@1: } cannam@1: cannam@1: d.sampleRate = sd->sampleRate; cannam@1: cannam@1: list.push_back(d); cannam@1: cannam@1: m_descriptor->releaseOutputDescriptor(sd); cannam@1: } cannam@1: cannam@1: return list; cannam@1: } cannam@1: cannam@1: PluginHostAdapter::FeatureSet cannam@1: PluginHostAdapter::process(float **inputBuffers, cannam@1: RealTime timestamp) cannam@1: { cannam@1: FeatureSet fs; cannam@1: if (!m_handle) return fs; cannam@1: cannam@1: int sec = timestamp.sec; cannam@1: int nsec = timestamp.nsec; cannam@1: cannam@1: VampFeatureList **features = m_descriptor->process(m_handle, cannam@1: inputBuffers, cannam@1: sec, nsec); cannam@1: cannam@1: convertFeatures(features, fs); cannam@1: m_descriptor->releaseFeatureSet(features); cannam@1: return fs; cannam@1: } cannam@1: cannam@1: PluginHostAdapter::FeatureSet cannam@1: PluginHostAdapter::getRemainingFeatures() cannam@1: { cannam@1: FeatureSet fs; cannam@1: if (!m_handle) return fs; cannam@1: cannam@1: VampFeatureList **features = m_descriptor->getRemainingFeatures(m_handle); cannam@1: cannam@1: convertFeatures(features, fs); cannam@1: m_descriptor->releaseFeatureSet(features); cannam@1: return fs; cannam@1: } cannam@1: cannam@1: void cannam@1: PluginHostAdapter::convertFeatures(VampFeatureList **features, cannam@1: FeatureSet &fs) cannam@1: { cannam@1: for (unsigned int i = 0; features[i]; ++i) { cannam@1: cannam@1: VampFeatureList &list = *features[i]; cannam@1: cannam@1: if (list.featureCount > 0) { cannam@1: cannam@1: for (unsigned int j = 0; j < list.featureCount; ++j) { cannam@1: cannam@1: Feature feature; cannam@1: feature.hasTimestamp = list.features[j].hasTimestamp; cannam@1: feature.timestamp = RealTime(list.features[j].sec, cannam@1: list.features[j].nsec); cannam@1: cannam@1: for (unsigned int k = 0; k < list.features[j].valueCount; ++k) { cannam@1: feature.values.push_back(list.features[j].values[k]); cannam@1: } cannam@1: cannam@1: feature.label = list.features[j].label; cannam@1: cannam@1: fs[i].push_back(feature); cannam@1: } cannam@1: } cannam@1: } cannam@1: } cannam@1: cannam@1: }