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 #ifdef WINDOWS_VST_SUPPORT
36 #include "ardour/vst_info_file.h"
38 #include "pbd/basename.h"
40 #endif // WINDOWS_VST_SUPPORT
43 #include "ardour/vst_info_file.h"
44 #include "ardour/linux_vst_support.h"
45 #include "pbd/basename.h"
47 #endif //LXVST_SUPPORT
49 #include <glibmm/miscutils.h>
50 #include <glibmm/pattern.h>
52 #include "pbd/pathscanner.h"
53 #include "pbd/whitespace.h"
54 #include "pbd/file_utils.h"
56 #include "ardour/debug.h"
57 #include "ardour/filesystem_paths.h"
58 #include "ardour/ladspa.h"
59 #include "ardour/ladspa_plugin.h"
60 #include "ardour/plugin.h"
61 #include "ardour/plugin_manager.h"
62 #include "ardour/rc_configuration.h"
64 #include "ardour/ladspa_search_path.h"
67 #include "ardour/lv2_plugin.h"
70 #ifdef WINDOWS_VST_SUPPORT
71 #include "ardour/windows_vst_plugin.h"
75 #include "ardour/lxvst_plugin.h"
78 #ifdef AUDIOUNIT_SUPPORT
79 #include "ardour/audio_unit.h"
80 #include <Carbon/Carbon.h>
83 #include "pbd/error.h"
84 #include "pbd/stl_delete.h"
88 #include "ardour/debug.h"
90 using namespace ARDOUR;
94 PluginManager* PluginManager::_instance = 0;
97 PluginManager::instance()
100 _instance = new PluginManager;
105 PluginManager::PluginManager ()
106 : _windows_vst_plugin_info(0)
107 , _lxvst_plugin_info(0)
108 , _ladspa_plugin_info(0)
109 , _lv2_plugin_info(0)
117 if ((s = getenv ("LADSPA_RDF_PATH"))){
121 if (lrdf_path.length() == 0) {
122 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
125 add_lrdf_data(lrdf_path);
126 add_ladspa_presets();
127 #ifdef WINDOWS_VST_SUPPORT
128 if (Config->get_use_windows_vst ()) {
129 add_windows_vst_presets ();
131 #endif /* WINDOWS_VST_SUPPORT */
134 if (Config->get_use_lxvst()) {
137 #endif /* Native LinuxVST support*/
139 if ((s = getenv ("VST_PATH"))) {
140 windows_vst_path = s;
141 } else if ((s = getenv ("VST_PLUGINS"))) {
142 windows_vst_path = s;
145 if ((s = getenv ("LXVST_PATH"))) {
147 } else if ((s = getenv ("LXVST_PLUGINS"))) {
151 if (_instance == 0) {
155 /* the plugin manager is constructed too early to use Profile */
157 if (getenv ("ARDOUR_SAE")) {
158 ladspa_plugin_whitelist.push_back (1203); // single band parametric
159 ladspa_plugin_whitelist.push_back (1772); // caps compressor
160 ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter
161 ladspa_plugin_whitelist.push_back (1075); // simple RMS expander
162 ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s)
163 ladspa_plugin_whitelist.push_back (1216); // gverb
164 ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter
167 BootMessage (_("Discovering Plugins"));
171 PluginManager::~PluginManager()
177 PluginManager::refresh ()
179 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
180 BootMessage (_("Discovering Plugins"));
186 #ifdef WINDOWS_VST_SUPPORT
187 if (Config->get_use_windows_vst()) {
188 windows_vst_refresh ();
190 #endif // WINDOWS_VST_SUPPORT
193 if(Config->get_use_lxvst()) {
196 #endif //Native linuxVST SUPPORT
198 #ifdef AUDIOUNIT_SUPPORT
202 PluginListChanged (); /* EMIT SIGNAL */
203 PluginScanMessage(X_("closeme"), "");
207 PluginManager::ladspa_refresh ()
209 if (_ladspa_plugin_info) {
210 _ladspa_plugin_info->clear ();
212 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
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.
221 vector<string> ladspa_modules;
223 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
225 Glib::PatternSpec so_extension_pattern("*.so");
226 Glib::PatternSpec dylib_extension_pattern("*.dylib");
227 Glib::PatternSpec dll_extension_pattern("*.dll");
229 find_matching_files_in_search_path (ladspa_search_path (),
230 so_extension_pattern, ladspa_modules);
232 find_matching_files_in_search_path (ladspa_search_path (),
233 dylib_extension_pattern, ladspa_modules);
235 find_matching_files_in_search_path (ladspa_search_path (),
236 dll_extension_pattern, ladspa_modules);
238 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
239 ARDOUR::PluginScanMessage(_("LADSPA"), *i);
240 ladspa_discover (*i);
244 static bool rdf_filter (const string &str, void* /*arg*/)
246 return str[0] != '.' &&
247 ((str.find(".rdf") == (str.length() - 4)) ||
248 (str.find(".rdfs") == (str.length() - 5)) ||
249 (str.find(".n3") == (str.length() - 3)) ||
250 (str.find(".ttl") == (str.length() - 4)));
254 PluginManager::add_ladspa_presets()
256 add_presets ("ladspa");
260 PluginManager::add_windows_vst_presets()
262 add_presets ("windows-vst");
266 PluginManager::add_lxvst_presets()
268 add_presets ("lxvst");
272 PluginManager::add_presets(string domain)
276 vector<string *> *presets;
277 vector<string *>::iterator x;
280 if ((envvar = getenv ("HOME")) == 0) {
284 string path = string_compose("%1/.%2/rdf", envvar, domain);
285 presets = scanner (path, rdf_filter, 0, false, true);
288 for (x = presets->begin(); x != presets->end (); ++x) {
289 string file = "file:" + **x;
290 if (lrdf_read_file(file.c_str())) {
291 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
295 vector_delete (presets);
301 PluginManager::add_lrdf_data (const string &path)
305 vector<string *>* rdf_files;
306 vector<string *>::iterator x;
308 rdf_files = scanner (path, rdf_filter, 0, false, true);
311 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
312 const string uri(string("file://") + **x);
314 if (lrdf_read_file(uri.c_str())) {
315 warning << "Could not parse rdf file: " << uri << endmsg;
319 vector_delete (rdf_files);
325 PluginManager::ladspa_discover (string path)
327 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
329 Glib::Module module(path);
330 const LADSPA_Descriptor *descriptor;
331 LADSPA_Descriptor_Function dfunc;
335 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
336 path, Glib::Module::get_last_error()) << endmsg;
341 if (!module.get_symbol("ladspa_descriptor", func)) {
342 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
343 error << Glib::Module::get_last_error() << endmsg;
347 dfunc = (LADSPA_Descriptor_Function)func;
349 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
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);
405 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
408 // GDB WILL NOT LIKE YOU IF YOU DO THIS
415 PluginManager::get_ladspa_category (uint32_t plugin_id)
419 lrdf_statement pattern;
421 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
422 pattern.subject = buf;
423 pattern.predicate = const_cast<char*>(RDF_TYPE);
425 pattern.object_type = lrdf_uri;
427 lrdf_statement* matches1 = lrdf_matches (&pattern);
433 pattern.subject = matches1->object;
434 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
436 pattern.object_type = lrdf_literal;
438 lrdf_statement* matches2 = lrdf_matches (&pattern);
439 lrdf_free_statements(matches1);
445 string label = matches2->object;
446 lrdf_free_statements(matches2);
448 /* Kludge LADSPA class names to be singular and match LV2 class names.
449 This avoids duplicate plugin menus for every class, which is necessary
450 to make the plugin category menu at all usable, but is obviously a
453 In the short term, lrdf could be updated so the labels match and a new
454 release made. To support both specs, we should probably be mapping the
455 URIs to the same category in code and perhaps tweaking that hierarchy
456 dynamically to suit the user. Personally, I (drobilla) think that time
457 is better spent replacing the little-used LRDF.
459 In the longer term, we will abandon LRDF entirely in favour of LV2 and
460 use that class hierarchy. Aside from fixing this problem properly, that
461 will also allow for translated labels. SWH plugins have been LV2 for
462 ages; TAP needs porting. I don't know of anything else with LRDF data.
464 if (label == "Utilities") {
466 } else if (label == "Pitch shifters") {
467 return "Pitch Shifter";
468 } else if (label != "Dynamics" && label != "Chorus"
469 &&label[label.length() - 1] == 's'
470 && label[label.length() - 2] != 's') {
471 return label.substr(0, label.length() - 1);
482 PluginManager::lv2_refresh ()
484 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
485 delete _lv2_plugin_info;
486 _lv2_plugin_info = LV2PluginInfo::discover();
490 #ifdef AUDIOUNIT_SUPPORT
492 PluginManager::au_refresh ()
494 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
495 delete _au_plugin_info;
496 _au_plugin_info = AUPluginInfo::discover();
501 #ifdef WINDOWS_VST_SUPPORT
504 PluginManager::windows_vst_refresh ()
506 if (_windows_vst_plugin_info) {
507 _windows_vst_plugin_info->clear ();
509 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
512 if (windows_vst_path.length() == 0) {
513 windows_vst_path = "/usr/local/lib/vst:/usr/lib/vst";
516 windows_vst_discover_from_path (windows_vst_path);
520 PluginManager::add_windows_vst_directory (string path)
522 if (windows_vst_discover_from_path (path) == 0) {
523 windows_vst_path += ':';
524 windows_vst_path += path;
530 static bool windows_vst_filter (const string& str, void * /*arg*/)
532 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
534 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
538 PluginManager::windows_vst_discover_from_path (string path)
541 vector<string *> *plugin_objects;
542 vector<string *>::iterator x;
545 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
547 plugin_objects = scanner (windows_vst_path, windows_vst_filter, 0, false, true);
549 if (plugin_objects) {
550 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
551 ARDOUR::PluginScanMessage(_("VST"), **x);
552 windows_vst_discover (**x);
555 vector_delete (plugin_objects);
562 PluginManager::windows_vst_discover (string path)
564 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
566 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()));
568 if (finfos->empty()) {
569 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
570 warning << "Cannot get Windows VST information from " << path << endmsg;
574 uint32_t discovered = 0;
575 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
579 if (!finfo->canProcessReplacing) {
580 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
581 finfo->name, PROGRAM_NAME)
586 PluginInfoPtr info (new WindowsVSTPluginInfo);
588 /* what a joke freeware VST is */
590 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
591 info->name = PBD::basename_nosuffix (path);
593 info->name = finfo->name;
597 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
598 info->unique_id = buf;
599 info->category = "VST";
601 info->creator = finfo->creator;
603 info->n_inputs.set_audio (finfo->numInputs);
604 info->n_outputs.set_audio (finfo->numOutputs);
605 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
606 info->type = ARDOUR::Windows_VST;
608 // TODO: check dup-IDs (lxvst AND windows vst)
609 bool duplicate = false;
611 if (!_windows_vst_plugin_info->empty()) {
612 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
613 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
614 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
622 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
623 _windows_vst_plugin_info->push_back (info);
628 vstfx_free_info_list (finfos);
629 return discovered > 0 ? 0 : -1;
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:"
647 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
648 "/usr/lib/vst:/usr/local/lib/vst";
651 lxvst_discover_from_path (lxvst_path);
655 PluginManager::add_lxvst_directory (string path)
657 if (lxvst_discover_from_path (path) == 0) {
665 static bool lxvst_filter (const string& str, void *)
667 /* Not a dotfile, has a prefix before a period, suffix is "so" */
669 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
673 PluginManager::lxvst_discover_from_path (string path)
676 vector<string *> *plugin_objects;
677 vector<string *>::iterator x;
684 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
686 plugin_objects = scanner (lxvst_path, lxvst_filter, 0, false, true);
688 if (plugin_objects) {
689 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
690 ARDOUR::PluginScanMessage(_("LXVST"), **x);
691 lxvst_discover (**x);
694 vector_delete (plugin_objects);
701 PluginManager::lxvst_discover (string path)
703 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
705 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()));
707 if (finfos->empty()) {
708 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
709 warning << "Cannot get Linux VST information from " << path << endmsg;
713 uint32_t discovered = 0;
714 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
718 if (!finfo->canProcessReplacing) {
719 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
720 finfo->name, PROGRAM_NAME)
725 PluginInfoPtr info(new LXVSTPluginInfo);
727 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
728 info->name = PBD::basename_nosuffix (path);
730 info->name = finfo->name;
734 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
735 info->unique_id = buf;
736 info->category = "linuxVSTs";
738 info->creator = finfo->creator;
740 info->n_inputs.set_audio (finfo->numInputs);
741 info->n_outputs.set_audio (finfo->numOutputs);
742 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
743 info->type = ARDOUR::LXVST;
745 /* Make sure we don't find the same plugin in more than one place along
746 the LXVST_PATH We can't use a simple 'find' because the path is included
747 in the PluginInfo, and that is the one thing we can be sure MUST be
748 different if a duplicate instance is found. So we just compare the type
749 and unique ID (which for some VSTs isn't actually unique...)
752 // TODO: check dup-IDs with windowsVST, too
753 bool duplicate = false;
754 if (!_lxvst_plugin_info->empty()) {
755 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
756 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
757 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
765 _lxvst_plugin_info->push_back (info);
770 vstfx_free_info_list (finfos);
771 return discovered > 0 ? 0 : -1;
774 #endif // LXVST_SUPPORT
777 PluginManager::PluginStatusType
778 PluginManager::get_status (const PluginInfoPtr& pi)
780 PluginStatus ps (pi->type, pi->unique_id);
781 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
782 if (i == statuses.end() ) {
790 PluginManager::save_statuses ()
793 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
795 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
801 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
813 ofs << "Windows-VST";
822 switch ((*i).status) {
835 ofs << (*i).unique_id;;
843 PluginManager::load_statuses ()
845 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
846 ifstream ifs (path.c_str());
856 PluginStatusType status;
873 /* rest of the line is the plugin ID */
875 ifs.getline (buf, sizeof (buf), '\n');
880 if (sstatus == "Normal") {
882 } else if (sstatus == "Favorite") {
884 } else if (sstatus == "Hidden") {
887 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
893 if (stype == "LADSPA") {
895 } else if (stype == "AudioUnit") {
897 } else if (stype == "LV2") {
899 } else if (stype == "Windows-VST") {
901 } else if (stype == "LXVST") {
904 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
910 strip_whitespace_edges (id);
911 set_status (type, id, status);
918 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
920 PluginStatus ps (t, id, status);
923 if (status == Normal) {
927 statuses.insert (ps);
930 ARDOUR::PluginInfoList&
931 PluginManager::windows_vst_plugin_info ()
933 #ifdef WINDOWS_VST_SUPPORT
934 if (!_windows_vst_plugin_info) {
935 windows_vst_refresh ();
937 return *_windows_vst_plugin_info;
939 return _empty_plugin_info;
943 ARDOUR::PluginInfoList&
944 PluginManager::lxvst_plugin_info ()
947 if (!_lxvst_plugin_info)
949 return *_lxvst_plugin_info;
951 return _empty_plugin_info;
955 ARDOUR::PluginInfoList&
956 PluginManager::ladspa_plugin_info ()
958 if (!_ladspa_plugin_info)
960 return *_ladspa_plugin_info;
963 ARDOUR::PluginInfoList&
964 PluginManager::lv2_plugin_info ()
967 if (!_lv2_plugin_info)
969 return *_lv2_plugin_info;
971 return _empty_plugin_info;
975 ARDOUR::PluginInfoList&
976 PluginManager::au_plugin_info ()
978 #ifdef AUDIOUNIT_SUPPORT
979 if (!_au_plugin_info)
981 return *_au_plugin_info;
983 return _empty_plugin_info;