Mercurial > hg > vamp-plugin-sdk
comparison host/vamp-simple-host.cpp @ 40:ae3e47e76d2d
* Add plugin path traversal and plugin listing option to vamp-simple-host
* Add more notes on plugin lookup and categorisation
author | cannam |
---|---|
date | Mon, 09 Oct 2006 12:45:14 +0000 |
parents | 13eae6cc6bac |
children | 1eb2419fc326 |
comparison
equal
deleted
inserted
replaced
39:46c39790588b | 40:ae3e47e76d2d |
---|---|
38 #include "PluginHostAdapter.h" | 38 #include "PluginHostAdapter.h" |
39 #include "vamp.h" | 39 #include "vamp.h" |
40 | 40 |
41 #include <iostream> | 41 #include <iostream> |
42 #include <sndfile.h> | 42 #include <sndfile.h> |
43 #include <dirent.h> // POSIX directory open and read | |
43 | 44 |
44 #include "system.h" | 45 #include "system.h" |
45 | 46 |
46 #include <cmath> | 47 #include <cmath> |
47 | 48 |
49 using std::cerr; | 50 using std::cerr; |
50 using std::endl; | 51 using std::endl; |
51 using std::string; | 52 using std::string; |
52 using std::vector; | 53 using std::vector; |
53 | 54 |
55 | |
56 | |
54 void printFeatures(int, int, int, Vamp::Plugin::FeatureSet); | 57 void printFeatures(int, int, int, Vamp::Plugin::FeatureSet); |
55 void transformInput(float *, size_t); | 58 void transformInput(float *, size_t); |
56 void fft(unsigned int, bool, double *, double *, double *, double *); | 59 void fft(unsigned int, bool, double *, double *, double *, double *); |
60 void printPluginPath(); | |
61 | |
62 #ifdef HAVE_OPENDIR | |
63 void enumeratePlugins(); | |
64 #endif | |
57 | 65 |
58 /* | 66 /* |
59 A very simple Vamp plugin host. Given the name of a plugin | 67 A very simple Vamp plugin host. Given the name of a plugin |
60 library and the name of a sound file on the command line, it loads | 68 library and the name of a sound file on the command line, it loads |
61 the first plugin in the library and runs it on the sound file, | 69 the first plugin in the library and runs it on the sound file, |
63 */ | 71 */ |
64 | 72 |
65 int main(int argc, char **argv) | 73 int main(int argc, char **argv) |
66 { | 74 { |
67 if (argc < 2 || argc > 4) { | 75 if (argc < 2 || argc > 4) { |
68 cerr << "Usage: " << argv[0] << " pluginlibrary.so[:plugin] [file.wav] [outputno]" << endl; | 76 char *scooter = argv[0]; |
77 char *name = 0; | |
78 while (scooter && *scooter) { | |
79 if (*scooter == '/' || *scooter == '\\') name = ++scooter; | |
80 else ++scooter; | |
81 } | |
82 if (!name || !*name) name = argv[0]; | |
83 cerr << "\n" | |
84 << name << ": A simple Vamp plugin host.\n\n" | |
85 "Centre for Digital Music, Queen Mary, University of London.\n" | |
86 "Copyright 2006 Chris Cannam and QMUL.\n" | |
87 "Freely redistributable; published under a BSD-style license.\n\n" | |
88 "Usage:\n\n" | |
89 " " << name << " pluginlibrary." << PLUGIN_SUFFIX << "\n\n" | |
90 " -- Load \"pluginlibrary\" and list the Vamp plugins it contains.\n\n" | |
91 " " << name << " pluginlibrary." << PLUGIN_SUFFIX << ":plugin file.wav [outputno]\n\n" | |
92 " -- Load plugin id \"plugin\" from \"pluginlibrary\" and run it on the\n" | |
93 " audio data in \"file.wav\", dumping the output from \"outputno\"\n" | |
94 " (default 0) to standard output.\n\n" | |
95 #ifdef HAVE_OPENDIR | |
96 " " << name << " -l\n\n" | |
97 " -- List the plugin libraries and Vamp plugins in the plugin search path.\n\n" | |
98 #endif | |
99 " " << name << " -p\n\n" | |
100 " -- Print out the Vamp plugin search path.\n\n" | |
101 "Note that this host does not use the plugin search path when loading a plugin.\nIf a plugin library is specified, it should be with a full file path.\n" | |
102 << endl; | |
69 return 2; | 103 return 2; |
70 } | 104 } |
71 | 105 |
106 if (argc == 2 && !strcmp(argv[1], "-l")) { | |
107 #ifdef HAVE_OPENDIR | |
108 enumeratePlugins(); | |
109 #endif | |
110 return 0; | |
111 } | |
112 if (argc == 2 && !strcmp(argv[1], "-p")) { | |
113 printPluginPath(); | |
114 return 0; | |
115 } | |
116 | |
72 cerr << endl << argv[0] << ": Running..." << endl; | 117 cerr << endl << argv[0] << ": Running..." << endl; |
73 | |
74 cerr << endl << "Vamp path is set to:" << endl; | |
75 vector<string> path = Vamp::PluginHostAdapter::getPluginPath(); | |
76 for (size_t i = 0; i < path.size(); ++i) { | |
77 cerr << "\t" << path[i] << endl; | |
78 } | |
79 cerr << "(This program doesn't use the path; just printing it for information)" << endl << endl; | |
80 | 118 |
81 string soname = argv[1]; | 119 string soname = argv[1]; |
82 string plugname = ""; | 120 string plugname = ""; |
83 string wavname; | 121 string wavname; |
84 if (argc >= 3) wavname = argv[2]; | 122 if (argc >= 3) wavname = argv[2]; |
85 | 123 |
86 int sep = soname.find(":"); | 124 int sep = soname.find(":"); |
87 if (sep >= 0 && sep < soname.length()) { | 125 if (sep >= 0 && sep < int(soname.length())) { |
88 plugname = soname.substr(sep + 1); | 126 plugname = soname.substr(sep + 1); |
89 soname = soname.substr(0, sep); | 127 soname = soname.substr(0, sep); |
90 } | 128 } |
91 | 129 |
92 void *libraryHandle = DLOPEN(soname, RTLD_LAZY); | 130 void *libraryHandle = DLOPEN(soname, RTLD_LAZY); |
296 | 334 |
297 DLCLOSE(libraryHandle); | 335 DLCLOSE(libraryHandle); |
298 sf_close(sndfile); | 336 sf_close(sndfile); |
299 return returnValue; | 337 return returnValue; |
300 } | 338 } |
339 | |
340 void | |
341 printPluginPath() | |
342 { | |
343 vector<string> path = Vamp::PluginHostAdapter::getPluginPath(); | |
344 for (size_t i = 0; i < path.size(); ++i) { | |
345 cerr << path[i] << endl; | |
346 } | |
347 } | |
348 | |
349 #ifdef HAVE_OPENDIR | |
350 | |
351 void | |
352 enumeratePlugins() | |
353 { | |
354 cerr << endl << "Vamp plugin libraries found in search path:" << endl; | |
355 vector<string> path = Vamp::PluginHostAdapter::getPluginPath(); | |
356 for (size_t i = 0; i < path.size(); ++i) { | |
357 cerr << "\n" << path[i] << ":" << endl; | |
358 DIR *d = opendir(path[i].c_str()); | |
359 if (!d) { | |
360 perror("Failed to open directory"); | |
361 continue; | |
362 } | |
363 struct dirent *e = 0; | |
364 while ((e = readdir(d))) { | |
365 if (!(e->d_type & DT_REG)) continue; | |
366 int len = strlen(e->d_name); | |
367 if (len < int(strlen(PLUGIN_SUFFIX) + 2) || | |
368 e->d_name[len - strlen(PLUGIN_SUFFIX) - 1] != '.' || | |
369 strcmp(e->d_name + len - strlen(PLUGIN_SUFFIX), PLUGIN_SUFFIX)) { | |
370 continue; | |
371 } | |
372 char *fp = new char[path[i].length() + len + 3]; | |
373 sprintf(fp, "%s/%s", path[i].c_str(), e->d_name); | |
374 void *handle = DLOPEN(string(fp), RTLD_LAZY); | |
375 if (handle) { | |
376 VampGetPluginDescriptorFunction fn = | |
377 (VampGetPluginDescriptorFunction)DLSYM | |
378 (handle, "vampGetPluginDescriptor"); | |
379 if (fn) { | |
380 cerr << "\n " << e->d_name << ":" << endl; | |
381 int index = 0; | |
382 const VampPluginDescriptor *descriptor = 0; | |
383 while ((descriptor = fn(index))) { | |
384 Vamp::PluginHostAdapter plugin(descriptor, 48000); | |
385 cerr << " [" << char('A' + index) << "] " | |
386 << plugin.getDescription() | |
387 << ", \"" << plugin.getName() << "\"" | |
388 << " [" << plugin.getMaker() | |
389 << "]" << std::endl; | |
390 Vamp::Plugin::OutputList outputs = | |
391 plugin.getOutputDescriptors(); | |
392 if (outputs.size() > 1) { | |
393 for (size_t j = 0; j < outputs.size(); ++j) { | |
394 cerr << " (" << j << ") " | |
395 << outputs[j].description << endl; | |
396 } | |
397 } | |
398 ++index; | |
399 } | |
400 } | |
401 DLCLOSE(handle); | |
402 } | |
403 } | |
404 closedir(d); | |
405 } | |
406 cerr << endl; | |
407 } | |
408 | |
409 #endif | |
410 | |
301 | 411 |
302 void | 412 void |
303 printFeatures(int frame, int sr, int output, Vamp::Plugin::FeatureSet features) | 413 printFeatures(int frame, int sr, int output, Vamp::Plugin::FeatureSet features) |
304 { | 414 { |
305 for (unsigned int i = 0; i < features[output].size(); ++i) { | 415 for (unsigned int i = 0; i < features[output].size(); ++i) { |