comparison 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
comparison
equal deleted inserted replaced
226:14029eb08472 227:6b30e064cab7
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2
3 /*
4 Vamp
5
6 An API for audio analysis and feature extraction plugins.
7
8 Centre for Digital Music, Queen Mary, University of London.
9 Copyright 2006 Chris Cannam.
10
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:
18
19 The above copyright notice and this permission notice shall be
20 included in all copies or substantial portions of the Software.
21
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.
29
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
34 authorization.
35 */
36
37 #include "PluginHostAdapter.h"
38 #include <cstdlib>
39
40 namespace Vamp
41 {
42
43 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
44 float inputSampleRate) :
45 Plugin(inputSampleRate),
46 m_descriptor(descriptor)
47 {
48 // std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
49 m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
50 if (!m_handle) {
51 // std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
52 }
53 }
54
55 PluginHostAdapter::~PluginHostAdapter()
56 {
57 // std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
58 if (m_handle) m_descriptor->cleanup(m_handle);
59 }
60
61 std::vector<std::string>
62 PluginHostAdapter::getPluginPath()
63 {
64 std::vector<std::string> path;
65 std::string envPath;
66
67 char *cpath = getenv("VAMP_PATH");
68 if (cpath) envPath = cpath;
69
70 #ifdef _WIN32
71 #define PATH_SEPARATOR ';'
72 #define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
73 #else
74 #define PATH_SEPARATOR ':'
75 #ifdef __APPLE__
76 #define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
77 #else
78 #define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
79 #endif
80 #endif
81
82 if (envPath == "") {
83 envPath = DEFAULT_VAMP_PATH;
84 char *chome = getenv("HOME");
85 if (chome) {
86 std::string home(chome);
87 std::string::size_type f;
88 while ((f = envPath.find("$HOME")) != std::string::npos &&
89 f < envPath.length()) {
90 envPath.replace(f, 5, home);
91 }
92 }
93 #ifdef _WIN32
94 char *cpfiles = getenv("ProgramFiles");
95 if (!cpfiles) cpfiles = "C:\\Program Files";
96 std::string pfiles(cpfiles);
97 std::string::size_type f;
98 while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
99 f < envPath.length()) {
100 envPath.replace(f, 14, pfiles);
101 }
102 #endif
103 }
104
105 std::string::size_type index = 0, newindex = 0;
106
107 while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
108 path.push_back(envPath.substr(index, newindex - index));
109 index = newindex + 1;
110 }
111
112 path.push_back(envPath.substr(index));
113
114 return path;
115 }
116
117 bool
118 PluginHostAdapter::initialise(size_t channels,
119 size_t stepSize,
120 size_t blockSize)
121 {
122 if (!m_handle) return false;
123 return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ?
124 true : false;
125 }
126
127 void
128 PluginHostAdapter::reset()
129 {
130 if (!m_handle) {
131 // std::cerr << "PluginHostAdapter::reset: no handle" << std::endl;
132 return;
133 }
134 // std::cerr << "PluginHostAdapter::reset(" << m_handle << ")" << std::endl;
135 m_descriptor->reset(m_handle);
136 }
137
138 PluginHostAdapter::InputDomain
139 PluginHostAdapter::getInputDomain() const
140 {
141 if (m_descriptor->inputDomain == vampFrequencyDomain) {
142 return FrequencyDomain;
143 } else {
144 return TimeDomain;
145 }
146 }
147
148 unsigned int
149 PluginHostAdapter::getVampApiVersion() const
150 {
151 return m_descriptor->vampApiVersion;
152 }
153
154 std::string
155 PluginHostAdapter::getIdentifier() const
156 {
157 return m_descriptor->identifier;
158 }
159
160 std::string
161 PluginHostAdapter::getName() const
162 {
163 return m_descriptor->name;
164 }
165
166 std::string
167 PluginHostAdapter::getDescription() const
168 {
169 return m_descriptor->description;
170 }
171
172 std::string
173 PluginHostAdapter::getMaker() const
174 {
175 return m_descriptor->maker;
176 }
177
178 int
179 PluginHostAdapter::getPluginVersion() const
180 {
181 return m_descriptor->pluginVersion;
182 }
183
184 std::string
185 PluginHostAdapter::getCopyright() const
186 {
187 return m_descriptor->copyright;
188 }
189
190 PluginHostAdapter::ParameterList
191 PluginHostAdapter::getParameterDescriptors() const
192 {
193 ParameterList list;
194 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
195 const VampParameterDescriptor *spd = m_descriptor->parameters[i];
196 ParameterDescriptor pd;
197 pd.identifier = spd->identifier;
198 pd.name = spd->name;
199 pd.description = spd->description;
200 pd.unit = spd->unit;
201 pd.minValue = spd->minValue;
202 pd.maxValue = spd->maxValue;
203 pd.defaultValue = spd->defaultValue;
204 pd.isQuantized = spd->isQuantized;
205 pd.quantizeStep = spd->quantizeStep;
206 if (pd.isQuantized && spd->valueNames) {
207 for (unsigned int j = 0; spd->valueNames[j]; ++j) {
208 pd.valueNames.push_back(spd->valueNames[j]);
209 }
210 }
211 list.push_back(pd);
212 }
213 return list;
214 }
215
216 float
217 PluginHostAdapter::getParameter(std::string param) const
218 {
219 if (!m_handle) return 0.0;
220
221 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
222 if (param == m_descriptor->parameters[i]->identifier) {
223 return m_descriptor->getParameter(m_handle, i);
224 }
225 }
226
227 return 0.0;
228 }
229
230 void
231 PluginHostAdapter::setParameter(std::string param,
232 float value)
233 {
234 if (!m_handle) return;
235
236 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
237 if (param == m_descriptor->parameters[i]->identifier) {
238 m_descriptor->setParameter(m_handle, i, value);
239 return;
240 }
241 }
242 }
243
244 PluginHostAdapter::ProgramList
245 PluginHostAdapter::getPrograms() const
246 {
247 ProgramList list;
248
249 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
250 list.push_back(m_descriptor->programs[i]);
251 }
252
253 return list;
254 }
255
256 std::string
257 PluginHostAdapter::getCurrentProgram() const
258 {
259 if (!m_handle) return "";
260
261 int pn = m_descriptor->getCurrentProgram(m_handle);
262 return m_descriptor->programs[pn];
263 }
264
265 void
266 PluginHostAdapter::selectProgram(std::string program)
267 {
268 if (!m_handle) return;
269
270 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
271 if (program == m_descriptor->programs[i]) {
272 m_descriptor->selectProgram(m_handle, i);
273 return;
274 }
275 }
276 }
277
278 size_t
279 PluginHostAdapter::getPreferredStepSize() const
280 {
281 if (!m_handle) return 0;
282 return m_descriptor->getPreferredStepSize(m_handle);
283 }
284
285 size_t
286 PluginHostAdapter::getPreferredBlockSize() const
287 {
288 if (!m_handle) return 0;
289 return m_descriptor->getPreferredBlockSize(m_handle);
290 }
291
292 size_t
293 PluginHostAdapter::getMinChannelCount() const
294 {
295 if (!m_handle) return 0;
296 return m_descriptor->getMinChannelCount(m_handle);
297 }
298
299 size_t
300 PluginHostAdapter::getMaxChannelCount() const
301 {
302 if (!m_handle) return 0;
303 return m_descriptor->getMaxChannelCount(m_handle);
304 }
305
306 PluginHostAdapter::OutputList
307 PluginHostAdapter::getOutputDescriptors() const
308 {
309 OutputList list;
310 if (!m_handle) {
311 // std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
312 return list;
313 }
314
315 unsigned int count = m_descriptor->getOutputCount(m_handle);
316
317 for (unsigned int i = 0; i < count; ++i) {
318 VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
319 OutputDescriptor d;
320 d.identifier = sd->identifier;
321 d.name = sd->name;
322 d.description = sd->description;
323 d.unit = sd->unit;
324 d.hasFixedBinCount = sd->hasFixedBinCount;
325 d.binCount = sd->binCount;
326 if (d.hasFixedBinCount) {
327 for (unsigned int j = 0; j < sd->binCount; ++j) {
328 d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
329 }
330 }
331 d.hasKnownExtents = sd->hasKnownExtents;
332 d.minValue = sd->minValue;
333 d.maxValue = sd->maxValue;
334 d.isQuantized = sd->isQuantized;
335 d.quantizeStep = sd->quantizeStep;
336
337 switch (sd->sampleType) {
338 case vampOneSamplePerStep:
339 d.sampleType = OutputDescriptor::OneSamplePerStep; break;
340 case vampFixedSampleRate:
341 d.sampleType = OutputDescriptor::FixedSampleRate; break;
342 case vampVariableSampleRate:
343 d.sampleType = OutputDescriptor::VariableSampleRate; break;
344 }
345
346 d.sampleRate = sd->sampleRate;
347
348 if (m_descriptor->vampApiVersion >= 2) {
349 d.hasDuration = sd->hasDuration;
350 } else {
351 d.hasDuration = false;
352 }
353
354 list.push_back(d);
355
356 m_descriptor->releaseOutputDescriptor(sd);
357 }
358
359 return list;
360 }
361
362 PluginHostAdapter::FeatureSet
363 PluginHostAdapter::process(const float *const *inputBuffers,
364 RealTime timestamp)
365 {
366 FeatureSet fs;
367 if (!m_handle) return fs;
368
369 int sec = timestamp.sec;
370 int nsec = timestamp.nsec;
371
372 VampFeatureList *features = m_descriptor->process(m_handle,
373 inputBuffers,
374 sec, nsec);
375
376 convertFeatures(features, fs);
377 m_descriptor->releaseFeatureSet(features);
378 return fs;
379 }
380
381 PluginHostAdapter::FeatureSet
382 PluginHostAdapter::getRemainingFeatures()
383 {
384 FeatureSet fs;
385 if (!m_handle) return fs;
386
387 VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle);
388
389 convertFeatures(features, fs);
390 m_descriptor->releaseFeatureSet(features);
391 return fs;
392 }
393
394 void
395 PluginHostAdapter::convertFeatures(VampFeatureList *features,
396 FeatureSet &fs)
397 {
398 if (!features) return;
399
400 unsigned int outputs = m_descriptor->getOutputCount(m_handle);
401
402 for (unsigned int i = 0; i < outputs; ++i) {
403
404 VampFeatureList &list = features[i];
405
406 if (list.featureCount > 0) {
407
408 Feature feature;
409 feature.values.reserve(list.features[0].v1.valueCount);
410
411 for (unsigned int j = 0; j < list.featureCount; ++j) {
412
413 feature.hasTimestamp = list.features[j].v1.hasTimestamp;
414 feature.timestamp = RealTime(list.features[j].v1.sec,
415 list.features[j].v1.nsec);
416 feature.hasDuration = false;
417
418 if (m_descriptor->vampApiVersion >= 2) {
419 unsigned int j2 = j + list.featureCount;
420 feature.hasDuration = list.features[j2].v2.hasDuration;
421 feature.duration = RealTime(list.features[j2].v2.durationSec,
422 list.features[j2].v2.durationNsec);
423 }
424
425 for (unsigned int k = 0; k < list.features[j].v1.valueCount; ++k) {
426 feature.values.push_back(list.features[j].v1.values[k]);
427 }
428
429 if (list.features[j].v1.label) {
430 feature.label = list.features[j].v1.label;
431 }
432
433 fs[i].push_back(feature);
434
435 if (list.features[j].v1.valueCount > 0) {
436 feature.values.clear();
437 }
438
439 if (list.features[j].v1.label) {
440 feature.label = "";
441 }
442 }
443 }
444 }
445 }
446
447 }