To check out this repository please hg clone the following URL, or open the URL using EasyMercurial or your preferred Mercurial client.

Statistics Download as Zip
| Branch: | Tag: | Revision:

root / src / vamp-hostsdk / PluginHostAdapter.cpp @ 532:569fc23fa37a

History | View | Annotate | Download (12.9 KB)

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 <vamp-hostsdk/PluginHostAdapter.h>
38
#include <cstdlib>
39

    
40
#include "Files.h"
41

    
42
#if ( VAMP_SDK_MAJOR_VERSION != 2 || VAMP_SDK_MINOR_VERSION != 9 )
43
#error Unexpected version of Vamp SDK header included
44
#endif
45

    
46
_VAMP_SDK_HOSTSPACE_BEGIN(PluginHostAdapter.cpp)
47

    
48
namespace Vamp
49
{
50

    
51
PluginHostAdapter::PluginHostAdapter(const VampPluginDescriptor *descriptor,
52
                                     float inputSampleRate) :
53
    Plugin(inputSampleRate),
54
    m_descriptor(descriptor)
55
{
56
//    std::cerr << "PluginHostAdapter::PluginHostAdapter (plugin = " << descriptor->name << ")" << std::endl;
57
    m_handle = m_descriptor->instantiate(m_descriptor, inputSampleRate);
58
    if (!m_handle) {
59
//        std::cerr << "WARNING: PluginHostAdapter: Plugin instantiation failed for plugin " << m_descriptor->name << std::endl;
60
    }
61
}
62

    
63
PluginHostAdapter::~PluginHostAdapter()
64
{
65
//    std::cerr << "PluginHostAdapter::~PluginHostAdapter (plugin = " << m_descriptor->name << ")" << std::endl;
66
    if (m_handle) m_descriptor->cleanup(m_handle);
67
}
68

    
69
std::vector<std::string>
70
PluginHostAdapter::getPluginPath()
71
{
72
    std::vector<std::string> path;
73
    std::string envPath;
74

    
75
    if (Files::isNonNative32Bit()) {
76
        (void)Files::getEnvUtf8("VAMP_PATH_32", envPath);
77
    } else {
78
        (void)Files::getEnvUtf8("VAMP_PATH", envPath);
79
    }
80

    
81
#ifdef _WIN32
82
#define PATH_SEPARATOR ';'
83
#define DEFAULT_VAMP_PATH "%ProgramFiles%\\Vamp Plugins"
84
#else
85
#define PATH_SEPARATOR ':'
86
#ifdef __APPLE__
87
#define DEFAULT_VAMP_PATH "$HOME/Library/Audio/Plug-Ins/Vamp:/Library/Audio/Plug-Ins/Vamp"
88
#else
89
#define DEFAULT_VAMP_PATH "$HOME/vamp:$HOME/.vamp:/usr/local/lib/vamp:/usr/lib/vamp"
90
#endif
91
#endif
92

    
93
    if (envPath == "") {
94
        envPath = DEFAULT_VAMP_PATH;
95
        std::string home;
96
        if (Files::getEnvUtf8("HOME", home)) {
97
            std::string::size_type f;
98
            while ((f = envPath.find("$HOME")) != std::string::npos &&
99
                    f < envPath.length()) {
100
                envPath.replace(f, 5, home);
101
            }
102
        }
103
#ifdef _WIN32
104
        std::string pfiles;
105
        if (!Files::getEnvUtf8("ProgramFiles", pfiles)) {
106
            pfiles = "C:\\Program Files";
107
        }
108
        std::string::size_type f;
109
        while ((f = envPath.find("%ProgramFiles%")) != std::string::npos &&
110
               f < envPath.length()) {
111
            envPath.replace(f, 14, pfiles);
112
        }
113
#endif
114
    }
115

    
116
    std::string::size_type index = 0, newindex = 0;
117

    
118
    while ((newindex = envPath.find(PATH_SEPARATOR, index)) < envPath.size()) {
119
        path.push_back(envPath.substr(index, newindex - index));
120
        index = newindex + 1;
121
    }
122
    
123
    path.push_back(envPath.substr(index));
124

    
125
    return path;
126
}
127

    
128
bool
129
PluginHostAdapter::initialise(size_t channels,
130
                              size_t stepSize,
131
                              size_t blockSize)
132
{
133
    if (!m_handle) return false;
134
    return m_descriptor->initialise
135
        (m_handle,
136
         (unsigned int)channels,
137
         (unsigned int)stepSize,
138
         (unsigned int)blockSize) ?
139
        true : false;
140
}
141

    
142
void
143
PluginHostAdapter::reset()
144
{
145
    if (!m_handle) {
146
//        std::cerr << "PluginHostAdapter::reset: no handle" << std::endl;
147
        return;
148
    }
149
//    std::cerr << "PluginHostAdapter::reset(" << m_handle << ")" << std::endl;
150
    m_descriptor->reset(m_handle);
151
}
152

    
153
PluginHostAdapter::InputDomain
154
PluginHostAdapter::getInputDomain() const
155
{
156
    if (m_descriptor->inputDomain == vampFrequencyDomain) {
157
        return FrequencyDomain;
158
    } else {
159
        return TimeDomain;
160
    }
161
}
162

    
163
unsigned int
164
PluginHostAdapter::getVampApiVersion() const
165
{
166
    return m_descriptor->vampApiVersion;
167
}
168

    
169
std::string
170
PluginHostAdapter::getIdentifier() const
171
{
172
    return m_descriptor->identifier;
173
}
174

    
175
std::string
176
PluginHostAdapter::getName() const
177
{
178
    return m_descriptor->name;
179
}
180

    
181
std::string
182
PluginHostAdapter::getDescription() const
183
{
184
    return m_descriptor->description;
185
}
186

    
187
std::string
188
PluginHostAdapter::getMaker() const
189
{
190
    return m_descriptor->maker;
191
}
192

    
193
int
194
PluginHostAdapter::getPluginVersion() const
195
{
196
    return m_descriptor->pluginVersion;
197
}
198

    
199
std::string
200
PluginHostAdapter::getCopyright() const
201
{
202
    return m_descriptor->copyright;
203
}
204

    
205
PluginHostAdapter::ParameterList
206
PluginHostAdapter::getParameterDescriptors() const
207
{
208
    ParameterList list;
209
    for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
210
        const VampParameterDescriptor *spd = m_descriptor->parameters[i];
211
        ParameterDescriptor pd;
212
        pd.identifier = spd->identifier;
213
        pd.name = spd->name;
214
        pd.description = spd->description;
215
        pd.unit = spd->unit;
216
        pd.minValue = spd->minValue;
217
        pd.maxValue = spd->maxValue;
218
        pd.defaultValue = spd->defaultValue;
219
        pd.isQuantized = spd->isQuantized;
220
        pd.quantizeStep = spd->quantizeStep;
221
        if (pd.isQuantized && spd->valueNames) {
222
            for (unsigned int j = 0; spd->valueNames[j]; ++j) {
223
                pd.valueNames.push_back(spd->valueNames[j]);
224
            }
225
        }
226
        list.push_back(pd);
227
    }
228
    return list;
229
}
230

    
231
float
232
PluginHostAdapter::getParameter(std::string param) const
233
{
234
    if (!m_handle) return 0.0;
235

    
236
    for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
237
        if (param == m_descriptor->parameters[i]->identifier) {
238
            return m_descriptor->getParameter(m_handle, i);
239
        }
240
    }
