Mercurial > hg > vamp-plugin-sdk
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 } |