cannam@0: cannam@0: cannam@0: VampPluginSDK: vamp-simple-host.cpp Source File cannam@0: cannam@0: cannam@0: cannam@0: cannam@0: cannam@0: cannam@0:

vamp-simple-host.cpp

Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
cannam@0: 00002 
cannam@0: 00003 /*
cannam@0: 00004     Vamp
cannam@0: 00005 
cannam@0: 00006     An API for audio analysis and feature extraction plugins.
cannam@0: 00007 
cannam@0: 00008     Centre for Digital Music, Queen Mary, University of London.
cannam@0: 00009     Copyright 2006 Chris Cannam.
cannam@0: 00010     FFT code from Don Cross's public domain FFT implementation.
cannam@0: 00011   
cannam@0: 00012     Permission is hereby granted, free of charge, to any person
cannam@0: 00013     obtaining a copy of this software and associated documentation
cannam@0: 00014     files (the "Software"), to deal in the Software without
cannam@0: 00015     restriction, including without limitation the rights to use, copy,
cannam@0: 00016     modify, merge, publish, distribute, sublicense, and/or sell copies
cannam@0: 00017     of the Software, and to permit persons to whom the Software is
cannam@0: 00018     furnished to do so, subject to the following conditions:
cannam@0: 00019 
cannam@0: 00020     The above copyright notice and this permission notice shall be
cannam@0: 00021     included in all copies or substantial portions of the Software.
cannam@0: 00022 
cannam@0: 00023     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
cannam@0: 00024     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
cannam@0: 00025     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
cannam@0: 00026     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
cannam@0: 00027     ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
cannam@0: 00028     CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
cannam@0: 00029     WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
cannam@0: 00030 
cannam@0: 00031     Except as contained in this notice, the names of the Centre for
cannam@0: 00032     Digital Music; Queen Mary, University of London; and Chris Cannam
cannam@0: 00033     shall not be used in advertising or otherwise to promote the sale,
cannam@0: 00034     use or other dealings in this Software without prior written
cannam@0: 00035     authorization.
cannam@0: 00036 */
cannam@0: 00037 
cannam@0: 00038 #include "vamp-sdk/PluginHostAdapter.h"
cannam@0: 00039 #include "vamp-sdk/hostext/PluginChannelAdapter.h"
cannam@0: 00040 #include "vamp-sdk/hostext/PluginInputDomainAdapter.h"
cannam@0: 00041 #include "vamp-sdk/hostext/PluginLoader.h"
cannam@0: 00042 #include "vamp/vamp.h"
cannam@0: 00043 
cannam@0: 00044 #include <iostream>
cannam@0: 00045 #include <fstream>
cannam@0: 00046 #include <set>
cannam@0: 00047 #include <sndfile.h>
cannam@0: 00048 
cannam@0: 00049 #include <cstring>
cannam@0: 00050 #include <cstdlib>
cannam@0: 00051 
cannam@0: 00052 #include "system.h"
cannam@0: 00053 
cannam@0: 00054 #include <cmath>
cannam@0: 00055 
cannam@0: 00056 using namespace std;
cannam@0: 00057 
cannam@0: 00058 using Vamp::Plugin;
cannam@0: 00059 using Vamp::PluginHostAdapter;
cannam@0: 00060 using Vamp::RealTime;
cannam@0: 00061 using Vamp::HostExt::PluginLoader;
cannam@0: 00062 
cannam@0: 00063 #define HOST_VERSION "1.1"
cannam@0: 00064 
cannam@0: 00065 enum Verbosity {
cannam@0: 00066     PluginIds,
cannam@0: 00067     PluginOutputIds,
cannam@0: 00068     PluginInformation
cannam@0: 00069 };
cannam@0: 00070 
cannam@0: 00071 void printFeatures(int, int, int, Plugin::FeatureSet, ofstream *, bool frames);
cannam@0: 00072 void transformInput(float *, size_t);
cannam@0: 00073 void fft(unsigned int, bool, double *, double *, double *, double *);
cannam@0: 00074 void printPluginPath(bool verbose);
cannam@0: 00075 void printPluginCategoryList();
cannam@0: 00076 void enumeratePlugins(Verbosity);
cannam@0: 00077 void listPluginsInLibrary(string soname);
cannam@0: 00078 int runPlugin(string myname, string soname, string id, string output,
cannam@0: 00079               int outputNo, string inputFile, string outfilename, bool frames);
cannam@0: 00080 
cannam@0: 00081 void usage(const char *name)
cannam@0: 00082 {
cannam@0: 00083     cerr << "\n"
cannam@0: 00084          << name << ": A simple Vamp plugin host.\n\n"
cannam@0: 00085         "Centre for Digital Music, Queen Mary, University of London.\n"
cannam@0: 00086         "Copyright 2006-2007 Chris Cannam and QMUL.\n"
cannam@0: 00087         "Freely redistributable; published under a BSD-style license.\n\n"
cannam@0: 00088         "Usage:\n\n"
cannam@0: 00089         "  " << name << " [-s] pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin[:output] file.wav [-o out.txt]\n"
cannam@0: 00090         "  " << name << " [-s] pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin file.wav [outputno] [-o out.txt]\n\n"
cannam@0: 00091         "    -- Load plugin id \"plugin\" from \"pluginlibrary\" and run it on the\n"
cannam@0: 00092         "       audio data in \"file.wav\", retrieving the named \"output\", or output\n"
cannam@0: 00093         "       number \"outputno\" (the first output by default) and dumping it to\n"
cannam@0: 00094         "       standard output, or to \"out.txt\" if the -o option is given.\n\n"
cannam@0: 00095         "       \"pluginlibrary\" should be a library name, not a file path; the\n"
cannam@0: 00096         "       standard Vamp library search path will be used to locate it.  If\n"
cannam@0: 00097         "       a file path is supplied, the directory part(s) will be ignored.\n\n"
cannam@0: 00098         "       If the -s option is given, results will be labelled with the audio\n"
cannam@0: 00099         "       sample frame at which they occur. Otherwise, they will be labelled\n"
cannam@0: 00100         "       with time in seconds.\n\n"
cannam@0: 00101         "  " << name << " -l\n\n"
cannam@0: 00102         "    -- List the plugin libraries and Vamp plugins in the library search path\n"
cannam@0: 00103         "       in a verbose human-readable format.\n\n"
cannam@0: 00104         "  " << name << " --list-ids\n\n"
cannam@0: 00105         "    -- List the plugins in the search path in a terse machine-readable format,\n"
cannam@0: 00106         "       in the form vamp:soname:identifier.\n\n"
cannam@0: 00107         "  " << name << " --list-outputs\n\n"
cannam@0: 00108         "    -- List the outputs for plugins in the search path in a machine-readable\n"
cannam@0: 00109         "       format, in the form vamp:soname:identifier:output.\n\n"
cannam@0: 00110         "  " << name << " --list-by-category\n\n"
cannam@0: 00111         "    -- List the plugins as a plugin index by category, in a machine-readable\n"
cannam@0: 00112         "       format.  The format may change in future releases.\n\n"
cannam@0: 00113         "  " << name << " -p\n\n"
cannam@0: 00114         "    -- Print out the Vamp library search path.\n\n"
cannam@0: 00115         "  " << name << " -v\n\n"
cannam@0: 00116         "    -- Display version information only.\n"
cannam@0: 00117          << endl;
cannam@0: 00118     exit(2);
cannam@0: 00119 }
cannam@0: 00120 
cannam@0: 00121 int main(int argc, char **argv)
cannam@0: 00122 {
cannam@0: 00123     char *scooter = argv[0];
cannam@0: 00124     char *name = 0;
cannam@0: 00125     while (scooter && *scooter) {
cannam@0: 00126         if (*scooter == '/' || *scooter == '\\') name = ++scooter;
cannam@0: 00127         else ++scooter;
cannam@0: 00128     }
cannam@0: 00129     if (!name || !*name) name = argv[0];
cannam@0: 00130     
cannam@0: 00131     if (argc < 2) usage(name);
cannam@0: 00132 
cannam@0: 00133     if (argc == 2) {
cannam@0: 00134 
cannam@0: 00135         if (!strcmp(argv[1], "-v")) {
cannam@0: 00136 
cannam@0: 00137             cout << "Simple Vamp plugin host version: " << HOST_VERSION << endl
cannam@0: 00138                  << "Vamp API version: " << VAMP_API_VERSION << endl
cannam@0: 00139                  << "Vamp SDK version: " << VAMP_SDK_VERSION << endl;
cannam@0: 00140             return 0;
cannam@0: 00141 
cannam@0: 00142         } else if (!strcmp(argv[1], "-l")) {
cannam@0: 00143 
cannam@0: 00144             printPluginPath(true);
cannam@0: 00145             enumeratePlugins(PluginInformation);
cannam@0: 00146             return 0;
cannam@0: 00147 
cannam@0: 00148         } else if (!strcmp(argv[1], "-p")) {
cannam@0: 00149 
cannam@0: 00150             printPluginPath(false);
cannam@0: 00151             return 0;
cannam@0: 00152 
cannam@0: 00153         } else if (!strcmp(argv[1], "--list-ids")) {
cannam@0: 00154 
cannam@0: 00155             enumeratePlugins(PluginIds);
cannam@0: 00156             return 0;
cannam@0: 00157 
cannam@0: 00158         } else if (!strcmp(argv[1], "--list-outputs")) {
cannam@0: 00159 
cannam@0: 00160             enumeratePlugins(PluginOutputIds);
cannam@0: 00161             return 0;
cannam@0: 00162 
cannam@0: 00163         } else if (!strcmp(argv[1], "--list-by-category")) {
cannam@0: 00164 
cannam@0: 00165             printPluginCategoryList();
cannam@0: 00166             return 0;
cannam@0: 00167 
cannam@0: 00168         } else usage(name);
cannam@0: 00169     }
cannam@0: 00170 
cannam@0: 00171     if (argc < 3) usage(name);
cannam@0: 00172 
cannam@0: 00173     bool useFrames = false;
cannam@0: 00174     
cannam@0: 00175     int base = 1;
cannam@0: 00176     if (!strcmp(argv[1], "-s")) {
cannam@0: 00177         useFrames = true;
cannam@0: 00178         base = 2;
cannam@0: 00179     }
cannam@0: 00180 
cannam@0: 00181     string soname = argv[base];
cannam@0: 00182     string wavname = argv[base+1];
cannam@0: 00183     string plugid = "";
cannam@0: 00184     string output = "";
cannam@0: 00185     int outputNo = -1;
cannam@0: 00186     string outfilename;
cannam@0: 00187 
cannam@0: 00188     if (argc >= base+3) {
cannam@0: 00189 
cannam@0: 00190         int idx = base+2;
cannam@0: 00191 
cannam@0: 00192         if (isdigit(*argv[idx])) {
cannam@0: 00193             outputNo = atoi(argv[idx++]);
cannam@0: 00194         }
cannam@0: 00195 
cannam@0: 00196         if (argc == idx + 2) {
cannam@0: 00197             if (!strcmp(argv[idx], "-o")) {
cannam@0: 00198                 outfilename = argv[idx+1];
cannam@0: 00199             } else usage(name);
cannam@0: 00200         } else if (argc != idx) {
cannam@0: 00201             (usage(name));
cannam@0: 00202         }
cannam@0: 00203     }
cannam@0: 00204 
cannam@0: 00205     cerr << endl << name << ": Running..." << endl;
cannam@0: 00206 
cannam@0: 00207     cerr << "Reading file: \"" << wavname << "\", writing to ";
cannam@0: 00208     if (outfilename == "") {
cannam@0: 00209         cerr << "standard output" << endl;
cannam@0: 00210     } else {
cannam@0: 00211         cerr << "\"" << outfilename << "\"" << endl;
cannam@0: 00212     }
cannam@0: 00213 
cannam@0: 00214     string::size_type sep = soname.find(':');
cannam@0: 00215 
cannam@0: 00216     if (sep != string::npos) {
cannam@0: 00217         plugid = soname.substr(sep + 1);
cannam@0: 00218         soname = soname.substr(0, sep);
cannam@0: 00219 
cannam@0: 00220         sep = plugid.find(':');
cannam@0: 00221         if (sep != string::npos) {
cannam@0: 00222             output = plugid.substr(sep + 1);
cannam@0: 00223             plugid = plugid.substr(0, sep);
cannam@0: 00224         }
cannam@0: 00225     }
cannam@0: 00226 
cannam@0: 00227     if (plugid == "") {
cannam@0: 00228         usage(name);
cannam@0: 00229     }
cannam@0: 00230 
cannam@0: 00231     if (output != "" && outputNo != -1) {
cannam@0: 00232         usage(name);
cannam@0: 00233     }
cannam@0: 00234 
cannam@0: 00235     if (output == "" && outputNo == -1) {
cannam@0: 00236         outputNo = 0;
cannam@0: 00237     }
cannam@0: 00238 
cannam@0: 00239     return runPlugin(name, soname, plugid, output, outputNo,
cannam@0: 00240                      wavname, outfilename, useFrames);
cannam@0: 00241 }
cannam@0: 00242 
cannam@0: 00243 
cannam@0: 00244 int runPlugin(string myname, string soname, string id,
cannam@0: 00245               string output, int outputNo, string wavname,
cannam@0: 00246               string outfilename, bool useFrames)
cannam@0: 00247 {
cannam@0: 00248     PluginLoader *loader = PluginLoader::getInstance();
cannam@0: 00249 
cannam@0: 00250     PluginLoader::PluginKey key = loader->composePluginKey(soname, id);
cannam@0: 00251     
cannam@0: 00252     SNDFILE *sndfile;
cannam@0: 00253     SF_INFO sfinfo;
cannam@0: 00254     memset(&sfinfo, 0, sizeof(SF_INFO));
cannam@0: 00255 
cannam@0: 00256     sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo);
cannam@0: 00257     if (!sndfile) {
cannam@0: 00258         cerr << myname << ": ERROR: Failed to open input file \""
cannam@0: 00259              << wavname << "\": " << sf_strerror(sndfile) << endl;
cannam@0: 00260         return 1;
cannam@0: 00261     }
cannam@0: 00262 
cannam@0: 00263     ofstream *out = 0;
cannam@0: 00264     if (outfilename != "") {
cannam@0: 00265         out = new ofstream(outfilename.c_str(), ios::out);
cannam@0: 00266         if (!*out) {
cannam@0: 00267             cerr << myname << ": ERROR: Failed to open output file \""
cannam@0: 00268                  << outfilename << "\" for writing" << endl;
cannam@0: 00269             delete out;
cannam@0: 00270             return 1;
cannam@0: 00271         }
cannam@0: 00272     }
cannam@0: 00273 
cannam@0: 00274     Plugin *plugin = loader->loadPlugin
cannam@0: 00275         (key, sfinfo.samplerate, PluginLoader::ADAPT_ALL_SAFE);
cannam@0: 00276     if (!plugin) {
cannam@0: 00277         cerr << myname << ": ERROR: Failed to load plugin \"" << id
cannam@0: 00278              << "\" from library \"" << soname << "\"" << endl;
cannam@0: 00279         sf_close(sndfile);
cannam@0: 00280         if (out) {
cannam@0: 00281             out->close();
cannam@0: 00282             delete out;
cannam@0: 00283         }
cannam@0: 00284         return 1;
cannam@0: 00285     }
cannam@0: 00286 
cannam@0: 00287     cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl;
cannam@0: 00288 
cannam@0: 00289     int blockSize = plugin->getPreferredBlockSize();
cannam@0: 00290     int stepSize = plugin->getPreferredStepSize();
cannam@0: 00291 
cannam@0: 00292     if (blockSize == 0) {
cannam@0: 00293         blockSize = 1024;
cannam@0: 00294     }
cannam@0: 00295     if (stepSize == 0) {
cannam@0: 00296         if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
cannam@0: 00297             stepSize = blockSize/2;
cannam@0: 00298         } else {
cannam@0: 00299             stepSize = blockSize;
cannam@0: 00300         }
cannam@0: 00301     } else if (stepSize > blockSize) {
cannam@0: 00302         cerr << "WARNING: stepSize " << stepSize << " > blockSize " << blockSize << ", resetting blockSize to ";
cannam@0: 00303         if (plugin->getInputDomain() == Plugin::FrequencyDomain) {
cannam@0: 00304             blockSize = stepSize * 2;
cannam@0: 00305         } else {
cannam@0: 00306             blockSize = stepSize;
cannam@0: 00307         }
cannam@0: 00308         cerr << blockSize << endl;
cannam@0: 00309     }
cannam@0: 00310 
cannam@0: 00311     int channels = sfinfo.channels;
cannam@0: 00312 
cannam@0: 00313     float *filebuf = new float[blockSize * channels];
cannam@0: 00314     float **plugbuf = new float*[channels];
cannam@0: 00315     for (int c = 0; c < channels; ++c) plugbuf[c] = new float[blockSize + 2];
cannam@0: 00316 
cannam@0: 00317     cerr << "Using block size = " << blockSize << ", step size = "
cannam@0: 00318               << stepSize << endl;
cannam@0: 00319 
cannam@0: 00320     int minch = plugin->getMinChannelCount();
cannam@0: 00321     int maxch = plugin->getMaxChannelCount();
cannam@0: 00322     cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl;
cannam@0: 00323     cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl;
cannam@0: 00324 
cannam@0: 00325     Plugin::OutputList outputs = plugin->getOutputDescriptors();
cannam@0: 00326     Plugin::OutputDescriptor od;
cannam@0: 00327 
cannam@0: 00328     int returnValue = 1;
cannam@0: 00329     int progress = 0;
cannam@0: 00330 
cannam@0: 00331     if (outputs.empty()) {
cannam@0: 00332         cerr << "ERROR: Plugin has no outputs!" << endl;
cannam@0: 00333         goto done;
cannam@0: 00334     }
cannam@0: 00335 
cannam@0: 00336     if (outputNo < 0) {
cannam@0: 00337 
cannam@0: 00338         for (size_t oi = 0; oi < outputs.size(); ++oi) {
cannam@0: 00339             if (outputs[oi].identifier == output) {
cannam@0: 00340                 outputNo = oi;
cannam@0: 00341                 break;
cannam@0: 00342             }
cannam@0: 00343         }
cannam@0: 00344 
cannam@0: 00345         if (outputNo < 0) {
cannam@0: 00346             cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl;
cannam@0: 00347             goto done;
cannam@0: 00348         }
cannam@0: 00349 
cannam@0: 00350     } else {
cannam@0: 00351 
cannam@0: 00352         if (int(outputs.size()) <= outputNo) {
cannam@0: 00353             cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl;
cannam@0: 00354             goto done;
cannam@0: 00355         }        
cannam@0: 00356     }
cannam@0: 00357 
cannam@0: 00358     od = outputs[outputNo];
cannam@0: 00359     cerr << "Output is: \"" << od.identifier << "\"" << endl;
cannam@0: 00360 
cannam@0: 00361     if (!plugin->initialise(channels, stepSize, blockSize)) {
cannam@0: 00362         cerr << "ERROR: Plugin initialise (channels = " << channels
cannam@0: 00363              << ", stepSize = " << stepSize << ", blockSize = "
cannam@0: 00364              << blockSize << ") failed." << endl;
cannam@0: 00365         goto done;
cannam@0: 00366     }
cannam@0: 00367 
cannam@0: 00368     for (size_t i = 0; i < sfinfo.frames; i += stepSize) {
cannam@0: 00369 
cannam@0: 00370         int count;
cannam@0: 00371 
cannam@0: 00372         if (sf_seek(sndfile, i, SEEK_SET) < 0) {
cannam@0: 00373             cerr << "ERROR: sf_seek failed: " << sf_strerror(sndfile) << endl;
cannam@0: 00374             break;
cannam@0: 00375         }
cannam@0: 00376         
cannam@0: 00377         if ((count = sf_readf_float(sndfile, filebuf, blockSize)) < 0) {
cannam@0: 00378             cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl;
cannam@0: 00379             break;
cannam@0: 00380         }
cannam@0: 00381 
cannam@0: 00382         for (int c = 0; c < channels; ++c) {
cannam@0: 00383             int j = 0;
cannam@0: 00384             while (j < count) {
cannam@0: 00385                 plugbuf[c][j] = filebuf[j * sfinfo.channels + c];
cannam@0: 00386                 ++j;
cannam@0: 00387             }
cannam@0: 00388             while (j < blockSize) {
cannam@0: 00389                 plugbuf[c][j] = 0.0f;
cannam@0: 00390                 ++j;
cannam@0: 00391             }
cannam@0: 00392         }
cannam@0: 00393 
cannam@0: 00394         printFeatures
cannam@0: 00395             (i, sfinfo.samplerate, outputNo, plugin->process
cannam@0: 00396              (plugbuf, RealTime::frame2RealTime(i, sfinfo.samplerate)),
cannam@0: 00397              out, useFrames);
cannam@0: 00398 
cannam@0: 00399         int pp = progress;
cannam@0: 00400         progress = lrintf((float(i) / sfinfo.frames) * 100.f);
cannam@0: 00401         if (progress != pp && out) {
cannam@0: 00402             cerr << "\r" << progress << "%";
cannam@0: 00403         }
cannam@0: 00404     }
cannam@0: 00405     if (out) cerr << "\rDone" << endl;
cannam@0: 00406 
cannam@0: 00407     printFeatures(sfinfo.frames, sfinfo.samplerate, outputNo,
cannam@0: 00408                   plugin->getRemainingFeatures(), out, useFrames);
cannam@0: 00409 
cannam@0: 00410     returnValue = 0;
cannam@0: 00411 
cannam@0: 00412 done:
cannam@0: 00413     delete plugin;
cannam@0: 00414     if (out) {
cannam@0: 00415         out->close();
cannam@0: 00416         delete out;
cannam@0: 00417     }
cannam@0: 00418     sf_close(sndfile);
cannam@0: 00419     return returnValue;
cannam@0: 00420 }
cannam@0: 00421 
cannam@0: 00422 void
cannam@0: 00423 printFeatures(int frame, int sr, int output,
cannam@0: 00424               Plugin::FeatureSet features, ofstream *out, bool useFrames)
cannam@0: 00425 {
cannam@0: 00426     for (unsigned int i = 0; i < features[output].size(); ++i) {
cannam@0: 00427 
cannam@0: 00428         if (useFrames) {
cannam@0: 00429 
cannam@0: 00430             int displayFrame = frame;
cannam@0: 00431 
cannam@0: 00432             if (features[output][i].hasTimestamp) {
cannam@0: 00433                 displayFrame = RealTime::realTime2Frame
cannam@0: 00434                     (features[output][i].timestamp, sr);
cannam@0: 00435             }
cannam@0: 00436 
cannam@0: 00437             (out ? *out : cout) << displayFrame << ":";
cannam@0: 00438 
cannam@0: 00439         } else {
cannam@0: 00440 
cannam@0: 00441             RealTime rt = RealTime::frame2RealTime(frame, sr);
cannam@0: 00442 
cannam@0: 00443             if (features[output][i].hasTimestamp) {
cannam@0: 00444                 rt = features[output][i].timestamp;
cannam@0: 00445             }
cannam@0: 00446 
cannam@0: 00447             (out ? *out : cout) << rt.toString() << ":";
cannam@0: 00448         }
cannam@0: 00449 
cannam@0: 00450         for (unsigned int j = 0; j < features[output][i].values.size(); ++j) {
cannam@0: 00451             (out ? *out : cout) << " " << features[output][i].values[j];
cannam@0: 00452         }
cannam@0: 00453 
cannam@0: 00454         (out ? *out : cout) << endl;
cannam@0: 00455     }
cannam@0: 00456 }
cannam@0: 00457 
cannam@0: 00458 void
cannam@0: 00459 printPluginPath(bool verbose)
cannam@0: 00460 {
cannam@0: 00461     if (verbose) {
cannam@0: 00462         cout << "\nVamp plugin search path: ";
cannam@0: 00463     }
cannam@0: 00464 
cannam@0: 00465     vector<string> path = PluginHostAdapter::getPluginPath();
cannam@0: 00466     for (size_t i = 0; i < path.size(); ++i) {
cannam@0: 00467         if (verbose) {
cannam@0: 00468             cout << "[" << path[i] << "]";
cannam@0: 00469         } else {
cannam@0: 00470             cout << path[i] << endl;
cannam@0: 00471         }
cannam@0: 00472     }
cannam@0: 00473 
cannam@0: 00474     if (verbose) cout << endl;
cannam@0: 00475 }
cannam@0: 00476 
cannam@0: 00477 void
cannam@0: 00478 enumeratePlugins(Verbosity verbosity)
cannam@0: 00479 {
cannam@0: 00480     PluginLoader *loader = PluginLoader::getInstance();
cannam@0: 00481 
cannam@0: 00482     if (verbosity == PluginInformation) {
cannam@0: 00483         cout << "\nVamp plugin libraries found in search path:" << endl;
cannam@0: 00484     }
cannam@0: 00485 
cannam@0: 00486     vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
cannam@0: 00487     typedef multimap<string, PluginLoader::PluginKey>
cannam@0: 00488         LibraryMap;
cannam@0: 00489     LibraryMap libraryMap;
cannam@0: 00490 
cannam@0: 00491     for (size_t i = 0; i < plugins.size(); ++i) {
cannam@0: 00492         string path = loader->getLibraryPathForPlugin(plugins[i]);
cannam@0: 00493         libraryMap.insert(LibraryMap::value_type(path, plugins[i]));
cannam@0: 00494     }
cannam@0: 00495 
cannam@0: 00496     string prevPath = "";
cannam@0: 00497     int index = 0;
cannam@0: 00498 
cannam@0: 00499     for (LibraryMap::iterator i = libraryMap.begin();
cannam@0: 00500          i != libraryMap.end(); ++i) {
cannam@0: 00501         
cannam@0: 00502         string path = i->first;
cannam@0: 00503         PluginLoader::PluginKey key = i->second;
cannam@0: 00504 
cannam@0: 00505         if (path != prevPath) {
cannam@0: 00506             prevPath = path;
cannam@0: 00507             index = 0;
cannam@0: 00508             if (verbosity == PluginInformation) {
cannam@0: 00509                 cout << "\n  " << path << ":" << endl;
cannam@0: 00510             }
cannam@0: 00511         }
cannam@0: 00512 
cannam@0: 00513         Plugin *plugin = loader->loadPlugin(key, 48000);
cannam@0: 00514         if (plugin) {
cannam@0: 00515 
cannam@0: 00516             char c = char('A' + index);
cannam@0: 00517             if (c > 'Z') c = char('a' + (index - 26));
cannam@0: 00518 
cannam@0: 00519             if (verbosity == PluginInformation) {
cannam@0: 00520 
cannam@0: 00521                 cout << "    [" << c << "] [v"
cannam@0: 00522                      << plugin->getVampApiVersion() << "] "
cannam@0: 00523                      << plugin->getName() << ", \""
cannam@0: 00524                      << plugin->getIdentifier() << "\"" << " ["
cannam@0: 00525                      << plugin->getMaker() << "]" << endl;
cannam@0: 00526 
cannam@0: 00527                 PluginLoader::PluginCategoryHierarchy category =
cannam@0: 00528                     loader->getPluginCategory(key);
cannam@0: 00529 
cannam@0: 00530                 if (!category.empty()) {
cannam@0: 00531                     cout << "       ";
cannam@0: 00532                     for (size_t ci = 0; ci < category.size(); ++ci) {
cannam@0: 00533                         cout << " > " << category[ci];
cannam@0: 00534                     }
cannam@0: 00535                     cout << endl;
cannam@0: 00536                 }
cannam@0: 00537 
cannam@0: 00538                 if (plugin->getDescription() != "") {
cannam@0: 00539                     cout << "        - " << plugin->getDescription() << endl;
cannam@0: 00540                 }
cannam@0: 00541 
cannam@0: 00542             } else if (verbosity == PluginIds) {
cannam@0: 00543                 cout << "vamp:" << key << endl;
cannam@0: 00544             }
cannam@0: 00545             
cannam@0: 00546             Plugin::OutputList outputs =
cannam@0: 00547                 plugin->getOutputDescriptors();
cannam@0: 00548 
cannam@0: 00549             if (outputs.size() > 1 || verbosity == PluginOutputIds) {
cannam@0: 00550                 for (size_t j = 0; j < outputs.size(); ++j) {
cannam@0: 00551                     if (verbosity == PluginInformation) {
cannam@0: 00552                         cout << "         (" << j << ") "
cannam@0: 00553                              << outputs[j].name << ", \""
cannam@0: 00554                              << outputs[j].identifier << "\"" << endl;
cannam@0: 00555                         if (outputs[j].description != "") {
cannam@0: 00556                             cout << "             - " 
cannam@0: 00557                                  << outputs[j].description << endl;
cannam@0: 00558                         }
cannam@0: 00559                     } else if (verbosity == PluginOutputIds) {
cannam@0: 00560                         cout << "vamp:" << key << ":" << outputs[j].identifier << endl;
cannam@0: 00561                     }
cannam@0: 00562                 }
cannam@0: 00563             }
cannam@0: 00564 
cannam@0: 00565             ++index;
cannam@0: 00566 
cannam@0: 00567             delete plugin;
cannam@0: 00568         }
cannam@0: 00569     }
cannam@0: 00570 
cannam@0: 00571     if (verbosity == PluginInformation) {
cannam@0: 00572         cout << endl;
cannam@0: 00573     }
cannam@0: 00574 }
cannam@0: 00575 
cannam@0: 00576 void
cannam@0: 00577 printPluginCategoryList()
cannam@0: 00578 {
cannam@0: 00579     PluginLoader *loader = PluginLoader::getInstance();
cannam@0: 00580 
cannam@0: 00581     vector<PluginLoader::PluginKey> plugins = loader->listPlugins();
cannam@0: 00582 
cannam@0: 00583     set<string> printedcats;
cannam@0: 00584 
cannam@0: 00585     for (size_t i = 0; i < plugins.size(); ++i) {
cannam@0: 00586 
cannam@0: 00587         PluginLoader::PluginKey key = plugins[i];
cannam@0: 00588         
cannam@0: 00589         PluginLoader::PluginCategoryHierarchy category =
cannam@0: 00590             loader->getPluginCategory(key);
cannam@0: 00591 
cannam@0: 00592         Plugin *plugin = loader->loadPlugin(key, 48000);
cannam@0: 00593         if (!plugin) continue;
cannam@0: 00594 
cannam@0: 00595         string catstr = "";
cannam@0: 00596 
cannam@0: 00597         if (category.empty()) catstr = '|';
cannam@0: 00598         else {
cannam@0: 00599             for (size_t j = 0; j < category.size(); ++j) {
cannam@0: 00600                 catstr += category[j];
cannam@0: 00601                 catstr += '|';
cannam@0: 00602                 if (printedcats.find(catstr) == printedcats.end()) {
cannam@0: 00603                     std::cout << catstr << std::endl;
cannam@0: 00604                     printedcats.insert(catstr);
cannam@0: 00605                 }
cannam@0: 00606             }
cannam@0: 00607         }
cannam@0: 00608 
cannam@0: 00609         std::cout << catstr << key << ":::" << plugin->getName() << ":::" << plugin->getMaker() << ":::" << plugin->getDescription() << std::endl;
cannam@0: 00610     }
cannam@0: 00611 }
cannam@0: 00612 
cannam@0: 
cannam@0:
Generated on Wed Jul 9 11:36:07 2008 for VampPluginSDK by  cannam@0: cannam@0: doxygen 1.5.5
cannam@0: cannam@0: