annotate host/vamp-simple-host.cpp @ 211:caa9d07bb9bd

* Update VC project file to handle proper export of plugin lookup function, and use the right dll name to match the other platforms and the .cat file
author cannam
date Sat, 18 Oct 2008 16:51:51 +0000
parents 1982246a3902
children
rev   line source
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@16 10 FFT code from Don Cross's public domain FFT implementation.
cannam@1 11
cannam@1 12 Permission is hereby granted, free of charge, to any person
cannam@1 13 obtaining a copy of this software and associated documentation
cannam@1 14 files (the "Software"), to deal in the Software without
cannam@1 15 restriction, including without limitation the rights to use, copy,
cannam@1 16 modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@1 17 of the Software, and to permit persons to whom the Software is
cannam@1 18 furnished to do so, subject to the following conditions:
cannam@1 19
cannam@1 20 The above copyright notice and this permission notice shall be
cannam@1 21 included in all copies or substantial portions of the Software.
cannam@1 22
cannam@1 23 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@1 24 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@1 25 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@6 26 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@1 27 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@1 28 CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@1 29 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@1 30
cannam@1 31 Except as contained in this notice, the names of the Centre for
cannam@1 32 Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@1 33 shall not be used in advertising or otherwise to promote the sale,
cannam@1 34 use or other dealings in this Software without prior written
cannam@1 35 authorization.
cannam@1 36 */
cannam@1 37
cannam@64 38 #include "vamp-sdk/PluginHostAdapter.h"
cannam@64 39 #include "vamp-sdk/hostext/PluginInputDomainAdapter.h"
cannam@64 40 #include "vamp-sdk/hostext/PluginLoader.h"
cannam@64 41 #include "vamp/vamp.h"
cannam@1 42
cannam@16 43 #include <iostream>
cannam@88 44 #include <fstream>
cannam@99 45 #include <set>
cannam@16 46 #include <sndfile.h>
cannam@1 47
cannam@130 48 #include <cstring>
cannam@130 49 #include <cstdlib>
cannam@130 50
cannam@1 51 #include "system.h"
cannam@1 52
cannam@19 53 #include <cmath>
cannam@19 54
cannam@99 55 using namespace std;
cannam@16 56
cannam@99 57 using Vamp::Plugin;
cannam@99 58 using Vamp::PluginHostAdapter;
cannam@99 59 using Vamp::RealTime;
cannam@64 60 using Vamp::HostExt::PluginLoader;
cannam@190 61 using Vamp::HostExt::PluginWrapper;
cannam@190 62 using Vamp::HostExt::PluginInputDomainAdapter;
cannam@64 63
cannam@190 64 #define HOST_VERSION "1.3"
cannam@40 65
cannam@95 66 enum Verbosity {
cannam@95 67 PluginIds,
cannam@95 68 PluginOutputIds,
cannam@95 69 PluginInformation
cannam@95 70 };
cannam@95 71
cannam@109 72 void printFeatures(int, int, int, Plugin::FeatureSet, ofstream *, bool frames);
cannam@16 73 void transformInput(float *, size_t);
cannam@16 74 void fft(unsigned int, bool, double *, double *, double *, double *);
cannam@64 75 void printPluginPath(bool verbose);
cannam@99 76 void printPluginCategoryList();
cannam@95 77 void enumeratePlugins(Verbosity);
cannam@64 78 void listPluginsInLibrary(string soname);
cannam@64 79 int runPlugin(string myname, string soname, string id, string output,
cannam@109 80 int outputNo, string inputFile, string outfilename, bool frames);
cannam@40 81
cannam@64 82 void usage(const char *name)
cannam@64 83 {
cannam@64 84 cerr << "\n"
cannam@64 85 << name << ": A simple Vamp plugin host.\n\n"
cannam@64 86 "Centre for Digital Music, Queen Mary, University of London.\n"
cannam@64 87 "Copyright 2006-2007 Chris Cannam and QMUL.\n"
cannam@64 88 "Freely redistributable; published under a BSD-style license.\n\n"
cannam@64 89 "Usage:\n\n"
cannam@109 90 " " << name << " [-s] pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin[:output] file.wav [-o out.txt]\n"
cannam@109 91 " " << name << " [-s] pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin file.wav [outputno] [-o out.txt]\n\n"
cannam@64 92 " -- Load plugin id \"plugin\" from \"pluginlibrary\" and run it on the\n"
cannam@73 93 " audio data in \"file.wav\", retrieving the named \"output\", or output\n"
cannam@73 94 " number \"outputno\" (the first output by default) and dumping it to\n"
cannam@95 95 " standard output, or to \"out.txt\" if the -o option is given.\n\n"
cannam@73 96 " \"pluginlibrary\" should be a library name, not a file path; the\n"
cannam@73 97 " standard Vamp library search path will be used to locate it. If\n"
cannam@73 98 " a file path is supplied, the directory part(s) will be ignored.\n\n"
cannam@109 99 " If the -s option is given, results will be labelled with the audio\n"
cannam@109 100 " sample frame at which they occur. Otherwise, they will be labelled\n"
cannam@109 101 " with time in seconds.\n\n"
cannam@64 102 " " << name << " -l\n\n"
cannam@95 103 " -- List the plugin libraries and Vamp plugins in the library search path\n"
cannam@95 104 " in a verbose human-readable format.\n\n"
cannam@95 105 " " << name << " --list-ids\n\n"
cannam@95 106 " -- List the plugins in the search path in a terse machine-readable format,\n"
cannam@95 107 " in the form vamp:soname:identifier.\n\n"
cannam@95 108 " " << name << " --list-outputs\n\n"
cannam@95 109 " -- List the outputs for plugins in the search path in a machine-readable\n"
cannam@95 110 " format, in the form vamp:soname:identifier:output.\n\n"
cannam@99 111 " " << name << " --list-by-category\n\n"
cannam@99 112 " -- List the plugins as a plugin index by category, in a machine-readable\n"
cannam@99 113 " format. The format may change in future releases.\n\n"
cannam@64 114 " " << name << " -p\n\n"
cannam@73 115 " -- Print out the Vamp library search path.\n\n"
cannam@64 116 " " << name << " -v\n\n"
cannam@95 117 " -- Display version information only.\n"
cannam@64 118 << endl;
cannam@64 119 exit(2);
cannam@64 120 }
cannam@1 121
cannam@1 122 int main(int argc, char **argv)
cannam@1 123 {
cannam@64 124 char *scooter = argv[0];
cannam@64 125 char *name = 0;
cannam@64 126 while (scooter && *scooter) {
cannam@64 127 if (*scooter == '/' || *scooter == '\\') name = ++scooter;
cannam@64 128 else ++scooter;
cannam@1 129 }
cannam@64 130 if (!name || !*name) name = argv[0];
cannam@43 131
cannam@88 132 if (argc < 2) usage(name);
cannam@64 133
cannam@88 134 if (argc == 2) {
cannam@88 135
cannam@88 136 if (!strcmp(argv[1], "-v")) {
cannam@88 137
cannam@88 138 cout << "Simple Vamp plugin host version: " << HOST_VERSION << endl
cannam@88 139 << "Vamp API version: " << VAMP_API_VERSION << endl
cannam@88 140 << "Vamp SDK version: " << VAMP_SDK_VERSION << endl;
cannam@88 141 return 0;
cannam@88 142
cannam@88 143 } else if (!strcmp(argv[1], "-l")) {
cannam@88 144
cannam@88 145 printPluginPath(true);
cannam@95 146 enumeratePlugins(PluginInformation);
cannam@88 147 return 0;
cannam@88 148
cannam@88 149 } else if (!strcmp(argv[1], "-p")) {
cannam@88 150
cannam@88 151 printPluginPath(false);
cannam@88 152 return 0;
cannam@88 153
cannam@95 154 } else if (!strcmp(argv[1], "--list-ids")) {
cannam@95 155
cannam@95 156 enumeratePlugins(PluginIds);
cannam@95 157 return 0;
cannam@95 158
cannam@95 159 } else if (!strcmp(argv[1], "--list-outputs")) {
cannam@95 160
cannam@95 161 enumeratePlugins(PluginOutputIds);
cannam@95 162 return 0;
cannam@95 163
cannam@99 164 } else if (!strcmp(argv[1], "--list-by-category")) {
cannam@99 165
cannam@99 166 printPluginCategoryList();
cannam@99 167 return 0;
cannam@99 168
cannam@88 169 } else usage(name);
cannam@64 170 }
cannam@64 171
cannam@88 172 if (argc < 3) usage(name);
cannam@88 173
cannam@109 174 bool useFrames = false;
cannam@109 175
cannam@109 176 int base = 1;
cannam@109 177 if (!strcmp(argv[1], "-s")) {
cannam@109 178 useFrames = true;
cannam@109 179 base = 2;
cannam@109 180 }
cannam@109 181
cannam@109 182 string soname = argv[base];
cannam@109 183 string wavname = argv[base+1];
cannam@88 184 string plugid = "";
cannam@88 185 string output = "";
cannam@88 186 int outputNo = -1;
cannam@88 187 string outfilename;
cannam@88 188
cannam@109 189 if (argc >= base+3) {
cannam@88 190
cannam@109 191 int idx = base+2;
cannam@88 192
cannam@88 193 if (isdigit(*argv[idx])) {
cannam@88 194 outputNo = atoi(argv[idx++]);
cannam@88 195 }
cannam@88 196
cannam@88 197 if (argc == idx + 2) {
cannam@88 198 if (!strcmp(argv[idx], "-o")) {
cannam@88 199 outfilename = argv[idx+1];
cannam@88 200 } else usage(name);
cannam@88 201 } else if (argc != idx) {
cannam@88 202 (usage(name));
cannam@88 203 }
cannam@40 204 }
cannam@40 205
cannam@64 206 cerr << endl << name << ": Running..." << endl;
cannam@1 207
cannam@88 208 cerr << "Reading file: \"" << wavname << "\", writing to ";
cannam@88 209 if (outfilename == "") {
cannam@88 210 cerr << "standard output" << endl;
cannam@88 211 } else {
cannam@88 212 cerr << "\"" << outfilename << "\"" << endl;
cannam@88 213 }
cannam@16 214
cannam@64 215 string::size_type sep = soname.find(':');
cannam@64 216
cannam@64 217 if (sep != string::npos) {
cannam@49 218 plugid = soname.substr(sep + 1);
cannam@20 219 soname = soname.substr(0, sep);
cannam@1 220
cannam@64 221 sep = plugid.find(':');
cannam@64 222 if (sep != string::npos) {
cannam@64 223 output = plugid.substr(sep + 1);
cannam@64 224 plugid = plugid.substr(0, sep);
cannam@16 225 }
cannam@16 226 }
cannam@16 227
cannam@64 228 if (plugid == "") {
cannam@64 229 usage(name);
cannam@16 230 }
cannam@64 231
cannam@64 232 if (output != "" && outputNo != -1) {
cannam@64 233 usage(name);
cannam@64 234 }
cannam@64 235
cannam@84 236 if (output == "" && outputNo == -1) {
cannam@84 237 outputNo = 0;
cannam@84 238 }
cannam@84 239
cannam@88 240 return runPlugin(name, soname, plugid, output, outputNo,
cannam@109 241 wavname, outfilename, useFrames);
cannam@64 242 }
cannam@64 243
cannam@64 244
cannam@64 245 int runPlugin(string myname, string soname, string id,
cannam@88 246 string output, int outputNo, string wavname,
cannam@109 247 string outfilename, bool useFrames)
cannam@64 248 {
cannam@64 249 PluginLoader *loader = PluginLoader::getInstance();
cannam@64 250
cannam@64 251 PluginLoader::PluginKey key = loader->composePluginKey(soname, id);
cannam@16 252
cannam@16 253 SNDFILE *sndfile;
cannam@16 254 SF_INFO sfinfo;
cannam@16 255 memset(&sfinfo, 0, sizeof(SF_INFO));
cannam@16 256
cannam@16 257 sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo);
cannam@16 258 if (!sndfile) {
cannam@64 259 cerr << myname << ": ERROR: Failed to open input file \""
cannam@64 260 << wavname << "\": " << sf_strerror(sndfile) << endl;
cannam@16 261 return 1;
cannam@16 262 }
cannam@16 263
cannam@88 264 ofstream *out = 0;
cannam@88 265 if (outfilename != "") {
cannam@88 266 out = new ofstream(outfilename.c_str(), ios::out);
cannam@88 267 if (!*out) {
cannam@88 268 cerr << myname << ": ERROR: Failed to open output file \""
cannam@88 269 << outfilename << "\" for writing" << endl;
cannam@88 270 delete out;
cannam@88 271 return 1;
cannam@88 272 }
cannam@88 273 }
cannam@88 274
cannam@99 275 Plugin *plugin = loader->loadPlugin
cannam@92 276 (key, sfinfo.samplerate, PluginLoader::ADAPT_ALL_SAFE);
cannam@64 277 if (!plugin) {
cannam@64 278 cerr << myname << ": ERROR: Failed to load plugin \"" << id
cannam@64 279 << "\" from library \"" << soname << "\"" << endl;
cannam@64 280 sf_close(sndfile);
cannam@88 281 if (out) {
cannam@88 282 out->close();
cannam@88 283 delete out;
cannam@88 284 }
cannam@64 285 return 1;
cannam@64 286 }
cannam@16 287
cannam@64 288 cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl;
cannam@16 289
cannam@16 290 int blockSize = plugin->getPreferredBlockSize();
cannam@16 291 int stepSize = plugin->getPreferredStepSize();
cannam@16 292
cannam@91 293 if (blockSize == 0) {
cannam@91 294 blockSize = 1024;
cannam@91 295 }
cannam@83 296 if (stepSize == 0) {
cannam@99 297 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
cannam@83 298 stepSize = blockSize/2;
cannam@83 299 } else {
cannam@83 300 stepSize = blockSize;
cannam@83 301 }
cannam@91 302 } else if (stepSize > blockSize) {
cannam@91 303 cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to ";
cannam@99 304 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
cannam@91 305 blockSize = stepSize * 2;
cannam@91 306 } else {
cannam@91 307 blockSize = stepSize;
cannam@91 308 }
cannam@91 309 cerr << blockSize << endl;
cannam@83 310 }
cannam@83 311
cannam@16 312 int channels = sfinfo.channels;
cannam@16 313
cannam@16 314 float *filebuf = new float[blockSize * channels];
cannam@16 315 float **plugbuf = new float*[channels];
cannam@47 316 for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
cannam@16 317
cannam@16 318 cerr << "Using block size = " << blockSize << ", step size = "
cannam@16 319 << stepSize << endl;
cannam@16 320
cannam@16 321 int minch = plugin->getMinChannelCount();
cannam@16 322 int maxch = plugin->getMaxChannelCount();
cannam@16 323 cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
cannam@64 324 cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
cannam@16 325
cannam@99 326 Plugin::OutputList outputs = plugin->getOutputDescriptors();
cannam@99 327 Plugin::OutputDescriptor od;
cannam@16 328
cannam@29 329 int returnValue = 1;
cannam@88 330 int progress = 0;
cannam@29 331
cannam@190 332 RealTime rt;
cannam@190 333 PluginWrapper *wrapper = 0;
cannam@190 334 RealTime adjustment = RealTime::zeroTime;
cannam@190 335
cannam@16 336 if (outputs.empty()) {
cannam@64 337 cerr << "ERROR: Plugin has no outputs!" << endl;
cannam@16 338 goto done;
cannam@16 339 }
cannam@16 340
cannam@64 341 if (outputNo < 0) {
cannam@16 342
cannam@64 343 for (size_t oi = 0; oi < outputs.size(); ++oi) {
cannam@64 344 if (outputs[oi].identifier == output) {
cannam@64 345 outputNo = oi;
cannam@64 346 break;
cannam@64 347 }
cannam@64 348 }
cannam@64 349
cannam@64 350 if (outputNo < 0) {
cannam@64 351 cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
cannam@64 352 goto done;
cannam@64 353 }
cannam@64 354
cannam@64 355 } else {
cannam@64 356
cannam@64 357 if (int(outputs.size()) <= outputNo) {
cannam@64 358 cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
cannam@64 359 goto done;
cannam@64 360 }
cannam@64 361 }
cannam@64 362
cannam@64 363 od = outputs[outputNo];
cannam@64 364 cerr << "Output is: \"" << od.identifier << "\"" << endl;
cannam@16 365
cannam@29 366 if (!plugin->initialise(channels, stepSize, blockSize)) {
cannam@29 367 cerr << "ERROR: Plugin initialise (channels = " << channels
cannam@29 368 << ", stepSize = " << stepSize << ", blockSize = "
cannam@29 369 << blockSize << ") failed." << endl;
cannam@29 370 goto done;
cannam@29 371 }
cannam@16 372
cannam@190 373 wrapper = dynamic_cast<PluginWrapper *>(plugin);
cannam@190 374 if (wrapper) {
cannam@190 375 PluginInputDomainAdapter *ida =
cannam@190 376 wrapper->getWrapper<PluginInputDomainAdapter>();
cannam@190 377 if (ida) adjustment = ida->getTimestampAdjustment();
cannam@190 378 }
cannam@190 379
cannam@16 380 for (size_t i = 0; i < sfinfo.frames; i += stepSize) {
cannam@16 381
cannam@16 382 int count;
cannam@16 383
cannam@16 384 if (sf_seek(sndfile, i, SEEK_SET) < 0) {
cannam@16 385 cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl;
cannam@16 386 break;
cannam@16 387 }
cannam@16 388
cannam@16 389 if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
cannam@16 390 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
cannam@16 391 break;
cannam@16 392 }
cannam@16 393
cannam@16 394 for (int c = 0; c < channels; ++c) {
cannam@64 395 int j = 0;
cannam@64 396 while (j < count) {
cannam@64 397 plugbuf[c][j] = filebuf[j * sfinfo.channels + c];
cannam@64 398 ++j;
cannam@64 399 }
cannam@64 400 while (j < blockSize) {
cannam@16 401 plugbuf[c][j] = 0.0f;
cannam@64 402 ++j;
cannam@16 403 }
cannam@16 404 }
cannam@16 405
cannam@190 406 rt = RealTime::frame2RealTime(i, sfinfo.samplerate);
cannam@190 407
cannam@16 408 printFeatures
cannam@190 409 (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
cannam@190 410 sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt),
cannam@109 411 out, useFrames);
cannam@88 412
cannam@88 413 int pp = progress;
cannam@88 414 progress = lrintf((float(i) / sfinfo.frames) * 100.f);
cannam@88 415 if (progress != pp && out) {
cannam@88 416 cerr << "\r" << progress << "%";
cannam@88 417 }
cannam@16 418 }
cannam@88 419 if (out) cerr << "\rDone" << endl;
cannam@16 420
cannam@190 421 rt = RealTime::frame2RealTime(sfinfo.frames, sfinfo.samplerate);
cannam@190 422
cannam@190 423 printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
cannam@190 424 sfinfo.samplerate, outputNo,
cannam@109 425 plugin->getRemainingFeatures(), out, useFrames);
cannam@16 426
cannam@29 427 returnValue = 0;
cannam@29 428
cannam@16 429 done:
cannam@16 430 delete plugin;
cannam@88 431 if (out) {
cannam@88 432 out->close();
cannam@88 433 delete out;
cannam@88 434 }
cannam@16 435 sf_close(sndfile);
cannam@29 436 return returnValue;
cannam@1 437 }
cannam@1 438
cannam@16 439 void
cannam@99 440 printFeatures(int frame, int sr, int output,
cannam@109 441 Plugin::FeatureSet features, ofstream *out, bool useFrames)
cannam@99 442 {
cannam@99 443 for (unsigned int i = 0; i < features[output].size(); ++i) {
cannam@99 444
cannam@109 445 if (useFrames) {
cannam@99 446
cannam@109 447 int displayFrame = frame;
cannam@109 448
cannam@109 449 if (features[output][i].hasTimestamp) {
cannam@109 450 displayFrame = RealTime::realTime2Frame
cannam@109 451 (features[output][i].timestamp, sr);
cannam@109 452 }
cannam@109 453
cannam@167 454 (out ? *out : cout) << displayFrame;
cannam@167 455
cannam@167 456 if (features[output][i].hasDuration) {
cannam@167 457 displayFrame = RealTime::realTime2Frame
cannam@167 458 (features[output][i].duration, sr);
cannam@167 459 (out ? *out : cout) << "," << displayFrame;
cannam@167 460 }
cannam@167 461
cannam@167 462 (out ? *out : cout) << ":";
cannam@109 463
cannam@109 464 } else {
cannam@109 465
cannam@109 466 RealTime rt = RealTime::frame2RealTime(frame, sr);
cannam@109 467
cannam@109 468 if (features[output][i].hasTimestamp) {
cannam@109 469 rt = features[output][i].timestamp;
cannam@109 470 }
cannam@109 471
cannam@167 472 (out ? *out : cout) << rt.toString();
cannam@167 473
cannam@167 474 if (features[output][i].hasDuration) {
cannam@167 475 rt = features[output][i].duration;
cannam@167 476 (out ? *out : cout) << "," << rt.toString();
cannam@167 477 }
cannam@167 478
cannam@167 479 (out ? *out : cout) << ":";
cannam@99 480 }
cannam@99 481
cannam@99 482 for (unsigned int j = 0; j < features[output][i].values.size(); ++j) {
cannam@99 483 (out ? *out : cout) << " " << features[output][i].values[j];
cannam@99 484 }
cannam@99 485
cannam@99 486 (out ? *out : cout) << endl;
cannam@99 487 }
cannam@99 488 }
cannam@99 489
cannam@99 490 void
cannam@64 491 printPluginPath(bool verbose)
cannam@40 492 {
cannam@64 493 if (verbose) {
cannam@64 494 cout << "\nVamp plugin search path: ";
cannam@64 495 }
cannam@64 496
cannam@99 497 vector<string> path = PluginHostAdapter::getPluginPath();
cannam@40 498 for (size_t i = 0; i < path.size(); ++i) {
cannam@64 499 if (verbose) {
cannam@64 500 cout << "[" << path[i] << "]";
cannam@64 501 } else {
cannam@64 502 cout << path[i] << endl;
cannam@64 503 }
cannam@40 504 }
cannam@64 505
cannam@64 506 if (verbose) cout << endl;
cannam@40 507 }
cannam@40 508
cannam@40 509 void
cannam@95 510 enumeratePlugins(Verbosity verbosity)
cannam@40 511 {
cannam@64 512 PluginLoader *loader = PluginLoader::getInstance();
cannam@64 513
cannam@95 514 if (verbosity == PluginInformation) {
cannam@95 515 cout << "\nVamp plugin libraries found in search path:" << endl;
cannam@95 516 }
cannam@64 517
cannam@99 518 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
cannam@99 519 typedef multimap<string, PluginLoader::PluginKey>
cannam@64 520 LibraryMap;
cannam@64 521 LibraryMap libraryMap;
cannam@64 522
cannam@64 523 for (size_t i = 0; i < plugins.size(); ++i) {
cannam@99 524 string path = loader->getLibraryPathForPlugin(plugins[i]);
cannam@64 525 libraryMap.insert(LibraryMap::value_type(path, plugins[i]));
cannam@64 526 }
cannam@64 527
cannam@99 528 string prevPath = "";
cannam@64 529 int index = 0;
cannam@64 530
cannam@64 531 for (LibraryMap::iterator i = libraryMap.begin();
cannam@64 532 i != libraryMap.end(); ++i) {
cannam@64 533
cannam@99 534 string path = i->first;
cannam@64 535 PluginLoader::PluginKey key = i->second;
cannam@64 536
cannam@64 537 if (path != prevPath) {
cannam@64 538 prevPath = path;
cannam@64 539 index = 0;
cannam@95 540 if (verbosity == PluginInformation) {
cannam@95 541 cout << "\n " << path << ":" << endl;
cannam@95 542 }
cannam@40 543 }
cannam@64 544
cannam@99 545 Plugin *plugin = loader->loadPlugin(key, 48000);
cannam@64 546 if (plugin) {
cannam@64 547
cannam@64 548 char c = char('A' + index);
cannam@64 549 if (c > 'Z') c = char('a' + (index - 26));
cannam@64 550
cannam@95 551 if (verbosity == PluginInformation) {
cannam@64 552
cannam@95 553 cout << " [" << c << "] [v"
cannam@95 554 << plugin->getVampApiVersion() << "] "
cannam@95 555 << plugin->getName() << ", \""
cannam@95 556 << plugin->getIdentifier() << "\"" << " ["
cannam@95 557 << plugin->getMaker() << "]" << endl;
cannam@95 558
cannam@95 559 PluginLoader::PluginCategoryHierarchy category =
cannam@95 560 loader->getPluginCategory(key);
cannam@95 561
cannam@95 562 if (!category.empty()) {
cannam@95 563 cout << " ";
cannam@95 564 for (size_t ci = 0; ci < category.size(); ++ci) {
cannam@95 565 cout << " > " << category[ci];
cannam@95 566 }
cannam@95 567 cout << endl;
cannam@64 568 }
cannam@95 569
cannam@95 570 if (plugin->getDescription() != "") {
cannam@95 571 cout << " - " << plugin->getDescription() << endl;
cannam@95 572 }
cannam@95 573
cannam@95 574 } else if (verbosity == PluginIds) {
cannam@95 575 cout << "vamp:" << key << endl;
cannam@47 576 }
cannam@95 577
cannam@99 578 Plugin::OutputList outputs =
cannam@64 579 plugin->getOutputDescriptors();
cannam@64 580
cannam@95 581 if (outputs.size() > 1 || verbosity == PluginOutputIds) {
cannam@64 582 for (size_t j = 0; j < outputs.size(); ++j) {
cannam@95 583 if (verbosity == PluginInformation) {
cannam@95 584 cout << " (" << j << ") "
cannam@95 585 << outputs[j].name << ", \""
cannam@95 586 << outputs[j].identifier << "\"" << endl;
cannam@95 587 if (outputs[j].description != "") {
cannam@95 588 cout << " - "
cannam@95 589 << outputs[j].description << endl;
cannam@95 590 }
cannam@95 591 } else if (verbosity == PluginOutputIds) {
cannam@95 592 cout << "vamp:" << key << ":" << outputs[j].identifier << endl;
cannam@40 593 }
cannam@40 594 }
cannam@64 595 }
cannam@64 596
cannam@64 597 ++index;
cannam@64 598
cannam@64 599 delete plugin;
cannam@40 600 }
cannam@40 601 }
cannam@64 602
cannam@95 603 if (verbosity == PluginInformation) {
cannam@95 604 cout << endl;
cannam@95 605 }
cannam@40 606 }
cannam@40 607
cannam@40 608 void
cannam@99 609 printPluginCategoryList()
cannam@16 610 {
cannam@99 611 PluginLoader *loader = PluginLoader::getInstance();
cannam@88 612
cannam@99 613 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
cannam@88 614
cannam@99 615 set<string> printedcats;
cannam@99 616
cannam@99 617 for (size_t i = 0; i < plugins.size(); ++i) {
cannam@99 618
cannam@99 619 PluginLoader::PluginKey key = plugins[i];
cannam@99 620
cannam@99 621 PluginLoader::PluginCategoryHierarchy category =
cannam@99 622 loader->getPluginCategory(key);
cannam@99 623
cannam@99 624 Plugin *plugin = loader->loadPlugin(key, 48000);
cannam@99 625 if (!plugin) continue;
cannam@99 626
cannam@99 627 string catstr = "";
cannam@99 628
cannam@99 629 if (category.empty()) catstr = '|';
cannam@99 630 else {
cannam@99 631 for (size_t j = 0; j < category.size(); ++j) {
cannam@99 632 catstr += category[j];
cannam@99 633 catstr += '|';
cannam@99 634 if (printedcats.find(catstr) == printedcats.end()) {
cannam@99 635 std::cout << catstr << std::endl;
cannam@99 636 printedcats.insert(catstr);
cannam@99 637 }
cannam@99 638 }
cannam@16 639 }
cannam@88 640
cannam@99 641 std::cout << catstr << key << ":::" << plugin->getName() << ":::" << plugin->getMaker() << ":::" << plugin->getDescription() << std::endl;
cannam@16 642 }
cannam@16 643 }
cannam@16 644