cannam@1
|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
cannam@1
|
2
|
cannam@1
|
3 /*
|
cannam@1
|
4 Vamp
|
cannam@1
|
5
|
cannam@1
|
6 An API for audio analysis and feature extraction plugins.
|
cannam@1
|
7
|
cannam@1
|
8 Centre for Digital Music, Queen Mary, University of London.
|
cannam@1
|
9 Copyright 2006 Chris Cannam.
|
cannam@1
|
10
|
cannam@1
|
11 Permission is hereby granted, free of charge, to any person
|
cannam@1
|
12 obtaining a copy of this software and associated documentation
|
cannam@1
|
13 files (the "Software"), to deal in the Software without
|
cannam@1
|
14 restriction, including without limitation the rights to use, copy,
|
cannam@1
|
15 modify, merge, publish, distribute, sublicense, and/or sell copies
|
cannam@1
|
16 of the Software, and to permit persons to whom the Software is
|
cannam@1
|
17 furnished to do so, subject to the following conditions:
|
cannam@1
|
18
|
cannam@1
|
19 The above copyright notice and this permission notice shall be
|
cannam@1
|
20 included in all copies or substantial portions of the Software.
|
cannam@1
|
21
|
cannam@1
|
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
cannam@1
|
23 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
cannam@1
|
24 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
cannam@6
|
25 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
|
cannam@1
|
26 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
|
cannam@1
|
27 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
cannam@1
|
28 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
cannam@1
|
29
|
cannam@1
|
30 Except as contained in this notice, the names of the Centre for
|
cannam@1
|
31 Digital Music; Queen Mary, University of London; and Chris Cannam
|
cannam@1
|
32 shall not be used in advertising or otherwise to promote the sale,
|
cannam@1
|
33 use or other dealings in this Software without prior written
|
cannam@1
|
34 authorization.
|
cannam@1
|
35 */
|
cannam@1
|
36
|
cannam@230
|
37 #include <vamp-hostsdk/PluginHostAdapter.h>
|
cannam@130
|
38 #include <cstdlib>
|
cannam@1
|
39
|
Chris@512
|
40 #include "Files.h"
|
Chris@512
|
41
|
Chris@539
|
42 #if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 10 )
|
cannam@308
|
43 #error Unexpected version of Vamp SDK header included
|
cannam@234
|
44 #endif
|
cannam@234
|
45
|
cannam@263
|
46 _VAMP_SDK_HOSTSPACE_BEGIN(PluginHostAdapter.cpp)
|
cannam@263
|
47
|
cannam@1
|
48 namespace Vamp
|
cannam@1
|
49 {
|
cannam@1
|
50
|
cannam@1
|
51 PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
|
cannam@1
|
52 float inputSampleRate) :
|
cannam@1
|
53 Plugin(inputSampleRate),
|
cannam@1
|
54 m_descriptor(descriptor)
|
cannam@1
|
55 {
|
cannam@15
|
56 // std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
|
cannam@1
|
57 m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
|
cannam@15
|
58 if (!m_handle) {
|
cannam@15
|
59 // std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
|
cannam@15
|
60 }
|
cannam@1
|
61 }
|
cannam@1
|
62
|
cannam@1
|
63 PluginHostAdapter::~PluginHostAdapter()
|
cannam@1
|
64 {
|
cannam@15
|
65 // std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
|
cannam@1
|
66 if (m_handle) m_descriptor->cleanup(m_handle);
|
cannam@1
|
67 }
|
cannam@1
|
68
|
cannam@32
|
69 std::vector<std::string>
|
cannam@32
|
70 PluginHostAdapter::getPluginPath()
|
cannam@32
|
71 {
|
cannam@32
|
72 std::vector<std::string> path;
|
cannam@32
|
73 std::string envPath;
|
cannam@32
|
74
|
Chris@513
|
75 if (Files::isNonNative32Bit()) {
|
Chris@513
|
76 (void)Files::getEnvUtf8("VAMP_PATH_32", envPath);
|
Chris@513
|
77 } else {
|
Chris@513
|
78 (void)Files::getEnvUtf8("VAMP_PATH", envPath);
|
Chris@513
|
79 }
|
cannam@32
|
80
|
cannam@32
|
81 #ifdef _WIN32
|
cannam@32
|
82 #define PATH_SEPARATOR ';'
|
cannam@32
|
83 #define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
|
cannam@32
|
84 #else
|
cannam@32
|
85 #define PATH_SEPARATOR ':'
|
cannam@32
|
86 #ifdef __APPLE__
|
cannam@35
|
87 #define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
|
cannam@32
|
88 #else
|
cannam@35
|
89 #define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
|
cannam@32
|
90 #endif
|
cannam@32
|
91 #endif
|
cannam@32
|
92
|
cannam@32
|
93 if (envPath == "") {
|
cannam@32
|
94 envPath = DEFAULT_VAMP_PATH;
|
Chris@512
|
95 std::string home;
|
Chris@512
|
96 if (Files::getEnvUtf8("HOME", home)) {
|
cannam@32
|
97 std::string::size_type f;
|
cannam@32
|
98 while ((f = envPath.find("$HOME")) != std::string::npos &&
|
cannam@32
|
99 f < envPath.length()) {
|
cannam@32
|
100 envPath.replace(f, 5, home);
|
cannam@32
|
101 }
|
cannam@32
|
102 }
|
cannam@32
|
103 #ifdef _WIN32
|
Chris@512
|
104 std::string pfiles;
|
Chris@512
|
105 if (!Files::getEnvUtf8("ProgramFiles", pfiles)) {
|
Chris@512
|
106 pfiles = "C:\\Program Files";
|
Chris@512
|
107 }
|
cannam@32
|
108 std::string::size_type f;
|
cannam@32
|
109 while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
|
cannam@32
|
110 f < envPath.length()) {
|
cannam@32
|
111 envPath.replace(f, 14, pfiles);
|
cannam@32
|
112 }
|
cannam@32
|
113 #endif
|
cannam@32
|
114 }
|
cannam@32
|
115
|
cannam@32
|
116 std::string::size_type index = 0, newindex = 0;
|
cannam@32
|
117
|
cannam@32
|
118 while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
|
cannam@32
|
119 path.push_back(envPath.substr(index, newindex - index));
|
cannam@32
|
120 index = newindex + 1;
|
cannam@32
|
121 }
|
cannam@32
|
122
|
cannam@32
|
123 path.push_back(envPath.substr(index));
|
cannam@32
|
124
|
cannam@32
|
125 return path;
|
cannam@32
|
126 }
|
cannam@32
|
127
|
cannam@1
|
128 bool
|
cannam@1
|
129 PluginHostAdapter::initialise(size_t channels,
|
cannam@1
|
130 size_t stepSize,
|
cannam@1
|
131 size_t blockSize)
|
cannam@1
|
132 {
|
cannam@1
|
133 if (!m_handle) return false;
|
Chris@421
|
134 return m_descriptor->initialise
|
Chris@421
|
135 (m_handle,
|
Chris@421
|
136 (unsigned int)channels,
|
Chris@421
|
137 (unsigned int)stepSize,
|
Chris@421
|
138 (unsigned int)blockSize) ?
|
cannam@1
|
139 true : false;
|
cannam@1
|
140 }
|
cannam@1
|
141
|
cannam@1
|
142 void
|
cannam@1
|
143 PluginHostAdapter::reset()
|
cannam@1
|
144 {
|
cannam@197
|
145 if (!m_handle) {
|
cannam@197
|
146 // std::cerr << "PluginHostAdapter::reset: no handle" << std::endl;
|
cannam@197
|
147 return;
|
cannam@197
|
148 }
|
cannam@197
|
149 // std::cerr << "PluginHostAdapter::reset(" << m_handle << ")" << std::endl;
|
cannam@1
|
150 m_descriptor->reset(m_handle);
|
cannam@1
|
151 }
|
cannam@1
|
152
|
cannam@1
|
153 PluginHostAdapter::InputDomain
|
cannam@1
|
154 PluginHostAdapter::getInputDomain() const
|
cannam@1
|
155 {
|
cannam@1
|
156 if (m_descriptor->inputDomain == vampFrequencyDomain) {
|
cannam@1
|
157 return FrequencyDomain;
|
cannam@1
|
158 } else {
|
cannam@1
|
159 return TimeDomain;
|
cannam@1
|
160 }
|
cannam@1
|
161 }
|
cannam@1
|
162
|
cannam@50
|
163 unsigned int
|
cannam@50
|
164 PluginHostAdapter::getVampApiVersion() const
|
cannam@50
|
165 {
|
cannam@50
|
166 return m_descriptor->vampApiVersion;
|
cannam@50
|
167 }
|
cannam@50
|
168
|
cannam@1
|
169 std::string
|
cannam@49
|
170 PluginHostAdapter::getIdentifier() const
|
cannam@49
|
171 {
|
cannam@49
|
172 return m_descriptor->identifier;
|
cannam@49
|
173 }
|
cannam@49
|
174
|
cannam@49
|
175 std::string
|
cannam@1
|
176 PluginHostAdapter::getName() const
|
cannam@1
|
177 {
|
cannam@1
|
178 return m_descriptor->name;
|
cannam@1
|
179 }
|
cannam@1
|
180
|
cannam@1
|
181 std::string
|
cannam@1
|
182 PluginHostAdapter::getDescription() const
|
cannam@1
|
183 {
|
cannam@1
|
184 return m_descriptor->description;
|
cannam@1
|
185 }
|
cannam@1
|
186
|
cannam@1
|
187 std::string
|
cannam@1
|
188 PluginHostAdapter::getMaker() const
|
cannam@1
|
189 {
|
cannam@1
|
190 return m_descriptor->maker;
|
cannam@1
|
191 }
|
cannam@1
|
192
|
cannam@1
|
193 int
|
cannam@1
|
194 PluginHostAdapter::getPluginVersion() const
|
cannam@1
|
195 {
|
cannam@1
|
196 return m_descriptor->pluginVersion;
|
cannam@1
|
197 }
|
cannam@1
|
198
|
cannam@1
|
199 std::string
|
cannam@1
|
200 PluginHostAdapter::getCopyright() const
|
cannam@1
|
201 {
|
cannam@1
|
202 return m_descriptor->copyright;
|
cannam@1
|
203 }
|
cannam@1
|
204
|
cannam@1
|
205 PluginHostAdapter::ParameterList
|
cannam@1
|
206 PluginHostAdapter::getParameterDescriptors() const
|
cannam@1
|
207 {
|
cannam@1
|
208 ParameterList list;
|
cannam@1
|
209 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
cannam@1
|
210 const VampParameterDescriptor *spd = m_descriptor->parameters[i];
|
cannam@1
|
211 ParameterDescriptor pd;
|
cannam@49
|
212 pd.identifier = spd->identifier;
|
cannam@1
|
213 pd.name = spd->name;
|
cannam@1
|
214 pd.description = spd->description;
|
cannam@1
|
215 pd.unit = spd->unit;
|
cannam@1
|
216 pd.minValue = spd->minValue;
|
cannam@1
|
217 pd.maxValue = spd->maxValue;
|
cannam@1
|
218 pd.defaultValue = spd->defaultValue;
|
cannam@1
|
219 pd.isQuantized = spd->isQuantized;
|
cannam@1
|
220 pd.quantizeStep = spd->quantizeStep;
|
cannam@9
|
221 if (pd.isQuantized && spd->valueNames) {
|
cannam@9
|
222 for (unsigned int j = 0; spd->valueNames[j]; ++j) {
|
cannam@9
|
223 pd.valueNames.push_back(spd->valueNames[j]);
|
cannam@9
|
224 }
|
cannam@9
|
225 }
|
cannam@1
|
226 list.push_back(pd);
|
cannam@1
|
227 }
|
cannam@1
|
228 return list;
|
cannam@1
|
229 }
|
cannam@1
|
230
|
cannam@1
|
231 float
|
cannam@1
|
232 PluginHostAdapter::getParameter(std::string param) const
|
cannam@1
|
233 {
|
cannam@1
|
234 if (!m_handle) return 0.0;
|
cannam@1
|
235
|
cannam@1
|
236 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
cannam@49
|
237 if (param == m_descriptor->parameters[i]->identifier) {
|
cannam@1
|
238 return m_descriptor->getParameter(m_handle, i);
|
cannam@1
|
239 }
|
cannam@1
|
240 }
|
cannam@1
|
241
|
cannam@1
|
242 return 0.0;
|
cannam@1
|
243 }
|
cannam@1
|
244
|
cannam@1
|
245 void
|
cannam@1
|
246 PluginHostAdapter::setParameter(std::string param,
|
cannam@1
|
247 float value)
|
cannam@1
|
248 {
|
cannam@1
|
249 if (!m_handle) return;
|
cannam@1
|
250
|
cannam@1
|
251 for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
|
cannam@49
|
252 if (param == m_descriptor->parameters[i]->identifier) {
|
cannam@1
|
253 m_descriptor->setParameter(m_handle, i, value);
|
cannam@1
|
254 return;
|
cannam@1
|
255 }
|
cannam@1
|
256 }
|
cannam@1
|
257 }
|
cannam@1
|
258
|
cannam@1
|
259 PluginHostAdapter::ProgramList
|
cannam@1
|
260 PluginHostAdapter::getPrograms() const
|
cannam@1
|
261 {
|
cannam@1
|
262 ProgramList list;
|
cannam@1
|
263
|
cannam@1
|
264 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
|
cannam@1
|
265 list.push_back(m_descriptor->programs[i]);
|
cannam@1
|
266 }
|
cannam@1
|
267
|
cannam@1
|
268 return list;
|
cannam@1
|
269 }
|
cannam@1
|
270
|
cannam@1
|
271 std::string
|
cannam@1
|
272 PluginHostAdapter::getCurrentProgram() const
|
cannam@1
|
273 {
|
cannam@1
|
274 if (!m_handle) return "";
|
cannam@1
|
275
|
cannam@1
|
276 int pn = m_descriptor->getCurrentProgram(m_handle);
|
Chris@345
|
277 if (pn < (int)m_descriptor->programCount) {
|
Chris@345
|
278 return m_descriptor->programs[pn];
|
Chris@345
|
279 } else {
|
Chris@345
|
280 return "";
|
Chris@345
|
281 }
|
cannam@1
|
282 }
|
cannam@1
|
283
|
cannam@1
|
284 void
|
cannam@1
|
285 PluginHostAdapter::selectProgram(std::string program)
|
cannam@1
|
286 {
|
cannam@1
|
287 if (!m_handle) return;
|
cannam@1
|
288
|
cannam@1
|
289 for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
|
cannam@1
|
290 if (program == m_descriptor->programs[i]) {
|
cannam@1
|
291 m_descriptor->selectProgram(m_handle, i);
|
cannam@1
|
292 return;
|
cannam@1
|
293 }
|
cannam@1
|
294 }
|
cannam@1
|
295 }
|
cannam@1
|
296
|
cannam@1
|
297 size_t
|
cannam@1
|
298 PluginHostAdapter::getPreferredStepSize() const
|
cannam@1
|
299 {
|
cannam@1
|
300 if (!m_handle) return 0;
|
cannam@1
|
301 return m_descriptor->getPreferredStepSize(m_handle);
|
cannam@1
|
302 }
|
cannam@1
|
303
|
cannam@1
|
304 size_t
|
cannam@1
|
305 PluginHostAdapter::getPreferredBlockSize() const
|
cannam@1
|
306 {
|
cannam@1
|
307 if (!m_handle) return 0;
|
cannam@1
|
308 return m_descriptor->getPreferredBlockSize(m_handle);
|
cannam@1
|
309 }
|
cannam@1
|
310
|
cannam@26
|
311 size_t
|
cannam@26
|
312 PluginHostAdapter::getMinChannelCount() const
|
cannam@26
|
313 {
|
cannam@26
|
314 if (!m_handle) return 0;
|
cannam@26
|
315 return m_descriptor->getMinChannelCount(m_handle);
|
cannam@26
|
316 }
|
cannam@26
|
317
|
cannam@26
|
318 size_t
|
cannam@26
|
319 PluginHostAdapter::getMaxChannelCount() const
|
cannam@26
|
320 {
|
cannam@26
|
321 if (!m_handle) return 0;
|
cannam@26
|
322 return m_descriptor->getMaxChannelCount(m_handle);
|
cannam@26
|
323 }
|
cannam@26
|
324
|
cannam@1
|
325 PluginHostAdapter::OutputList
|
cannam@1
|
326 PluginHostAdapter::getOutputDescriptors() const
|
cannam@1
|
327 {
|
cannam@1
|
328 OutputList list;
|
cannam@15
|
329 if (!m_handle) {
|
cannam@15
|
330 // std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
|
cannam@15
|
331 return list;
|
cannam@15
|
332 }
|
cannam@1
|
333
|
cannam@1
|
334 unsigned int count = m_descriptor->getOutputCount(m_handle);
|
cannam@1
|
335
|
cannam@1
|
336 for (unsigned int i = 0; i < count; ++i) {
|
cannam@1
|
337 VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
|
cannam@1
|
338 OutputDescriptor d;
|
cannam@49
|
339 d.identifier = sd->identifier;
|
cannam@1
|
340 d.name = sd->name;
|
cannam@1
|
341 d.description = sd->description;
|
cannam@1
|
342 d.unit = sd->unit;
|
cannam@9
|
343 d.hasFixedBinCount = sd->hasFixedBinCount;
|
cannam@9
|
344 d.binCount = sd->binCount;
|
cannam@240
|
345 if (d.hasFixedBinCount && sd->binNames) {
|
cannam@9
|
346 for (unsigned int j = 0; j < sd->binCount; ++j) {
|
cannam@9
|
347 d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
|
cannam@9
|
348 }
|
cannam@1
|
349 }
|
cannam@1
|
350 d.hasKnownExtents = sd->hasKnownExtents;
|
cannam@1
|
351 d.minValue = sd->minValue;
|
cannam@1
|
352 d.maxValue = sd->maxValue;
|
cannam@1
|
353 d.isQuantized = sd->isQuantized;
|
cannam@1
|
354 d.quantizeStep = sd->quantizeStep;
|
cannam@1
|
355
|
cannam@1
|
356 switch (sd->sampleType) {
|
cannam@1
|
357 case vampOneSamplePerStep:
|
cannam@1
|
358 d.sampleType = OutputDescriptor::OneSamplePerStep; break;
|
cannam@1
|
359 case vampFixedSampleRate:
|
cannam@1
|
360 d.sampleType = OutputDescriptor::FixedSampleRate; break;
|
cannam@1
|
361 case vampVariableSampleRate:
|
cannam@1
|
362 d.sampleType = OutputDescriptor::VariableSampleRate; break;
|
cannam@1
|
363 }
|
cannam@1
|
364
|
cannam@1
|
365 d.sampleRate = sd->sampleRate;
|
cannam@1
|
366
|
cannam@192
|
367 if (m_descriptor->vampApiVersion >= 2) {
|
cannam@192
|
368 d.hasDuration = sd->hasDuration;
|
cannam@192
|
369 } else {
|
cannam@192
|
370 d.hasDuration = false;
|
cannam@192
|
371 }
|
cannam@192
|
372
|
cannam@1
|
373 list.push_back(d);
|
cannam@1
|
374
|
cannam@1
|
375 m_descriptor->releaseOutputDescriptor(sd);
|
cannam@1
|
376 }
|
cannam@1
|
377
|
cannam@1
|
378 return list;
|
cannam@1
|
379 }
|
cannam@1
|
380
|
cannam@1
|
381 PluginHostAdapter::FeatureSet
|
cannam@47
|
382 PluginHostAdapter::process(const float *const *inputBuffers,
|
cannam@47
|
383 RealTime timestamp)
|
cannam@1
|
384 {
|
cannam@1
|
385 FeatureSet fs;
|
cannam@1
|
386 if (!m_handle) return fs;
|
cannam@1
|
387
|
cannam@1
|
388 int sec = timestamp.sec;
|
cannam@1
|
389 int nsec = timestamp.nsec;
|
cannam@1
|
390
|
cannam@12
|
391 VampFeatureList *features = m_descriptor->process(m_handle,
|
cannam@1
|
392 inputBuffers,
|
cannam@1
|
393 sec, nsec);
|
cannam@1
|
394
|
cannam@1
|
395 convertFeatures(features, fs);
|
cannam@1
|
396 m_descriptor->releaseFeatureSet(features);
|
cannam@1
|
397 return fs;
|
cannam@1
|
398 }
|
cannam@1
|
399
|
cannam@1
|
400 PluginHostAdapter::FeatureSet
|
cannam@1
|
401 PluginHostAdapter::getRemainingFeatures()
|
cannam@1
|
402 {
|
cannam@1
|
403 FeatureSet fs;
|
cannam@1
|
404 if (!m_handle) return fs;
|
cannam@1
|
405
|
cannam@12
|
406 VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle);
|
cannam@1
|
407
|
cannam@1
|
408 convertFeatures(features, fs);
|
cannam@1
|
409 m_descriptor->releaseFeatureSet(features);
|
cannam@1
|
410 return fs;
|
cannam@1
|
411 }
|
cannam@1
|
412
|
cannam@1
|
413 void
|
cannam@12
|
414 PluginHostAdapter::convertFeatures(VampFeatureList *features,
|
cannam@1
|
415 FeatureSet &fs)
|
cannam@1
|
416 {
|
cannam@7
|
417 if (!features) return;
|
cannam@7
|
418
|
cannam@12
|
419 unsigned int outputs = m_descriptor->getOutputCount(m_handle);
|
cannam@12
|
420
|
cannam@12
|
421 for (unsigned int i = 0; i < outputs; ++i) {
|
cannam@1
|
422
|
cannam@12
|
423 VampFeatureList &list = features[i];
|
cannam@1
|
424
|
cannam@1
|
425 if (list.featureCount > 0) {
|
cannam@1
|
426
|
cannam@108
|
427 Feature feature;
|
cannam@168
|
428 feature.values.reserve(list.features[0].v1.valueCount);
|
cannam@108
|
429
|
cannam@1
|
430 for (unsigned int j = 0; j < list.featureCount; ++j) {
|
cannam@108
|
431
|
cannam@168
|
432 feature.hasTimestamp = list.features[j].v1.hasTimestamp;
|
cannam@168
|
433 feature.timestamp = RealTime(list.features[j].v1.sec,
|
cannam@168
|
434 list.features[j].v1.nsec);
|
cannam@168
|
435 feature.hasDuration = false;
|
cannam@1
|
436
|
cannam@167
|
437 if (m_descriptor->vampApiVersion >= 2) {
|
cannam@168
|
438 unsigned int j2 = j + list.featureCount;
|
cannam@168
|
439 feature.hasDuration = list.features[j2].v2.hasDuration;
|
cannam@168
|
440 feature.duration = RealTime(list.features[j2].v2.durationSec,
|
cannam@168
|
441 list.features[j2].v2.durationNsec);
|
cannam@167
|
442 }
|
cannam@167
|
443
|
cannam@168
|
444 for (unsigned int k = 0; k < list.features[j].v1.valueCount; ++k) {
|
cannam@168
|
445 feature.values.push_back(list.features[j].v1.values[k]);
|
cannam@1
|
446 }
|
cannam@7
|
447
|
cannam@168
|
448 if (list.features[j].v1.label) {
|
cannam@168
|
449 feature.label = list.features[j].v1.label;
|
cannam@7
|
450 }
|
cannam@1
|
451
|
cannam@1
|
452 fs[i].push_back(feature);
|
cannam@108
|
453
|
cannam@168
|
454 if (list.features[j].v1.valueCount > 0) {
|
cannam@108
|
455 feature.values.clear();
|
cannam@108
|
456 }
|
cannam@108
|
457
|
cannam@168
|
458 if (list.features[j].v1.label) {
|
cannam@108
|
459 feature.label = "";
|
cannam@108
|
460 }
|
cannam@1
|
461 }
|
cannam@1
|
462 }
|
cannam@1
|
463 }
|
cannam@1
|
464 }
|
cannam@1
|
465
|
cannam@1
|
466 }
|
cannam@263
|
467
|
cannam@263
|
468 _VAMP_SDK_HOSTSPACE_END(PluginHostAdapter.cpp)
|
cannam@263
|
469
|