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