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.5"
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 int overlapSize = blockSize - stepSize;
00343 sf_count_t currentStep = 0;
00344 int finalStepsRemaining = max(1, (blockSize / stepSize) - 1);
00345
00346 int channels = sfinfo.channels;
00347
00348 float *filebuf = new float[blockSize * channels];
00349 float **plugbuf = new float*[channels];
00350 for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
00351
00352 cerr << "Using block size = " << blockSize << ", step size = "
00353 << stepSize << endl;
00354
00355
00356
00357
00358
00359 int minch = plugin->getMinChannelCount();
00360 int maxch = plugin->getMaxChannelCount();
00361 cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
00362 cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
00363
00364 Plugin::OutputList outputs = plugin->getOutputDescriptors();
00365 Plugin::OutputDescriptor od;
00366
00367 int returnValue = 1;
00368 int progress = 0;
00369
00370 RealTime rt;
00371 PluginWrapper *wrapper = 0;
00372 RealTime adjustment = RealTime::zeroTime;
00373
00374 if (outputs.empty()) {
00375 cerr << "ERROR: Plugin has no outputs!" << endl;
00376 goto done;
00377 }
00378
00379 if (outputNo < 0) {
00380
00381 for (size_t oi = 0; oi < outputs.size(); ++oi) {
00382 if (outputs[oi].identifier == output) {
00383 outputNo = oi;
00384 break;
00385 }
00386 }
00387
00388 if (outputNo < 0) {
00389 cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
00390 goto done;
00391 }
00392
00393 } else {
00394
00395 if (int(outputs.size()) <= outputNo) {
00396 cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
00397 goto done;
00398 }
00399 }
00400
00401 od = outputs[outputNo];
00402 cerr << "Output is: \"" << od.identifier << "\"" << endl;
00403
00404 if (!plugin->initialise(channels, stepSize, blockSize)) {
00405 cerr << "ERROR: Plugin initialise (channels = " << channels
00406 << ", stepSize = " << stepSize << ", blockSize = "
00407 << blockSize << ") failed." << endl;
00408 goto done;
00409 }
00410
00411 wrapper = dynamic_cast<PluginWrapper *>(plugin);
00412 if (wrapper) {
00413
00414
00415 PluginInputDomainAdapter *ida =
00416 wrapper->getWrapper<PluginInputDomainAdapter>();
00417 if (ida) adjustment = ida->getTimestampAdjustment();
00418 }
00419
00420
00421 do {
00422
00423 int count;
00424
00425 if ((blockSize==stepSize) || (currentStep==0)) {
00426
00427 if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
00428 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
00429 break;
00430 }
00431 if (count != blockSize) --finalStepsRemaining;
00432 } else {
00433
00434 memmove(filebuf, filebuf + (stepSize * channels), overlapSize * channels * sizeof(float));
00435 if ((count = sf_readf_float(sndfile, filebuf + (overlapSize * channels), stepSize)) < 0) {
00436 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
00437 break;
00438 }
00439 if (count != stepSize) --finalStepsRemaining;
00440 count += overlapSize;
00441 }
00442
00443 for (int c = 0; c < channels; ++c) {
00444 int j = 0;
00445 while (j < count) {
00446 plugbuf[c][j] = filebuf[j * sfinfo.channels + c];
00447 ++j;
00448 }
00449 while (j < blockSize) {
00450 plugbuf[c][j] = 0.0f;
00451 ++j;
00452 }
00453 }
00454
00455 rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
00456
00457 printFeatures
00458 (RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
00459 sfinfo.samplerate, outputNo, plugin->process(plugbuf, rt),
00460 out, useFrames);
00461
00462 if (sfinfo.frames > 0){
00463 int pp = progress;
00464 progress = lrintf((float(currentStep * stepSize) / sfinfo.frames) * 100.f);
00465 if (progress != pp && out) {
00466 cerr << "\r" << progress << "%";
00467 }
00468 }
00469
00470 ++currentStep;
00471
00472 } while (finalStepsRemaining > 0);
00473
00474 if (out) cerr << "\rDone" << endl;
00475
00476 rt = RealTime::frame2RealTime(currentStep * stepSize, sfinfo.samplerate);
00477
00478 printFeatures(RealTime::realTime2Frame(rt + adjustment, sfinfo.samplerate),
00479 sfinfo.samplerate, outputNo,
00480 plugin->getRemainingFeatures(), out, useFrames);
00481
00482 returnValue = 0;
00483
00484 done:
00485 delete plugin;
00486 if (out) {
00487 out->close();
00488 delete out;
00489 }
00490 sf_close(sndfile);
00491 return returnValue;
00492 }
00493
00494 void
00495 printFeatures(int frame, int sr, int output,
00496 Plugin::FeatureSet features, ofstream *out, bool useFrames)
00497 {
00498 for (unsigned int i = 0; i < features[output].size(); ++i) {
00499
00500 if (useFrames) {
00501
00502 int displayFrame = frame;
00503
00504 if (features[output][i].hasTimestamp) {
00505 displayFrame = RealTime::realTime2Frame
00506 (features[output][i].timestamp, sr);
00507 }
00508
00509 (out ? *out : cout) << displayFrame;
00510
00511 if (features[output][i].hasDuration) {
00512 displayFrame = RealTime::realTime2Frame
00513 (features[output][i].duration, sr);
00514 (out ? *out : cout) << "," << displayFrame;
00515 }
00516
00517 (out ? *out : cout) << ":";
00518
00519 } else {
00520
00521 RealTime rt = RealTime::frame2RealTime(frame, sr);
00522
00523 if (features[output][i].hasTimestamp) {
00524 rt = features[output][i].timestamp;
00525 }
00526
00527 (out ? *out : cout) << rt.toString();
00528
00529 if (features[output][i].hasDuration) {
00530 rt = features[output][i].duration;
00531 (out ? *out : cout) << "," << rt.toString();
00532 }
00533
00534 (out ? *out : cout) << ":";
00535 }
00536
00537 for (unsigned int j = 0; j < features[output][i].values.size(); ++j) {
00538 (out ? *out : cout) << " " << features[output][i].values[j];
00539 }
00540 (out ? *out : cout) << " " << features[output][i].label;
00541
00542 (out ? *out : cout) << endl;
00543 }
00544 }
00545
00546 void
00547 printPluginPath(bool verbose)
00548 {
00549 if (verbose) {
00550 cout << "\nVamp plugin search path: ";
00551 }
00552
00553 vector<string> path = PluginHostAdapter::getPluginPath();
00554 for (size_t i = 0; i < path.size(); ++i) {
00555 if (verbose) {
00556 cout << "[" << path[i] << "]";
00557 } else {
00558 cout << path[i] << endl;
00559 }
00560 }
00561
00562 if (verbose) cout << endl;
00563 }
00564
00565 static
00566 string
00567 header(string text, int level)
00568 {
00569 string out = '\n' + text + '\n';
00570 for (size_t i = 0; i < text.length(); ++i) {
00571 out += (level == 1 ? '=' : level == 2 ? '-' : '~');
00572 }
00573 out += '\n';
00574 return out;
00575 }
00576
00577 void
00578 enumeratePlugins(Verbosity verbosity)
00579 {
00580 PluginLoader *loader = PluginLoader::getInstance();
00581
00582 if (verbosity == PluginInformation) {
00583 cout << "\nVamp plugin libraries found in search path:" << endl;
00584 }
00585
00586 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
00587 typedef multimap<string, PluginLoader::PluginKey>
00588 LibraryMap;
00589 LibraryMap libraryMap;
00590
00591 for (size_t i = 0; i < plugins.size(); ++i) {
00592 string path = loader->getLibraryPathForPlugin(plugins[i]);
00593 libraryMap.insert(LibraryMap::value_type(path, plugins[i]));
00594 }
00595
00596 string prevPath = "";
00597 int index = 0;
00598
00599 for (LibraryMap::iterator i = libraryMap.begin();
00600 i != libraryMap.end(); ++i) {
00601
00602 string path = i->first;
00603 PluginLoader::PluginKey key = i->second;
00604
00605 if (path != prevPath) {
00606 prevPath = path;
00607 index = 0;
00608 if (verbosity == PluginInformation) {
00609 cout << "\n " << path << ":" << endl;
00610 } else if (verbosity == PluginInformationDetailed) {
00611 string::size_type ki = i->second.find(':');
00612 string text = "Library \"" + i->second.substr(0, ki) + "\"";
00613 cout << "\n" << header(text, 1);
00614 }
00615 }
00616
00617 Plugin *plugin = loader->loadPlugin(key, 48000);
00618 if (plugin) {
00619
00620 char c = char('A' + index);
00621 if (c > 'Z') c = char('a' + (index - 26));
00622
00623 PluginLoader::PluginCategoryHierarchy category =
00624 loader->getPluginCategory(key);
00625 string catstr;
00626 if (!category.empty()) {
00627 for (size_t ci = 0; ci < category.size(); ++ci) {
00628 if (ci > 0) catstr += " > ";
00629 catstr += category[ci];
00630 }
00631 }
00632
00633 if (verbosity == PluginInformation) {
00634
00635 cout << " [" << c << "] [v"
00636 << plugin->getVampApiVersion() << "] "
00637 << plugin->getName() << ", \""
00638 << plugin->getIdentifier() << "\"" << " ["
00639 << plugin->getMaker() << "]" << endl;
00640
00641 if (catstr != "") {
00642 cout << " > " << catstr << endl;
00643 }
00644
00645 if (plugin->getDescription() != "") {
00646 cout << " - " << plugin->getDescription() << endl;
00647 }
00648
00649 } else if (verbosity == PluginInformationDetailed) {
00650
00651 cout << header(plugin->getName(), 2);
00652 cout << " - Identifier: "
00653 << key << endl;
00654 cout << " - Plugin Version: "
00655 << plugin->getPluginVersion() << endl;
00656 cout << " - Vamp API Version: "
00657 << plugin->getVampApiVersion() << endl;
00658 cout << " - Maker: \""
00659 << plugin->getMaker() << "\"" << endl;
00660 cout << " - Copyright: \""
00661 << plugin->getCopyright() << "\"" << endl;
00662 cout << " - Description: \""
00663 << plugin->getDescription() << "\"" << endl;
00664 cout << " - Input Domain: "
00665 << (plugin->getInputDomain() == Vamp::Plugin::TimeDomain ?
00666 "Time Domain" : "Frequency Domain") << endl;
00667 cout << " - Default Step Size: "
00668 << plugin->getPreferredStepSize() << endl;
00669 cout << " - Default Block Size: "
00670 << plugin->getPreferredBlockSize() << endl;
00671 cout << " - Minimum Channels: "
00672 << plugin->getMinChannelCount() << endl;
00673 cout << " - Maximum Channels: "
00674 << plugin->getMaxChannelCount() << endl;
00675
00676 } else if (verbosity == PluginIds) {
00677 cout << "vamp:" << key << endl;
00678 }
00679
00680 Plugin::OutputList outputs =
00681 plugin->getOutputDescriptors();
00682
00683 if (verbosity == PluginInformationDetailed) {
00684
00685 Plugin::ParameterList params = plugin->getParameterDescriptors();
00686 for (size_t j = 0; j < params.size(); ++j) {
00687 Plugin::ParameterDescriptor &pd(params[j]);
00688 cout << "\nParameter " << j+1 << ": \"" << pd.name << "\"" << endl;
00689 cout << " - Identifier: " << pd.identifier << endl;
00690 cout << " - Description: \"" << pd.description << "\"" << endl;
00691 if (pd.unit != "") {
00692 cout << " - Unit: " << pd.unit << endl;
00693 }
00694 cout << " - Range: ";
00695 cout << pd.minValue << " -> " << pd.maxValue << endl;
00696 cout << " - Default: ";
00697 cout << pd.defaultValue << endl;
00698 if (pd.isQuantized) {
00699 cout << " - Quantize Step: "
00700 << pd.quantizeStep << endl;
00701 }
00702 if (!pd.valueNames.empty()) {
00703 cout << " - Value Names: ";
00704 for (size_t k = 0; k < pd.valueNames.size(); ++k) {
00705 if (k > 0) cout << ", ";
00706 cout << "\"" << pd.valueNames[k] << "\"";
00707 }
00708 cout << endl;
00709 }
00710 }
00711
00712 if (outputs.empty()) {
00713 cout << "\n** Note: This plugin reports no outputs!" << endl;
00714 }
00715 for (size_t j = 0; j < outputs.size(); ++j) {
00716 Plugin::OutputDescriptor &od(outputs[j]);
00717 cout << "\nOutput " << j+1 << ": \"" << od.name << "\"" << endl;
00718 cout << " - Identifier: " << od.identifier << endl;
00719 cout << " - Description: \"" << od.description << "\"" << endl;
00720 if (od.unit != "") {
00721 cout << " - Unit: " << od.unit << endl;
00722 }
00723 if (od.hasFixedBinCount) {
00724 cout << " - Default Bin Count: " << od.binCount << endl;
00725 }
00726 if (!od.binNames.empty()) {
00727 bool have = false;
00728 for (size_t k = 0; k < od.binNames.size(); ++k) {
00729 if (od.binNames[k] != "") {
00730 have = true; break;
00731 }
00732 }
00733 if (have) {
00734 cout << " - Bin Names: ";
00735 for (size_t k = 0; k < od.binNames.size(); ++k) {
00736 if (k > 0) cout << ", ";
00737 cout << "\"" << od.binNames[k] << "\"";
00738 }
00739 cout << endl;
00740 }
00741 }
00742 if (od.hasKnownExtents) {
00743 cout << " - Default Extents: ";
00744 cout << od.minValue << " -> " << od.maxValue << endl;
00745 }
00746 if (od.isQuantized) {
00747 cout << " - Quantize Step: "
00748 << od.quantizeStep << endl;
00749 }
00750 cout << " - Sample Type: "
00751 << (od.sampleType ==
00752 Plugin::OutputDescriptor::OneSamplePerStep ?
00753 "One Sample Per Step" :
00754 od.sampleType ==
00755 Plugin::OutputDescriptor::FixedSampleRate ?
00756 "Fixed Sample Rate" :
00757 "Variable Sample Rate") << endl;
00758 if (od.sampleType !=
00759 Plugin::OutputDescriptor::OneSamplePerStep) {
00760 cout << " - Default Rate: "
00761 << od.sampleRate << endl;
00762 }
00763 cout << " - Has Duration: "
00764 << (od.hasDuration ? "Yes" : "No") << endl;
00765 }
00766 }
00767
00768 if (outputs.size() > 1 || verbosity == PluginOutputIds) {
00769 for (size_t j = 0; j < outputs.size(); ++j) {
00770 if (verbosity == PluginInformation) {
00771 cout << " (" << j << ") "
00772 << outputs[j].name << ", \""
00773 << outputs[j].identifier << "\"" << endl;
00774 if (outputs[j].description != "") {
00775 cout << " - "
00776 << outputs[j].description << endl;
00777 }
00778 } else if (verbosity == PluginOutputIds) {
00779 cout << "vamp:" << key << ":" << outputs[j].identifier << endl;
00780 }
00781 }
00782 }
00783
00784 ++index;
00785
00786 delete plugin;
00787 }
00788 }
00789
00790 if (verbosity == PluginInformation ||
00791 verbosity == PluginInformationDetailed) {
00792 cout << endl;
00793 }
00794 }
00795
00796 void
00797 printPluginCategoryList()
00798 {
00799 PluginLoader *loader = PluginLoader::getInstance();
00800
00801 vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
00802
00803 set<string> printedcats;
00804
00805 for (size_t i = 0; i < plugins.size(); ++i) {
00806
00807 PluginLoader::PluginKey key = plugins[i];
00808
00809 PluginLoader::PluginCategoryHierarchy category =
00810 loader->getPluginCategory(key);
00811
00812 Plugin *plugin = loader->loadPlugin(key, 48000);
00813 if (!plugin) continue;
00814
00815 string catstr = "";
00816
00817 if (category.empty()) catstr = '|';
00818 else {
00819 for (size_t j = 0; j < category.size(); ++j) {
00820 catstr += category[j];
00821 catstr += '|';
00822 if (printedcats.find(catstr) == printedcats.end()) {
00823 std::cout << catstr << std::endl;
00824 printedcats.insert(catstr);
00825 }
00826 }
00827 }
00828
00829 std::cout << catstr << key << ":::" << plugin->getName() << ":::" << plugin->getMaker() << ":::" << plugin->getDescription() << std::endl;
00830 }
00831 }
00832