annotate rdf/generator/template-generator.cpp @ 145:521ff35b8b4c

* fix available_plugin (was string instead of uri)
author cannam
date Fri, 20 Jun 2008 14:09:09 +0000
parents a4aad47aaf96
children 6b80bb85083b
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@139 51 @prefix vamp: <http://www.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@138 97 foaf:maker [ foaf:name \""+plugin->getMaker()+"\"] ; # FIXME could give plugin author's URI here\n\
cannam@138 98 cc:license <FIXME license for the plugin> ; \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++)
cannam@144 110 res+=" vamp:parameter_descriptor 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@144 115 res+=" vamp:output_descriptor 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@142 123 string res=\
cannam@144 124 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:ParameterDescriptor ;\n\
cannam@138 125 vamp:identifier \""+p.identifier+"\" ;\n\
cannam@138 126 dc:title \""+p.name+"\" ;\n\
cannam@138 127 dc:format \""+p.unit+"\" ;\n\
cannam@139 128 vamp:min_value "+to_string(p.minValue)+" ;\n\
cannam@139 129 vamp:max_value "+to_string(p.maxValue)+" ;\n\
cannam@139 130 vamp:default_value "+to_string(p.defaultValue)+" .\n\n";
cannam@142 131 return res;
cannam@138 132 }
cannam@138 133
cannam@144 134 string describe_output(Plugin *plugin, Plugin::OutputDescriptor o)
cannam@138 135 {
cannam@138 136
cannam@142 137 //we need to distinguish here between different output types:
cannam@142 138 //DenseOutput
cannam@142 139 //SparseOutput
cannam@142 140 //TrackLevelOutput
cannam@139 141
cannam@139 142
cannam@142 143 //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 144
cannam@142 145 string res;
cannam@139 146
cannam@142 147 if (o.sampleType == Plugin::OutputDescriptor::VariableSampleRate)
cannam@142 148 {
cannam@139 149
cannam@142 150 res=\
cannam@144 151 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:SparseOutput ;\n\
cannam@139 152 vamp:identifier \""+o.identifier+"\" ;\n\
cannam@139 153 dc:title \""+o.name+"\" ;\n\
cannam@139 154 dc:description \""+o.description+"\" ;\n\
cannam@139 155 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
cannam@139 156 vamp:is_quantized \""+(o.isQuantized == 1 ? "true" : "false")+"\" ;\n\
cannam@139 157 vamp:unit \""+(o.unit)+"\" ;\n";
cannam@139 158
cannam@139 159
cannam@139 160
cannam@142 161 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
cannam@142 162 if (o.hasFixedBinCount)
cannam@142 163 {
cannam@144 164 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
cannam@144 165 res+=" vamp:bin_names (";
cannam@138 166
cannam@142 167 unsigned int i;
cannam@142 168 for (i=0; i+1 < o.binNames.size(); i++)
cannam@142 169 res+=" \""+o.binNames[i]+"\"";
cannam@142 170 if (i < o.binNames.size())
cannam@142 171 res+=" \""+o.binNames[i]+"\"";
cannam@142 172 res+=");\n";
cannam@142 173 }
cannam@139 174
cannam@142 175 if (o.isQuantized)
cannam@142 176 {
cannam@144 177 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
cannam@139 178 }
cannam@138 179
cannam@144 180 res+=" vamp:sample_type vamp:VariableSampleRate ;\n";
cannam@142 181 if (o.sampleRate > 0.0f)
cannam@144 182 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
cannam@142 183
cannam@142 184 }
cannam@139 185
cannam@142 186 //If we do not have SparseOutput, then we have DenseOutput. TrackLevelOutput can not be inferred from the plugin directly without actually
cannam@142 187 //running the plugin.
cannam@142 188 else{
cannam@142 189
cannam@142 190 res=\
cannam@144 191 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:DenseOutput ;\n\
cannam@139 192 vamp:identifier \""+o.identifier+"\" ;\n\
cannam@139 193 dc:title \""+o.name+"\" ;\n\
cannam@139 194 dc:description \""+o.description+"\" ;\n\
cannam@139 195 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
cannam@139 196 vamp:is_quantised \""+(o.isQuantized == 1 ? "true" : "false")+"\" ;\n\
cannam@139 197 vamp:unit \""+(o.unit)+"\" ;\n";
cannam@139 198
cannam@139 199
cannam@139 200
cannam@142 201 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
cannam@142 202 if (o.hasFixedBinCount)
cannam@142 203 {
cannam@144 204 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
cannam@144 205 res+=" vamp:bin_names (";
cannam@139 206
cannam@142 207 unsigned int i;
cannam@142 208 for (i=0; i+1 < o.binNames.size(); i++)
cannam@142 209 res+=" \""+o.binNames[i]+"\"";
cannam@142 210 if (i < o.binNames.size())
cannam@142 211 res+=" \""+o.binNames[i]+"\"";
cannam@142 212 res+=");\n";
cannam@139 213 }
cannam@139 214
cannam@142 215 if (o.isQuantized)
cannam@142 216 {
cannam@144 217 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
cannam@142 218 }
cannam@138 219
cannam@142 220
cannam@142 221 else if (o.sampleType == Plugin::OutputDescriptor::FixedSampleRate)
cannam@142 222 {
cannam@144 223 res+=" vamp:sample_type vamp:FixedSampleRate ;\n";
cannam@144 224 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
cannam@142 225 }
cannam@142 226 else if (o.sampleType == Plugin::OutputDescriptor::OneSamplePerStep)
cannam@144 227 res+=" vamp:sample_type vamp:OneSamplePerStep ;\n";
cannam@142 228 else
cannam@142 229 {
cannam@142 230 cerr<<"Incomprehensible sampleType for output descriptor "+o.identifier<<" !"<<endl;
cannam@142 231 exit(1);
cannam@142 232 }
cannam@142 233 }
cannam@142 234
cannam@142 235 //There is no way to know this in advance, but we can use the km a bit for this.
cannam@142 236 res+=" vamp:computes_feature_type <FIXME feature type URI> ;\n";
cannam@142 237 res+=" vamp:computes_event_type <FIXME event type URI> ;\n";
cannam@142 238 res+=" .\n";
cannam@142 239
cannam@142 240 return res;
cannam@138 241 }
cannam@139 242
cannam@144 243 string describe(vector<Plugin *> plugins, string pluginBundleBaseURI,
cannam@144 244 string describerURI, string libname)
cannam@138 245 {
cannam@144 246 string res = describe_namespaces(pluginBundleBaseURI, libname);
cannam@138 247
cannam@144 248 res += describe_doc(describerURI, pluginBundleBaseURI, libname);
cannam@138 249
cannam@144 250 res += describe_library(libname, plugins);
cannam@144 251
cannam@144 252 for (size_t i = 0; i < plugins.size(); ++i) {
cannam@144 253
cannam@144 254 Plugin *plugin = plugins[i];
cannam@144 255
cannam@144 256 res += describe_plugin(plugin);
cannam@138 257
cannam@144 258 Plugin::ParameterList params = plugin->getParameterDescriptors();
cannam@144 259 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
cannam@144 260 res += describe_param(plugin, *i);
cannam@138 261
cannam@144 262 Plugin::OutputList outputs = plugin->getOutputDescriptors();
cannam@144 263 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
cannam@144 264 res += describe_output(plugin, *i);
cannam@144 265 }
cannam@138 266
cannam@142 267 return res;
cannam@138 268 }
cannam@138 269
cannam@138 270 int main(int argc, char **argv)
cannam@138 271 {
cannam@144 272 if (argc < 3) usage();
cannam@138 273
cannam@144 274 bool interactive = false;
cannam@144 275 if (!strcmp(argv[1], "-i")) interactive = true;
cannam@138 276
cannam@144 277 if (!interactive && argc < 4) usage();
cannam@138 278
cannam@138 279 string pluginBundleBaseURI, describerURI;
cannam@144 280
cannam@144 281 int argidx = 2;
cannam@138 282
cannam@144 283 if (!interactive) {
cannam@138 284 pluginBundleBaseURI = argv[1];
cannam@138 285 describerURI = argv[2];
cannam@144 286 argidx = 3;
cannam@144 287 } else {
cannam@138 288 cerr << "Please enter the base URI for the plugin bundle : ";
cannam@138 289 getline(cin, pluginBundleBaseURI);
cannam@138 290 cerr << "Please enter your URI : ";
cannam@138 291 getline(cin, describerURI);
cannam@138 292 }
cannam@144 293
cannam@144 294 vector<Plugin *> plugins;
cannam@144 295 string libname;
cannam@144 296
cannam@144 297 PluginLoader *loader = PluginLoader::getInstance();
cannam@144 298
cannam@144 299 while (argidx < argc) {
cannam@144 300
cannam@144 301 string pluginName = argv[argidx];
cannam@144 302
cannam@144 303 if (pluginName.substr(0, 5) == "vamp:") {
cannam@144 304 pluginName = pluginName.substr(5);
cannam@144 305 }
cannam@144 306
cannam@144 307 string mylibname = pluginName.substr(0, pluginName.find(':'));
cannam@144 308
cannam@144 309 if (libname == "") libname = mylibname;
cannam@144 310 else if (libname != mylibname) {
cannam@144 311 cerr << "ERROR: All plugins specified on command line must originate in the same library" << endl;
cannam@144 312 exit(1);
cannam@144 313 }
cannam@144 314
cannam@144 315 if (mylibname == pluginName) { // pluginName is a library, not a plugin
cannam@144 316
cannam@144 317 PluginLoader::PluginKeyList list = loader->listPlugins();
cannam@144 318 for (size_t i = 0; i < list.size(); ++i) {
cannam@144 319 string thislibname = list[i].substr(0, list[i].find(':'));
cannam@144 320 if (thislibname != mylibname) continue;
cannam@144 321 Plugin *plugin = loader->loadPlugin(list[i], 44100);
cannam@144 322 if (!plugin) {
cannam@144 323 cerr << "ERROR: Plugin \"" << list[i] << "\" could not be loaded" << endl;
cannam@144 324 exit(1);
cannam@144 325 }
cannam@144 326 plugins.push_back(plugin);
cannam@144 327 }
cannam@144 328 } else { // pluginName is a plugin
cannam@144 329
cannam@144 330 Plugin *plugin = loader->loadPlugin(pluginName, size_t(44100));
cannam@144 331 if (!plugin) {
cannam@144 332 cerr << "ERROR: Plugin \"" << pluginName << "\" could not be loaded" << endl;
cannam@144 333 exit(1);
cannam@144 334 }
cannam@144 335 plugins.push_back(plugin);
cannam@144 336 }
cannam@144 337
cannam@144 338 ++argidx;
cannam@144 339 }
cannam@138 340
cannam@144 341 cout << describe(plugins, pluginBundleBaseURI, describerURI, libname) << endl;
cannam@138 342
cannam@138 343 return 0;
cannam@138 344 }
cannam@138 345
cannam@138 346