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@194
|
105 res+=" vamp:input_domain vamp:TimeDomain ;\n";
|
cannam@138
|
106
|
cannam@138
|
107
|
cannam@142
|
108 Plugin::ParameterList params = plugin->getParameterDescriptors();
|
cannam@194
|
109 if (!params.empty()) res+="\n";
|
cannam@142
|
110 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
|
dpastor@156
|
111 res+=" vamp:parameter plugbase:"+plugin->getIdentifier()+"_param_"+(*i).identifier+" ;\n";
|
cannam@194
|
112 if (!params.empty()) res+="\n";
|
cannam@138
|
113
|
cannam@142
|
114 Plugin::OutputList outputs = plugin->getOutputDescriptors();
|
cannam@142
|
115 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
|
cannam@158
|
116 res+=" vamp:output plugbase:"+plugin->getIdentifier()+"_output_"+(*i).identifier+" ;\n";
|
cannam@142
|
117 res+=" .\n";
|
cannam@138
|
118
|
cannam@142
|
119 return res;
|
cannam@138
|
120 }
|
cannam@138
|
121
|
cannam@144
|
122 string describe_param(Plugin *plugin, Plugin::ParameterDescriptor p)
|
cannam@138
|
123 {
|
cannam@148
|
124
|
cannam@148
|
125 //FIXME: dc:format and vamp:unit are the same???
|
dpastor@157
|
126 //Should be a QUantizedParameter also a Parameter??
|
cannam@148
|
127 if(p.isQuantized){
|
cannam@148
|
128 string res=\
|
dpastor@156
|
129 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:QuantizedParameter ;\n\
|
cannam@148
|
130 vamp:identifier \""+p.identifier+"\" ;\n\
|
cannam@148
|
131 dc:title \""+p.name+"\" ;\n\
|
cannam@148
|
132 dc:format \""+p.unit+"\" ;\n\
|
cannam@148
|
133 vamp:min_value "+to_string(p.minValue)+" ;\n\
|
cannam@148
|
134 vamp:max_value "+to_string(p.maxValue)+" ;\n\
|
cannam@148
|
135 vamp:unit \""+p.unit+"\" ;\n\
|
cannam@152
|
136 vamp:quantize_step "+to_string(p.quantizeStep)+" ;\n\
|
cannam@148
|
137 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
|
cannam@148
|
138 vamp:value_names (";
|
cannam@148
|
139
|
cannam@148
|
140 unsigned int i;
|
cannam@148
|
141 for (i=0; i+1 < p.valueNames.size(); i++)
|
cannam@148
|
142 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
143 if (i < p.valueNames.size())
|
cannam@148
|
144 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
145 res+=");\n";
|
cannam@148
|
146
|
cannam@148
|
147 res+=" .\n";
|
cannam@148
|
148
|
cannam@148
|
149 return res;
|
cannam@148
|
150
|
cannam@148
|
151 }else{
|
cannam@142
|
152 string res=\
|
dpastor@156
|
153 "plugbase:"+plugin->getIdentifier()+"_param_"+p.identifier+" a vamp:Parameter ;\n\
|
cannam@138
|
154 vamp:identifier \""+p.identifier+"\" ;\n\
|
cannam@138
|
155 dc:title \""+p.name+"\" ;\n\
|
cannam@138
|
156 dc:format \""+p.unit+"\" ;\n\
|
cannam@139
|
157 vamp:min_value "+to_string(p.minValue)+" ;\n\
|
cannam@139
|
158 vamp:max_value "+to_string(p.maxValue)+" ;\n\
|
cannam@148
|
159 vamp:unit \""+p.unit+"\" ;\n\
|
cannam@148
|
160 vamp:default_value "+to_string(p.defaultValue)+" ;\n\
|
cannam@148
|
161 vamp:value_names (";
|
cannam@148
|
162
|
cannam@148
|
163 unsigned int i;
|
cannam@148
|
164 for (i=0; i+1 < p.valueNames.size(); i++)
|
cannam@148
|
165 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
166 if (i < p.valueNames.size())
|
cannam@148
|
167 res+=" \""+p.valueNames[i]+"\"";
|
cannam@148
|
168 res+=");\n";
|
cannam@148
|
169
|
cannam@148
|
170 res+=" .\n";
|
cannam@148
|
171
|
cannam@142
|
172 return res;
|
cannam@148
|
173
|
cannam@148
|
174 }
|
cannam@138
|
175 }
|
cannam@138
|
176
|
cannam@144
|
177 string describe_output(Plugin *plugin, Plugin::OutputDescriptor o)
|
cannam@138
|
178 {
|
cannam@138
|
179
|
cannam@142
|
180 //we need to distinguish here between different output types:
|
cannam@148
|
181
|
cannam@148
|
182 //Quantize or not
|
cannam@148
|
183 //KnownExtents or not
|
cannam@148
|
184 //Data output classification:
|
cannam@142
|
185 //DenseOutput
|
cannam@142
|
186 //SparseOutput
|
cannam@142
|
187 //TrackLevelOutput
|
cannam@139
|
188
|
cannam@139
|
189
|
cannam@168
|
190 // SparseOutput: variable sample rate. Events are not evenly
|
cannam@168
|
191 // spaced so we need to record the time associated with the event
|
cannam@168
|
192 // as it its not ensured that we have an event after the next one
|
cannam@168
|
193 // (but there is not time to set the duration, it has to be
|
cannam@168
|
194 // calculated as the different between 2 different events). The
|
cannam@168
|
195 // timestamp must be read.
|
cannam@139
|
196
|
cannam@142
|
197 string res;
|
cannam@139
|
198
|
cannam@168
|
199 if (o.sampleType == Plugin::OutputDescriptor::VariableSampleRate ||
|
cannam@168
|
200 !o.hasFixedBinCount)
|
cannam@142
|
201 {
|
cannam@139
|
202
|
cannam@142
|
203 res=\
|
cannam@144
|
204 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:SparseOutput ;\n\
|
cannam@139
|
205 vamp:identifier \""+o.identifier+"\" ;\n\
|
cannam@139
|
206 dc:title \""+o.name+"\" ;\n\
|
cannam@139
|
207 dc:description \""+o.description+"\" ;\n\
|
cannam@139
|
208 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
|
cannam@139
|
209 vamp:unit \""+(o.unit)+"\" ;\n";
|
cannam@139
|
210
|
cannam@148
|
211
|
cannam@148
|
212 //another type of output
|
cannam@148
|
213 if(o.isQuantized){
|
cannam@148
|
214
|
cannam@148
|
215 res+=" a vamp:QuantizedOutput ;\n";
|
cannam@148
|
216 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
|
cannam@148
|
217 }
|
cannam@148
|
218
|
cannam@148
|
219 //and yet another type
|
cannam@148
|
220 if(o.hasKnownExtents){
|
cannam@148
|
221
|
cannam@148
|
222 res+=" a vamp:KnownExtentsOutput ;\n";
|
cannam@148
|
223 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
|
cannam@148
|
224 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
|
cannam@148
|
225 }
|
cannam@139
|
226
|
cannam@142
|
227 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
|
cannam@142
|
228 if (o.hasFixedBinCount)
|
cannam@142
|
229 {
|
cannam@144
|
230 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
|
cannam@144
|
231 res+=" vamp:bin_names (";
|
cannam@138
|
232
|
cannam@142
|
233 unsigned int i;
|
cannam@142
|
234 for (i=0; i+1 < o.binNames.size(); i++)
|
cannam@142
|
235 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
236 if (i < o.binNames.size())
|
cannam@142
|
237 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
238 res+=");\n";
|
cannam@142
|
239 }
|
cannam@148
|
240
|
cannam@144
|
241 res+=" vamp:sample_type vamp:VariableSampleRate ;\n";
|
cannam@142
|
242 if (o.sampleRate > 0.0f)
|
cannam@144
|
243 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
|
cannam@142
|
244
|
cannam@142
|
245 }
|
cannam@139
|
246
|
cannam@142
|
247 //If we do not have SparseOutput, then we have DenseOutput. TrackLevelOutput can not be inferred from the plugin directly without actually
|
cannam@142
|
248 //running the plugin.
|
cannam@142
|
249 else{
|
cannam@142
|
250
|
cannam@142
|
251 res=\
|
cannam@144
|
252 "plugbase:"+plugin->getIdentifier()+"_output_"+o.identifier+" a vamp:DenseOutput ;\n\
|
cannam@139
|
253 vamp:identifier \""+o.identifier+"\" ;\n\
|
cannam@139
|
254 dc:title \""+o.name+"\" ;\n\
|
cannam@139
|
255 dc:description \""+o.description+"\" ;\n\
|
cannam@139
|
256 vamp:fixed_bin_count \""+(o.hasFixedBinCount == 1 ? "true" : "false")+"\" ;\n\
|
cannam@139
|
257 vamp:unit \""+(o.unit)+"\" ;\n";
|
cannam@139
|
258
|
cannam@139
|
259
|
cannam@148
|
260 //another type of output
|
cannam@148
|
261 if(o.isQuantized){
|
cannam@148
|
262
|
cannam@148
|
263 res+=" a vamp:QuantizedOutput ;\n";
|
cannam@148
|
264 res+=" vamp:quantize_step "+to_string(o.quantizeStep)+" ;\n";
|
cannam@148
|
265 }
|
cannam@148
|
266
|
cannam@148
|
267 //and yet another type
|
cannam@148
|
268 if(o.hasKnownExtents){
|
cannam@148
|
269
|
cannam@148
|
270 res+=" a vamp:KnownExtentsOutput ;\n";
|
cannam@148
|
271 res+=" vamp:min_value "+to_string(o.minValue)+" ;\n";
|
cannam@148
|
272 res+=" vamp:max_value "+to_string(o.maxValue)+" ;\n";
|
cannam@148
|
273 }
|
cannam@139
|
274
|
cannam@142
|
275 // FIXME ? Bin names may vary based on plugin setup, so including them here might be misleading...
|
cannam@142
|
276 if (o.hasFixedBinCount)
|
cannam@142
|
277 {
|
cannam@144
|
278 res+=" vamp:bin_count "+to_string(o.binCount)+" ;\n";
|
cannam@144
|
279 res+=" vamp:bin_names (";
|
cannam@139
|
280
|
cannam@142
|
281 unsigned int i;
|
cannam@142
|
282 for (i=0; i+1 < o.binNames.size(); i++)
|
cannam@142
|
283 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
284 if (i < o.binNames.size())
|
cannam@142
|
285 res+=" \""+o.binNames[i]+"\"";
|
cannam@142
|
286 res+=");\n";
|
cannam@139
|
287 }
|
cannam@139
|
288
|
cannam@142
|
289 else if (o.sampleType == Plugin::OutputDescriptor::FixedSampleRate)
|
cannam@142
|
290 {
|
cannam@144
|
291 res+=" vamp:sample_type vamp:FixedSampleRate ;\n";
|
cannam@144
|
292 res+=" vamp:sample_rate "+to_string(o.sampleRate)+" ;\n";
|
cannam@142
|
293 }
|
cannam@142
|
294 else if (o.sampleType == Plugin::OutputDescriptor::OneSamplePerStep)
|
cannam@144
|
295 res+=" vamp:sample_type vamp:OneSamplePerStep ;\n";
|
cannam@142
|
296 else
|
cannam@142
|
297 {
|
cannam@142
|
298 cerr<<"Incomprehensible sampleType for output descriptor "+o.identifier<<" !"<<endl;
|
cannam@142
|
299 exit(1);
|
cannam@142
|
300 }
|
cannam@142
|
301 }
|
cannam@142
|
302
|
cannam@142
|
303 //There is no way to know this in advance, but we can use the km a bit for this.
|
cannam@159
|
304 res+="# vamp:computes_event_type <Place event type URI here and uncomment> ;\n";
|
cannam@159
|
305 res+="# vamp:computes_feature <Place feature attribute URI here and uncomment> ;\n";
|
cannam@159
|
306 res+="# vamp:computes_signal_type <Place signal type URI here and uncomment> ;\n";
|
cannam@142
|
307 res+=" .\n";
|
cannam@142
|
308
|
cannam@142
|
309 return res;
|
cannam@138
|
310 }
|
cannam@139
|
311
|
cannam@144
|
312 string describe(vector<Plugin *> plugins, string pluginBundleBaseURI,
|
cannam@144
|
313 string describerURI, string libname)
|
cannam@138
|
314 {
|
cannam@144
|
315 string res = describe_namespaces(pluginBundleBaseURI, libname);
|
cannam@138
|
316
|
cannam@144
|
317 res += describe_doc(describerURI, pluginBundleBaseURI, libname);
|
cannam@138
|
318
|
cannam@144
|
319 res += describe_library(libname, plugins);
|
cannam@144
|
320
|
cannam@144
|
321 for (size_t i = 0; i < plugins.size(); ++i) {
|
cannam@144
|
322
|
cannam@144
|
323 Plugin *plugin = plugins[i];
|
cannam@144
|
324
|
cannam@144
|
325 res += describe_plugin(plugin);
|
cannam@138
|
326
|
cannam@144
|
327 Plugin::ParameterList params = plugin->getParameterDescriptors();
|
cannam@144
|
328 for (Plugin::ParameterList::const_iterator i = params.begin(); i != params.end(); i++)
|
cannam@144
|
329 res += describe_param(plugin, *i);
|
cannam@138
|
330
|
cannam@144
|
331 Plugin::OutputList outputs = plugin->getOutputDescriptors();
|
cannam@144
|
332 for (Plugin::OutputList::const_iterator i = outputs.begin(); i!= outputs.end(); i++)
|
cannam@144
|
333 res += describe_output(plugin, *i);
|
cannam@144
|
334 }
|
cannam@138
|
335
|
cannam@142
|
336 return res;
|
cannam@138
|
337 }
|
cannam@138
|
338
|
cannam@138
|
339 int main(int argc, char **argv)
|
cannam@138
|
340 {
|
cannam@144
|
341 if (argc < 3) usage();
|
cannam@138
|
342
|
cannam@144
|
343 bool interactive = false;
|
cannam@144
|
344 if (!strcmp(argv[1], "-i")) interactive = true;
|
cannam@138
|
345
|
cannam@144
|
346 if (!interactive && argc < 4) usage();
|
cannam@138
|
347
|
cannam@138
|
348 string pluginBundleBaseURI, describerURI;
|
cannam@144
|
349
|
cannam@144
|
350 int argidx = 2;
|
cannam@138
|
351
|
cannam@144
|
352 if (!interactive) {
|
cannam@138
|
353 pluginBundleBaseURI = argv[1];
|
cannam@138
|
354 describerURI = argv[2];
|
cannam@144
|
355 argidx = 3;
|
cannam@144
|
356 } else {
|
cannam@138
|
357 cerr << "Please enter the base URI for the plugin bundle : ";
|
cannam@138
|
358 getline(cin, pluginBundleBaseURI);
|
cannam@138
|
359 cerr << "Please enter your URI : ";
|
cannam@138
|
360 getline(cin, describerURI);
|
cannam@138
|
361 }
|
cannam@144
|
362
|
cannam@144
|
363 vector<Plugin *> plugins;
|
cannam@144
|
364 string libname;
|
cannam@144
|
365
|
cannam@144
|
366 PluginLoader *loader = PluginLoader::getInstance();
|
cannam@144
|
367
|
cannam@144
|
368 while (argidx < argc) {
|
cannam@144
|
369
|
cannam@144
|
370 string pluginName = argv[argidx];
|
cannam@144
|
371
|
cannam@144
|
372 if (pluginName.substr(0, 5) == "vamp:") {
|
cannam@144
|
373 pluginName = pluginName.substr(5);
|
cannam@144
|
374 }
|
cannam@144
|
375
|
cannam@144
|
376 string mylibname = pluginName.substr(0, pluginName.find(':'));
|
cannam@144
|
377
|
cannam@144
|
378 if (libname == "") libname = mylibname;
|
cannam@144
|
379 else if (libname != mylibname) {
|
cannam@144
|
380 cerr << "ERROR: All plugins specified on command line must originate in the same library" << endl;
|
cannam@144
|
381 exit(1);
|
cannam@144
|
382 }
|
cannam@144
|
383
|
cannam@144
|
384 if (mylibname == pluginName) { // pluginName is a library, not a plugin
|
cannam@144
|
385
|
cannam@144
|
386 PluginLoader::PluginKeyList list = loader->listPlugins();
|
cannam@144
|
387 for (size_t i = 0; i < list.size(); ++i) {
|
cannam@144
|
388 string thislibname = list[i].substr(0, list[i].find(':'));
|
cannam@144
|
389 if (thislibname != mylibname) continue;
|
cannam@144
|
390 Plugin *plugin = loader->loadPlugin(list[i], 44100);
|
cannam@144
|
391 if (!plugin) {
|
cannam@144
|
392 cerr << "ERROR: Plugin \"" << list[i] << "\" could not be loaded" << endl;
|
cannam@144
|
393 exit(1);
|
cannam@144
|
394 }
|
cannam@144
|
395 plugins.push_back(plugin);
|
cannam@144
|
396 }
|
cannam@151
|
397
|
cannam@151
|
398 if (plugins.empty()) {
|
cannam@151
|
399 cerr << "ERROR: Plugin library \"" << mylibname << "\" does not exist, could not be opened, or contains no plugins" << endl;
|
cannam@151
|
400 exit(1);
|
cannam@151
|
401 }
|
cannam@151
|
402
|
cannam@144
|
403 } else { // pluginName is a plugin
|
cannam@144
|
404
|
cannam@144
|
405 Plugin *plugin = loader->loadPlugin(pluginName, size_t(44100));
|
cannam@144
|
406 if (!plugin) {
|
cannam@144
|
407 cerr << "ERROR: Plugin \"" << pluginName << "\" could not be loaded" << endl;
|
cannam@144
|
408 exit(1);
|
cannam@144
|
409 }
|
cannam@144
|
410 plugins.push_back(plugin);
|
cannam@144
|
411 }
|
cannam@144
|
412
|
cannam@144
|
413 ++argidx;
|
cannam@144
|
414 }
|
cannam@138
|
415
|
cannam@144
|
416 cout << describe(plugins, pluginBundleBaseURI, describerURI, libname) << endl;
|
cannam@138
|
417
|
cannam@138
|
418 return 0;
|
cannam@138
|
419 }
|
cannam@138
|
420
|
cannam@138
|
421
|