241

    
242
    return 0.0;
243
}
244

    
245
void
246
PluginHostAdapter::setParameter(std::string param, 
247
                                float value)
248
{
249
    if (!m_handle) return;
250

    
251
    for (unsigned int i = 0; i < m_descriptor->parameterCount; ++i) {
252
        if (param == m_descriptor->parameters[i]->identifier) {
253
            m_descriptor->setParameter(m_handle, i, value);
254
            return;
255
        }
256
    }
257
}
258

    
259
PluginHostAdapter::ProgramList
260
PluginHostAdapter::getPrograms() const
261
{
262
    ProgramList list;
263
    
264
    for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
265
        list.push_back(m_descriptor->programs[i]);
266
    }
267
    
268
    return list;
269
}
270

    
271
std::string
272
PluginHostAdapter::getCurrentProgram() const
273
{
274
    if (!m_handle) return "";
275

    
276
    int pn = m_descriptor->getCurrentProgram(m_handle);
277
    if (pn < (int)m_descriptor->programCount) {
278
        return m_descriptor->programs[pn];
279
    } else {
280
        return "";
281
    }
282
}
283

    
284
void
285
PluginHostAdapter::selectProgram(std::string program)
286
{
287
    if (!m_handle) return;
288

    
289
    for (unsigned int i = 0; i < m_descriptor->programCount; ++i) {
290
        if (program == m_descriptor->programs[i]) {
291
            m_descriptor->selectProgram(m_handle, i);
292
            return;
293
        }
294
    }
295
}
296

    
297
size_t
298
PluginHostAdapter::getPreferredStepSize() const
299
{
300
    if (!m_handle) return 0;
301
    return m_descriptor->getPreferredStepSize(m_handle);
302
}
303

    
304
size_t
305
PluginHostAdapter::getPreferredBlockSize() const
306
{
307
    if (!m_handle) return 0;
308
    return m_descriptor->getPreferredBlockSize(m_handle);
309
}
310

    
311
size_t
312
PluginHostAdapter::getMinChannelCount() const
313
{
314
    if (!m_handle) return 0;
315
    return m_descriptor->getMinChannelCount(m_handle);
316
}
317

    
318
size_t
319
PluginHostAdapter::getMaxChannelCount() const
320
{
321
    if (!m_handle) return 0;
322
    return m_descriptor->getMaxChannelCount(m_handle);
323
}
324

    
325
PluginHostAdapter::OutputList
326
PluginHostAdapter::getOutputDescriptors() const
327
{
328
    OutputList list;
329
    if (!m_handle) {
330
//        std::cerr << "PluginHostAdapter::getOutputDescriptors: no handle " << std::endl;
331
        return list;
332
    }
333

    
334
    unsigned int count = m_descriptor->getOutputCount(m_handle);
335

    
336
    for (unsigned int i = 0; i < count; ++i) {
337
        VampOutputDescriptor *sd = m_descriptor->getOutputDescriptor(m_handle, i);
338
        OutputDescriptor d;
339
        d.identifier = sd->identifier;
340
        d.name = sd->name;
341
        d.description = sd->description;
342
        d.unit = sd->unit;
343
        d.hasFixedBinCount = sd->hasFixedBinCount;
344
        d.binCount = sd->binCount;
345
        if (d.hasFixedBinCount && sd->binNames) {
346
            for (unsigned int j = 0; j < sd->binCount; ++j) {
347
                d.binNames.push_back(sd->binNames[j] ? sd->binNames[j] : "");
348
            }
349
        }
350
        d.hasKnownExtents = sd->hasKnownExtents;
351
        d.minValue = sd->minValue;
352
        d.maxValue = sd->maxValue;
353
        d.isQuantized = sd->isQuantized;
354
        d.quantizeStep = sd->quantizeStep;
355

    
356
        switch (sd->sampleType) {
357
        case vampOneSamplePerStep:
358
            d.sampleType = OutputDescriptor::OneSamplePerStep; break;
359
        case vampFixedSampleRate:
360
            d.sampleType = OutputDescriptor::FixedSampleRate; break;
361
        case vampVariableSampleRate:
362
            d.sampleType = OutputDescriptor::VariableSampleRate; break;
363
        }
364

    
365
        d.sampleRate = sd->sampleRate;
366

    
367
        if (m_descriptor->vampApiVersion >= 2) {
368
            d.hasDuration = sd->hasDuration;
369
        } else {
370
            d.hasDuration = false;
371
        }
372

    
373
        list.push_back(d);
374

    
375
        m_descriptor->releaseOutputDescriptor(sd);
376
    }
377

    
378
    return list;
379
}
380

    
381
PluginHostAdapter::FeatureSet
382
PluginHostAdapter::process(const float *const *inputBuffers,
383
                           RealTime timestamp)
