2 Copyright (C) 2000-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "libardour-config.h"
26 #include <sys/types.h>
35 #include "pbd/basename.h"
39 #include <glibmm/miscutils.h>
41 #include "pbd/pathscanner.h"
42 #include "pbd/whitespace.h"
44 #include "ardour/ladspa.h"
45 #include "ardour/session.h"
46 #include "ardour/plugin_manager.h"
47 #include "ardour/plugin.h"
48 #include "ardour/ladspa_plugin.h"
49 #include "ardour/filesystem_paths.h"
52 #include <slv2/slv2.h>
53 #include "ardour/lv2_plugin.h"
57 #include "ardour/vst_plugin.h"
60 #ifdef HAVE_AUDIOUNITS
61 #include "ardour/audio_unit.h"
62 #include <Carbon/Carbon.h>
65 #include "pbd/error.h"
66 #include "pbd/stl_delete.h"
70 using namespace ARDOUR;
74 PluginManager* PluginManager::_manager = 0;
76 PluginManager::PluginManager ()
78 , _ladspa_plugin_info(0)
87 #ifdef HAVE_AUDIOUNITS
88 ProcessSerialNumber psn = { 0, kCurrentProcess };
89 OSStatus returnCode = TransformProcessType(& psn, kProcessTransformToForegroundApplication);
90 if( returnCode != 0) {
91 error << _("Cannot become GUI app") << endmsg;
95 if ((s = getenv ("LADSPA_RDF_PATH"))){
99 if (lrdf_path.length() == 0) {
100 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
103 add_lrdf_data(lrdf_path);
104 add_ladspa_presets();
106 if (Config->get_use_vst()) {
109 #endif /* VST_SUPPORT */
111 if ((s = getenv ("LADSPA_PATH"))) {
115 if ((s = getenv ("VST_PATH"))) {
117 } else if ((s = getenv ("VST_PLUGINS"))) {
125 /* the plugin manager is constructed too early to use Profile */
127 if (getenv ("ARDOUR_SAE")) {
128 ladspa_plugin_whitelist.push_back (1203); // single band parametric
129 ladspa_plugin_whitelist.push_back (1772); // caps compressor
130 ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter
131 ladspa_plugin_whitelist.push_back (1075); // simple RMS expander
132 ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s)
133 ladspa_plugin_whitelist.push_back (1216); // gverb
134 ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter
138 _lv2_world = new LV2World();
141 BootMessage (_("Discovering Plugins"));
145 PluginManager::~PluginManager()
154 PluginManager::refresh ()
161 if (Config->get_use_vst()) {
164 #endif // VST_SUPPORT
165 #ifdef HAVE_AUDIOUNITS
169 PluginListChanged (); /* EMIT SIGNAL */
173 PluginManager::ladspa_refresh ()
175 if (_ladspa_plugin_info)
176 _ladspa_plugin_info->clear ();
178 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
180 static const char *standard_paths[] = {
181 "/usr/local/lib64/ladspa",
182 "/usr/local/lib/ladspa",
185 "/Library/Audio/Plug-Ins/LADSPA",
189 /* allow LADSPA_PATH to augment, not override standard locations */
191 /* Only add standard locations to ladspa_path if it doesn't
192 * already contain them. Check for trailing G_DIR_SEPARATOR too.
196 for (i = 0; standard_paths[i][0]; i++) {
197 size_t found = ladspa_path.find(standard_paths[i]);
198 if (found != ladspa_path.npos) {
199 switch (ladspa_path[found + strlen(standard_paths[i])]) {
203 case G_DIR_SEPARATOR :
204 if (ladspa_path[found + strlen(standard_paths[i]) + 1] == ':' ||
205 ladspa_path[found + strlen(standard_paths[i]) + 1] == '\0') {
210 if (!ladspa_path.empty())
213 ladspa_path += standard_paths[i];
217 ladspa_discover_from_path (ladspa_path);
222 PluginManager::add_ladspa_directory (string path)
224 if (ladspa_discover_from_path (path) == 0) {
232 static bool ladspa_filter (const string& str, void */*arg*/)
234 /* Not a dotfile, has a prefix before a period, suffix is "so" */
236 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
240 PluginManager::ladspa_discover_from_path (string /*path*/)
243 vector<string *> *plugin_objects;
244 vector<string *>::iterator x;
247 plugin_objects = scanner (ladspa_path, ladspa_filter, 0, true, true);
249 if (plugin_objects) {
250 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
251 ladspa_discover (**x);
255 vector_delete (plugin_objects);
259 static bool rdf_filter (const string &str, void* /*arg*/)
261 return str[0] != '.' &&
262 ((str.find(".rdf") == (str.length() - 4)) ||
263 (str.find(".rdfs") == (str.length() - 5)) ||
264 (str.find(".n3") == (str.length() - 3)) ||
265 (str.find(".ttl") == (str.length() - 4)));
269 PluginManager::add_ladspa_presets()
271 add_presets ("ladspa");
275 PluginManager::add_vst_presets()
280 PluginManager::add_presets(string domain)
284 vector<string *> *presets;
285 vector<string *>::iterator x;
288 if ((envvar = getenv ("HOME")) == 0) {
292 string path = string_compose("%1/.%2/rdf", envvar, domain);
293 presets = scanner (path, rdf_filter, 0, true, true);
296 for (x = presets->begin(); x != presets->end (); ++x) {
297 string file = "file:" + **x;
298 if (lrdf_read_file(file.c_str())) {
299 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
304 vector_delete (presets);
308 PluginManager::add_lrdf_data (const string &path)
311 vector<string *>* rdf_files;
312 vector<string *>::iterator x;
314 rdf_files = scanner (path, rdf_filter, 0, true, true);
317 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
318 const string uri(string("file://") + **x);
320 if (lrdf_read_file(uri.c_str())) {
321 warning << "Could not parse rdf file: " << uri << endmsg;
326 vector_delete (rdf_files);
330 PluginManager::ladspa_discover (string path)
333 const LADSPA_Descriptor *descriptor;
334 LADSPA_Descriptor_Function dfunc;
337 if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
338 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
342 dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
344 if ((errstr = dlerror()) != 0) {
345 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
346 error << errstr << endmsg;
351 for (uint32_t i = 0; ; ++i) {
352 if ((descriptor = dfunc (i)) == 0) {
356 if (!ladspa_plugin_whitelist.empty()) {
357 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
362 PluginInfoPtr info(new LadspaPluginInfo);
363 info->name = descriptor->Name;
364 info->category = get_ladspa_category(descriptor->UniqueID);
365 info->creator = descriptor->Maker;
368 info->n_inputs = ChanCount();
369 info->n_outputs = ChanCount();
370 info->type = ARDOUR::LADSPA;
373 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
374 info->unique_id = buf;
376 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
377 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
378 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
379 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
381 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
382 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
387 if(_ladspa_plugin_info->empty()){
388 _ladspa_plugin_info->push_back (info);
391 //Ensure that the plugin is not already in the plugin list.
395 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
396 if(0 == info->unique_id.compare((*i)->unique_id)){
402 _ladspa_plugin_info->push_back (info);
406 // GDB WILL NOT LIKE YOU IF YOU DO THIS
413 PluginManager::get_ladspa_category (uint32_t plugin_id)
416 lrdf_statement pattern;
418 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
419 pattern.subject = buf;
420 pattern.predicate = (char*)RDF_TYPE;
422 pattern.object_type = lrdf_uri;
424 lrdf_statement* matches1 = lrdf_matches (&pattern);
430 pattern.subject = matches1->object;
431 pattern.predicate = (char*)(LADSPA_BASE "hasLabel");
433 pattern.object_type = lrdf_literal;
435 lrdf_statement* matches2 = lrdf_matches (&pattern);
436 lrdf_free_statements(matches1);
442 string label = matches2->object;
443 lrdf_free_statements(matches2);
445 /* Kludge LADSPA class names to be singular and match LV2 class names.
446 This avoids duplicate plugin menus for every class, which is necessary
447 to make the plugin category menu at all usable, but is obviously a
450 In the short term, lrdf could be updated so the labels match and a new
451 release made. To support both specs, we should probably be mapping the
452 URIs to the same category in code and perhaps tweaking that hierarchy
453 dynamically to suit the user. Personally, I (drobilla) think that time
454 is better spent replacing the little-used LRDF.
456 In the longer term, we will abandon LRDF entirely in favour of LV2 and
457 use that class hierarchy. Aside from fixing this problem properly, that
458 will also allow for translated labels. SWH plugins have been LV2 for
459 ages; TAP needs porting. I don't know of anything else with LRDF data.
461 if (label == "Utilities") {
463 } else if (label == "Pitch shifters") {
464 return "Pitch Shifter";
465 } else if (label != "Dynamics" && label != "Chorus"
466 &&label[label.length() - 1] == 's'
467 && label[label.length() - 2] != 's') {
468 return label.substr(0, label.length() - 1);
476 PluginManager::lv2_refresh ()
478 delete _lv2_plugin_info;
479 _lv2_plugin_info = LV2PluginInfo::discover(_lv2_world);
483 #ifdef HAVE_AUDIOUNITS
485 PluginManager::au_refresh ()
487 delete _au_plugin_info;
488 _au_plugin_info = AUPluginInfo::discover();
496 PluginManager::vst_refresh ()
498 if (_vst_plugin_info)
499 _vst_plugin_info->clear ();
501 _vst_plugin_info = new ARDOUR::PluginInfoList();
503 if (vst_path.length() == 0) {
504 vst_path = "/usr/local/lib/vst:/usr/lib/vst";
507 vst_discover_from_path (vst_path);
511 PluginManager::add_vst_directory (string path)
513 if (vst_discover_from_path (path) == 0) {
521 static bool vst_filter (const string& str, void *arg)
523 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
525 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
529 PluginManager::vst_discover_from_path (string path)
532 vector<string *> *plugin_objects;
533 vector<string *>::iterator x;
536 info << "detecting VST plugins along " << path << endmsg;
538 plugin_objects = scanner (vst_path, vst_filter, 0, true, true);
540 if (plugin_objects) {
541 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
546 vector_delete (plugin_objects);
551 PluginManager::vst_discover (string path)
556 if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
557 warning << "Cannot get VST information from " << path << endmsg;
561 if (!finfo->canProcessReplacing) {
562 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time"),
567 PluginInfoPtr info(new VSTPluginInfo);
569 /* what a joke freeware VST is */
571 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
572 info->name = PBD::basename_nosuffix (path);
574 info->name = finfo->name;
578 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
579 info->unique_id = buf;
580 info->category = "VST";
582 info->creator = finfo->creator;
584 info->n_inputs.set_audio (finfo->numInputs);
585 info->n_outputs.set_audio (finfo->numOutputs);
586 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
587 info->type = ARDOUR::VST;
589 _vst_plugin_info->push_back (info);
590 fst_free_info (finfo);
595 #endif // VST_SUPPORT
597 PluginManager::PluginStatusType
598 PluginManager::get_status (const PluginInfoPtr& pi)
600 PluginStatus ps (pi->type, pi->unique_id);
601 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
602 if (i == statuses.end() ) {
610 PluginManager::save_statuses ()
613 sys::path path = user_config_directory();
614 path /= "plugin_statuses";
616 ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
622 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
640 switch ((*i).status) {
653 ofs << (*i).unique_id;;
661 PluginManager::load_statuses ()
663 sys::path path = user_config_directory();
664 path /= "plugin_statuses";
665 ifstream ifs (path.to_string().c_str());
675 PluginStatusType status;
692 /* rest of the line is the plugin ID */
694 ifs.getline (buf, sizeof (buf), '\n');
699 if (sstatus == "Normal") {
701 } else if (sstatus == "Favorite") {
703 } else if (sstatus == "Hidden") {
706 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
712 if (stype == "LADSPA") {
714 } else if (stype == "AudioUnit") {
716 } else if (stype == "LV2") {
718 } else if (stype == "VST") {
721 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
727 strip_whitespace_edges (id);
728 set_status (type, id, status);
735 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
737 PluginStatus ps (t, id, status);
740 if (status == Normal) {
744 pair<PluginStatusList::iterator, bool> res = statuses.insert (ps);
745 //cerr << "Added " << t << " " << id << " " << status << " success ? " << res.second << endl;
748 ARDOUR::PluginInfoList&
749 PluginManager::vst_plugin_info ()
752 if (!_vst_plugin_info)
754 return *_vst_plugin_info;
756 return _empty_plugin_info;
760 ARDOUR::PluginInfoList&
761 PluginManager::ladspa_plugin_info ()
763 if (!_ladspa_plugin_info)
765 return *_ladspa_plugin_info;
768 ARDOUR::PluginInfoList&
769 PluginManager::lv2_plugin_info ()
772 if (!_lv2_plugin_info)
774 return *_lv2_plugin_info;
776 return _empty_plugin_info;
780 ARDOUR::PluginInfoList&
781 PluginManager::au_plugin_info ()
783 #ifdef HAVE_AUDIOUNITS
784 if (!_au_plugin_info)
786 return *_au_plugin_info;
788 return _empty_plugin_info;