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";
652 lxvst_discover_from_path (lxvst_path);
656 PluginManager::add_lxvst_directory (string path)
658 if (lxvst_discover_from_path (path) == 0) {
666 static bool lxvst_filter (const string& str, void *)
668 /* Not a dotfile, has a prefix before a period, suffix is "so" */
670 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
674 PluginManager::lxvst_discover_from_path (string path)
677 vector<string *> *plugin_objects;
678 vector<string *>::iterator x;
681 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
683 plugin_objects = scanner (lxvst_path, lxvst_filter, 0, false, true);
685 if (plugin_objects) {
686 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
687 lxvst_discover (**x);
690 vector_delete (plugin_objects);
697 PluginManager::lxvst_discover (string path)
702 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
704 if ((finfo = vstfx_get_info (const_cast<char *> (path.c_str()))) == 0) {
708 if (!finfo->canProcessReplacing) {
709 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
710 finfo->name, PROGRAM_NAME)
714 PluginInfoPtr info(new LXVSTPluginInfo);
716 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
717 info->name = PBD::basename_nosuffix (path);
719 info->name = finfo->name;
723 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
724 info->unique_id = buf;
725 info->category = "linuxVSTs";
727 info->creator = finfo->creator;
729 info->n_inputs.set_audio (finfo->numInputs);
730 info->n_outputs.set_audio (finfo->numOutputs);
731 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
732 info->type = ARDOUR::LXVST;
734 /* Make sure we don't find the same plugin in more than one place along
735 the LXVST_PATH We can't use a simple 'find' because the path is included
736 in the PluginInfo, and that is the one thing we can be sure MUST be
737 different if a duplicate instance is found. So we just compare the type
738 and unique ID (which for some VSTs isn't actually unique...)
741 if (!_lxvst_plugin_info->empty()) {
742 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
743 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
744 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
745 vstfx_free_info(finfo);
751 _lxvst_plugin_info->push_back (info);
752 vstfx_free_info (finfo);
757 #endif // LXVST_SUPPORT
760 PluginManager::PluginStatusType
761 PluginManager::get_status (const PluginInfoPtr& pi)
763 PluginStatus ps (pi->type, pi->unique_id);
764 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
765 if (i == statuses.end() ) {
773 PluginManager::save_statuses ()
776 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
778 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
784 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
796 ofs << "Windows-VST";
805 switch ((*i).status) {
818 ofs << (*i).unique_id;;
826 PluginManager::load_statuses ()
828 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
829 ifstream ifs (path.c_str());
839 PluginStatusType status;
856 /* rest of the line is the plugin ID */
858 ifs.getline (buf, sizeof (buf), '\n');
863 if (sstatus == "Normal") {
865 } else if (sstatus == "Favorite") {
867 } else if (sstatus == "Hidden") {
870 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
876 if (stype == "LADSPA") {
878 } else if (stype == "AudioUnit") {
880 } else if (stype == "LV2") {
882 } else if (stype == "Windows-VST") {
884 } else if (stype == "LXVST") {
887 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
893 strip_whitespace_edges (id);
894 set_status (type, id, status);
901 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
903 PluginStatus ps (t, id, status);
906 if (status == Normal) {
910 statuses.insert (ps);
913 ARDOUR::PluginInfoList&
914 PluginManager::windows_vst_plugin_info ()
916 #ifdef WINDOWS_VST_SUPPORT
917 if (!_windows_vst_plugin_info) {
918 windows_vst_refresh ();
920 return *_windows_vst_plugin_info;
922 return _empty_plugin_info;
926 ARDOUR::PluginInfoList&
927 PluginManager::lxvst_plugin_info ()
930 if (!_lxvst_plugin_info)
932 return *_lxvst_plugin_info;
934 return _empty_plugin_info;
938 ARDOUR::PluginInfoList&
939 PluginManager::ladspa_plugin_info ()
941 if (!_ladspa_plugin_info)
943 return *_ladspa_plugin_info;
946 ARDOUR::PluginInfoList&
947 PluginManager::lv2_plugin_info ()
950 if (!_lv2_plugin_info)
952 return *_lv2_plugin_info;
954 return _empty_plugin_info;
958 ARDOUR::PluginInfoList&
959 PluginManager::au_plugin_info ()
961 #ifdef AUDIOUNIT_SUPPORT
962 if (!_au_plugin_info)
964 return *_au_plugin_info;
966 return _empty_plugin_info;