annotate rdf/generator/vamp-rdf-template-generator.cpp @ 541:0e32c328b02a tip

Added tag vamp-plugin-sdk-v2.10 for changeset fa74c473e48c
author Chris Cannam
date Mon, 18 May 2020 11:53:49 +0100
parents aede6e90a6b8
children
rev   line source
cannam@138 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
cannam@138 2
cannam@231 3 #include <vamp-hostsdk/PluginHostAdapter.h>
cannam@233 4 #include <vamp-hostsdk/PluginChannelAdapter.h>
cannam@233 5 #include <vamp-hostsdk/PluginInputDomainAdapter.h>
cannam@233 6 #include <vamp-hostsdk/PluginLoader.h>
cannam@231 7 #include <vamp/vamp.h>
cannam@138 8
cannam@138 9 #include <iostream>
cannam@138 10 #include <fstream>
cannam@138 11 #include <sstream>
cannam@138 12
cannam@138 13 #include <cmath>
cannam@232 14 #include <cstdlib>
cannam@232 15 #include <cstring>
cannam@138 16
cannam@243 17 #include <cstdlib>
cannam@243 18 #include <cstring>
cannam@243 19
cannam@138 20 using std::cout;
cannam@138 21 using std::cin;
cannam@138 22 using std::cerr;
cannam@138 23 using std::getline;
cannam@138 24 using std::endl;
cannam@138 25 using std::string;
cannam@138 26 using std::vector;
cannam@138 27 using std::ofstream;
cannam@138 28 using std::ios;
cannam@138 29
cannam@138 30 using Vamp::HostExt::PluginLoader;
cannam@138 31 using Vamp::Plugin;
cannam@138 32
Chris@364 33 string programURI = "http://vamp-plugins.org/rdf/template-generator";
cannam@138 34
cannam@138 35 void usage()
cannam@138 36 {
cannam@217 37 cerr << endl;
cannam@251 38 cerr << "vamp-rdf-template-generator: Create a skeleton RDF description file describing" << endl;
cannam@251 39 cerr << "a Vamp plugin library using the Vamp ontology." << endl;
cannam@217 40 cerr << endl;
cannam@217 41 cerr << "Usage:" << endl;
cannam@251 42 cerr << " vamp-rdf-template-generator -i vamp:soname[:plugin] [vamp:soname[:plugin] ...]" << endl;
cannam@251 43 cerr << " vamp-rdf-template-generator PLUGIN_BASE_URI [ -m YOUR_URI ] [vamp:]soname[:plugin] [[vamp:]soname[:plugin] ...]" << endl;
cannam@217 44 cerr << endl;
cannam@217 45 cerr << "Example:" << endl;
cannam@251 46 cerr << " vamp-rdf-template-generator http://vamp-plugins.org/rdf/plugins/ vamp-example-plugins" << endl;
cannam@217 47 cerr << endl;
cannam@138 48 exit(2);
cannam@138 49 }
cannam@138 50
cannam@138 51 template <class T>
cannam@138 52 inline string to_string (const T& t)
cannam@138 53 {
cannam@138 54 std::stringstream ss;
cannam@138 55 ss << t;
cannam@138 56 return ss.str();
cannam@138 57 }
cannam@138 58
cannam@144 59 string describe_namespaces(string pluginBundleBaseURI, string libname)
cannam@138 60 {
cannam@142 61 string res=\
cannam@142 62 "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\
cannam@138 63 @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n\
cannam@147 64 @prefix vamp: <http://purl.org/ontology/vamp/> .\n\
cannam@144 65 @prefix plugbase: <"+pluginBundleBaseURI+libname+"#> .\n\
cannam@138 66 @prefix owl: <http://www.w3.org/2002/07/owl#> .\n\
cannam@138 67 @prefix dc: <http://purl.org/dc/elements/1.1/> .\n\
cannam@138 68 @prefix af: <http://purl.org/ontology/af/> .\n\
cannam@138 69 @prefix foaf: <http://xmlns.com/foaf/0.1/> .\n\
Chris@364 70 @prefix doap: <http://usefulinc.com/ns/doap#> .\n\
cannam@138 71 @prefix cc: <http://web.resource.org/cc/> .\n\
cannam@267 72 @prefix : <#> .\n\n";
cannam@138 73
cannam@142 74 return res;
cannam@138 75 }
cannam@138 76
cannam@144 77 string describe_doc(string describerURI, string pluginBundleBaseURI,
cannam@144 78 string libname)
cannam@138 79 {
Chris@364 80 string res = "\n## Properties of this document\n\n\
Chris@364 81 <> a vamp:PluginDescription ;\n";
Chris@364 82
cannam@217 83 if (describerURI != "") {
cannam@217 84 res += " foaf:maker <"+describerURI+"> ;\n";
cannam@217 85 }
Chris@364 86
cannam@217 87 res += "\
Chris@364 88 foaf:maker <"+programURI+"> ;\n\
Chris@364 89 foaf:primaryTopic <"+pluginBundleBaseURI+libname+"> .\n\n";
cannam@142 90 return res;
cannam@138 91 }
cannam@138 92
Chris@364 93 bool have_multiple_makers(vector<Plugin *> plugins)
Chris@364 94 {
Chris@364 95 string firstMaker = "";
Chris@364 96 for (size_t i = 0; i < plugins.size(); ++i) {
Chris@364 97 if (i == 0) {
Chris@364 98 firstMaker = plugins[i]->getMaker();
Chris@364 99 } else if (plugins[i]->getMaker() != firstMaker) {
Chris@364 100 return true;
Chris@364 101 }
Chris@364 102 }
Chris@364 103 return false;
Chris@364 104 }
Chris@364 105
Chris@364 106 string describe_maker(vector<Plugin *> plugins, bool multipleMakers)
Chris@364 107 {
Chris@364 108 string res = "\n## Maker of the whole plugin library\n\n\
Chris@364 109 :library_maker\n";
Chris@364 110
Chris@364 111 if (!multipleMakers) {
Chris@364 112 string name;
Chris@364 113 if (!plugins.empty()) {
Chris@364 114 name = plugins[0]->getMaker();
Chris@364 115 }
Chris@364 116 res += "\
Chris@364 117 foaf:name \"" + name + "\" ;\n\
Chris@364 118 # foaf:page <> ; # Place maker's homepage URL in here and uncomment\n\
Chris@364 119 # foaf:logo <> ; # URL of an image here, if you happen to have a logo\n";
Chris@364 120
Chris@364 121 } else {
Chris@364 122 res += "\
Chris@364 123 foaf:name \"Multiple makers\" ;\n";
Chris@364 124 }
Chris@364 125
Chris@364 126 res += " .\n\n";
Chris@364 127 return res;
Chris@364 128 }
cannam@138 129
cannam@144 130 string describe_library(string libname, vector<Plugin *> plugins)
cannam@144 131 {
Chris@364 132 string res = "\n## Properties of the plugin library, and references to the plugins it contains\n\n\
Chris@364 133 plugbase:library a vamp:PluginLibrary ;\n\
Chris@364 134 vamp:identifier \""+libname+"\" ;\n\
Chris@364 135 foaf:maker :library_maker";
cannam@144 136
cannam@144 137 for (size_t i = 0; i < plugins.size(); ++i) {
cannam@218 138 res += " ; \n\
Chris@364 139 vamp:available_plugin plugbase:"+plugins[i]->getIdentifier();
cannam@144 140 }
cannam@144 141
cannam@218 142 res += " ; \n\
Chris@364 143 # dc:title \"\" ; # Place library name here and uncomment\n\
Chris@364 144 # dc:description \"\" ; # Place library description here and uncomment\n\
Chris@364 145 # foaf:page <> ; # Place more-info HTML page URL here and uncomment\n\
Chris@364 146 # doap:download-page <> ; # Place download HTML page URL here and uncomment\n\
cannam@218 147 .\n\n";
cannam@144 148 return res;
cannam@144 149 }
cannam@144 150
Chris@364 151 string describe_plugin(Plugin* plugin, bool multipleMakers)
cannam@138 152 {
Chris@364 153 string res = "\n## Properties of the " + plugin->getName() + " plugin\n\n\
Chris@364 154 plugbase:"+plugin->getIdentifier()+" a vamp:Plugin ;\n\
cannam@138 155 dc:title \""+plugin->getName()+"\" ;\n\
cannam@139 156 vamp:name \""+plugin->getName()+"\" ;\n\
cannam@221 157 dc:description \"\"\""+plugin->getDescription()+"\"\"\" ;\n\
Chris@364 158 foaf:maker ";
Chris@364 159
Chris@364 160 if (multipleMakers) {
Chris@364 161 res += "[ foaf:name \""+plugin->getMaker()+"\" ] ;\n";
Chris@364 162 } else {
Chris@364 163 res += ":library_maker ;\n";
Chris@364 164 }
Chris@364 165
Chris@364 166 res += "\
cannam@224 167 dc:rights \"\"\""+plugin->getCopyright()+"\"\"\" ;\n\
cannam@154 168 # cc:license <Place plugin license URI here and uncomment> ; \n\
cannam@138 169 vamp:identifier \""+plugin->getIdentifier()+"\" ;\n\
cannam@138 170 vamp:vamp_API_version vamp:api_version_"+to_string(plugin->getVampApiVersion())+" ;\n\
cannam@138 171 owl:versionInfo \""+to_string(plugin->getPluginVersion())+"\" ;\n";
cannam@142 172 if (plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain)
cannam@142 173 res+=" vamp:input_domain vamp:FrequencyDomain ;\n\n";
cannam@142 174 else
cannam@194 175 res+=" vamp:input_domain vamp:TimeDomain ;\n";
cannam@138 176
cannam@142 177 Plugin::ParameterList params = plugin->getParameterDescriptors();
cannam@142 178 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
dpastor@156 179 res+=" vamp:parameter plugbase:"+plugin->getIdentifier()+"_param_"+(*i).identifier+" ;\n";
cannam@194 180 if (!params.empty()) res+="\n";
cannam@138 181
cannam@142 182 Plugin::OutputList outputs = plugin->getOutputDescriptors();
cannam@142 183 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
cannam@158 184 res+=" vamp:output plugbase:"+plugin->getIdentifier()+"_output_"+(*i).identifier+" ;\n";
cannam@142 185 res+=" .\n";
cannam@138 186
cannam@142 187 return res;
cannam@138 188 }
cannam@138 189
cannam@144 190 string describe_param(Plugin *plugin, Plugin::ParameterDescriptor p)
cannam@138 191 {
cannam@148 192
cannam@148 193 //FIXME: dc:format and vamp:unit are the same???
dpastor@157 194 //Should be a QUantizedParameter also a Parameter??
cannam@148 195 if(p.isQuantized){
cannam@148 196 string res=\
dpastor@156 197 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:QuantizedParameter ;\n\
cannam@148 198 vamp:identifier \""+p.identifier+"\" ;\n\
cannam@148 199 dc:title \""+p.name+"\" ;\n\
cannam@148 200 dc:format \""+p.unit+"\" ;\n\
cannam@148 201 vamp:min_value "+to_string(p.minValue)+" ;\n\
cannam@148 202 vamp:max_value "+to_string(p.maxValue)+" ;\n\
cannam@148 203 vamp:unit \""+p.unit+"\" ;\n\
cannam@152 204 vamp:quantize_step "+to_string(p.quantizeStep)+" ;\n\
cannam@148 205 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
cannam@148 206 vamp:value_names (";
cannam@148 207
cannam@148 208 unsigned int i;
cannam@148 209 for (i=0; i+1 < p.valueNames.size(); i++)
cannam@148 210 res+=" \""+p.valueNames[i]+"\"";
cannam@148 211 if (i < p.valueNames.size())
cannam@148 212 res+=" \""+p.valueNames[i]+"\"";
cannam@148 213 res+=");\n";
cannam@148 214
cannam@148 215 res+=" .\n";
cannam@148 216
cannam@148 217 return res;
cannam@148 218
cannam@148 219 }else{
cannam@142 220 string res=\
dpastor@156 221 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:Parameter ;\n\
cannam@138 222 vamp:identifier \""+p.identifier+"\" ;\n\
cannam@138 223 dc:title \""+p.name+"\" ;\n\
cannam@138 224 dc:format \""+p.unit+"\" ;\n\
cannam@139 225 vamp:min_value "+to_string(p.minValue)+" ;\n\
cannam@139 226 vamp:max_value "+to_string(p.maxValue)+" ;\n\
cannam@148 227 vamp:unit \""+p.unit+"\" ;\n\
cannam@148 228 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
cannam@148 229 vamp:value_names (";
cannam@148 230
cannam@148 231 unsigned int i;
cannam@148 232 for (i=0; i+1 < p.valueNames.size(); i++)
cannam@148 233 res+=" \""+p.valueNames[i]+"\"";
cannam@148 234 if (i < p.valueNames.size())
cannam@148 235 res+=" \""+p.valueNames[i]+"\"";
cannam@148 236 res+=");\n";
cannam@148 237
cannam@148 238 res+=" .\n";
cannam@148 239
cannam@142 240 return res;
cannam@148 241
cannam@148 242 }
cannam@138 243 }
cannam@138 244
cannam@144 245 string describe_output(Plugin *plugin, Plugin::OutputDescriptor o)
cannam@138 246 {
cannam@138 247
cannam@142 248 //we need to distinguish here between different output types:
cannam@148 249
cannam@148 250 //Quantize or not
cannam@148 251 //KnownExtents or not
cannam@148 252 //Data output classification:
cannam@142 253 //DenseOutput
cannam@142 254 //SparseOutput
cannam@142 255 //TrackLevelOutput
cannam@139 256
cannam@139 257
cannam@168 258 // SparseOutput: variable sample rate. Events are not evenly
cannam@168 259 // spaced so we need to record the time associated with the event
cannam@168 260 // as it its not ensured that we have an event after the next one
cannam@168 261 // (but there is not time to set the duration, it has to be
cannam@168 262 // calculated as the different between 2 different events). The
cannam@168 263 // timestamp must be read.
cannam@139 264
cannam@142 265 string res;
cannam@139 266
cannam@168 267 if (o.sampleType == Plugin::OutputDescriptor::VariableSampleRate ||
cannam@168 268 !o.hasFixedBinCount)
cannam@142 269 {
cannam@139 270
cannam@142 271 res=\
cannam@144 272 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:SparseOutput ;\n\
cannam@139 273 vamp:identifier \""+o.identifier+"\" ;\n\
cannam@139 274 dc:title \""+o.name+"\" ;\n\
cannam@273 275 dc:description \"\"\""+o.description+"\"\"\" ;\n\
cannam@139 276 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
cannam@139 277 vamp:unit \""+(o.unit)+"\" ;\n";
cannam@139 278
cannam@148 279
cannam@148 280 //another type of output
cannam@148 281 if(o.isQuantized){
cannam@148 282
cannam@148 283 res+=" a vamp:QuantizedOutput ;\n";
cannam@148 284 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
cannam@148 285 }
cannam@148 286
cannam@148 287 //and yet another type
cannam@148 288 if(o.hasKnownExtents){
cannam@148 289
cannam@148 290 res+=" a vamp:KnownExtentsOutput ;\n";
cannam@148 291 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
cannam@148 292 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
cannam@148 293 }
cannam@139 294
cannam@142 295 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
cannam@142 296 if (o.hasFixedBinCount)
cannam@142 297 {
cannam@144 298 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
cannam@138 299
cannam@264 300 bool haveBinNames = false;
cannam@308 301 for (unsigned int i=0; i < o.binNames.size(); i++) {
cannam@264 302 if (o.binNames[i] != "") {
cannam@264 303 haveBinNames = true;
cannam@264 304 break;
cannam@264 305 }
cannam@264 306 }
cannam@264 307
cannam@264 308 if (haveBinNames) {
cannam@264 309 res+=" vamp:bin_names (";
cannam@264 310
cannam@264 311 unsigned int i;
cannam@264 312 for (i=0; i+1 < o.binNames.size(); i++)
cannam@264 313 res+=" \""+o.binNames[i]+"\"";
cannam@264 314 if (i < o.binNames.size())
cannam@264 315 res+=" \""+o.binNames[i]+"\"";
cannam@264 316 res+=");\n";
cannam@264 317 }
cannam@142 318 }
cannam@148 319
cannam@144 320 res+=" vamp:sample_type vamp:VariableSampleRate ;\n";
cannam@142 321 if (o.sampleRate > 0.0f)
cannam@144 322 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
cannam@142 323
cannam@142 324 }
cannam@139 325
cannam@142 326 //If we do not have SparseOutput, then we have DenseOutput. TrackLevelOutput can not be inferred from the plugin directly without actually
cannam@142 327 //running the plugin.
cannam@142 328 else{
cannam@142 329
cannam@142 330 res=\
cannam@144 331 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:DenseOutput ;\n\
cannam@139 332 vamp:identifier \""+o.identifier+"\" ;\n\
cannam@139 333 dc:title \""+o.name+"\" ;\n\
cannam@273 334 dc:description \"\"\""+o.description+"\"\"\" ;\n\
cannam@139 335 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
cannam@139 336 vamp:unit \""+(o.unit)+"\" ;\n";
cannam@139 337
cannam@139 338
cannam@148 339 //another type of output
cannam@148 340 if(o.isQuantized){
cannam@148 341
cannam@148 342 res+=" a vamp:QuantizedOutput ;\n";
cannam@148 343 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
cannam@148 344 }
cannam@148 345
cannam@148 346 //and yet another type
cannam@148 347 if(o.hasKnownExtents){
cannam@148 348
cannam@148 349 res+=" a vamp:KnownExtentsOutput ;\n";
cannam@148 350 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
cannam@148 351 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
cannam@148 352 }
cannam@139 353
cannam@142 354 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
cannam@142 355 if (o.hasFixedBinCount)
cannam@142 356 {
cannam@144 357 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
cannam@139 358
cannam@264 359 bool haveBinNames = false;
cannam@308 360 for (unsigned int i=0; i < o.binNames.size(); i++) {
cannam@264 361 if (o.binNames[i] != "") {
cannam@264 362 haveBinNames = true;
cannam@264 363 break;
cannam@264 364 }
cannam@264 365 }
cannam@264 366
cannam@264 367 if (haveBinNames) {
cannam@264 368 res+=" vamp:bin_names (";
cannam@264 369
cannam@264 370 unsigned int i;
cannam@264 371 for (i=0; i+1 < o.binNames.size(); i++)
cannam@264 372 res+=" \""+o.binNames[i]+"\"";
cannam@264 373 if (i < o.binNames.size())
cannam@264 374 res+=" \""+o.binNames[i]+"\"";
cannam@264 375 res+=");\n";
cannam@264 376 }
cannam@139 377 }
cannam@139 378
cannam@142 379 else if (o.sampleType == Plugin::OutputDescriptor::FixedSampleRate)
cannam@142 380 {
cannam@144 381 res+=" vamp:sample_type vamp:FixedSampleRate ;\n";
cannam@144 382 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
cannam@142 383 }
cannam@142 384 else if (o.sampleType == Plugin::OutputDescriptor::OneSamplePerStep)
cannam@144 385 res+=" vamp:sample_type vamp:OneSamplePerStep ;\n";
cannam@142 386 else
cannam@142 387 {
cannam@142 388 cerr<<"Incomprehensible sampleType for output descriptor "+o.identifier<<" !"<<endl;
cannam@142 389 exit(1);
cannam@142 390 }
cannam@142 391 }
cannam@142 392
cannam@142 393 //There is no way to know this in advance, but we can use the km a bit for this.
cannam@159 394 res+="# vamp:computes_event_type <Place event type URI here and uncomment> ;\n";
cannam@159 395 res+="# vamp:computes_feature <Place feature attribute URI here and uncomment> ;\n";
cannam@159 396 res+="# vamp:computes_signal_type <Place signal type URI here and uncomment> ;\n";
cannam@142 397 res+=" .\n";
cannam@142 398
cannam@142 399 return res;
cannam@138 400 }
cannam@139 401
cannam@144 402 string describe(vector<Plugin *> plugins, string pluginBundleBaseURI,
cannam@144 403 string describerURI, string libname)
cannam@138 404 {
Chris@364 405 bool multipleMakers = have_multiple_makers(plugins);
Chris@364 406
cannam@144 407 string res = describe_namespaces(pluginBundleBaseURI, libname);
cannam@138 408
cannam@144 409 res += describe_doc(describerURI, pluginBundleBaseURI, libname);
cannam@138 410
Chris@364 411 res += describe_maker(plugins, multipleMakers);
Chris@364 412
cannam@144 413 res += describe_library(libname, plugins);
cannam@144 414
cannam@144 415 for (size_t i = 0; i < plugins.size(); ++i) {
cannam@144 416
cannam@144 417 Plugin *plugin = plugins[i];
cannam@144 418
Chris@364 419 res += describe_plugin(plugin, multipleMakers);
cannam@138 420
cannam@144 421 Plugin::ParameterList params = plugin->getParameterDescriptors();
cannam@144 422 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
cannam@144 423 res += describe_param(plugin, *i);
cannam@138 424
cannam@144 425 Plugin::OutputList outputs = plugin->getOutputDescriptors();
cannam@144 426 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
cannam@144 427 res += describe_output(plugin, *i);
cannam@144 428 }
cannam@138 429
cannam@142 430 return res;
cannam@138 431 }
cannam@138 432
cannam@138 433 int main(int argc, char **argv)
cannam@138 434 {
cannam@144 435 if (argc < 3) usage();
cannam@138 436
cannam@144 437 bool interactive = false;
cannam@144 438 if (!strcmp(argv[1], "-i")) interactive = true;
cannam@138 439
cannam@217 440 if (!interactive && argc < 3) usage();
cannam@138 441
cannam@138 442 string pluginBundleBaseURI, describerURI;
cannam@144 443
cannam@144 444 int argidx = 2;
cannam@138 445
cannam@144 446 if (!interactive) {
cannam@138 447 pluginBundleBaseURI = argv[1];
cannam@217 448 if (!strcmp(argv[2], "-m")) {
cannam@217 449 if (argc < 5) usage();
cannam@217 450 describerURI = argv[3];
cannam@217 451 argidx = 4;
cannam@217 452 }
cannam@144 453 } else {
cannam@138 454 cerr << "Please enter the base URI for the plugin bundle : ";
cannam@138 455 getline(cin, pluginBundleBaseURI);
cannam@217 456 cerr << "Please enter your URI (empty to omit) : ";
cannam@138 457 getline(cin, describerURI);
cannam@138 458 }
cannam@144 459
cannam@144 460 vector<Plugin *> plugins;
cannam@144 461 string libname;
cannam@144 462
cannam@144 463 PluginLoader *loader = PluginLoader::getInstance();
cannam@144 464
cannam@144 465 while (argidx < argc) {
cannam@144 466
cannam@144 467 string pluginName = argv[argidx];
cannam@144 468
cannam@144 469 if (pluginName.substr(0, 5) == "vamp:") {
cannam@144 470 pluginName = pluginName.substr(5);
cannam@144 471 }
cannam@144 472
cannam@144 473 string mylibname = pluginName.substr(0, pluginName.find(':'));
cannam@144 474
cannam@144 475 if (libname == "") libname = mylibname;
cannam@144 476 else if (libname != mylibname) {
cannam@144 477 cerr << "ERROR: All plugins specified on command line must originate in the same library" << endl;
cannam@144 478 exit(1);
cannam@144 479 }
cannam@144 480
cannam@144 481 if (mylibname == pluginName) { // pluginName is a library, not a plugin
cannam@144 482
cannam@144 483 PluginLoader::PluginKeyList list = loader->listPlugins();
cannam@144 484 for (size_t i = 0; i < list.size(); ++i) {
cannam@144 485 string thislibname = list[i].substr(0, list[i].find(':'));
cannam@144 486 if (thislibname != mylibname) continue;
cannam@144 487 Plugin *plugin = loader->loadPlugin(list[i], 44100);
cannam@144 488 if (!plugin) {
cannam@144 489 cerr << "ERROR: Plugin \"" << list[i] << "\" could not be loaded" << endl;
cannam@144 490 exit(1);
cannam@144 491 }
cannam@144 492 plugins.push_back(plugin);
cannam@144 493 }
cannam@151 494
cannam@151 495 if (plugins.empty()) {
cannam@151 496 cerr << "ERROR: Plugin library \"" << mylibname << "\" does not exist, could not be opened, or contains no plugins" << endl;
cannam@151 497 exit(1);
cannam@151 498 }
cannam@151 499
cannam@144 500 } else { // pluginName is a plugin
cannam@144 501
cannam@144 502 Plugin *plugin = loader->loadPlugin(pluginName, size_t(44100));
cannam@144 503 if (!plugin) {
cannam@144 504 cerr << "ERROR: Plugin \"" << pluginName << "\" could not be loaded" << endl;
cannam@144 505 exit(1);
cannam@144 506 }
cannam@144 507 plugins.push_back(plugin);
cannam@144 508 }
cannam@144 509
cannam@144 510 ++argidx;
cannam@144 511 }
cannam@138 512
cannam@144 513 cout << describe(plugins, pluginBundleBaseURI, describerURI, libname) << endl;
cannam@138 514
cannam@138 515 return 0;
cannam@138 516 }
cannam@138 517
cannam@138 518