00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include <vamp-hostsdk/PluginHostAdapter.h>
00050 #include <vamp-hostsdk/PluginInputDomainAdapter.h>
00051 #include <vamp-hostsdk/PluginLoader.h>
00052
00053 #include <iostream>
00054 #include <fstream>
00055 #include <set>
00056 #include <sndfile.h>
00057
00058 #include <cstring>
00059 #include <cstdlib>
00060
00061 #include "system.h"
00062
00063 #include <cmath>
00064
00065 using namespace std;
00066
00067 using Vamp::Plugin;
00068 using Vamp::PluginHostAdapter;
00069 using Vamp::RealTime;
00070 using Vamp::HostExt::PluginLoader;
00071 using Vamp::HostExt::PluginWrapper;
00072 using Vamp::HostExt::PluginInputDomainAdapter;
00073
00074 #define HOST_VERSION "1.4"
00075
00076 enum Verbosity {
00077 PluginIds,
00078 PluginOutputIds,
00079 PluginInformation,
00080 PluginInformationDetailed
00081 };
00082
00083 void printFeatures(int, int, int, Plugin::FeatureSet, ofstream *, bool frames);
00084 void transformInput(float *, size_t);
00085 void fft(unsigned int, bool, double *, double *, double *, double *);
00086 void printPluginPath(bool verbose);
00087 void printPluginCategoryList();
00088 void enumeratePlugins(Verbosity);
00089 void listPluginsInLibrary(string soname);
00090 int runPlugin(string myname, string soname, string id, string output,
00091 int outputNo, string inputFile, string outfilename, bool frames);
00092
00093 void usage(const char *name)
00094 {
00095 cerr << "\n"
00096 << name << ": A command-line host for Vamp audio analysis plugins.\n\n"
00097 "Centre for Digital Music, Queen Mary, University of London.\n"
00098 "Copyright 2006-2009 Chris Cannam and QMUL.\n"
00099 "Freely redistributable; published under a BSD-style license.\n\n"
00100 "Usage:\n\n"
00101 " " << name << " [-s] pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin[:output] file.wav [-o out.txt]\n"
00102 " " << name << " [-s] pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin file.wav [outputno] [-o out.txt]\n\n"
00103 " -- Load plugin id \"plugin\" from \"pluginlibrary\" and run it on the\n"
00104 " audio data in \"file.wav\", retrieving the named \"output\", or output\n"
00105 " number \"outputno\" (the first output by default) and dumping it to\n"
00106 " standard output, or to \"out.txt\" if the -o option is given.\n\n"
00107 " \"pluginlibrary\" should be a library name, not a file path; the\n"
00108 " standard Vamp library search path will be used to locate it. If\n"
00109 " a file path is supplied, the directory part(s) will be ignored.\n\n"
00110 " If the -s option is given, results will be labelled with the audio\n"
00111 " sample frame at which they occur. Otherwise, they will be labelled\n"
00112 " with time in seconds.\n\n"
00113 " " << name << " -l\n"
00114 " " << name << " --list\n\n"
00115 " -- List the plugin libraries and Vamp plugins in the library search path\n"
00116 " in a verbose human-readable format.\n\n"
00117 " " << name << " --list-full\n\n"
00118 " -- List all data reported by all the Vamp plugins in the library search\n"
00119 " path in a very verbose human-readable format.\n\n"
00120 " " << name << " --list-ids\n\n"
00121 " -- List the plugins in the search path in a terse machine-readable format,\n"
00122 " in the form vamp:soname:identifier.\n\n"
00123 " " << name << " --list-outputs\n\n"
00124 " -- List the outputs for plugins in the search path in a machine-readable\n"
00125 " format, in the form vamp:soname:identifier:output.\n\n"
00126 " " << name << " --list-by-category\n\n"
00127 " -- List the plugins as a plugin index by category, in a machine-readable\n"
00128 " format. The format may change in future releases.\n\n"
00129 " " << name << " -p\n\n"
00130 " -- Print out the Vamp library search path.\n\n"
00131 " " << name << " -v\n\n"
00132 " -- Display version information only.\n"
00133 << endl;
00134 exit(2);
00135 }
00136
00137 int main(int argc, char **argv)
00138 {
00139 char *scooter = argv[0];
00140 char *name = 0;
00141 while (scooter && *scooter) {
00142 if (*scooter == '/' || *scooter == '\\') name = ++scooter;
00143 else ++scooter;
00144 }
00145 if (!name || !*name) name = argv[0];
00146
00147 if (argc < 2) usage(name);
00148
00149 if (argc == 2) {
00150
00151 if (!strcmp(argv[1], "-v")) {
00152
00153 cout << "Simple Vamp plugin host version: " << HOST_VERSION << endl
00154 << "Vamp API version: " << VAMP_API_VERSION << endl
00155 << "Vamp SDK version: " << VAMP_SDK_VERSION << endl;
00156 return 0;
00157
00158 } else if (!strcmp(argv[1], "-l") || !strcmp(argv[1], "--list")) {
00159
00160 printPluginPath(true);
00161 enumeratePlugins(PluginInformation);
00162 return 0;
00163
00164 } else if (!strcmp(argv[1], "--list-full")) {
00165
00166 enumeratePlugins(PluginInformationDetailed);
00167 return 0;
00168
00169 } else if (!strcmp(argv[1], "-p")) {
00170
00171 printPluginPath(false);
00172 return 0;
00173
00174 } else if (!strcmp(argv[1], "--list-ids")) {
00175
00176 enumeratePlugins(PluginIds);
00177 return 0;
00178
00179 } else if (!strcmp(argv[1], "--list-outputs")) {
00180
00181 enumeratePlugins(PluginOutputIds);
00182 return 0;
00183
00184 } else if (!strcmp(argv[1], "--list-by-category")) {
00185
00186 printPluginCategoryList();
00187 return 0;
00188
00189 } else usage(name);
00190 }
00191
00192 if (argc < 3) usage(name);
00193
00194 bool useFrames = false;
00195
00196 int base = 1;
00197 if (!strcmp(argv[1], "-s")) {
00198 useFrames = true;
00199 base = 2;
00200 }
00201
00202 string soname = argv[base];
00203 string wavname = argv[base+1];
00204 string plugid = "";
00205 string output = "";
00206 int outputNo = -1;
00207 string outfilename;
00208
00209 if (argc >= base+3) {
00210
00211 int idx = base+2;
00212
00213 if (isdigit(*argv[idx])) {
00214 outputNo = atoi(argv[idx++]);
00215 }
00216
00217 if (argc == idx + 2) {
00218 if (!strcmp(argv[idx], "-o")) {
00219 outfilename = argv[idx+1];
00220 } else usage(name);
00221 } else if (argc != idx) {
00222 (usage(name));
00223 }
00224 }
00225
00226 cerr << endl << name << ": Running..." << endl;
00227
00228 cerr << "Reading file: \"" << wavname << "\", writing to ";
00229 if (outfilename == "") {
00230 cerr << "standard output" << endl;
00231 } else {
00232 cerr << "\"" << outfilename << "\"" << endl;
00233 }
00234
00235 string::size_type sep = soname.find(':');
00236
00237 if (sep != string::npos) {
00238 plugid = soname.substr(sep + 1);
00239 soname = soname.substr(0, sep);
00240
00241 sep = plugid.find(':');
00242 if (sep != string::npos) {
00243 output = plugid.substr(sep + 1);
00244 plugid = plugid.substr(0, sep);
00245 }
00246 }
00247
00248 if (plugid == "") {
00249 usage(name);
00250 }
00251
00252 if (output != "" && outputNo != -1) {
00253 usage(name);
00254 }
00255
00256 if (output == "" && outputNo == -1) {
00257 outputNo = 0;
00258 }
00259
00260 return runPlugin(name, soname, plugid, output, outputNo,
00261 wavname, outfilename, useFrames);
00262 }
00263
00264
00265 int runPlugin(string myname, string soname, string id,
00266 string output, int outputNo, string wavname,
00267 string outfilename, bool useFrames)
00268 {
00269 PluginLoader *loader = PluginLoader::getInstance();
00270
00271 PluginLoader::PluginKey key = loader->composePluginKey(soname, id);
00272
00273 SNDFILE *sndfile;
00274 SF_INFO sfinfo;
00275 memset(&sfinfo, 0, sizeof(SF_INFO));
00276
00277 sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo);
00278 if (!sndfile) {
00279 cerr << myname << ": ERROR: Failed to open input file \""
00280 << wavname << "\": " << sf_strerror(sndfile) << endl;
00281 return 1;
00282 }
00283
00284 ofstream *out = 0;
00285 if (outfilename != "") {
00286 out = new ofstream(outfilename.c_str(), ios::out);
00287 if (!*out) {
00288 cerr << myname << ": ERROR: Failed to open output file \""
00289 << outfilename << "\" for writing" << endl;
00290 delete out;
00291 return 1;
00292 }
00293 }
00294
00295 Plugin *plugin = loader->loadPlugin
00296 (key, sfinfo.samplerate, PluginLoader::ADAPT_ALL_SAFE);
00297 if (!plugin) {
00298 cerr << myname << ": ERROR: Failed to load plugin \"" << id
00299 << "\" from library \"" << soname << "\"" << endl;
00300 sf_close(sndfile);
00301 if (out) {
00302 out->close();
00303 delete out;
00304 }
00305 return 1;
00306 }
00307
00308 cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl;
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 int blockSize = plugin->getPreferredBlockSize();
00322 int stepSize = plugin->getPreferredStepSize();
00323
00324 if (blockSize == 0) {
00325 blockSize = 1024;
00326 }
00327 if (stepSize == 0) {
00328 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
00329 stepSize = blockSize/2;
00330 } else {
00331 stepSize = blockSize;
00332 }
00333 } else if (stepSize > blockSize) {
00334 cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to ";
00335 if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
00336 blockSize = stepSize * 2;
00337 } else {
00338 blockSize = stepSize;
00339 }
00340 cerr << blockSize << endl;
00341 }
00342
00343 int channels = sfinfo.channels;
00344
00345 float *filebuf = new float[blockSize * channels];
00346 float **plugbuf = new float*[channels];
00347 for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
00348
00349 cerr << "Using block size = " << blockSize << ", step size = "
00350 << stepSize << endl;
00351
00352
00353
00354
00355
00356 int minch = plugin->getMinChannelCount();
00357 int maxch = plugin->getMaxChannelCount();
00358 cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
00359 cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
00360
00361 Plugin::OutputList outputs = plugin->getOutputDescriptors();
00362 Plugin::OutputDescriptor od;
00363
00364 int returnValue = 1;
00365 int progress = 0;
00366
00367 RealTime rt;
00368 PluginWrapper *wrapper = 0;
00369 RealTime adjustment = RealTime::zeroTime;
00370
00371 if (outputs.empty()) {
00372 cerr << "ERROR: Plugin has no outputs!" << endl;
00373 goto done;
00374 }
00375
00376 if (outputNo < 0) {
00377
00378 for (size_t oi = 0; oi < outputs.size(); ++oi) {
00379 if (outputs[oi].identifier == output) {
00380 outputNo = oi;
00381 break;
00382 }
00383 }
00384
00385 if (outputNo < 0) {
00386 cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
00387 goto done;
00388 }
00389
00390 } else {
00391
00392 if (int(outputs.size()) <= outputNo) {
00393 cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
00394 goto done;
00395 }
00396 }
00397
00398 od = outputs[outputNo];
00399 cerr << "Output is: \"" << od.identifier << "\"" << endl;
00400
00401 if (!plugin->initialise(channels, stepSize, blockSize)) {
00402 cerr << "ERROR: Plugin initialise (channels = " << channels
00403 << ", stepSize = " << stepSize << ", blockSize = "
00404 << blockSize << ") failed." << endl;
00405 goto done;
00406 }
00407
00408 wrapper = dynamic_cast<PluginWrapper *>(plugin);
00409 if (wrapper) {
00410
00411
00412 PluginInputDomainAdapter *ida =
00413 wrapper->getWrapper<PluginInputDomainAdapter>();
00414 if (ida) adjustment = ida->getTimestampAdjustment();
00415 }
00416
00417 for (sf_count_t i = 0; i < sfinfo.frames; i += stepSize) {
00418
00419 int count;
00420
00421 if (sf_seek(sndfile, i, SEEK_SET) < 0) {
00422 cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl;
00423 break;
00424 }
00425
00426 if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
00427 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
00428 break;
00429 }
00430
00431 for (int c = 0; c < channels; ++c) {
00432 int j = 0;
00433 while (j < count) {
00434 plugbuf[c][j] = filebuf[j * sfinfo.channels + c];
00435 ++j;
00436 }
00437 while (j < blockSize) {
00438 plugbuf[c][j] = 0.0f;
00439 ++j;
00440 }
00441 }
00442
00443 rt = RealTime::frame2RealTime(i, sfinfo.samplerate);
00444
00445 printFeatures
00446 (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
00447 sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt),
00448 out, useFrames);
00449
00450 int pp = progress;
00451 progress = lrintf((float(i) / sfinfo.frames) * 100.f);
00452 if (progress != pp && out) {
00453 cerr << "\r" << progress << "%";
00454 }
00455 }
00456 if (out) cerr << "\rDone" << endl;
00457
00458 rt = RealTime::frame2RealTime(sfinfo.frames, sfinfo.samplerate);
00459
00460 printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
00461 sfinfo.samplerate, outputNo,
00462 plugin->getRemainingFeatures(), out, useFrames);
00463
00464 returnValue = 0;
00465
00466 done:
00467 delete plugin;
00468 if (out) {
00469 out->close();
00470 delete out;
00471 }
00472 sf_close(sndfile);
00473 return returnValue;
00474 }
00475
00476 void
00477 printFeatures(int frame, int sr, int output,
00478 Plugin::FeatureSet features, ofstream *out, bool useFrames)
00479 {
00480 for (unsigned int i = 0; i < features[output].size(); ++i) {
00481
00482 if (useFrames) {
00483
00484 int displayFrame = frame;
00485
00486 if (features[output][i].hasTimestamp) {
00487 displayFrame = RealTime::realTime2Frame
00488 (features[output][i].timestamp, sr);
00489 }
00490
00491 (out ? *out : cout) << displayFrame;
00492
00493 if (features[output][i].hasDuration) {
00494 displayFrame = RealTime::realTime2Frame
00495 (features[output][i].duration, sr);
00496 (out ? *out : cout) << "," << displayFrame;
00497 }
00498
00499 (out ? *out : cout) << ":";
00500
00501 } else {
00502
00503 RealTime rt = RealTime::frame2RealTime(frame, sr);
00504
00505 if (features[output][i].hasTimestamp) {
00506 rt = features[output][i].timestamp;
00507 }
00508
00509 (out ? *out : cout) << rt.toString();
00510
00511 if (features[output][i].hasDuration) {
00512 rt = features[output][i].duration;
00513 (out ? *out : cout) << "," << rt.toString();
00514 }
00515
00516 (out ? *out : cout) << ":";
00517 }
00518
00519 for (unsigned int j = 0; j < features[output][i].values.size(); ++j) {
00520 (out ? *out : cout) << " " << features[output][i].values[j];
00521 }
00522
00523 (out ? *out : cout) << endl;
00524 }
00525 }
00526
00527 void
00528 printPluginPath(bool verbose)
00529 {
00530 if (verbose) {
00531 cout << "\nVamp plugin search path: ";
00532 }
00533
00534 vector<string> path = PluginHostAdapter::getPluginPath();
00535 for (size_t i = 0; i < path.size(); ++i) {
00536 if (verbose) {
00537 cout << "[" << path[i] << "]";
00538 } else {
00539 cout << path[i] << endl;
00540 }
00541 }
00542
00543 if (verbose) cout << endl;
00544 }
00545
00546 static
00547 string
00548 header(string text, int level)
00549 {
00550 string out = '\n' + text + '\n';
00551 for (size_t i = 0; i < text.length(); ++i) {
00552 out += (level == 1 ? '=' : level == 2 ? '-' : '~');
00553 }
00554 out += '\n';
00555 return out;
00556 }
00557
00558 void
00559 enumeratePlugins(Verbosity verbosity)
00560 {
00561 PluginLoader *loader = PluginLoader::getInstance();
00562
00563 if (verbosity == PluginInformation) {
00564 cout << "\nVamp plugin libraries found in search path:" << endl;
00565 }
00566
00567 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
00568 typedef multimap<string, PluginLoader::PluginKey>
00569 LibraryMap;
00570 LibraryMap libraryMap;
00571
00572 for (size_t i = 0; i < plugins.size(); ++i) {
00573 string path = loader->getLibraryPathForPlugin(plugins[i]);
00574 libraryMap.insert(LibraryMap::value_type(path, plugins[i]));
00575 }
00576
00577 string prevPath = "";
00578 int index = 0;
00579
00580 for (LibraryMap::iterator i = libraryMap.begin();
00581 i != libraryMap.end(); ++i) {
00582
00583 string path = i->first;
00584 PluginLoader::PluginKey key = i->second;
00585
00586 if (path != prevPath) {
00587 prevPath = path;
00588 index = 0;
00589 if (verbosity == PluginInformation) {
00590 cout << "\n " << path << ":" << endl;
00591 } else if (verbosity == PluginInformationDetailed) {
00592 string::size_type ki = i->second.find(':');
00593 string text = "Library \"" + i->second.substr(0, ki) + "\"";
00594 cout << "\n" << header(text, 1);
00595 }
00596 }
00597
00598 Plugin *plugin = loader->loadPlugin(key, 48000);
00599 if (plugin) {
00600
00601 char c = char('A' + index);
00602 if (c > 'Z') c = char('a' + (index - 26));
00603
00604 PluginLoader::PluginCategoryHierarchy category =
00605 loader->getPluginCategory(key);
00606 string catstr;
00607 if (!category.empty()) {
00608 for (size_t ci = 0; ci < category.size(); ++ci) {
00609 if (ci > 0) catstr += " > ";
00610 catstr += category[ci];
00611 }
00612 }
00613
00614 if (verbosity == PluginInformation) {
00615
00616 cout << " [" << c << "] [v"
00617 << plugin->getVampApiVersion() << "] "
00618 << plugin->getName() << ", \""
00619 << plugin->getIdentifier() << "\"" << " ["
00620 << plugin->getMaker() << "]" << endl;
00621
00622 if (catstr != "") {
00623 cout << " > " << catstr << endl;
00624 }
00625
00626 if (plugin->getDescription() != "") {
00627 cout << " - " << plugin->getDescription() << endl;
00628 }
00629
00630 } else if (verbosity == PluginInformationDetailed) {
00631
00632 cout << header(plugin->getName(), 2);
00633 cout << " - Identifier: "
00634 << key << endl;
00635 cout << " - Plugin Version: "
00636 << plugin->getPluginVersion() << endl;
00637 cout << " - Vamp API Version: "
00638 << plugin->getVampApiVersion() << endl;
00639 cout << " - Maker: \""
00640 << plugin->getMaker() << "\"" << endl;
00641 cout << " - Copyright: \""
00642 << plugin->getCopyright() << "\"" << endl;
00643 cout << " - Description: \""
00644 << plugin->getDescription() << "\"" << endl;
00645 cout << " - Input Domain: "
00646 << (plugin->getInputDomain() == Vamp::Plugin::TimeDomain ?
00647 "Time Domain" : "Frequency Domain") << endl;
00648 cout << " - Default Step Size: "
00649 << plugin->getPreferredStepSize() << endl;
00650 cout << " - Default Block Size: "
00651 << plugin->getPreferredBlockSize() << endl;
00652 cout << " - Minimum Channels: "
00653 << plugin->getMinChannelCount() << endl;
00654 cout << " - Maximum Channels: "
00655 << plugin->getMaxChannelCount() << endl;
00656
00657 } else if (verbosity == PluginIds) {
00658 cout << "vamp:" << key << endl;
00659 }
00660
00661 Plugin::OutputList outputs =
00662 plugin->getOutputDescriptors();
00663
00664 if (verbosity == PluginInformationDetailed) {
00665
00666 Plugin::ParameterList params = plugin->getParameterDescriptors();
00667 for (size_t j = 0; j < params.size(); ++j) {
00668 Plugin::ParameterDescriptor &pd(params[j]);
00669 cout << "\nParameter " << j+1 << ": \"" << pd.name << "\"" << endl;
00670 cout << " - Identifier: " << pd.identifier << endl;
00671 cout << " - Description: \"" << pd.description << "\"" << endl;
00672 if (pd.unit != "") {
00673 cout << " - Unit: " << pd.unit << endl;
00674 }
00675 cout << " - Range: ";
00676 cout << pd.minValue << " -> " << pd.maxValue << endl;
00677 cout << " - Default: ";
00678 cout << pd.defaultValue << endl;
00679 if (pd.isQuantized) {
00680 cout << " - Quantize Step: "
00681 << pd.quantizeStep << endl;
00682 }
00683 if (!pd.valueNames.empty()) {
00684 cout << " - Value Names: ";
00685 for (size_t k = 0; k < pd.valueNames.size(); ++k) {
00686 if (k > 0) cout << ", ";
00687 cout << "\"" << pd.valueNames[k] << "\"";
00688 }
00689 cout << endl;
00690 }
00691 }
00692
00693 if (outputs.empty()) {
00694 cout << "\n** Note: This plugin reports no outputs!" << endl;
00695 }
00696 for (size_t j = 0; j < outputs.size(); ++j) {
00697 Plugin::OutputDescriptor &od(outputs[j]);
00698 cout << "\nOutput " << j+1 << ": \"" << od.name << "\"" << endl;
00699 cout << " - Identifier: " << od.identifier << endl;
00700 cout << " - Description: \"" << od.description << "\"" << endl;
00701 if (od.unit != "") {
00702 cout << " - Unit: " << od.unit << endl;
00703 }
00704 if (od.hasFixedBinCount) {
00705 cout << " - Default Bin Count: " << od.binCount << endl;
00706 }
00707 if (!od.binNames.empty()) {
00708 bool have = false;
00709 for (size_t k = 0; k < od.binNames.size(); ++k) {
00710 if (od.binNames[k] != "") {
00711 have = true; break;
00712 }
00713 }
00714 if (have) {
00715 cout << " - Bin Names: ";
00716 for (size_t k = 0; k < od.binNames.size(); ++k) {
00717 if (k > 0) cout << ", ";
00718 cout << "\"" << od.binNames[k] << "\"";
00719 }
00720 cout << endl;
00721 }
00722 }
00723 if (od.hasKnownExtents) {
00724 cout << " - Default Extents: ";
00725 cout << od.minValue << " -> " << od.maxValue << endl;
00726 }
00727 if (od.isQuantized) {
00728 cout << " - Quantize Step: "
00729 << od.quantizeStep << endl;
00730 }
00731 cout << " - Sample Type: "
00732 << (od.sampleType ==
00733 Plugin::OutputDescriptor::OneSamplePerStep ?
00734 "One Sample Per Step" :
00735 od.sampleType ==
00736 Plugin::OutputDescriptor::FixedSampleRate ?
00737 "Fixed Sample Rate" :
00738 "Variable Sample Rate") << endl;
00739 if (od.sampleType !=
00740 Plugin::OutputDescriptor::OneSamplePerStep) {
00741 cout << " - Default Rate: "
00742 << od.sampleRate << endl;
00743 }
00744 cout << " - Has Duration: "
00745 << (od.hasDuration ? "Yes" : "No") << endl;
00746 }
00747 }
00748
00749 if (outputs.size() > 1 || verbosity == PluginOutputIds) {
00750 for (size_t j = 0; j < outputs.size(); ++j) {
00751 if (verbosity == PluginInformation) {
00752 cout << " (" << j << ") "
00753 << outputs[j].name << ", \""
00754 << outputs[j].identifier << "\"" << endl;
00755 if (outputs[j].description != "") {
00756 cout << " - "
00757 << outputs[j].description << endl;
00758 }
00759 } else if (verbosity == PluginOutputIds) {
00760 cout << "vamp:" << key << ":" << outputs[j].identifier << endl;
00761 }
00762 }
00763 }
00764
00765 ++index;
00766
00767 delete plugin;
00768 }
00769 }
00770
00771 if (verbosity == PluginInformation ||
00772 verbosity == PluginInformationDetailed) {
00773 cout << endl;
00774 }
00775 }
00776
00777 void
00778 printPluginCategoryList()
00779 {
00780 PluginLoader *loader = PluginLoader::getInstance();
00781
00782 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
00783
00784 set<string> printedcats;
00785
00786 for (size_t i = 0; i < plugins.size(); ++i) {
00787
00788 PluginLoader::PluginKey key = plugins[i];
00789
00790 PluginLoader::PluginCategoryHierarchy category =
00791 loader->getPluginCategory(key);
00792
00793 Plugin *plugin = loader->loadPlugin(key, 48000);
00794 if (!plugin) continue;
00795
00796 string catstr = "";
00797
00798 if (category.empty()) catstr = '|';
00799 else {
00800 for (size_t j = 0; j < category.size(); ++j) {
00801 catstr += category[j];
00802 catstr += '|';
00803 if (printedcats.find(catstr) == printedcats.end()) {
00804 std::cout << catstr << std::endl;
00805 printedcats.insert(catstr);
00806 }
00807 }
00808 }
00809
00810 std::cout << catstr << key << ":::" << plugin->getName() << ":::" << plugin->getMaker() << ":::" << plugin->getDescription() << std::endl;
00811 }
00812 }
00813