Mercurial > hg > vamp-plugin-sdk
comparison vamp-sdk/PluginHostAdapter.cpp @ 58:0284955e31e5 host-factory-stuff
* reshuffle
author | cannam |
---|---|
date | Thu, 24 May 2007 10:05:00 +0000 |
parents | vamp-hostsdk/PluginHostAdapter.cpp@4ab6224110ef |
children |
comparison
equal
deleted
inserted
replaced
57:09a1aac6c362 | 58:0284955e31e5 |
---|---|
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 | |
39 namespace Vamp | |
40 { | |
41 | |
42 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor, | |
43 float inputSampleRate) : | |
44 Plugin(inputSampleRate), | |
45 m_descriptor(descriptor) | |
46 { | |
47 // std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl; | |
48 m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate); | |
49 if (!m_handle) { | |
50 // std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl; | |
51 } | |
52 } | |
53 | |
54 PluginHostAdapter::~PluginHostAdapter() | |
55 { | |
56 // std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl; | |
57 if (m_handle) m_descriptor->cleanup(m_handle); | |
58 } | |
59 | |
60 std::vector<std::string> | |
61 PluginHostAdapter::getPluginPath() | |
62 { | |
63 std::vector<std::string> path; | |
64 std::string envPath; | |
65 | |
66 char *cpath = getenv("VAMP_PATH"); | |
67 if (cpath) envPath = cpath; | |
68 | |
69 #ifdef _WIN32 | |
70 #define PATH_SEPARATOR ';' | |
71 #define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins" | |
72 #else | |
73 #define PATH_SEPARATOR ':' | |
74 #ifdef __APPLE__ | |
75 #define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp" | |
76 #else | |
77 #define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp" | |
78 #endif | |
79 #endif | |
80 | |
81 if (envPath == "") { | |
82 envPath = DEFAULT_VAMP_PATH; | |
83 char *chome = getenv("HOME"); | |
84 if (chome) { | |
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); | |
90 } | |
91 } | |
92 #ifdef _WIN32 | |
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); | |
100 } | |
101 #endif | |
102 } | |
103 | |
104 std::string::size_type index = 0, newindex = 0; | |
105 | |
106 while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) { | |
107 path.push_back(envPath.substr(index, newindex - index)); | |
108 index = newindex + 1; | |
109 } | |
110 | |
111 path.push_back(envPath.substr(index)); | |
112 | |
113 return path; | |
114 } | |
115 | |
116 bool | |
117 PluginHostAdapter::initialise(size_t channels, | |
118 size_t stepSize, | |
119 size_t blockSize) | |
120 { | |
121 if (!m_handle) return false; | |
122 return m_descriptor->initialise(m_handle, channels, stepSize, blockSize) ? | |
123 true : false; | |
124 } | |
125 | |
126 void | |
127 PluginHostAdapter::reset() | |
128 { | |
129 if (!m_handle) return; | |
130 m_descriptor->reset(m_handle); | |
131 } | |
132 | |
133 PluginHostAdapter::InputDomain | |
134 PluginHostAdapter::getInputDomain() const | |
135 { | |
136 if (m_descriptor->inputDomain == vampFrequencyDomain) { | |
137 return FrequencyDomain; | |
138 } else { | |
139 return TimeDomain; | |
140 } | |
141 } | |
142 | |
143 unsigned int | |
144 PluginHostAdapter::getVampApiVersion() const | |
145 { | |
146 return m_descriptor->vampApiVersion; | |
147 } | |
148 | |
149 std::string | |
150 PluginHostAdapter::getIdentifier() const | |
151 { | |
152 return m_descriptor->identifier; | |
153 } | |
154 | |
155 std::string | |
156 PluginHostAdapter::getName() const | |
157 { | |
158 return m_descriptor->name; | |
159 } | |
160 | |
161 std::string | |
162 PluginHostAdapter::getDescription() const | |
163 { | |
164 return m_descriptor->description; | |
165 } | |
166 | |
167 std::string | |
168 PluginHostAdapter::getMaker() const | |
169 { | |
170 return m_descriptor->maker; | |
171 } | |
172 | |
173 int | |
174 PluginHostAdapter::getPluginVersion() const | |
175 { | |
176 return m_descriptor->pluginVersion; | |
177 } | |
178 | |
179 std::string | |
180 PluginHostAdapter::getCopyright() const | |
181 { | |
182 return m_descriptor->copyright; | |
183 } | |
184 | |
185 PluginHostAdapter::ParameterList | |
186 PluginHostAdapter::getParameterDescriptors() const | |
187 { | |
188 ParameterList list; | |
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; | |
193 pd.name = spd->name; | |
194 pd.description = spd->description; | |
195 pd.unit = spd->unit; | |
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]); | |
204 } | |
205 } | |
206 list.push_back(pd); | |
207 } | |
208 return list; | |
209 } | |
210 | |
211 float | |
212 PluginHostAdapter::getParameter(std::string param) const | |
213 { | |
214 if (!m_handle) return 0.0; | |
215 | |
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); | |
219 } | |
220 } | |
221 | |
222 return 0.0; | |
223 } | |
224 | |
225 void | |
226 PluginHostAdapter::setParameter(std::string param, | |
227 float value) | |
228 { | |
229 if (!m_handle) return; | |
230 | |
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); | |
234 return; | |
235 } | |
236 } | |
237 } | |
238 | |
239 PluginHostAdapter::ProgramList | |
240 PluginHostAdapter::getPrograms() const | |
241 { | |
242 ProgramList list; | |
243 | |
244 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) { | |
245 list.push_back(m_descriptor->programs[i]); | |
246 } | |
247 | |
248 return list; | |
249 } | |
250 | |
251 std::string | |
252 PluginHostAdapter::getCurrentProgram() const | |
253 { | |
254 if (!m_handle) return ""; | |
255 | |
256 int pn = m_descriptor->getCurrentProgram(m_handle); | |
257 return m_descriptor->programs[pn]; | |
258 } | |
259 | |
260 void | |
261 PluginHostAdapter::selectProgram(std::string program) | |
262 { | |
263 if (!m_handle) return; | |
264 | |
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); | |
268 return; | |
269 } | |
270 } | |
271 } | |
272 | |
273 size_t | |
274 PluginHostAdapter::getPreferredStepSize() const | |
275 { | |
276 if (!m_handle) return 0; | |
277 return m_descriptor->getPreferredStepSize(m_handle); | |
278 } | |
279 | |
280 size_t | |
281 PluginHostAdapter::getPreferredBlockSize() const | |
282 { | |
283 if (!m_handle) return 0; | |
284 return m_descriptor->getPreferredBlockSize(m_handle); | |
285 } | |
286 | |
287 size_t | |
288 PluginHostAdapter::getMinChannelCount() const | |
289 { | |
290 if (!m_handle) return 0; | |
291 return m_descriptor->getMinChannelCount(m_handle); | |
292 } | |
293 | |
294 size_t | |
295 PluginHostAdapter::getMaxChannelCount() const | |
296 { | |
297 if (!m_handle) return 0; | |
298 return m_descriptor->getMaxChannelCount(m_handle); | |
299 } | |
300 | |
301 PluginHostAdapter::OutputList | |
302 PluginHostAdapter::getOutputDescriptors() const | |
303 { | |
304 OutputList list; | |
305 if (!m_handle) { | |
306 // std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl; | |
307 return list; | |
308 } | |
309 | |
310 unsigned int count = m_descriptor->getOutputCount(m_handle); | |
311 | |
312 for (unsigned int i = 0; i < count; ++i) { | |
313 VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i); | |
314 OutputDescriptor d; | |
315 d.identifier = sd->identifier; | |
316 d.name = sd->name; | |
317 d.description = sd->description; | |
318 d.unit = sd->unit; | |
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] : ""); | |
324 } | |
325 } | |
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; | |
331 | |
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; | |
339 } | |
340 | |
341 d.sampleRate = sd->sampleRate; | |
342 | |
343 list.push_back(d); | |
344 | |
345 m_descriptor->releaseOutputDescriptor(sd); | |
346 } | |
347 | |
348 return list; | |
349 } | |
350 | |
351 PluginHostAdapter::FeatureSet | |
352 PluginHostAdapter::process(const float *const *inputBuffers, | |
353 RealTime timestamp) | |
354 { | |
355 FeatureSet fs; | |
356 if (!m_handle) return fs; | |
357 | |
358 int sec = timestamp.sec; | |
359 int nsec = timestamp.nsec; | |
360 | |
361 VampFeatureList *features = m_descriptor->process(m_handle, | |
362 inputBuffers, | |
363 sec, nsec); | |
364 | |
365 convertFeatures(features, fs); | |
366 m_descriptor->releaseFeatureSet(features); | |
367 return fs; | |
368 } | |
369 | |
370 PluginHostAdapter::FeatureSet | |
371 PluginHostAdapter::getRemainingFeatures() | |
372 { | |
373 FeatureSet fs; | |
374 if (!m_handle) return fs; | |
375 | |
376 VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle); | |
377 | |
378 convertFeatures(features, fs); | |
379 m_descriptor->releaseFeatureSet(features); | |
380 return fs; | |
381 } | |
382 | |
383 void | |
384 PluginHostAdapter::convertFeatures(VampFeatureList *features, | |
385 FeatureSet &fs) | |
386 { | |
387 if (!features) return; | |
388 | |
389 unsigned int outputs = m_descriptor->getOutputCount(m_handle); | |
390 | |
391 for (unsigned int i = 0; i < outputs; ++i) { | |
392 | |
393 VampFeatureList &list = features[i]; | |
394 | |
395 if (list.featureCount > 0) { | |
396 | |
397 for (unsigned int j = 0; j < list.featureCount; ++j) { | |
398 | |
399 Feature feature; | |
400 feature.hasTimestamp = list.features[j].hasTimestamp; | |
401 feature.timestamp = RealTime(list.features[j].sec, | |
402 list.features[j].nsec); | |
403 | |
404 for (unsigned int k = 0; k < list.features[j].valueCount; ++k) { | |
405 feature.values.push_back(list.features[j].values[k]); | |
406 } | |
407 | |
408 if (list.features[j].label) { | |
409 feature.label = list.features[j].label; | |
410 } | |
411 | |
412 fs[i].push_back(feature); | |
413 } | |
414 } | |
415 } | |
416 } | |
417 | |
418 } |