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>
33 #ifdef WINDOWS_VST_SUPPORT
35 #include "pbd/basename.h"
37 #endif // WINDOWS_VST_SUPPORT
40 #include "ardour/linux_vst_support.h"
41 #include "pbd/basename.h"
43 #endif //LXVST_SUPPORT
45 #include <glibmm/miscutils.h>
47 #include "pbd/pathscanner.h"
48 #include "pbd/whitespace.h"
50 #include "ardour/debug.h"
51 #include "ardour/filesystem_paths.h"
52 #include "ardour/ladspa.h"
53 #include "ardour/ladspa_plugin.h"
54 #include "ardour/plugin.h"
55 #include "ardour/plugin_manager.h"
56 #include "ardour/session.h"
59 #include "ardour/lv2_plugin.h"
62 #ifdef WINDOWS_VST_SUPPORT
63 #include "ardour/windows_vst_plugin.h"
67 #include "ardour/lxvst_plugin.h"
70 #ifdef AUDIOUNIT_SUPPORT
71 #include "ardour/audio_unit.h"
72 #include <Carbon/Carbon.h>
75 #include "pbd/error.h"
76 #include "pbd/stl_delete.h"
80 using namespace ARDOUR;
84 PluginManager* PluginManager::_instance = 0;
87 PluginManager::instance()
90 _instance = new PluginManager;
95 PluginManager::PluginManager ()
96 : _windows_vst_plugin_info(0)
97 , _lxvst_plugin_info(0)
98 , _ladspa_plugin_info(0)
107 if ((s = getenv ("LADSPA_RDF_PATH"))){
111 if (lrdf_path.length() == 0) {
112 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
115 add_lrdf_data(lrdf_path);
116 add_ladspa_presets();
117 #ifdef WINDOWS_VST_SUPPORT
118 if (Config->get_use_windows_vst ()) {
119 add_windows_vst_presets ();
121 #endif /* WINDOWS_VST_SUPPORT */
124 if (Config->get_use_lxvst()) {
127 #endif /* Native LinuxVST support*/
129 if ((s = getenv ("LADSPA_PATH"))) {
133 if ((s = getenv ("VST_PATH"))) {
134 windows_vst_path = s;
135 } else if ((s = getenv ("VST_PLUGINS"))) {
136 windows_vst_path = s;
139 if ((s = getenv ("LXVST_PATH"))) {
141 } else if ((s = getenv ("LXVST_PLUGINS"))) {
145 if (_instance == 0) {
149 /* the plugin manager is constructed too early to use Profile */
151 if (getenv ("ARDOUR_SAE")) {
152 ladspa_plugin_whitelist.push_back (1203); // single band parametric
153 ladspa_plugin_whitelist.push_back (1772); // caps compressor
154 ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter
155 ladspa_plugin_whitelist.push_back (1075); // simple RMS expander
156 ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s)
157 ladspa_plugin_whitelist.push_back (1216); // gverb
158 ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter
161 BootMessage (_("Discovering Plugins"));
165 PluginManager::~PluginManager()
171 PluginManager::refresh ()
173 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
179 #ifdef WINDOWS_VST_SUPPORT
180 if (Config->get_use_windows_vst()) {
181 windows_vst_refresh ();
183 #endif // WINDOWS_VST_SUPPORT
186 if(Config->get_use_lxvst()) {
189 #endif //Native linuxVST SUPPORT
191 #ifdef AUDIOUNIT_SUPPORT
195 PluginListChanged (); /* EMIT SIGNAL */
199 PluginManager::ladspa_refresh ()
201 if (_ladspa_plugin_info)
202 _ladspa_plugin_info->clear ();
204 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
206 static const char *standard_paths[] = {
207 "/usr/local/lib64/ladspa",
208 "/usr/local/lib/ladspa",
211 "/Library/Audio/Plug-Ins/LADSPA",
215 /* allow LADSPA_PATH to augment, not override standard locations */
217 /* Only add standard locations to ladspa_path if it doesn't
218 * already contain them. Check for trailing G_DIR_SEPARATOR too.
222 for (i = 0; standard_paths[i][0]; i++) {
223 size_t found = ladspa_path.find(standard_paths[i]);
224 if (found != ladspa_path.npos) {
225 switch (ladspa_path[found + strlen(standard_paths[i])]) {
229 case G_DIR_SEPARATOR :
230 if (ladspa_path[found + strlen(standard_paths[i]) + 1] == ':' ||
231 ladspa_path[found + strlen(standard_paths[i]) + 1] == '\0') {
236 if (!ladspa_path.empty())
239 ladspa_path += standard_paths[i];
243 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_path));
245 ladspa_discover_from_path (ladspa_path);
250 PluginManager::add_ladspa_directory (string path)
252 if (ladspa_discover_from_path (path) == 0) {
260 static bool ladspa_filter (const string& str, void */*arg*/)
262 /* Not a dotfile, has a prefix before a period, suffix is "so" */
264 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
268 PluginManager::ladspa_discover_from_path (string /*path*/)
271 vector<string *> *plugin_objects;
272 vector<string *>::iterator x;
275 plugin_objects = scanner (ladspa_path, ladspa_filter, 0, false, true);
277 if (plugin_objects) {
278 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
279 ladspa_discover (**x);
283 vector_delete (plugin_objects);
287 static bool rdf_filter (const string &str, void* /*arg*/)
289 return str[0] != '.' &&
290 ((str.find(".rdf") == (str.length() - 4)) ||
291 (str.find(".rdfs") == (str.length() - 5)) ||
292 (str.find(".n3") == (str.length() - 3)) ||
293 (str.find(".ttl") == (str.length() - 4)));
297 PluginManager::add_ladspa_presets()
299 add_presets ("ladspa");
303 PluginManager::add_windows_vst_presets()
305 add_presets ("windows-vst");
309 PluginManager::add_lxvst_presets()
311 add_presets ("lxvst");
315 PluginManager::add_presets(string domain)
319 vector<string *> *presets;
320 vector<string *>::iterator x;
323 if ((envvar = getenv ("HOME")) == 0) {
327 string path = string_compose("%1/.%2/rdf", envvar, domain);
328 presets = scanner (path, rdf_filter, 0, false, true);
331 for (x = presets->begin(); x != presets->end (); ++x) {
332 string file = "file:" + **x;
333 if (lrdf_read_file(file.c_str())) {
334 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
339 vector_delete (presets);
343 PluginManager::add_lrdf_data (const string &path)
346 vector<string *>* rdf_files;
347 vector<string *>::iterator x;
349 rdf_files = scanner (path, rdf_filter, 0, false, true);
352 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
353 const string uri(string("file://") + **x);
355 if (lrdf_read_file(uri.c_str())) {
356 warning << "Could not parse rdf file: " << uri << endmsg;
361 vector_delete (rdf_files);
365 PluginManager::ladspa_discover (string path)
368 const LADSPA_Descriptor *descriptor;
369 LADSPA_Descriptor_Function dfunc;
372 if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
373 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
377 dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
379 if ((errstr = dlerror()) != 0) {
380 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
381 error << errstr << endmsg;
386 for (uint32_t i = 0; ; ++i) {
387 if ((descriptor = dfunc (i)) == 0) {
391 if (!ladspa_plugin_whitelist.empty()) {
392 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
397 PluginInfoPtr info(new LadspaPluginInfo);
398 info->name = descriptor->Name;
399 info->category = get_ladspa_category(descriptor->UniqueID);
400 info->creator = descriptor->Maker;
403 info->n_inputs = ChanCount();
404 info->n_outputs = ChanCount();
405 info->type = ARDOUR::LADSPA;
408 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
409 info->unique_id = buf;
411 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
412 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
413 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
414 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
416 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
417 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
422 if(_ladspa_plugin_info->empty()){
423 _ladspa_plugin_info->push_back (info);
426 //Ensure that the plugin is not already in the plugin list.
430 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
431 if(0 == info->unique_id.compare((*i)->unique_id)){
437 _ladspa_plugin_info->push_back (info);
441 // GDB WILL NOT LIKE YOU IF YOU DO THIS
448 PluginManager::get_ladspa_category (uint32_t plugin_id)
451 lrdf_statement pattern;
453 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
454 pattern.subject = buf;
455 pattern.predicate = (char*)RDF_TYPE;
457 pattern.object_type = lrdf_uri;
459 lrdf_statement* matches1 = lrdf_matches (&pattern);
465 pattern.subject = matches1->object;
466 pattern.predicate = (char*)(LADSPA_BASE "hasLabel");
468 pattern.object_type = lrdf_literal;
470 lrdf_statement* matches2 = lrdf_matches (&pattern);
471 lrdf_free_statements(matches1);
477 string label = matches2->object;
478 lrdf_free_statements(matches2);
480 /* Kludge LADSPA class names to be singular and match LV2 class names.
481 This avoids duplicate plugin menus for every class, which is necessary
482 to make the plugin category menu at all usable, but is obviously a
485 In the short term, lrdf could be updated so the labels match and a new
486 release made. To support both specs, we should probably be mapping the
487 URIs to the same category in code and perhaps tweaking that hierarchy
488 dynamically to suit the user. Personally, I (drobilla) think that time
489 is better spent replacing the little-used LRDF.
491 In the longer term, we will abandon LRDF entirely in favour of LV2 and
492 use that class hierarchy. Aside from fixing this problem properly, that
493 will also allow for translated labels. SWH plugins have been LV2 for
494 ages; TAP needs porting. I don't know of anything else with LRDF data.
496 if (label == "Utilities") {
498 } else if (label == "Pitch shifters") {
499 return "Pitch Shifter";
500 } else if (label != "Dynamics" && label != "Chorus"
501 &&label[label.length() - 1] == 's'
502 && label[label.length() - 2] != 's') {
503 return label.substr(0, label.length() - 1);
511 PluginManager::lv2_refresh ()
513 delete _lv2_plugin_info;
514 _lv2_plugin_info = LV2PluginInfo::discover();
518 #ifdef AUDIOUNIT_SUPPORT
520 PluginManager::au_refresh ()
522 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
523 delete _au_plugin_info;
524 _au_plugin_info = AUPluginInfo::discover();
529 #ifdef WINDOWS_VST_SUPPORT
532 PluginManager::windows_vst_refresh ()
534 if (_windows_vst_plugin_info) {
535 _windows_vst_plugin_info->clear ();
537 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
540 if (windows_vst_path.length() == 0) {
541 windows_vst_path = "/usr/local/lib/vst:/usr/lib/vst";
544 windows_vst_discover_from_path (windows_vst_path);
548 PluginManager::add_windows_vst_directory (string path)
550 if (windows_vst_discover_from_path (path) == 0) {
551 windows_vst_path += ':';
552 windows_vst_path += path;
558 static bool windows_vst_filter (const string& str, void *arg)
560 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
562 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
566 PluginManager::windows_vst_discover_from_path (string path)
569 vector<string *> *plugin_objects;
570 vector<string *>::iterator x;
573 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
575 plugin_objects = scanner (windows_vst_path, windows_vst_filter, 0, false, true);
577 if (plugin_objects) {
578 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
579 windows_vst_discover (**x);
583 vector_delete (plugin_objects);
588 PluginManager::windows_vst_discover (string path)
593 if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
594 warning << "Cannot get Windows VST information from " << path << endmsg;
598 if (!finfo->canProcessReplacing) {
599 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time"),
604 PluginInfoPtr info (new WindowsVSTPluginInfo);
606 /* what a joke freeware VST is */
608 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
609 info->name = PBD::basename_nosuffix (path);
611 info->name = finfo->name;
615 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
616 info->unique_id = buf;
617 info->category = "VST";
619 info->creator = finfo->creator;
621 info->n_inputs.set_audio (finfo->numInputs);
622 info->n_outputs.set_audio (finfo->numOutputs);
623 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
624 info->type = ARDOUR::Windows_VST;
626 _windows_vst_plugin_info->push_back (info);
627 fst_free_info (finfo);
632 #endif // WINDOWS_VST_SUPPORT
637 PluginManager::lxvst_refresh ()
639 if (_lxvst_plugin_info) {
640 _lxvst_plugin_info->clear ();
642 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
645 if (lxvst_path.length() == 0) {
646 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst";
649 lxvst_discover_from_path (lxvst_path);
653 PluginManager::add_lxvst_directory (string path)
655 if (lxvst_discover_from_path (path) == 0) {
663 static bool lxvst_filter (const string& str, void *)
665 /* Not a dotfile, has a prefix before a period, suffix is "so" */
667 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
671 PluginManager::lxvst_discover_from_path (string path)
674 vector<string *> *plugin_objects;
675 vector<string *>::iterator x;
678 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
680 plugin_objects = scanner (lxvst_path, lxvst_filter, 0, false, true);
682 if (plugin_objects) {
683 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
684 lxvst_discover (**x);
688 vector_delete (plugin_objects);
693 PluginManager::lxvst_discover (string path)
698 if ((finfo = vstfx_get_info (const_cast<char *> (path.c_str()))) == 0) {
702 if (!finfo->canProcessReplacing) {
703 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in ardour at this time"),
708 PluginInfoPtr info(new LXVSTPluginInfo);
710 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
711 info->name = PBD::basename_nosuffix (path);
713 info->name = finfo->name;
717 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
718 info->unique_id = buf;
719 info->category = "linuxVSTs";
721 info->creator = finfo->creator;
723 info->n_inputs.set_audio (finfo->numInputs);
724 info->n_outputs.set_audio (finfo->numOutputs);
725 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
726 info->type = ARDOUR::LXVST;
728 /* Make sure we don't find the same plugin in more than one place along
729 the LXVST_PATH We can't use a simple 'find' because the path is included
730 in the PluginInfo, and that is the one thing we can be sure MUST be
731 different if a duplicate instance is found. So we just compare the type
732 and unique ID (which for some VSTs isn't actually unique...)
735 if (!_lxvst_plugin_info->empty()) {
736 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
737 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
738 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
739 vstfx_free_info(finfo);
745 _lxvst_plugin_info->push_back (info);
746 vstfx_free_info (finfo);
751 #endif // LXVST_SUPPORT
754 PluginManager::PluginStatusType
755 PluginManager::get_status (const PluginInfoPtr& pi)
757 PluginStatus ps (pi->type, pi->unique_id);
758 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
759 if (i == statuses.end() ) {
767 PluginManager::save_statuses ()
770 sys::path path = user_config_directory();
771 path /= "plugin_statuses";
773 ofs.open (path.to_string().c_str(), ios_base::openmode (ios::out|ios::trunc));
779 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
791 ofs << "Windows-VST";
800 switch ((*i).status) {
813 ofs << (*i).unique_id;;
821 PluginManager::load_statuses ()
823 sys::path path = user_config_directory();
824 path /= "plugin_statuses";
825 ifstream ifs (path.to_string().c_str());
835 PluginStatusType status;
852 /* rest of the line is the plugin ID */
854 ifs.getline (buf, sizeof (buf), '\n');
859 if (sstatus == "Normal") {
861 } else if (sstatus == "Favorite") {
863 } else if (sstatus == "Hidden") {
866 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
872 if (stype == "LADSPA") {
874 } else if (stype == "AudioUnit") {
876 } else if (stype == "LV2") {
878 } else if (stype == "Windows-VST") {
880 } else if (stype == "LXVST") {
883 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
889 strip_whitespace_edges (id);
890 set_status (type, id, status);
897 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
899 PluginStatus ps (t, id, status);
902 if (status == Normal) {
906 statuses.insert (ps);
909 ARDOUR::PluginInfoList&
910 PluginManager::windows_vst_plugin_info ()
912 #ifdef WINDOWS_VST_SUPPORT
913 if (!_windows_vst_plugin_info) {
914 windows_vst_refresh ();
916 return *_windows_vst_plugin_info;
918 return _empty_plugin_info;
922 ARDOUR::PluginInfoList&
923 PluginManager::lxvst_plugin_info ()
926 if (!_lxvst_plugin_info)
928 return *_lxvst_plugin_info;
930 return _empty_plugin_info;
934 ARDOUR::PluginInfoList&
935 PluginManager::ladspa_plugin_info ()
937 if (!_ladspa_plugin_info)
939 return *_ladspa_plugin_info;
942 ARDOUR::PluginInfoList&
943 PluginManager::lv2_plugin_info ()
946 if (!_lv2_plugin_info)
948 return *_lv2_plugin_info;
950 return _empty_plugin_info;
954 ARDOUR::PluginInfoList&
955 PluginManager::au_plugin_info ()
957 #ifdef AUDIOUNIT_SUPPORT
958 if (!_au_plugin_info)
960 return *_au_plugin_info;
962 return _empty_plugin_info;