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/rc_configuration.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);
282 vector_delete (plugin_objects);
288 static bool rdf_filter (const string &str, void* /*arg*/)
290 return str[0] != '.' &&
291 ((str.find(".rdf") == (str.length() - 4)) ||
292 (str.find(".rdfs") == (str.length() - 5)) ||
293 (str.find(".n3") == (str.length() - 3)) ||
294 (str.find(".ttl") == (str.length() - 4)));
298 PluginManager::add_ladspa_presets()
300 add_presets ("ladspa");
304 PluginManager::add_windows_vst_presets()
306 add_presets ("windows-vst");
310 PluginManager::add_lxvst_presets()
312 add_presets ("lxvst");
316 PluginManager::add_presets(string domain)
320 vector<string *> *presets;
321 vector<string *>::iterator x;
324 if ((envvar = getenv ("HOME")) == 0) {
328 string path = string_compose("%1/.%2/rdf", envvar, domain);
329 presets = scanner (path, rdf_filter, 0, false, true);
332 for (x = presets->begin(); x != presets->end (); ++x) {
333 string file = "file:" + **x;
334 if (lrdf_read_file(file.c_str())) {
335 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
339 vector_delete (presets);
344 PluginManager::add_lrdf_data (const string &path)
347 vector<string *>* rdf_files;
348 vector<string *>::iterator x;
350 rdf_files = scanner (path, rdf_filter, 0, false, true);
353 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
354 const string uri(string("file://") + **x);
356 if (lrdf_read_file(uri.c_str())) {
357 warning << "Could not parse rdf file: " << uri << endmsg;
361 vector_delete (rdf_files);
366 PluginManager::ladspa_discover (string path)
369 const LADSPA_Descriptor *descriptor;
370 LADSPA_Descriptor_Function dfunc;
373 if ((module = dlopen (path.c_str(), RTLD_NOW)) == 0) {
374 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"), path, dlerror()) << endmsg;
378 dfunc = (LADSPA_Descriptor_Function) dlsym (module, "ladspa_descriptor");
380 if ((errstr = dlerror()) != 0) {
381 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
382 error << errstr << endmsg;
387 for (uint32_t i = 0; ; ++i) {
388 if ((descriptor = dfunc (i)) == 0) {
392 if (!ladspa_plugin_whitelist.empty()) {
393 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
398 PluginInfoPtr info(new LadspaPluginInfo);
399 info->name = descriptor->Name;
400 info->category = get_ladspa_category(descriptor->UniqueID);
401 info->creator = descriptor->Maker;
404 info->n_inputs = ChanCount();
405 info->n_outputs = ChanCount();
406 info->type = ARDOUR::LADSPA;
409 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
410 info->unique_id = buf;
412 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
413 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
414 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
415 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
417 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
418 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
423 if(_ladspa_plugin_info->empty()){
424 _ladspa_plugin_info->push_back (info);
427 //Ensure that the plugin is not already in the plugin list.
431 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
432 if(0 == info->unique_id.compare((*i)->unique_id)){
438 _ladspa_plugin_info->push_back (info);
442 // GDB WILL NOT LIKE YOU IF YOU DO THIS
449 PluginManager::get_ladspa_category (uint32_t plugin_id)
452 lrdf_statement pattern;
454 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
455 pattern.subject = buf;
456 pattern.predicate = const_cast<char*>(RDF_TYPE);
458 pattern.object_type = lrdf_uri;
460 lrdf_statement* matches1 = lrdf_matches (&pattern);
466 pattern.subject = matches1->object;
467 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
469 pattern.object_type = lrdf_literal;
471 lrdf_statement* matches2 = lrdf_matches (&pattern);
472 lrdf_free_statements(matches1);
478 string label = matches2->object;
479 lrdf_free_statements(matches2);
481 /* Kludge LADSPA class names to be singular and match LV2 class names.
482 This avoids duplicate plugin menus for every class, which is necessary
483 to make the plugin category menu at all usable, but is obviously a
486 In the short term, lrdf could be updated so the labels match and a new
487 release made. To support both specs, we should probably be mapping the
488 URIs to the same category in code and perhaps tweaking that hierarchy
489 dynamically to suit the user. Personally, I (drobilla) think that time
490 is better spent replacing the little-used LRDF.
492 In the longer term, we will abandon LRDF entirely in favour of LV2 and
493 use that class hierarchy. Aside from fixing this problem properly, that
494 will also allow for translated labels. SWH plugins have been LV2 for
495 ages; TAP needs porting. I don't know of anything else with LRDF data.
497 if (label == "Utilities") {
499 } else if (label == "Pitch shifters") {
500 return "Pitch Shifter";
501 } else if (label != "Dynamics" && label != "Chorus"
502 &&label[label.length() - 1] == 's'
503 && label[label.length() - 2] != 's') {
504 return label.substr(0, label.length() - 1);
512 PluginManager::lv2_refresh ()
514 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
515 delete _lv2_plugin_info;
516 _lv2_plugin_info = LV2PluginInfo::discover();
520 #ifdef AUDIOUNIT_SUPPORT
522 PluginManager::au_refresh ()
524 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
525 delete _au_plugin_info;
526 _au_plugin_info = AUPluginInfo::discover();
531 #ifdef WINDOWS_VST_SUPPORT
534 PluginManager::windows_vst_refresh ()
536 if (_windows_vst_plugin_info) {
537 _windows_vst_plugin_info->clear ();
539 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
542 if (windows_vst_path.length() == 0) {
543 windows_vst_path = "/usr/local/lib/vst:/usr/lib/vst";
546 windows_vst_discover_from_path (windows_vst_path);
550 PluginManager::add_windows_vst_directory (string path)
552 if (windows_vst_discover_from_path (path) == 0) {
553 windows_vst_path += ':';
554 windows_vst_path += path;
560 static bool windows_vst_filter (const string& str, void *arg)
562 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
564 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
568 PluginManager::windows_vst_discover_from_path (string path)
571 vector<string *> *plugin_objects;
572 vector<string *>::iterator x;
575 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
577 plugin_objects = scanner (windows_vst_path, windows_vst_filter, 0, false, true);
579 if (plugin_objects) {
580 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
581 windows_vst_discover (**x);
584 vector_delete (plugin_objects);
591 PluginManager::windows_vst_discover (string path)
596 if ((finfo = fst_get_info (const_cast<char *> (path.c_str()))) == 0) {
597 warning << "Cannot get Windows VST information from " << path << endmsg;
601 if (!finfo->canProcessReplacing) {
602 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
603 finfo->name, PROGRAM_NAME)
607 PluginInfoPtr info (new WindowsVSTPluginInfo);
609 /* what a joke freeware VST is */
611 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
612 info->name = PBD::basename_nosuffix (path);
614 info->name = finfo->name;
618 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
619 info->unique_id = buf;
620 info->category = "VST";
622 info->creator = finfo->creator;
624 info->n_inputs.set_audio (finfo->numInputs);
625 info->n_outputs.set_audio (finfo->numOutputs);
626 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
627 info->type = ARDOUR::Windows_VST;
629 _windows_vst_plugin_info->push_back (info);
630 fst_free_info (finfo);
635 #endif // WINDOWS_VST_SUPPORT
640 PluginManager::lxvst_refresh ()
642 if (_lxvst_plugin_info) {
643 _lxvst_plugin_info->clear ();
645 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
648 if (lxvst_path.length() == 0) {
649 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
650 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
651 "/usr/lib/vst:/usr/local/lib/vst";
654 lxvst_discover_from_path (lxvst_path);
658 PluginManager::add_lxvst_directory (string path)
660 if (lxvst_discover_from_path (path) == 0) {
668 static bool lxvst_filter (const string& str, void *)
670 /* Not a dotfile, has a prefix before a period, suffix is "so" */
672 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
676 PluginManager::lxvst_discover_from_path (string path)
679 vector<string *> *plugin_objects;
680 vector<string *>::iterator x;
683 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
685 plugin_objects = scanner (lxvst_path, lxvst_filter, 0, false, true);
687 if (plugin_objects) {
688 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
689 lxvst_discover (**x);
692 vector_delete (plugin_objects);
699 PluginManager::lxvst_discover (string path)
704 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
706 if ((finfo = vstfx_get_info (const_cast<char *> (path.c_str()))) == 0) {
710 if (!finfo->canProcessReplacing) {
711 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
712 finfo->name, PROGRAM_NAME)
716 PluginInfoPtr info(new LXVSTPluginInfo);
718 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
719 info->name = PBD::basename_nosuffix (path);
721 info->name = finfo->name;
725 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
726 info->unique_id = buf;
727 info->category = "linuxVSTs";
729 info->creator = finfo->creator;
731 info->n_inputs.set_audio (finfo->numInputs);
732 info->n_outputs.set_audio (finfo->numOutputs);
733 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
734 info->type = ARDOUR::LXVST;
736 /* Make sure we don't find the same plugin in more than one place along
737 the LXVST_PATH We can't use a simple 'find' because the path is included
738 in the PluginInfo, and that is the one thing we can be sure MUST be
739 different if a duplicate instance is found. So we just compare the type
740 and unique ID (which for some VSTs isn't actually unique...)
743 if (!_lxvst_plugin_info->empty()) {
744 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
745 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
746 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
747 vstfx_free_info(finfo);
753 _lxvst_plugin_info->push_back (info);
754 vstfx_free_info (finfo);
759 #endif // LXVST_SUPPORT
762 PluginManager::PluginStatusType
763 PluginManager::get_status (const PluginInfoPtr& pi)
765 PluginStatus ps (pi->type, pi->unique_id);
766 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
767 if (i == statuses.end() ) {
775 PluginManager::save_statuses ()
778 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
780 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
786 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
798 ofs << "Windows-VST";
807 switch ((*i).status) {
820 ofs << (*i).unique_id;;
828 PluginManager::load_statuses ()
830 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
831 ifstream ifs (path.c_str());
841 PluginStatusType status;
858 /* rest of the line is the plugin ID */
860 ifs.getline (buf, sizeof (buf), '\n');
865 if (sstatus == "Normal") {
867 } else if (sstatus == "Favorite") {
869 } else if (sstatus == "Hidden") {
872 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
878 if (stype == "LADSPA") {
880 } else if (stype == "AudioUnit") {
882 } else if (stype == "LV2") {
884 } else if (stype == "Windows-VST") {
886 } else if (stype == "LXVST") {
889 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
895 strip_whitespace_edges (id);
896 set_status (type, id, status);
903 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
905 PluginStatus ps (t, id, status);
908 if (status == Normal) {
912 statuses.insert (ps);
915 ARDOUR::PluginInfoList&
916 PluginManager::windows_vst_plugin_info ()
918 #ifdef WINDOWS_VST_SUPPORT
919 if (!_windows_vst_plugin_info) {
920 windows_vst_refresh ();
922 return *_windows_vst_plugin_info;
924 return _empty_plugin_info;
928 ARDOUR::PluginInfoList&
929 PluginManager::lxvst_plugin_info ()
932 if (!_lxvst_plugin_info)
934 return *_lxvst_plugin_info;
936 return _empty_plugin_info;
940 ARDOUR::PluginInfoList&
941 PluginManager::ladspa_plugin_info ()
943 if (!_ladspa_plugin_info)
945 return *_ladspa_plugin_info;
948 ARDOUR::PluginInfoList&
949 PluginManager::lv2_plugin_info ()
952 if (!_lv2_plugin_info)
954 return *_lv2_plugin_info;
956 return _empty_plugin_info;
960 ARDOUR::PluginInfoList&
961 PluginManager::au_plugin_info ()
963 #ifdef AUDIOUNIT_SUPPORT
964 if (!_au_plugin_info)
966 return *_au_plugin_info;
968 return _empty_plugin_info;