1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
6 An API for audio analysis and feature extraction plugins.
8 Centre for Digital Music, Queen Mary, University of London.
9 Copyright 2006 Chris Cannam.
11 Permission is hereby granted, free of charge, to any person
12 obtaining a copy of this software and associated documentation
13 files (the "Software"), to deal in the Software without
14 restriction, including without limitation the rights to use, copy,
15 modify, merge, publish, distribute, sublicense, and/or sell copies
16 of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 Except as contained in this notice, the names of the Centre for
31 Digital Music; Queen Mary, University of London; and Chris Cannam
32 shall not be used in advertising or otherwise to promote the sale,
33 use or other dealings in this Software without prior written
37 #include "PluginHostAdapter.h"
42 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
43 float inputSampleRate) :
44 Plugin(inputSampleRate),
45 m_descriptor(descriptor)
47 // std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
48 m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
50 // std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
54 PluginHostAdapter::~PluginHostAdapter()
56 // std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
57 if (m_handle) m_descriptor->cleanup(m_handle);
60 std::vector<std::string>
61 PluginHostAdapter::getPluginPath()
63 std::vector<std::string> path;
66 char *cpath = getenv("VAMP_PATH");
67 if (cpath) envPath = cpath;
70 #define PATH_SEPARATOR ';'
71 #define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
73 #define PATH_SEPARATOR ':'
75 #define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
77 #define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
82 envPath = DEFAULT_VAMP_PATH;
83 char *chome = getenv("HOME");
85 std::string home(chome);
86 std::string::size_type f;
87 while ((f = envPath.find("$HOME")) != std::string::npos &&
88 f < envPath.length()) {
89 envPath.replace(f, 5, home);
93 char *cpfiles = getenv("ProgramFiles");
94 if (!cpfiles) cpfiles = "C:\\Program Files";
95 std::string pfiles(cpfiles);
96 std::string::size_type f;
97 while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
98 f < envPath.length()) {
99 envPath.replace(f, 14, pfiles);
104 std::string::size_type index = 0, newindex = 0;
106 while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
107 path.push_back(envPath.substr(index, newindex - index));
108 index = newindex + 1;
111 path.push_back(envPath.substr(index));
117 PluginHostAdapter::initialise(size_t channels,
121 if (!m_handle) return false;
122 return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
127 PluginHostAdapter::reset()
129 if (!m_handle) return;
130 m_descriptor->reset(m_handle);
133 PluginHostAdapter::InputDomain
134 PluginHostAdapter::getInputDomain() const
136 if (m_descriptor->inputDomain == vampFrequencyDomain) {
137 return FrequencyDomain;
144 PluginHostAdapter::getVampApiVersion() const
146 return m_descriptor->vampApiVersion;
150 PluginHostAdapter::getIdentifier() const
152 return m_descriptor->identifier;
156 PluginHostAdapter::getName() const
158 return m_descriptor->name;
162 PluginHostAdapter::getDescription() const
164 return m_descriptor->description;
168 PluginHostAdapter::getMaker() const
170 return m_descriptor->maker;
174 PluginHostAdapter::getPluginVersion() const
176 return m_descriptor->pluginVersion;
180 PluginHostAdapter::getCopyright() const
182 return m_descriptor->copyright;
185 PluginHostAdapter::ParameterList
186 PluginHostAdapter::getParameterDescriptors() const
189 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
190 const VampParameterDescriptor *spd = m_descriptor->parameters[i];
191 ParameterDescriptor pd;
192 pd.identifier = spd->identifier;
194 pd.description = spd->description;
196 pd.minValue = spd->minValue;
197 pd.maxValue = spd->maxValue;
198 pd.defaultValue = spd->defaultValue;
199 pd.isQuantized = spd->isQuantized;
200 pd.quantizeStep = spd->quantizeStep;
201 if (pd.isQuantized && spd->valueNames) {
202 for (unsigned int j = 0; spd->valueNames[j]; ++j) {
203 pd.valueNames.push_back(spd->valueNames[j]);
212 PluginHostAdapter::getParameter(std::string param) const
214 if (!m_handle) return 0.0;
216 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
217 if (param == m_descriptor->parameters[i]->identifier) {
218 return m_descriptor->getParameter(m_handle, i);
226 PluginHostAdapter::setParameter(std::string param,
229 if (!m_handle) return;
231 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
232 if (param == m_descriptor->parameters[i]->identifier) {
233 m_descriptor->setParameter(m_handle, i, value);
239 PluginHostAdapter::ProgramList
240 PluginHostAdapter::getPrograms() const
244 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
245 list.push_back(m_descriptor->programs[i]);
252 PluginHostAdapter::getCurrentProgram() const
254 if (!m_handle) return "";
256 int pn = m_descriptor->getCurrentProgram(m_handle);
257 return m_descriptor->programs[pn];
261 PluginHostAdapter::selectProgram(std::string program)
263 if (!m_handle) return;
265 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
266 if (program == m_descriptor->programs[i]) {
267 m_descriptor->selectProgram(m_handle, i);
274 PluginHostAdapter::getPreferredStepSize() const
276 if (!m_handle) return 0;
277 return m_descriptor->getPreferredStepSize(m_handle);
281 PluginHostAdapter::getPreferredBlockSize() const
283 if (!m_handle) return 0;
284 return m_descriptor->getPreferredBlockSize(m_handle);
288 PluginHostAdapter::getMinChannelCount() const
290 if (!m_handle) return 0;
291 return m_descriptor->getMinChannelCount(m_handle);
295 PluginHostAdapter::getMaxChannelCount() const
297 if (!m_handle) return 0;
298 return m_descriptor->getMaxChannelCount(m_handle);
301 PluginHostAdapter::OutputList
302 PluginHostAdapter::getOutputDescriptors() const
306 // std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
310 unsigned int count = m_descriptor->getOutputCount(m_handle);
312 for (unsigned int i = 0; i < count; ++i) {
313 VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
315 d.identifier = sd->identifier;
317 d.description = sd->description;
319 d.hasFixedBinCount = sd->hasFixedBinCount;
320 d.binCount = sd->binCount;
321 if (d.hasFixedBinCount) {
322 for (unsigned int j = 0; j < sd->binCount; ++j) {
323 d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
326 d.hasKnownExtents = sd->hasKnownExtents;
327 d.minValue = sd->minValue;
328 d.maxValue = sd->maxValue;
329 d.isQuantized = sd->isQuantized;
330 d.quantizeStep = sd->quantizeStep;
332 switch (sd->sampleType) {
333 case vampOneSamplePerStep:
334 d.sampleType = OutputDescriptor::OneSamplePerStep; break;
335 case vampFixedSampleRate:
336 d.sampleType = OutputDescriptor::FixedSampleRate; break;
337 case vampVariableSampleRate:
338 d.sampleType = OutputDescriptor::VariableSampleRate; break;
341 d.sampleRate = sd->sampleRate;
345 m_descriptor->releaseOutputDescriptor(sd);
351 PluginHostAdapter::FeatureSet
352 PluginHostAdapter::process(const float *const *inputBuffers,
356 if (!m_handle) return fs;
358 int sec = timestamp.sec;
359 int nsec = timestamp.nsec;
361 VampFeatureList *features = m_descriptor->process(m_handle,
365 convertFeatures(features, fs);
366 m_descriptor->releaseFeatureSet(features);
370 PluginHostAdapter::FeatureSet
371 PluginHostAdapter::getRemainingFeatures()
374 if (!m_handle) return fs;
376 VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle);
378 convertFeatures(features, fs);
379 m_descriptor->releaseFeatureSet(features);
384 PluginHostAdapter::convertFeatures(VampFeatureList *features,
387 if (!features) return;
389 unsigned int outputs = m_descriptor->getOutputCount(m_handle);
391 for (unsigned int i = 0; i < outputs; ++i) {
393 VampFeatureList &list = features[i];
395 if (list.featureCount > 0) {
397 for (unsigned int j = 0; j < list.featureCount; ++j) {
400 feature.hasTimestamp = list.features[j].hasTimestamp;
401 feature.timestamp = RealTime(list.features[j].sec,
402 list.features[j].nsec);
404 for (unsigned int k = 0; k < list.features[j].valueCount; ++k) {
405 feature.values.push_back(list.features[j].values[k]);
408 if (list.features[j].label) {
409 feature.label = list.features[j].label;
412 fs[i].push_back(feature);