cannam@0: cannam@0: cannam@0: VampPluginSDK: PluginHostAdapter.cpp Source File cannam@0: cannam@0: cannam@0: cannam@0: cannam@0: cannam@0: cannam@0:

PluginHostAdapter.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
cannam@0: 00002 
cannam@0: 00003 /*
cannam@0: 00004     Vamp
cannam@0: 00005 
cannam@0: 00006     An API for audio analysis and feature extraction plugins.
cannam@0: 00007 
cannam@0: 00008     Centre for Digital Music, Queen Mary, University of London.
cannam@0: 00009     Copyright 2006 Chris Cannam.
cannam@0: 00010   
cannam@0: 00011     Permission is hereby granted, free of charge, to any person
cannam@0: 00012     obtaining a copy of this software and associated documentation
cannam@0: 00013     files (the "Software"), to deal in the Software without
cannam@0: 00014     restriction, including without limitation the rights to use, copy,
cannam@0: 00015     modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@0: 00016     of the Software, and to permit persons to whom the Software is
cannam@0: 00017     furnished to do so, subject to the following conditions:
cannam@0: 00018 
cannam@0: 00019     The above copyright notice and this permission notice shall be
cannam@0: 00020     included in all copies or substantial portions of the Software.
cannam@0: 00021 
cannam@0: 00022     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@0: 00023     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@0: 00024     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@0: 00025     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@0: 00026     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@0: 00027     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@0: 00028     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@0: 00029 
cannam@0: 00030     Except as contained in this notice, the names of the Centre for
cannam@0: 00031     Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@0: 00032     shall not be used in advertising or otherwise to promote the sale,
cannam@0: 00033     use or other dealings in this Software without prior written
cannam@0: 00034     authorization.
cannam@0: 00035 */
cannam@0: 00036 
cannam@0: 00037 #include "PluginHostAdapter.h"
cannam@0: 00038 #include <cstdlib>
cannam@0: 00039 
cannam@0: 00040 namespace Vamp
cannam@0: 00041 {
cannam@0: 00042 
cannam@0: 00043 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
cannam@0: 00044                                      float inputSampleRate) :
cannam@0: 00045     Plugin(inputSampleRate),
cannam@0: 00046     m_descriptor(descriptor)
cannam@0: 00047 {
cannam@0: 00048 //    std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
cannam@0: 00049     m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
cannam@0: 00050     if (!m_handle) {
cannam@0: 00051 //        std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
cannam@0: 00052     }
cannam@0: 00053 }
cannam@0: 00054 
cannam@0: 00055 PluginHostAdapter::~PluginHostAdapter()
cannam@0: 00056 {
cannam@0: 00057 //    std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
cannam@0: 00058     if (m_handle) m_descriptor->cleanup(m_handle);
cannam@0: 00059 }
cannam@0: 00060 
cannam@0: 00061 std::vector<std::string>
cannam@0: 00062 PluginHostAdapter::getPluginPath()
cannam@0: 00063 {
cannam@0: 00064     std::vector<std::string> path;
cannam@0: 00065     std::string envPath;
cannam@0: 00066 
cannam@0: 00067     char *cpath = getenv("VAMP_PATH");
cannam@0: 00068     if (cpath) envPath = cpath;
cannam@0: 00069 
cannam@0: 00070 #ifdef _WIN32
cannam@0: 00071 #define PATH_SEPARATOR ';'
cannam@0: 00072 #define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
cannam@0: 00073 #else
cannam@0: 00074 #define PATH_SEPARATOR ':'
cannam@0: 00075 #ifdef __APPLE__
cannam@0: 00076 #define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
cannam@0: 00077 #else
cannam@0: 00078 #define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
cannam@0: 00079 #endif
cannam@0: 00080 #endif
cannam@0: 00081 
cannam@0: 00082     if (envPath == "") {
cannam@0: 00083         envPath = DEFAULT_VAMP_PATH;
cannam@0: 00084         char *chome = getenv("HOME");
cannam@0: 00085         if (chome) {
cannam@0: 00086             std::string home(chome);
cannam@0: 00087             std::string::size_type f;
cannam@0: 00088             while ((f = envPath.find("$HOME")) != std::string::npos &&
cannam@0: 00089                     f < envPath.length()) {
cannam@0: 00090                 envPath.replace(f, 5, home);
cannam@0: 00091             }
cannam@0: 00092         }
cannam@0: 00093 #ifdef _WIN32
cannam@0: 00094         char *cpfiles = getenv("ProgramFiles");
cannam@0: 00095         if (!cpfiles) cpfiles = "C:\\Program Files";
cannam@0: 00096         std::string pfiles(cpfiles);
cannam@0: 00097         std::string::size_type f;
cannam@0: 00098         while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
cannam@0: 00099                f < envPath.length()) {
cannam@0: 00100             envPath.replace(f, 14, pfiles);
cannam@0: 00101         }
cannam@0: 00102 #endif
cannam@0: 00103     }
cannam@0: 00104 
cannam@0: 00105     std::string::size_type index = 0, newindex = 0;
cannam@0: 00106 
cannam@0: 00107     while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
cannam@0: 00108         path.push_back(envPath.substr(index, newindex - index));
cannam@0: 00109         index = newindex + 1;
cannam@0: 00110     }
cannam@0: 00111     
cannam@0: 00112     path.push_back(envPath.substr(index));
cannam@0: 00113 
cannam@0: 00114     return path;
cannam@0: 00115 }
cannam@0: 00116 
cannam@0: 00117 bool
cannam@0: 00118 PluginHostAdapter::initialise(size_t channels,
cannam@0: 00119                               size_t stepSize,
cannam@0: 00120                               size_t blockSize)
cannam@0: 00121 {
cannam@0: 00122     if (!m_handle) return false;
cannam@0: 00123     return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
cannam@0: 00124         true : false;
cannam@0: 00125 }
cannam@0: 00126 
cannam@0: 00127 void
cannam@0: 00128 PluginHostAdapter::reset()
cannam@0: 00129 {
cannam@0: 00130     if (!m_handle) return;
cannam@0: 00131     m_descriptor->reset(m_handle);
cannam@0: 00132 }
cannam@0: 00133 
cannam@0: 00134 PluginHostAdapter::InputDomain
cannam@0: 00135 PluginHostAdapter::getInputDomain() const
cannam@0: 00136 {
cannam@0: 00137     if (m_descriptor->inputDomain == vampFrequencyDomain) {
cannam@0: 00138         return FrequencyDomain;
cannam@0: 00139     } else {
cannam@0: 00140         return TimeDomain;
cannam@0: 00141     }
cannam@0: 00142 }
cannam@0: 00143 
cannam@0: 00144 unsigned int
cannam@0: 00145 PluginHostAdapter::getVampApiVersion() const
cannam@0: 00146 {
cannam@0: 00147     return m_descriptor->vampApiVersion;
cannam@0: 00148 }
cannam@0: 00149 
cannam@0: 00150 std::string
cannam@0: 00151 PluginHostAdapter::getIdentifier() const
cannam@0: 00152 {
cannam@0: 00153     return m_descriptor->identifier;
cannam@0: 00154 }
cannam@0: 00155 
cannam@0: 00156 std::string
cannam@0: 00157 PluginHostAdapter::getName() const
cannam@0: 00158 {
cannam@0: 00159     return m_descriptor->name;
cannam@0: 00160 }
cannam@0: 00161 
cannam@0: 00162 std::string
cannam@0: 00163 PluginHostAdapter::getDescription() const
cannam@0: 00164 {
cannam@0: 00165     return m_descriptor->description;
cannam@0: 00166 }
cannam@0: 00167 
cannam@0: 00168 std::string
cannam@0: 00169 PluginHostAdapter::getMaker() const
cannam@0: 00170 {
cannam@0: 00171     return m_descriptor->maker;
cannam@0: 00172 }
cannam@0: 00173 
cannam@0: 00174 int
cannam@0: 00175 PluginHostAdapter::getPluginVersion() const
cannam@0: 00176 {
cannam@0: 00177     return m_descriptor->pluginVersion;
cannam@0: 00178 }
cannam@0: 00179 
cannam@0: 00180 std::string
cannam@0: 00181 PluginHostAdapter::getCopyright() const
cannam@0: 00182 {
cannam@0: 00183     return m_descriptor->copyright;
cannam@0: 00184 }
cannam@0: 00185 
cannam@0: 00186 PluginHostAdapter::ParameterList
cannam@0: 00187 PluginHostAdapter::getParameterDescriptors() const
cannam@0: 00188 {
cannam@0: 00189     ParameterList list;
cannam@0: 00190     for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@0: 00191         const VampParameterDescriptor *spd = m_descriptor->parameters[i];
cannam@0: 00192         ParameterDescriptor pd;
cannam@0: 00193         pd.identifier = spd->identifier;
cannam@0: 00194         pd.name = spd->name;
cannam@0: 00195         pd.description = spd->description;
cannam@0: 00196         pd.unit = spd->unit;
cannam@0: 00197         pd.minValue = spd->minValue;
cannam@0: 00198         pd.maxValue = spd->maxValue;
cannam@0: 00199         pd.defaultValue = spd->defaultValue;
cannam@0: 00200         pd.isQuantized = spd->isQuantized;
cannam@0: 00201         pd.quantizeStep = spd->quantizeStep;
cannam@0: 00202         if (pd.isQuantized && spd->valueNames) {
cannam@0: 00203             for (unsigned int j = 0; spd->valueNames[j]; ++j) {
cannam@0: 00204                 pd.valueNames.push_back(spd->valueNames[j]);
cannam@0: 00205             }
cannam@0: 00206         }
cannam@0: 00207         list.push_back(pd);
cannam@0: 00208     }
cannam@0: 00209     return list;
cannam@0: 00210 }
cannam@0: 00211 
cannam@0: 00212 float
cannam@0: 00213 PluginHostAdapter::getParameter(std::string param) const
cannam@0: 00214 {
cannam@0: 00215     if (!m_handle) return 0.0;
cannam@0: 00216 
cannam@0: 00217     for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@0: 00218         if (param == m_descriptor->parameters[i]->identifier) {
cannam@0: 00219             return m_descriptor->getParameter(m_handle, i);
cannam@0: 00220         }
cannam@0: 00221     }
cannam@0: 00222 
cannam@0: 00223     return 0.0;
cannam@0: 00224 }
cannam@0: 00225 
cannam@0: 00226 void
cannam@0: 00227 PluginHostAdapter::setParameter(std::string param, 
cannam@0: 00228                                 float value)
cannam@0: 00229 {
cannam@0: 00230     if (!m_handle) return;
cannam@0: 00231 
cannam@0: 00232     for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
cannam@0: 00233         if (param == m_descriptor->parameters[i]->identifier) {
cannam@0: 00234             m_descriptor->setParameter(m_handle, i, value);
cannam@0: 00235             return;
cannam@0: 00236         }
cannam@0: 00237     }
cannam@0: 00238 }
cannam@0: 00239 
cannam@0: 00240 PluginHostAdapter::ProgramList
cannam@0: 00241 PluginHostAdapter::getPrograms() const
cannam@0: 00242 {
cannam@0: 00243     ProgramList list;
cannam@0: 00244     
cannam@0: 00245     for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
cannam@0: 00246         list.push_back(m_descriptor->programs[i]);
cannam@0: 00247     }
cannam@0: 00248     
cannam@0: 00249     return list;
cannam@0: 00250 }
cannam@0: 00251 
cannam@0: 00252 std::string
cannam@0: 00253 PluginHostAdapter::getCurrentProgram() const
cannam@0: 00254 {
cannam@0: 00255     if (!m_handle) return "";
cannam@0: 00256 
cannam@0: 00257     int pn = m_descriptor->getCurrentProgram(m_handle);
cannam@0: 00258     return m_descriptor->programs[pn];
cannam@0: 00259 }
cannam@0: 00260 
cannam@0: 00261 void
cannam@0: 00262 PluginHostAdapter::selectProgram(std::string program)
cannam@0: 00263 {
cannam@0: 00264     if (!m_handle) return;
cannam@0: 00265 
cannam@0: 00266     for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
cannam@0: 00267         if (program == m_descriptor->programs[i]) {
cannam@0: 00268             m_descriptor->selectProgram(m_handle, i);
cannam@0: 00269             return;
cannam@0: 00270         }
cannam@0: 00271     }
cannam@0: 00272 }
cannam@0: 00273 
cannam@0: 00274 size_t
cannam@0: 00275 PluginHostAdapter::getPreferredStepSize() const
cannam@0: 00276 {
cannam@0: 00277     if (!m_handle) return 0;
cannam@0: 00278     return m_descriptor->getPreferredStepSize(m_handle);
cannam@0: 00279 }
cannam@0: 00280 
cannam@0: 00281 size_t
cannam@0: 00282 PluginHostAdapter::getPreferredBlockSize() const
cannam@0: 00283 {
cannam@0: 00284     if (!m_handle) return 0;
cannam@0: 00285     return m_descriptor->getPreferredBlockSize(m_handle);
cannam@0: 00286 }
cannam@0: 00287 
cannam@0: 00288 size_t
cannam@0: 00289 PluginHostAdapter::getMinChannelCount() const
cannam@0: 00290 {
cannam@0: 00291     if (!m_handle) return 0;
cannam@0: 00292     return m_descriptor->getMinChannelCount(m_handle);
cannam@0: 00293 }
cannam@0: 00294 
cannam@0: 00295 size_t
cannam@0: 00296 PluginHostAdapter::getMaxChannelCount() const
cannam@0: 00297 {
cannam@0: 00298     if (!m_handle) return 0;
cannam@0: 00299     return m_descriptor->getMaxChannelCount(m_handle);
cannam@0: 00300 }
cannam@0: 00301 
cannam@0: 00302 PluginHostAdapter::OutputList
cannam@0: 00303 PluginHostAdapter::getOutputDescriptors() const
cannam@0: 00304 {
cannam@0: 00305     OutputList list;
cannam@0: 00306     if (!m_handle) {
cannam@0: 00307 //        std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
cannam@0: 00308         return list;
cannam@0: 00309     }
cannam@0: 00310 
cannam@0: 00311     unsigned int count = m_descriptor->getOutputCount(m_handle);
cannam@0: 00312 
cannam@0: 00313     for (unsigned int i = 0; i < count; ++i) {
cannam@0: 00314         VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
cannam@0: 00315         OutputDescriptor d;
cannam@0: 00316         d.identifier = sd->identifier;
cannam@0: 00317         d.name = sd->name;
cannam@0: 00318         d.description = sd->description;
cannam@0: 00319         d.unit = sd->unit;
cannam@0: 00320         d.hasFixedBinCount = sd->hasFixedBinCount;
cannam@0: 00321         d.binCount = sd->binCount;
cannam@0: 00322         if (d.hasFixedBinCount) {
cannam@0: 00323             for (unsigned int j = 0; j < sd->binCount; ++j) {
cannam@0: 00324                 d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
cannam@0: 00325             }
cannam@0: 00326         }
cannam@0: 00327         d.hasKnownExtents = sd->hasKnownExtents;
cannam@0: 00328         d.minValue = sd->minValue;
cannam@0: 00329         d.maxValue = sd->maxValue;
cannam@0: 00330         d.isQuantized = sd->isQuantized;
cannam@0: 00331         d.quantizeStep = sd->quantizeStep;
cannam@0: 00332 
cannam@0: 00333         switch (sd->sampleType) {
cannam@0: 00334         case vampOneSamplePerStep:
cannam@0: 00335             d.sampleType = OutputDescriptor::OneSamplePerStep; break;
cannam@0: 00336         case vampFixedSampleRate:
cannam@0: 00337             d.sampleType = OutputDescriptor::FixedSampleRate; break;
cannam@0: 00338         case vampVariableSampleRate:
cannam@0: 00339             d.sampleType = OutputDescriptor::VariableSampleRate; break;
cannam@0: 00340         }
cannam@0: 00341 
cannam@0: 00342         d.sampleRate = sd->sampleRate;
cannam@0: 00343 
cannam@0: 00344         list.push_back(d);
cannam@0: 00345 
cannam@0: 00346         m_descriptor->releaseOutputDescriptor(sd);
cannam@0: 00347     }
cannam@0: 00348 
cannam@0: 00349     return list;
cannam@0: 00350 }
cannam@0: 00351 
cannam@0: 00352 PluginHostAdapter::FeatureSet
cannam@0: 00353 PluginHostAdapter::process(const float *const *inputBuffers,
cannam@0: 00354                            RealTime timestamp)
cannam@0: 00355 {
cannam@0: 00356     FeatureSet fs;
cannam@0: 00357     if (!m_handle) return fs;
cannam@0: 00358 
cannam@0: 00359     int sec = timestamp.sec;
cannam@0: 00360     int nsec = timestamp.nsec;
cannam@0: 00361     
cannam@0: 00362     VampFeatureList *features = m_descriptor->process(m_handle,
cannam@0: 00363                                                       inputBuffers,
cannam@0: 00364                                                       sec, nsec);
cannam@0: 00365     
cannam@0: 00366     convertFeatures(features, fs);
cannam@0: 00367     m_descriptor->releaseFeatureSet(features);
cannam@0: 00368     return fs;
cannam@0: 00369 }
cannam@0: 00370 
cannam@0: 00371 PluginHostAdapter::FeatureSet
cannam@0: 00372 PluginHostAdapter::getRemainingFeatures()
cannam@0: 00373 {
cannam@0: 00374     FeatureSet fs;
cannam@0: 00375     if (!m_handle) return fs;
cannam@0: 00376     
cannam@0: 00377     VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle); 
cannam@0: 00378 
cannam@0: 00379     convertFeatures(features, fs);
cannam@0: 00380     m_descriptor->releaseFeatureSet(features);
cannam@0: 00381     return fs;
cannam@0: 00382 }
cannam@0: 00383 
cannam@0: 00384 void
cannam@0: 00385 PluginHostAdapter::convertFeatures(VampFeatureList *features,
cannam@0: 00386                                    FeatureSet &fs)
cannam@0: 00387 {
cannam@0: 00388     if (!features) return;
cannam@0: 00389 
cannam@0: 00390     unsigned int outputs = m_descriptor->getOutputCount(m_handle);
cannam@0: 00391 
cannam@0: 00392     for (unsigned int i = 0; i < outputs; ++i) {
cannam@0: 00393         
cannam@0: 00394         VampFeatureList &list = features[i];
cannam@0: 00395 
cannam@0: 00396         if (list.featureCount > 0) {
cannam@0: 00397 
cannam@0: 00398             Feature feature;
cannam@0: 00399             feature.values.reserve(list.features[0].valueCount);
cannam@0: 00400 
cannam@0: 00401             for (unsigned int j = 0; j < list.featureCount; ++j) {
cannam@0: 00402 
cannam@0: 00403                 feature.hasTimestamp = list.features[j].hasTimestamp;
cannam@0: 00404                 feature.timestamp = RealTime(list.features[j].sec,
cannam@0: 00405                                              list.features[j].nsec);
cannam@0: 00406 
cannam@0: 00407                 for (unsigned int k = 0; k < list.features[j].valueCount; ++k) {
cannam@0: 00408                     feature.values.push_back(list.features[j].values[k]);
cannam@0: 00409                 }
cannam@0: 00410 
cannam@0: 00411                 if (list.features[j].label) {
cannam@0: 00412                     feature.label = list.features[j].label;
cannam@0: 00413                 }
cannam@0: 00414 
cannam@0: 00415                 fs[i].push_back(feature);
cannam@0: 00416 
cannam@0: 00417                 if (list.features[j].valueCount > 0) {
cannam@0: 00418                     feature.values.clear();
cannam@0: 00419                 }
cannam@0: 00420 
cannam@0: 00421                 if (list.features[j].label) {
cannam@0: 00422                     feature.label = "";
cannam@0: 00423                 }
cannam@0: 00424             }
cannam@0: 00425         }
cannam@0: 00426     }
cannam@0: 00427 }
cannam@0: 00428 
cannam@0: 00429 }
cannam@0: 
cannam@0:
Generated on Wed Jul 9 11:36:06 2008 for VampPluginSDK by  cannam@0: cannam@0: doxygen 1.5.5
cannam@0: cannam@0: