annotate rdf/generator/template-generator.cpp @ 158:7c08ba8083b2

* Update vamp example plugins rdf against new ontology * Update vamp.rdf again (with right base url)
author cannam
date Wed, 25 Jun 2008 12:20:22 +0000
parents 62ab43ce9790
children 64709b340651
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@138 3 #include "vamp-sdk/PluginHostAdapter.h"
cannam@138 4 #include "vamp-sdk/hostext/PluginChannelAdapter.h"
cannam@138 5 #include "vamp-sdk/hostext/PluginInputDomainAdapter.h"
cannam@138 6 #include "vamp-sdk/hostext/PluginLoader.h"
cannam@138 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 #include <sndfile.h>
cannam@138 13
cannam@138 14 #include <cmath>
cannam@138 15
cannam@138 16 using std::cout;
cannam@138 17 using std::cin;
cannam@138 18 using std::cerr;
cannam@138 19 using std::getline;
cannam@138 20 using std::endl;
cannam@138 21 using std::string;
cannam@138 22 using std::vector;
cannam@138 23 using std::ofstream;
cannam@138 24 using std::ios;
cannam@138 25
cannam@138 26 using Vamp::HostExt::PluginLoader;
cannam@138 27 using Vamp::Plugin;
cannam@138 28
cannam@138 29 string programURI = "http://www.vamp-plugins.org/doap.rdf#template-generator";
cannam@138 30
cannam@138 31 void usage()
cannam@138 32 {
cannam@144 33 cerr << "usage: template-generator -i vamp:soname[:plugin] [vamp:soname[:plugin] ...]" << endl;
cannam@144 34 cerr << "usage: template-generator PLUGIN_BASE_URI YOUR_URI vamp:soname[:plugin] [vamp:soname[:plugin] ...]" << endl;
cannam@138 35 exit(2);
cannam@138 36 }
cannam@138 37
cannam@138 38 template <class T>
cannam@138 39 inline string to_string (const T& t)
cannam@138 40 {
cannam@138 41 std::stringstream ss;
cannam@138 42 ss << t;
cannam@138 43 return ss.str();
cannam@138 44 }
cannam@138 45
cannam@144 46 string describe_namespaces(string pluginBundleBaseURI, string libname)
cannam@138 47 {
cannam@142 48 string res=\
cannam@142 49 "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .\n\
cannam@138 50 @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .\n\
cannam@147 51 @prefix vamp: <http://purl.org/ontology/vamp/> .\n\
cannam@144 52 @prefix plugbase: <"+pluginBundleBaseURI+libname+"#> .\n\
cannam@138 53 @prefix owl: <http://www.w3.org/2002/07/owl#> .\n\
cannam@138 54 @prefix dc: <http://purl.org/dc/elements/1.1/> .\n\
cannam@138 55 @prefix af: <http://purl.org/ontology/af/> .\n\
cannam@138 56 @prefix foaf: <http://xmlns.com/foaf/0.1/> .\n\
cannam@138 57 @prefix cc: <http://web.resource.org/cc/> .\n\
cannam@138 58 @prefix : <> .\n\n";
cannam@138 59
cannam@142 60 return res;
cannam@138 61 }
cannam@138 62
cannam@144 63 string describe_doc(string describerURI, string pluginBundleBaseURI,
cannam@144 64 string libname)
cannam@138 65 {
cannam@142 66 string res=\
cannam@142 67 "<> a vamp:PluginDescription ;\n\
cannam@144 68 foaf:maker <"+describerURI+"> ;\n\
cannam@144 69 foaf:maker <"+programURI+"> ;\n\
cannam@144 70 foaf:primaryTopic <"+pluginBundleBaseURI+libname+"> .\n\n";
cannam@142 71 return res;
cannam@138 72 }
cannam@138 73
cannam@138 74
cannam@144 75 string describe_library(string libname, vector<Plugin *> plugins)
cannam@144 76 {
cannam@144 77 string res=\
cannam@144 78 ":"+libname+" a vamp:PluginLibrary ;\n\
cannam@144 79 vamp:identifier \""+libname+"\" ";
cannam@144 80
cannam@144 81 for (size_t i = 0; i < plugins.size(); ++i) {
cannam@144 82 res += "; \n\
cannam@145 83 vamp:available_plugin plugbase:"+plugins[i]->getIdentifier();
cannam@144 84 }
cannam@144 85
cannam@144 86 res += " .\n\n";
cannam@144 87 return res;
cannam@144 88 }
cannam@144 89
cannam@138 90 string describe_plugin(Plugin* plugin)
cannam@138 91 {
cannam@142 92 string res=\
cannam@142 93 "plugbase:"+plugin->getIdentifier()+" a vamp:Plugin ;\n\
cannam@138 94 dc:title \""+plugin->getName()+"\" ;\n\
cannam@139 95 vamp:name \""+plugin->getName()+"\" ;\n\
cannam@138 96 dc:description \""+plugin->getDescription()+"\" ;\n\
cannam@154 97 foaf:maker [ foaf:name \""+plugin->getMaker()+"\" ] ; # FIXME could give plugin author's URI here\n\
cannam@154 98 # cc:license <Place plugin license URI here and uncomment> ; \n\
cannam@138 99 vamp:identifier \""+plugin->getIdentifier()+"\" ;\n\
cannam@138 100 vamp:vamp_API_version vamp:api_version_"+to_string(plugin->getVampApiVersion())+" ;\n\
cannam@138 101 owl:versionInfo \""+to_string(plugin->getPluginVersion())+"\" ;\n";
cannam@142 102 if (plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain)
cannam@142 103 res+=" vamp:input_domain vamp:FrequencyDomain ;\n\n";
cannam@142 104 else
cannam@142 105 res+=" vamp:input_domain vamp:TimeDomain ;\n\n";
cannam@138 106
cannam@138 107
cannam@142 108 Plugin::ParameterList params = plugin->getParameterDescriptors();
cannam@142 109 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
dpastor@156 110 res+=" vamp:parameter plugbase:"+plugin->getIdentifier()+"_param_"+(*i).identifier+" ;\n";
cannam@142 111 res+="\n";
cannam@138 112
cannam@142 113 Plugin::OutputList outputs = plugin->getOutputDescriptors();
cannam@142 114 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
cannam@158 115 res+=" vamp:output plugbase:"+plugin->getIdentifier()+"_output_"+(*i).identifier+" ;\n";
cannam@142 116 res+=" .\n";
cannam@138 117
cannam@142 118 return res;
cannam@138 119 }
cannam@138 120
cannam@144 121 string describe_param(Plugin *plugin, Plugin::ParameterDescriptor p)
cannam@138 122 {
cannam@148 123
cannam@148 124 //FIXME: dc:format and vamp:unit are the same???
dpastor@157 125 //Should be a QUantizedParameter also a Parameter??
cannam@148 126 if(p.isQuantized){
cannam@148 127 string res=\
dpastor@156 128 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:QuantizedParameter ;\n\
cannam@148 129 vamp:identifier \""+p.identifier+"\" ;\n\
cannam@148 130 dc:title \""+p.name+"\" ;\n\
cannam@148 131 dc:format \""+p.unit+"\" ;\n\
cannam@148 132 vamp:min_value "+to_string(p.minValue)+" ;\n\
cannam@148 133 vamp:max_value "+to_string(p.maxValue)+" ;\n\
cannam@148 134 vamp:unit \""+p.unit+"\" ;\n\
cannam@152 135 vamp:quantize_step "+to_string(p.quantizeStep)+" ;\n\
cannam@148 136 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
cannam@148 137 vamp:value_names (";
cannam@148 138
cannam@148 139 unsigned int i;
cannam@148 140 for (i=0; i+1 < p.valueNames.size(); i++)
cannam@148 141 res+=" \""+p.valueNames[i]+"\"";
cannam@148 142 if (i < p.valueNames.size())
cannam@148 143 res+=" \""+p.valueNames[i]+"\"";
cannam@148 144 res+=");\n";
cannam@148 145
cannam@148 146 res+=" .\n";
cannam@148 147
cannam@148 148 return res;
cannam@148 149
cannam@148 150 }else{
cannam@142 151 string res=\
dpastor@156 152 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:Parameter ;\n\
cannam@138 153 vamp:identifier \""+p.identifier+"\" ;\n\
cannam@138 154 dc:title \""+p.name+"\" ;\n\
cannam@138 155 dc:format \""+p.unit+"\" ;\n\
cannam@139 156 vamp:min_value "+to_string(p.minValue)+" ;\n\
cannam@139 157 vamp:max_value "+to_string(p.maxValue)+" ;\n\
cannam@148 158 vamp:unit \""+p.unit+"\" ;\n\
cannam@148 159 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
cannam@148 160 vamp:value_names (";
cannam@148 161
cannam@148 162 unsigned int i;
cannam@148 163 for (i=0; i+1 < p.valueNames.size(); i++)
cannam@148 164 res+=" \""+p.valueNames[i]+"\"";
cannam@148 165 if (i < p.valueNames.size())
cannam@148 166 res+=" \""+p.valueNames[i]+"\"";
cannam@148 167 res+=");\n";
cannam@148 168
cannam@148 169 res+=" .\n";
cannam@148 170
cannam@142 171 return res;
cannam@148 172
cannam@148 173 }
cannam@138 174 }
cannam@138 175
cannam@144 176 string describe_output(Plugin *plugin, Plugin::OutputDescriptor o)
cannam@138 177 {
cannam@138 178
cannam@142 179 //we need to distinguish here between different output types:
cannam@148 180
cannam@148 181 //Quantize or not
cannam@148 182 //KnownExtents or not
cannam@148 183 //Data output classification:
cannam@142 184 //DenseOutput
cannam@142 185 //SparseOutput
cannam@142 186 //TrackLevelOutput
cannam@139 187
cannam@139 188
cannam@142 189 //SparseOutput: variable sample rate. Events are not evenly spaced so we need to record the time associated with the event as it its not ensured that we have an event after the next one (but there is not time to set the duration, it has to be calculated as the different between 2 different events). The timestamp must be read.
cannam@139 190
cannam@142 191 string res;
cannam@139 192
cannam@142 193 if (o.sampleType == Plugin::OutputDescriptor::VariableSampleRate)
cannam@142 194 {
cannam@139 195
cannam@142 196 res=\
cannam@144 197 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:SparseOutput ;\n\
cannam@139 198 vamp:identifier \""+o.identifier+"\" ;\n\
cannam@139 199 dc:title \""+o.name+"\" ;\n\
cannam@139 200 dc:description \""+o.description+"\" ;\n\
cannam@139 201 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
cannam@139 202 vamp:unit \""+(o.unit)+"\" ;\n";
cannam@139 203
cannam@148 204
cannam@148 205 //another type of output
cannam@148 206 if(o.isQuantized){
cannam@148 207
cannam@148 208 res+=" a vamp:QuantizedOutput ;\n";
cannam@148 209 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
cannam@148 210 }
cannam@148 211
cannam@148 212 //and yet another type
cannam@148 213 if(o.hasKnownExtents){
cannam@148 214
cannam@148 215 res+=" a vamp:KnownExtentsOutput ;\n";
cannam@148 216 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
cannam@148 217 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
cannam@148 218 }
cannam@139 219
cannam@142 220 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
cannam@142 221 if (o.hasFixedBinCount)
cannam@142 222 {
cannam@144 223 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
cannam@144 224 res+=" vamp:bin_names (";
cannam@138 225
cannam@142 226 unsigned int i;
cannam@142 227 for (i=0; i+1 < o.binNames.size(); i++)
cannam@142 228 res+=" \""+o.binNames[i]+"\"";
cannam@142 229 if (i < o.binNames.size())
cannam@142 230 res+=" \""+o.binNames[i]+"\"";
cannam@142 231 res+=");\n";
cannam@142 232 }
cannam@148 233
cannam@144 234 res+=" vamp:sample_type vamp:VariableSampleRate ;\n";
cannam@142 235 if (o.sampleRate > 0.0f)
cannam@144 236 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
cannam@142 237
cannam@142 238 }
cannam@139 239
cannam@142 240 //If we do not have SparseOutput, then we have DenseOutput. TrackLevelOutput can not be inferred from the plugin directly without actually
cannam@142 241 //running the plugin.
cannam@142 242 else{
cannam@142 243
cannam@142 244 res=\
cannam@144 245 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:DenseOutput ;\n\
cannam@139 246 vamp:identifier \""+o.identifier+"\" ;\n\
cannam@139 247 dc:title \""+o.name+"\" ;\n\
cannam@139 248 dc:description \""+o.description+"\" ;\n\
cannam@139 249 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
cannam@139 250 vamp:unit \""+(o.unit)+"\" ;\n";
cannam@139 251
cannam@139 252
cannam@148 253 //another type of output
cannam@148 254 if(o.isQuantized){
cannam@148 255
cannam@148 256 res+=" a vamp:QuantizedOutput ;\n";
cannam@148 257 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
cannam@148 258 }
cannam@148 259
cannam@148 260 //and yet another type
cannam@148 261 if(o.hasKnownExtents){
cannam@148 262
cannam@148 263 res+=" a vamp:KnownExtentsOutput ;\n";
cannam@148 264 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
cannam@148 265 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
cannam@148 266 }
cannam@139 267
cannam@142 268 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
cannam@142 269 if (o.hasFixedBinCount)
cannam@142 270 {
cannam@144 271 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
cannam@144 272 res+=" vamp:bin_names (";
cannam@139 273
cannam@142 274 unsigned int i;
cannam@142 275 for (i=0; i+1 < o.binNames.size(); i++)
cannam@142 276 res+=" \""+o.binNames[i]+"\"";
cannam@142 277 if (i < o.binNames.size())
cannam@142 278 res+=" \""+o.binNames[i]+"\"";
cannam@142 279 res+=");\n";
cannam@139 280 }
cannam@139 281
cannam@142 282 else if (o.sampleType == Plugin::OutputDescriptor::FixedSampleRate)
cannam@142 283 {
cannam@144 284 res+=" vamp:sample_type vamp:FixedSampleRate ;\n";
cannam@144 285 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
cannam@142 286 }
cannam@142 287 else if (o.sampleType == Plugin::OutputDescriptor::OneSamplePerStep)
cannam@144 288 res+=" vamp:sample_type vamp:OneSamplePerStep ;\n";
cannam@142 289 else
cannam@142 290 {
cannam@142 291 cerr<<"Incomprehensible sampleType for output descriptor "+o.identifier<<" !"<<endl;
cannam@142 292 exit(1);
cannam@142 293 }
cannam@142 294 }
cannam@142 295
cannam@142 296 //There is no way to know this in advance, but we can use the km a bit for this.
cannam@154 297 res+="# vamp:computes_feature_type <Place feature type URI here and uncomment> ;\n";
cannam@154 298 res+="# vamp:computes_event_type <Place event type URI here and uncomment> ;\n";
cannam@142 299 res+=" .\n";
cannam@142 300
cannam@142 301 return res;
cannam@138 302 }
cannam@139 303
cannam@144 304 string describe(vector<Plugin *> plugins, string pluginBundleBaseURI,
cannam@144 305 string describerURI, string libname)
cannam@138 306 {
cannam@144 307 string res = describe_namespaces(pluginBundleBaseURI, libname);
cannam@138 308
cannam@144 309 res += describe_doc(describerURI, pluginBundleBaseURI, libname);
cannam@138 310
cannam@144 311 res += describe_library(libname, plugins);
cannam@144 312
cannam@144 313 for (size_t i = 0; i < plugins.size(); ++i) {
cannam@144 314
cannam@144 315 Plugin *plugin = plugins[i];
cannam@144 316
cannam@144 317 res += describe_plugin(plugin);
cannam@138 318
cannam@144 319 Plugin::ParameterList params = plugin->getParameterDescriptors();
cannam@144 320 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
cannam@144 321 res += describe_param(plugin, *i);
cannam@138 322
cannam@144 323 Plugin::OutputList outputs = plugin->getOutputDescriptors();
cannam@144 324 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
cannam@144 325 res += describe_output(plugin, *i);
cannam@144 326 }
cannam@138 327
cannam@142 328 return res;
cannam@138 329 }
cannam@138 330
cannam@138 331 int main(int argc, char **argv)
cannam@138 332 {
cannam@144 333 if (argc < 3) usage();
cannam@138 334
cannam@144 335 bool interactive = false;
cannam@144 336 if (!strcmp(argv[1], "-i")) interactive = true;
cannam@138 337
cannam@144 338 if (!interactive && argc < 4) usage();
cannam@138 339
cannam@138 340 string pluginBundleBaseURI, describerURI;
cannam@144 341
cannam@144 342 int argidx = 2;
cannam@138 343
cannam@144 344 if (!interactive) {
cannam@138 345 pluginBundleBaseURI = argv[1];
cannam@138 346 describerURI = argv[2];
cannam@144 347 argidx = 3;
cannam@144 348 } else {
cannam@138 349 cerr << "Please enter the base URI for the plugin bundle : ";
cannam@138 350 getline(cin, pluginBundleBaseURI);
cannam@138 351 cerr << "Please enter your URI : ";
cannam@138 352 getline(cin, describerURI);
cannam@138 353 }
cannam@144 354
cannam@144 355 vector<Plugin *> plugins;
cannam@144 356 string libname;
cannam@144 357
cannam@144 358 PluginLoader *loader = PluginLoader::getInstance();
cannam@144 359
cannam@144 360 while (argidx < argc) {
cannam@144 361
cannam@144 362 string pluginName = argv[argidx];
cannam@144 363
cannam@144 364 if (pluginName.substr(0, 5) == "vamp:") {
cannam@144 365 pluginName = pluginName.substr(5);
cannam@144 366 }
cannam@144 367
cannam@144 368 string mylibname = pluginName.substr(0, pluginName.find(':'));
cannam@144 369
cannam@144 370 if (libname == "") libname = mylibname;
cannam@144 371 else if (libname != mylibname) {
cannam@144 372 cerr << "ERROR: All plugins specified on command line must originate in the same library" << endl;
cannam@144 373 exit(1);
cannam@144 374 }
cannam@144 375
cannam@144 376 if (mylibname == pluginName) { // pluginName is a library, not a plugin
cannam@144 377
cannam@144 378 PluginLoader::PluginKeyList list = loader->listPlugins();
cannam@144 379 for (size_t i = 0; i < list.size(); ++i) {
cannam@144 380 string thislibname = list[i].substr(0, list[i].find(':'));
cannam@144 381 if (thislibname != mylibname) continue;
cannam@144 382 Plugin *plugin = loader->loadPlugin(list[i], 44100);
cannam@144 383 if (!plugin) {
cannam@144 384 cerr << "ERROR: Plugin \"" << list[i] << "\" could not be loaded" << endl;
cannam@144 385 exit(1);
cannam@144 386 }
cannam@144 387 plugins.push_back(plugin);
cannam@144 388 }
cannam@151 389
cannam@151 390 if (plugins.empty()) {
cannam@151 391 cerr << "ERROR: Plugin library \"" << mylibname << "\" does not exist, could not be opened, or contains no plugins" << endl;
cannam@151 392 exit(1);
cannam@151 393 }
cannam@151 394
cannam@144 395 } else { // pluginName is a plugin
cannam@144 396
cannam@144 397 Plugin *plugin = loader->loadPlugin(pluginName, size_t(44100));
cannam@144 398 if (!plugin) {
cannam@144 399 cerr << "ERROR: Plugin \"" << pluginName << "\" could not be loaded" << endl;
cannam@144 400 exit(1);
cannam@144 401 }
cannam@144 402 plugins.push_back(plugin);
cannam@144 403 }
cannam@144 404
cannam@144 405 ++argidx;
cannam@144 406 }
cannam@138 407
cannam@144 408 cout << describe(plugins, pluginBundleBaseURI, describerURI, libname) << endl;
cannam@138 409
cannam@138 410 return 0;
cannam@138 411 }
cannam@138 412
cannam@138 413