diff src/vamp-hostsdk/PluginHostAdapter.cpp @ 227:6b30e064cab7 distinct-libraries

* more moving
author cannam
date Thu, 06 Nov 2008 14:13:12 +0000
parents src/PluginHostAdapter.cpp@14029eb08472
children 5ee166dccfff
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vamp-hostsdk/PluginHostAdapter.cpp	Thu Nov 06 14:13:12 2008 +0000
@@ -0,0 +1,447 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Vamp
+
+    An API for audio analysis and feature extraction plugins.
+
+    Centre for Digital Music, Queen Mary, University of London.
+    Copyright 2006 Chris Cannam.
+  
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use, copy,
+    modify, merge, publish, distribute, sublicense, and/or sell copies
+    of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
+    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+    Except as contained in this notice, the names of the Centre for
+    Digital Music; Queen Mary, University of London; and Chris Cannam
+    shall not be used in advertising or otherwise to promote the sale,
+    use or other dealings in this Software without prior written
+    authorization.
+*/
+
+#include "PluginHostAdapter.h"
+#include <cstdlib>
+
+namespace Vamp
+{
+
+PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
+                                     float inputSampleRate) :
+    Plugin(inputSampleRate),
+    m_descriptor(descriptor)
+{
+//    std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
+    m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
+    if (!m_handle) {
+//        std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
+    }
+}
+
+PluginHostAdapter::~PluginHostAdapter()
+{
+//    std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
+    if (m_handle) m_descriptor->cleanup(m_handle);
+}
+
+std::vector<std::string>
+PluginHostAdapter::getPluginPath()
+{
+    std::vector<std::string> path;
+    std::string envPath;
+
+    char *cpath = getenv("VAMP_PATH");
+    if (cpath) envPath = cpath;
+
+#ifdef _WIN32
+#define PATH_SEPARATOR ';'
+#define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
+#else
+#define PATH_SEPARATOR ':'
+#ifdef __APPLE__
+#define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
+#else
+#define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
+#endif
+#endif
+
+    if (envPath == "") {
+        envPath = DEFAULT_VAMP_PATH;
+        char *chome = getenv("HOME");
+        if (chome) {
+            std::string home(chome);
+            std::string::size_type f;
+            while ((f = envPath.find("$HOME")) != std::string::npos &&
+                    f < envPath.length()) {
+                envPath.replace(f, 5, home);
+            }
+        }
+#ifdef _WIN32
+        char *cpfiles = getenv("ProgramFiles");
+        if (!cpfiles) cpfiles = "C:\\Program Files";
+        std::string pfiles(cpfiles);
+        std::string::size_type f;
+        while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
+               f < envPath.length()) {
+            envPath.replace(f, 14, pfiles);
+        }
+#endif
+    }
+
+    std::string::size_type index = 0, newindex = 0;
+
+    while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
+	path.push_back(envPath.substr(index, newindex - index));
+	index = newindex + 1;
+    }
+    
+    path.push_back(envPath.substr(index));
+
+    return path;
+}
+
+bool
+PluginHostAdapter::initialise(size_t channels,
+                              size_t stepSize,
+                              size_t blockSize)
+{
+    if (!m_handle) return false;
+    return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
+        true : false;
+}
+
+void
+PluginHostAdapter::reset()
+{
+    if (!m_handle) {
+//        std::cerr << "PluginHostAdapter::reset: no handle" << std::endl;
+        return;
+    }
+//    std::cerr << "PluginHostAdapter::reset(" << m_handle << ")" << std::endl;
+    m_descriptor->reset(m_handle);
+}
+
+PluginHostAdapter::InputDomain
+PluginHostAdapter::getInputDomain() const
+{
+    if (m_descriptor->inputDomain == vampFrequencyDomain) {
+        return FrequencyDomain;
+    } else {
+        return TimeDomain;
+    }
+}
+
+unsigned int
+PluginHostAdapter::getVampApiVersion() const
+{
+    return m_descriptor->vampApiVersion;
+}
+
+std::string
+PluginHostAdapter::getIdentifier() const
+{
+    return m_descriptor->identifier;
+}
+
+std::string
+PluginHostAdapter::getName() const
+{
+    return m_descriptor->name;
+}
+
+std::string
+PluginHostAdapter::getDescription() const
+{
+    return m_descriptor->description;
+}
+
+std::string
+PluginHostAdapter::getMaker() const
+{
+    return m_descriptor->maker;
+}
+
+int
+PluginHostAdapter::getPluginVersion() const
+{
+    return m_descriptor->pluginVersion;
+}
+
+std::string
+PluginHostAdapter::getCopyright() const
+{
+    return m_descriptor->copyright;
+}
+
+PluginHostAdapter::ParameterList
+PluginHostAdapter::getParameterDescriptors() const
+{
+    ParameterList list;
+    for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
+        const VampParameterDescriptor *spd = m_descriptor->parameters[i];
+        ParameterDescriptor pd;
+        pd.identifier = spd->identifier;
+        pd.name = spd->name;
+        pd.description = spd->description;
+        pd.unit = spd->unit;
+        pd.minValue = spd->minValue;
+        pd.maxValue = spd->maxValue;
+        pd.defaultValue = spd->defaultValue;
+        pd.isQuantized = spd->isQuantized;
+        pd.quantizeStep = spd->quantizeStep;
+        if (pd.isQuantized && spd->valueNames) {
+            for (unsigned int j = 0; spd->valueNames[j]; ++j) {
+                pd.valueNames.push_back(spd->valueNames[j]);
+            }
+        }
+        list.push_back(pd);
+    }
+    return list;
+}
+
+float
+PluginHostAdapter::getParameter(std::string param) const
+{
+    if (!m_handle) return 0.0;
+
+    for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
+        if (param == m_descriptor->parameters[i]->identifier) {
+            return m_descriptor->getParameter(m_handle, i);
+        }
+    }
+
+    return 0.0;
+}
+
+void
+PluginHostAdapter::setParameter(std::string param, 
+                                float value)
+{
+    if (!m_handle) return;
+
+    for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
+        if (param == m_descriptor->parameters[i]->identifier) {
+            m_descriptor->setParameter(m_handle, i, value);
+            return;
+        }
+    }
+}
+
+PluginHostAdapter::ProgramList
+PluginHostAdapter::getPrograms() const
+{
+    ProgramList list;
+    
+    for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
+        list.push_back(m_descriptor->programs[i]);
+    }
+    
+    return list;
+}
+
+std::string
+PluginHostAdapter::getCurrentProgram() const
+{
+    if (!m_handle) return "";
+
+    int pn = m_descriptor->getCurrentProgram(m_handle);
+    return m_descriptor->programs[pn];
+}
+
+void
+PluginHostAdapter::selectProgram(std::string program)
+{
+    if (!m_handle) return;
+
+    for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
+        if (program == m_descriptor->programs[i]) {
+            m_descriptor->selectProgram(m_handle, i);
+            return;
+        }
+    }
+}
+
+size_t
+PluginHostAdapter::getPreferredStepSize() const
+{
+    if (!m_handle) return 0;
+    return m_descriptor->getPreferredStepSize(m_handle);
+}
+
+size_t
+PluginHostAdapter::getPreferredBlockSize() const
+{
+    if (!m_handle) return 0;
+    return m_descriptor->getPreferredBlockSize(m_handle);
+}
+
+size_t
+PluginHostAdapter::getMinChannelCount() const
+{
+    if (!m_handle) return 0;
+    return m_descriptor->getMinChannelCount(m_handle);
+}
+
+size_t
+PluginHostAdapter::getMaxChannelCount() const
+{
+    if (!m_handle) return 0;
+    return m_descriptor->getMaxChannelCount(m_handle);
+}
+
+PluginHostAdapter::OutputList
+PluginHostAdapter::getOutputDescriptors() const
+{
+    OutputList list;
+    if (!m_handle) {
+//        std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
+        return list;
+    }
+
+    unsigned int count = m_descriptor->getOutputCount(m_handle);
+
+    for (unsigned int i = 0; i < count; ++i) {
+        VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
+        OutputDescriptor d;
+        d.identifier = sd->identifier;
+        d.name = sd->name;
+        d.description = sd->description;
+        d.unit = sd->unit;
+        d.hasFixedBinCount = sd->hasFixedBinCount;
+        d.binCount = sd->binCount;
+        if (d.hasFixedBinCount) {
+            for (unsigned int j = 0; j < sd->binCount; ++j) {
+                d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
+            }
+        }
+        d.hasKnownExtents = sd->hasKnownExtents;
+        d.minValue = sd->minValue;
+        d.maxValue = sd->maxValue;
+        d.isQuantized = sd->isQuantized;
+        d.quantizeStep = sd->quantizeStep;
+
+        switch (sd->sampleType) {
+        case vampOneSamplePerStep:
+            d.sampleType = OutputDescriptor::OneSamplePerStep; break;
+        case vampFixedSampleRate:
+            d.sampleType = OutputDescriptor::FixedSampleRate; break;
+        case vampVariableSampleRate:
+            d.sampleType = OutputDescriptor::VariableSampleRate; break;
+        }
+
+        d.sampleRate = sd->sampleRate;
+
+        if (m_descriptor->vampApiVersion >= 2) {
+            d.hasDuration = sd->hasDuration;
+        } else {
+            d.hasDuration = false;
+        }
+
+        list.push_back(d);
+
+        m_descriptor->releaseOutputDescriptor(sd);
+    }
+
+    return list;
+}
+
+PluginHostAdapter::FeatureSet
+PluginHostAdapter::process(const float *const *inputBuffers,
+                           RealTime timestamp)
+{
+    FeatureSet fs;
+    if (!m_handle) return fs;
+
+    int sec = timestamp.sec;
+    int nsec = timestamp.nsec;
+    
+    VampFeatureList *features = m_descriptor->process(m_handle,
+                                                      inputBuffers,
+                                                      sec, nsec);
+    
+    convertFeatures(features, fs);
+    m_descriptor->releaseFeatureSet(features);
+    return fs;
+}
+
+PluginHostAdapter::FeatureSet
+PluginHostAdapter::getRemainingFeatures()
+{
+    FeatureSet fs;
+    if (!m_handle) return fs;
+    
+    VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle); 
+
+    convertFeatures(features, fs);
+    m_descriptor->releaseFeatureSet(features);
+    return fs;
+}
+
+void
+PluginHostAdapter::convertFeatures(VampFeatureList *features,
+                                   FeatureSet &fs)
+{
+    if (!features) return;
+
+    unsigned int outputs = m_descriptor->getOutputCount(m_handle);
+
+    for (unsigned int i = 0; i < outputs; ++i) {
+        
+        VampFeatureList &list = features[i];
+
+        if (list.featureCount > 0) {
+
+            Feature feature;
+            feature.values.reserve(list.features[0].v1.valueCount);
+
+            for (unsigned int j = 0; j < list.featureCount; ++j) {
+
+                feature.hasTimestamp = list.features[j].v1.hasTimestamp;
+                feature.timestamp = RealTime(list.features[j].v1.sec,
+                                             list.features[j].v1.nsec);
+                feature.hasDuration = false;
+
+                if (m_descriptor->vampApiVersion >= 2) {
+                    unsigned int j2 = j + list.featureCount;
+                    feature.hasDuration = list.features[j2].v2.hasDuration;
+                    feature.duration = RealTime(list.features[j2].v2.durationSec,
+                                                list.features[j2].v2.durationNsec);
+                }
+
+                for (unsigned int k = 0; k < list.features[j].v1.valueCount; ++k) {
+                    feature.values.push_back(list.features[j].v1.values[k]);
+                }
+
+                if (list.features[j].v1.label) {
+                    feature.label = list.features[j].v1.label;
+                }
+
+                fs[i].push_back(feature);
+
+                if (list.features[j].v1.valueCount > 0) {
+                    feature.values.clear();
+                }
+
+                if (list.features[j].v1.label) {
+                    feature.label = "";
+                }
+            }
+        }
+    }
+}
+
+}