384
{
385
    FeatureSet fs;
386
    if (!m_handle) return fs;
387

    
388
    int sec = timestamp.sec;
389
    int nsec = timestamp.nsec;
390
    
391
    VampFeatureList *features = m_descriptor->process(m_handle,
392
                                                      inputBuffers,
393
                                                      sec, nsec);
394
    
395
    convertFeatures(features, fs);
396
    m_descriptor->releaseFeatureSet(features);
397
    return fs;
398
}
399

    
400
PluginHostAdapter::FeatureSet
401
PluginHostAdapter::getRemainingFeatures()
402
{
403
    FeatureSet fs;
404
    if (!m_handle) return fs;
405
    
406
    VampFeatureList *features = m_descriptor->getRemainingFeatures(m_handle); 
407

    
408
    convertFeatures(features, fs);
409
    m_descriptor->releaseFeatureSet(features);
410
    return fs;
411
}
412

    
413
void
414
PluginHostAdapter::convertFeatures(VampFeatureList *features,
415
                                   FeatureSet &fs)
416
{
417
    if (!features) return;
418

    
419
    unsigned int outputs = m_descriptor->getOutputCount(m_handle);
420

    
421
    for (unsigned int i = 0; i < outputs; ++i) {
422
        
423
        VampFeatureList &list = features[i];
424

    
425
        if (list.featureCount > 0) {
426

    
427
            Feature feature;
428
            feature.values.reserve(list.features[0].v1.valueCount);
429

    
430
            for (unsigned int j = 0; j < list.featureCount; ++j) {
431

    
432
                feature.hasTimestamp = list.features[j].v1.hasTimestamp;
433
                feature.timestamp = RealTime(list.features[j].v1.sec,
434
                                             list.features[j].v1.nsec);
435
                feature.hasDuration = false;
436

    
437
                if (m_descriptor->vampApiVersion >= 2) {
438
                    unsigned int j2 = j + list.featureCount;
439
                    feature.hasDuration = list.features[j2].v2.hasDuration;
440
                    feature.duration = RealTime(list.features[j2].v2.durationSec,
441
                                                list.features[j2].v2.durationNsec);
442
                }
443

    
444
                for (unsigned int k = 0; k < list.features[j].v1.valueCount; ++k) {
445
                    feature.values.push_back(list.features[j].v1.values[k]);
446
                }
447

    
448
                if (list.features[j].v1.label) {
449
                    feature.label = list.features[j].v1.label;
450
                }
451

    
452
                fs[i].push_back(feature);
453

    
454
                if (list.features[j].v1.valueCount > 0) {
455
                    feature.values.clear();
456
                }
457

    
458
                if (list.features[j].v1.label) {
459
                    feature.label = "";
460
                }
461
            }
462
        }
463
    }
464
}
465

    
466
}
467

    
468
_VAMP_SDK_HOSTSPACE_END(PluginHostAdapter.cpp)
469