Mercurial > hg > vamp-plugin-sdk
comparison host/vamp-simple-host.cpp @ 59:fa79c4ec847d host-factory-stuff
* Put hostext stuff in the HostExt sub-namespace
* Tidy up system-specific stuff in PluginLoader
* Make PluginLoader return a deletion-notifying wrapper which permits the
library to be unloaded when no longer in use
* Add PluginChannelAdapter
* Make vamp-simple-host use PluginChannelAdapter, and use the PluginLoader
for plugin-running task. Also some other enhancements to host
author | cannam |
---|---|
date | Thu, 24 May 2007 15:17:07 +0000 |
parents | 09a1aac6c362 |
children | 97c5ac99d725 |
comparison
equal
deleted
inserted
replaced
58:0284955e31e5 | 59:fa79c4ec847d |
---|---|
33 shall not be used in advertising or otherwise to promote the sale, | 33 shall not be used in advertising or otherwise to promote the sale, |
34 use or other dealings in this Software without prior written | 34 use or other dealings in this Software without prior written |
35 authorization. | 35 authorization. |
36 */ | 36 */ |
37 | 37 |
38 #include "PluginHostAdapter.h" | 38 #include "vamp-sdk/PluginHostAdapter.h" |
39 #include "PluginInputDomainAdapter.h" | 39 #include "vamp-sdk/hostext/PluginChannelAdapter.h" |
40 #include "PluginLoader.h" | 40 #include "vamp-sdk/hostext/PluginInputDomainAdapter.h" |
41 #include "vamp.h" | 41 #include "vamp-sdk/hostext/PluginLoader.h" |
42 #include "vamp/vamp.h" | |
42 | 43 |
43 #include <iostream> | 44 #include <iostream> |
44 #include <sndfile.h> | 45 #include <sndfile.h> |
45 | 46 |
46 #include "system.h" | 47 #include "system.h" |
51 using std::cerr; | 52 using std::cerr; |
52 using std::endl; | 53 using std::endl; |
53 using std::string; | 54 using std::string; |
54 using std::vector; | 55 using std::vector; |
55 | 56 |
56 #define HOST_VERSION "1.0" | 57 using Vamp::HostExt::PluginLoader; |
58 | |
59 #define HOST_VERSION "1.1" | |
57 | 60 |
58 void printFeatures(int, int, int, Vamp::Plugin::FeatureSet); | 61 void printFeatures(int, int, int, Vamp::Plugin::FeatureSet); |
59 void transformInput(float *, size_t); | 62 void transformInput(float *, size_t); |
60 void fft(unsigned int, bool, double *, double *, double *, double *); | 63 void fft(unsigned int, bool, double *, double *, double *, double *); |
61 void printPluginPath(); | 64 void printPluginPath(bool verbose); |
62 void enumeratePlugins(); | 65 void enumeratePlugins(); |
63 | 66 void listPluginsInLibrary(string soname); |
64 /* | 67 int runPlugin(string myname, string soname, string id, string output, |
65 A very simple Vamp plugin host. Given the name of a plugin | 68 int outputNo, string inputFile); |
66 library and the name of a sound file on the command line, it loads | 69 |
67 the first plugin in the library and runs it on the sound file, | 70 void usage(const char *name) |
68 dumping the plugin's first output to stdout. | 71 { |
69 */ | 72 cerr << "\n" |
73 << name << ": A simple Vamp plugin host.\n\n" | |
74 "Centre for Digital Music, Queen Mary, University of London.\n" | |
75 "Copyright 2006-2007 Chris Cannam and QMUL.\n" | |
76 "Freely redistributable; published under a BSD-style license.\n\n" | |
77 "Usage:\n\n" | |
78 " " << name << " pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin[:output] file.wav\n" | |
79 " " << name << " pluginlibrary[." << PLUGIN_SUFFIX << "]:plugin file.wav [outputno]\n\n" | |
80 " -- Load plugin id \"plugin\" from \"pluginlibrary\" and run it on the\n" | |
81 " audio data in \"file.wav\"; retrieve the named \"output\", or output\n" | |
82 " number \"outputno\" (the first output by default) and dump it to\n" | |
83 " standard output.\n\n" | |
84 " " << name << " -l\n\n" | |
85 " -- List the plugin libraries and Vamp plugins in the plugin search path.\n\n" | |
86 " " << name << " -p\n\n" | |
87 " -- Print out the Vamp plugin search path.\n\n" | |
88 " " << name << " -v\n\n" | |
89 " -- Display version information only.\n\n" | |
90 << endl; | |
91 exit(2); | |
92 } | |
70 | 93 |
71 int main(int argc, char **argv) | 94 int main(int argc, char **argv) |
72 { | 95 { |
96 char *scooter = argv[0]; | |
97 char *name = 0; | |
98 while (scooter && *scooter) { | |
99 if (*scooter == '/' || *scooter == '\\') name = ++scooter; | |
100 else ++scooter; | |
101 } | |
102 if (!name || !*name) name = argv[0]; | |
103 | |
73 if (argc < 2 || argc > 4 || | 104 if (argc < 2 || argc > 4 || |
74 (argc == 2 && | 105 (argc == 2 && |
75 (!strcmp(argv[1], "-?") || | 106 (!strcmp(argv[1], "-?") || |
76 !strcmp(argv[1], "-h") || | 107 !strcmp(argv[1], "-h") || |
77 !strcmp(argv[1], "--help")))) { | 108 !strcmp(argv[1], "--help")))) { |
78 | 109 |
79 char *scooter = argv[0]; | 110 usage(name); // does not return |
80 char *name = 0; | 111 } |
81 while (scooter && *scooter) { | 112 |
82 if (*scooter == '/' || *scooter == '\\') name = ++scooter; | |
83 else ++scooter; | |
84 } | |
85 if (!name || !*name) name = argv[0]; | |
86 cerr << "\n" | |
87 << name << ": A simple Vamp plugin host.\n\n" | |
88 "Centre for Digital Music, Queen Mary, University of London.\n" | |
89 "Copyright 2006 Chris Cannam and QMUL.\n" | |
90 "Freely redistributable; published under a BSD-style license.\n\n" | |
91 "Usage:\n\n" | |
92 " " << name << " pluginlibrary." << PLUGIN_SUFFIX << "\n\n" | |
93 " -- Load \"pluginlibrary\" and list the Vamp plugins it contains.\n\n" | |
94 " " << name << " pluginlibrary." << PLUGIN_SUFFIX << ":plugin file.wav [outputno]\n\n" | |
95 " -- Load plugin id \"plugin\" from \"pluginlibrary\" and run it on the\n" | |
96 " audio data in \"file.wav\", dumping the output from \"outputno\"\n" | |
97 " (default 0) to standard output.\n\n" | |
98 #ifdef HAVE_OPENDIR | |
99 " " << name << " -l\n\n" | |
100 " -- List the plugin libraries and Vamp plugins in the plugin search path.\n\n" | |
101 #endif | |
102 " " << name << " -p\n\n" | |
103 " -- Print out the Vamp plugin search path.\n\n" | |
104 " " << name << " -v\n\n" | |
105 " -- Display version information only.\n\n" | |
106 "Note that this host does not use the plugin search path when loadinga plugin.\nIf a plugin library is specified, it should be with a full file path.\n" | |
107 << endl; | |
108 return 2; | |
109 } | |
110 | |
111 if (argc == 2 && !strcmp(argv[1], "-v")) { | 113 if (argc == 2 && !strcmp(argv[1], "-v")) { |
112 cout << "Simple Vamp plugin host version: " << HOST_VERSION << endl | 114 cout << "Simple Vamp plugin host version: " << HOST_VERSION << endl |
113 << "Vamp API version: " << VAMP_API_VERSION << endl | 115 << "Vamp API version: " << VAMP_API_VERSION << endl |
114 << "Vamp SDK version: " << VAMP_SDK_VERSION << endl; | 116 << "Vamp SDK version: " << VAMP_SDK_VERSION << endl; |
115 return 0; | 117 return 0; |
116 } | 118 } |
117 | 119 |
118 if (argc == 2 && !strcmp(argv[1], "-l")) { | 120 if (argc == 2 && !strcmp(argv[1], "-l")) { |
121 printPluginPath(true); | |
119 enumeratePlugins(); | 122 enumeratePlugins(); |
120 return 0; | 123 return 0; |
121 } | 124 } |
122 if (argc == 2 && !strcmp(argv[1], "-p")) { | 125 if (argc == 2 && !strcmp(argv[1], "-p")) { |
123 printPluginPath(); | 126 printPluginPath(false); |
124 return 0; | 127 return 0; |
125 } | 128 } |
126 | 129 |
127 cerr << endl << argv[0] << ": Running..." << endl; | 130 cerr << endl << name << ": Running..." << endl; |
128 | 131 |
129 string soname = argv[1]; | 132 string soname = argv[1]; |
130 string plugid = ""; | 133 string plugid = ""; |
134 string output = ""; | |
135 int outputNo = -1; | |
131 string wavname; | 136 string wavname; |
132 if (argc >= 3) wavname = argv[2]; | 137 if (argc >= 3) wavname = argv[2]; |
133 | 138 |
134 int sep = soname.find(":"); | 139 string::size_type sep = soname.find(':'); |
135 if (sep >= 0 && sep < int(soname.length())) { | 140 |
141 if (sep != string::npos) { | |
136 plugid = soname.substr(sep + 1); | 142 plugid = soname.substr(sep + 1); |
137 soname = soname.substr(0, sep); | 143 soname = soname.substr(0, sep); |
138 } | 144 |
139 | 145 sep = plugid.find(':'); |
140 void *libraryHandle = DLOPEN(soname, RTLD_LAZY); | 146 if (sep != string::npos) { |
141 | 147 output = plugid.substr(sep + 1); |
142 if (!libraryHandle) { | 148 plugid = plugid.substr(0, sep); |
143 cerr << argv[0] << ": Failed to open plugin library " | 149 } |
144 << soname << ": " << DLERROR() << endl; | 150 } |
145 return 1; | 151 |
146 } | 152 if (plugid == "") { |
147 | 153 usage(name); |
148 cerr << argv[0] << ": Opened plugin library " << soname << endl; | 154 } |
149 | 155 |
150 VampGetPluginDescriptorFunction fn = (VampGetPluginDescriptorFunction) | 156 if (argc == 4) outputNo = atoi(argv[3]); |
151 DLSYM(libraryHandle, "vampGetPluginDescriptor"); | 157 |
152 | 158 if (output != "" && outputNo != -1) { |
153 if (!fn) { | 159 usage(name); |
154 cerr << argv[0] << ": No Vamp descriptor function in library " | 160 } |
155 << soname << endl; | 161 |
156 DLCLOSE(libraryHandle); | 162 return runPlugin(name, soname, plugid, output, outputNo, wavname); |
157 return 1; | 163 } |
158 } | 164 |
159 | 165 |
160 cerr << argv[0] << ": Found plugin descriptor function" << endl; | 166 int runPlugin(string myname, string soname, string id, |
161 | 167 string output, int outputNo, string wavname) |
162 int index = 0; | 168 { |
163 int plugnumber = -1; | 169 PluginLoader *loader = PluginLoader::getInstance(); |
164 const VampPluginDescriptor *descriptor = 0; | 170 |
165 | 171 PluginLoader::PluginKey key = loader->composePluginKey(soname, id); |
166 while ((descriptor = fn(VAMP_API_VERSION, index))) { | |
167 | |
168 Vamp::PluginHostAdapter plugin(descriptor, 48000); | |
169 cerr << argv[0] << ": Plugin " << (index+1) | |
170 << " is \"" << plugin.getIdentifier() << "\"" << endl; | |
171 | |
172 if (plugin.getIdentifier() == plugid) plugnumber = index; | |
173 | |
174 ++index; | |
175 } | |
176 | |
177 cerr << argv[0] << ": Done\n" << endl; | |
178 | |
179 if (wavname == "") { | |
180 DLCLOSE(libraryHandle); | |
181 return 0; | |
182 } | |
183 | |
184 if (plugnumber < 0) { | |
185 if (plugid != "") { | |
186 cerr << "ERROR: No such plugin as " << plugid << " in library" | |
187 << endl; | |
188 DLCLOSE(libraryHandle); | |
189 return 0; | |
190 } else { | |
191 plugnumber = 0; | |
192 } | |
193 } | |
194 | |
195 descriptor = fn(VAMP_API_VERSION, plugnumber); | |
196 if (!descriptor) { | |
197 DLCLOSE(libraryHandle); | |
198 return 0; | |
199 } | |
200 | 172 |
201 SNDFILE *sndfile; | 173 SNDFILE *sndfile; |
202 SF_INFO sfinfo; | 174 SF_INFO sfinfo; |
203 memset(&sfinfo, 0, sizeof(SF_INFO)); | 175 memset(&sfinfo, 0, sizeof(SF_INFO)); |
204 | 176 |
205 sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo); | 177 sndfile = sf_open(wavname.c_str(), SFM_READ, &sfinfo); |
206 if (!sndfile) { | 178 if (!sndfile) { |
207 cerr << "ERROR: Failed to open input file \"" << wavname << "\": " | 179 cerr << myname << ": ERROR: Failed to open input file \"" |
208 << sf_strerror(sndfile) << endl; | 180 << wavname << "\": " << sf_strerror(sndfile) << endl; |
209 DLCLOSE(libraryHandle); | |
210 return 1; | 181 return 1; |
211 } | 182 } |
212 | 183 |
184 Vamp::Plugin *basePlugin = loader->loadPlugin(key, sfinfo.samplerate); | |
185 if (!basePlugin) { | |
186 cerr << myname << ": ERROR: Failed to load plugin \"" << id | |
187 << "\" from library \"" << soname << "\"" << endl; | |
188 sf_close(sndfile); | |
189 return 1; | |
190 } | |
191 | |
213 Vamp::Plugin *plugin = | 192 Vamp::Plugin *plugin = |
214 new Vamp::PluginInputDomainAdapter | 193 new Vamp::HostExt::PluginChannelAdapter |
215 (new Vamp::PluginHostAdapter(descriptor, sfinfo.samplerate)); | 194 (new Vamp::HostExt::PluginInputDomainAdapter(basePlugin)); |
216 | 195 |
217 cerr << "Running " << plugin->getIdentifier() << "..." << endl; | 196 cerr << "Running plugin: \"" << plugin->getIdentifier() << "\"..." << endl; |
218 | 197 |
219 int blockSize = plugin->getPreferredBlockSize(); | 198 int blockSize = plugin->getPreferredBlockSize(); |
220 int stepSize = plugin->getPreferredStepSize(); | 199 int stepSize = plugin->getPreferredStepSize(); |
221 | |
222 cerr << "Preferred block size = " << blockSize << ", step size = " | |
223 << stepSize << endl; | |
224 | |
225 if (blockSize == 0) blockSize = 1024; | |
226 | |
227 bool rightBlockSize = true; | |
228 | |
229 if (plugin->getInputDomain() == Vamp::Plugin::FrequencyDomain) { | |
230 | |
231 int p = 1, b = blockSize; | |
232 while (b) { | |
233 p <<= 1; | |
234 b >>= 1; | |
235 } | |
236 if (p != blockSize * 2) { | |
237 cerr << "WARNING: Plugin requested non-power-of-two block size of " | |
238 << blockSize << ",\nwhich is not supported by this host. "; | |
239 blockSize = p; | |
240 cerr << "Rounding up to " << blockSize << "." << endl; | |
241 rightBlockSize = false; | |
242 } | |
243 if (stepSize == 0) stepSize = blockSize / 2; | |
244 | |
245 } else { | |
246 | |
247 if (stepSize == 0) stepSize = blockSize; | |
248 } | |
249 | 200 |
250 int channels = sfinfo.channels; | 201 int channels = sfinfo.channels; |
251 | 202 |
252 float *filebuf = new float[blockSize * channels]; | 203 float *filebuf = new float[blockSize * channels]; |
253 float **plugbuf = new float*[channels]; | 204 float **plugbuf = new float*[channels]; |
257 << stepSize << endl; | 208 << stepSize << endl; |
258 | 209 |
259 int minch = plugin->getMinChannelCount(); | 210 int minch = plugin->getMinChannelCount(); |
260 int maxch = plugin->getMaxChannelCount(); | 211 int maxch = plugin->getMaxChannelCount(); |
261 cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl; | 212 cerr << "Plugin accepts " << minch << " -> " << maxch << " channel(s)" << endl; |
213 cerr << "Sound file has " << channels << " (will mix/augment if necessary)" << endl; | |
262 | 214 |
263 Vamp::Plugin::OutputList outputs = plugin->getOutputDescriptors(); | 215 Vamp::Plugin::OutputList outputs = plugin->getOutputDescriptors(); |
264 Vamp::Plugin::OutputDescriptor od; | 216 Vamp::Plugin::OutputDescriptor od; |
265 | 217 |
266 int returnValue = 1; | 218 int returnValue = 1; |
267 | 219 |
268 int output = 0; | 220 if (outputs.empty()) { |
269 if (argc == 4) output = atoi(argv[3]); | 221 cerr << "ERROR: Plugin has no outputs!" << endl; |
270 | 222 goto done; |
271 bool mix = false; | 223 } |
272 | 224 |
273 if (minch > channels || maxch < channels) { | 225 if (outputNo < 0) { |
274 if (minch == 1) { | 226 |
275 cerr << "WARNING: Sound file has " << channels << " channels, mixing down to 1" << endl; | 227 for (size_t oi = 0; oi < outputs.size(); ++oi) { |
276 mix = true; | 228 if (outputs[oi].identifier == output) { |
277 channels = 1; | 229 outputNo = oi; |
278 } else { | 230 break; |
279 cerr << "ERROR: Sound file has " << channels << " channels, out of range for plugin" << endl; | 231 } |
232 } | |
233 | |
234 if (outputNo < 0) { | |
235 cerr << "ERROR: Non-existent output \"" << output << "\" requested" << endl; | |
280 goto done; | 236 goto done; |
281 } | 237 } |
282 } | 238 |
283 | 239 } else { |
284 if (outputs.empty()) { | 240 |
285 cerr << "Plugin has no outputs!" << endl; | 241 if (int(outputs.size()) <= outputNo) { |
286 goto done; | 242 cerr << "ERROR: Output " << outputNo << " requested, but plugin has only " << outputs.size() << " output(s)" << endl; |
287 } | 243 goto done; |
288 | 244 } |
289 if (int(outputs.size()) <= output) { | 245 } |
290 cerr << "Output " << output << " requested, but plugin has only " << outputs.size() << " output(s)" << endl; | 246 |
291 goto done; | 247 od = outputs[outputNo]; |
292 } | 248 cerr << "Output is: \"" << od.identifier << "\"" << endl; |
293 | |
294 od = outputs[output]; | |
295 cerr << "Output is " << od.identifier << endl; | |
296 | 249 |
297 if (!plugin->initialise(channels, stepSize, blockSize)) { | 250 if (!plugin->initialise(channels, stepSize, blockSize)) { |
298 cerr << "ERROR: Plugin initialise (channels = " << channels | 251 cerr << "ERROR: Plugin initialise (channels = " << channels |
299 << ", stepSize = " << stepSize << ", blockSize = " | 252 << ", stepSize = " << stepSize << ", blockSize = " |
300 << blockSize << ") failed." << endl; | 253 << blockSize << ") failed." << endl; |
301 if (!rightBlockSize) { | |
302 cerr << "(Probably because I couldn't provide the plugin's preferred block size.)" << endl; | |
303 } | |
304 goto done; | 254 goto done; |
305 } | 255 } |
306 | 256 |
307 for (size_t i = 0; i < sfinfo.frames; i += stepSize) { | 257 for (size_t i = 0; i < sfinfo.frames; i += stepSize) { |
308 | 258 |
317 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl; | 267 cerr << "ERROR: sf_readf_float failed: " << sf_strerror(sndfile) << endl; |
318 break; | 268 break; |
319 } | 269 } |
320 | 270 |
321 for (int c = 0; c < channels; ++c) { | 271 for (int c = 0; c < channels; ++c) { |
322 for (int j = 0; j < blockSize; ++j) { | 272 int j = 0; |
273 while (j < count) { | |
274 plugbuf[c][j] = filebuf[j * sfinfo.channels + c]; | |
275 ++j; | |
276 } | |
277 while (j < blockSize) { | |
323 plugbuf[c][j] = 0.0f; | 278 plugbuf[c][j] = 0.0f; |
324 } | 279 ++j; |
325 } | |
326 | |
327 for (int j = 0; j < blockSize && j < count; ++j) { | |
328 int tc = 0; | |
329 for (int c = 0; c < sfinfo.channels; ++c) { | |
330 tc = c; | |
331 if (mix) tc = 0; | |
332 plugbuf[tc][j] += filebuf[j * sfinfo.channels + c]; | |
333 } | |
334 if (mix) { | |
335 plugbuf[0][j] /= sfinfo.channels; | |
336 } | 280 } |
337 } | 281 } |
338 | 282 |
339 printFeatures | 283 printFeatures |
340 (i, sfinfo.samplerate, output, plugin->process | 284 (i, sfinfo.samplerate, outputNo, plugin->process |
341 (plugbuf, Vamp::RealTime::frame2RealTime(i, sfinfo.samplerate))); | 285 (plugbuf, Vamp::RealTime::frame2RealTime(i, sfinfo.samplerate))); |
342 } | 286 } |
343 | 287 |
344 printFeatures(sfinfo.frames, sfinfo.samplerate, output, | 288 printFeatures(sfinfo.frames, sfinfo.samplerate, outputNo, |
345 plugin->getRemainingFeatures()); | 289 plugin->getRemainingFeatures()); |
346 | 290 |
347 returnValue = 0; | 291 returnValue = 0; |
348 | 292 |
349 done: | 293 done: |
350 delete plugin; | 294 delete plugin; |
351 | |
352 DLCLOSE(libraryHandle); | |
353 sf_close(sndfile); | 295 sf_close(sndfile); |
354 return returnValue; | 296 return returnValue; |
355 } | 297 } |
356 | 298 |
357 void | 299 void |
358 printPluginPath() | 300 printPluginPath(bool verbose) |
359 { | 301 { |
302 if (verbose) { | |
303 cout << "\nVamp plugin search path: "; | |
304 } | |
305 | |
360 vector<string> path = Vamp::PluginHostAdapter::getPluginPath(); | 306 vector<string> path = Vamp::PluginHostAdapter::getPluginPath(); |
361 for (size_t i = 0; i < path.size(); ++i) { | 307 for (size_t i = 0; i < path.size(); ++i) { |
362 cerr << path[i] << endl; | 308 if (verbose) { |
363 } | 309 cout << "[" << path[i] << "]"; |
310 } else { | |
311 cout << path[i] << endl; | |
312 } | |
313 } | |
314 | |
315 if (verbose) cout << endl; | |
364 } | 316 } |
365 | 317 |
366 void | 318 void |
367 enumeratePlugins() | 319 enumeratePlugins() |
368 { | 320 { |
369 Vamp::PluginLoader loader; | 321 PluginLoader *loader = PluginLoader::getInstance(); |
370 | 322 |
371 cerr << endl << "Vamp plugin libraries found in search path:" << endl; | 323 cout << "\nVamp plugin libraries found in search path:" << endl; |
372 | 324 |
373 std::vector<Vamp::PluginLoader::PluginKey> plugins = loader.listPlugins(); | 325 std::vector<PluginLoader::PluginKey> plugins = loader->listPlugins(); |
374 typedef std::multimap<std::string, Vamp::PluginLoader::PluginKey> | 326 typedef std::multimap<std::string, PluginLoader::PluginKey> |
375 LibraryMap; | 327 LibraryMap; |
376 LibraryMap libraryMap; | 328 LibraryMap libraryMap; |
377 | 329 |
378 for (size_t i = 0; i < plugins.size(); ++i) { | 330 for (size_t i = 0; i < plugins.size(); ++i) { |
379 std::string path = loader.getLibraryPathForPlugin(plugins[i]); | 331 std::string path = loader->getLibraryPathForPlugin(plugins[i]); |
380 libraryMap.insert(LibraryMap::value_type(path, plugins[i])); | 332 libraryMap.insert(LibraryMap::value_type(path, plugins[i])); |
381 } | 333 } |
382 | 334 |
383 std::string prevPath = ""; | 335 std::string prevPath = ""; |
384 int index = 0; | 336 int index = 0; |
385 | 337 |
386 for (LibraryMap::iterator i = libraryMap.begin(); | 338 for (LibraryMap::iterator i = libraryMap.begin(); |
387 i != libraryMap.end(); ++i) { | 339 i != libraryMap.end(); ++i) { |
388 | 340 |
389 std::string path = i->first; | 341 std::string path = i->first; |
390 Vamp::PluginLoader::PluginKey key = i->second; | 342 PluginLoader::PluginKey key = i->second; |
391 | 343 |
392 if (path != prevPath) { | 344 if (path != prevPath) { |
393 prevPath = path; | 345 prevPath = path; |
394 index = 0; | 346 index = 0; |
395 cerr << "\n " << path << ":" << endl; | 347 cout << "\n " << path << ":" << endl; |
396 } | 348 } |
397 | 349 |
398 Vamp::Plugin *plugin = loader.load(key, 48000); | 350 Vamp::Plugin *plugin = loader->loadPlugin(key, 48000); |
399 if (plugin) { | 351 if (plugin) { |
400 | 352 |
401 char c = char('A' + index); | 353 char c = char('A' + index); |
402 if (c > 'Z') c = char('a' + (index - 26)); | 354 if (c > 'Z') c = char('a' + (index - 26)); |
403 | 355 |
404 cerr << " [" << c << "] [v" | 356 cout << " [" << c << "] [v" |
405 << plugin->getVampApiVersion() << "] " | 357 << plugin->getVampApiVersion() << "] " |
406 << plugin->getName() << ", \"" | 358 << plugin->getName() << ", \"" |
407 << plugin->getIdentifier() << "\"" << " [" | 359 << plugin->getIdentifier() << "\"" << " [" |
408 << plugin->getMaker() << "]" << endl; | 360 << plugin->getMaker() << "]" << endl; |
409 | 361 |
410 // cerr << "looking up category for " << key << " ..." << endl; | 362 PluginLoader::PluginCategoryHierarchy category = |
411 Vamp::PluginLoader::PluginCategoryHierarchy category = | 363 loader->getPluginCategory(key); |
412 loader.getPluginCategory(key); | |
413 if (!category.empty()) { | 364 if (!category.empty()) { |
414 cerr << " "; | 365 cout << " "; |
415 for (size_t ci = 0; ci < category.size(); ++ci) { | 366 for (size_t ci = 0; ci < category.size(); ++ci) { |
416 cerr << " > " << category[ci]; | 367 cout << " > " << category[ci]; |
417 } | 368 } |
418 cerr << endl; | 369 cout << endl; |
419 } | 370 } |
420 | 371 |
421 if (plugin->getDescription() != "") { | 372 if (plugin->getDescription() != "") { |
422 cerr << " - " << plugin->getDescription() << endl; | 373 cout << " - " << plugin->getDescription() << endl; |
423 } | 374 } |
424 | 375 |
425 Vamp::Plugin::OutputList outputs = | 376 Vamp::Plugin::OutputList outputs = |
426 plugin->getOutputDescriptors(); | 377 plugin->getOutputDescriptors(); |
427 | 378 |
428 if (outputs.size() > 1) { | 379 if (outputs.size() > 1) { |
429 for (size_t j = 0; j < outputs.size(); ++j) { | 380 for (size_t j = 0; j < outputs.size(); ++j) { |
430 cerr << " (" << j << ") " | 381 cout << " (" << j << ") " |
431 << outputs[j].name << ", \"" | 382 << outputs[j].name << ", \"" |
432 << outputs[j].identifier << "\"" << endl; | 383 << outputs[j].identifier << "\"" << endl; |
433 if (outputs[j].description != "") { | 384 if (outputs[j].description != "") { |
434 cerr << " - " | 385 cout << " - " |
435 << outputs[j].description << endl; | 386 << outputs[j].description << endl; |
436 } | 387 } |
437 } | 388 } |
438 } | 389 } |
439 | 390 |
440 ++index; | 391 ++index; |
441 } | 392 |
442 } | 393 delete plugin; |
443 | 394 } |
444 cerr << endl; | 395 } |
396 | |
397 cout << endl; | |
445 } | 398 } |
446 | 399 |
447 void | 400 void |
448 printFeatures(int frame, int sr, int output, Vamp::Plugin::FeatureSet features) | 401 printFeatures(int frame, int sr, int output, Vamp::Plugin::FeatureSet features) |
449 { | 402 { |