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");
185 #ifdef WINDOWS_VST_SUPPORT
186 if (Config->get_use_windows_vst()) {
187 windows_vst_refresh ();
189 #endif // WINDOWS_VST_SUPPORT
192 if(Config->get_use_lxvst()) {
195 #endif //Native linuxVST SUPPORT
197 #ifdef AUDIOUNIT_SUPPORT
201 PluginListChanged (); /* EMIT SIGNAL */
205 PluginManager::ladspa_refresh ()
207 if (_ladspa_plugin_info) {
208 _ladspa_plugin_info->clear ();
210 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
213 /* allow LADSPA_PATH to augment, not override standard locations */
215 /* Only add standard locations to ladspa_path if it doesn't
216 * already contain them. Check for trailing G_DIR_SEPARATOR too.
219 vector<string> ladspa_modules;
221 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
223 Glib::PatternSpec so_extension_pattern("*.so");
224 Glib::PatternSpec dylib_extension_pattern("*.dylib");
225 Glib::PatternSpec dll_extension_pattern("*.dll");
227 find_matching_files_in_search_path (ladspa_search_path (),
228 so_extension_pattern, ladspa_modules);
230 find_matching_files_in_search_path (ladspa_search_path (),
231 dylib_extension_pattern, ladspa_modules);
233 find_matching_files_in_search_path (ladspa_search_path (),
234 dll_extension_pattern, ladspa_modules);
236 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
237 ladspa_discover (*i);
241 static bool rdf_filter (const string &str, void* /*arg*/)
243 return str[0] != '.' &&
244 ((str.find(".rdf") == (str.length() - 4)) ||
245 (str.find(".rdfs") == (str.length() - 5)) ||
246 (str.find(".n3") == (str.length() - 3)) ||
247 (str.find(".ttl") == (str.length() - 4)));
251 PluginManager::add_ladspa_presets()
253 add_presets ("ladspa");
257 PluginManager::add_windows_vst_presets()
259 add_presets ("windows-vst");
263 PluginManager::add_lxvst_presets()
265 add_presets ("lxvst");
269 PluginManager::add_presets(string domain)
273 vector<string *> *presets;
274 vector<string *>::iterator x;
277 if ((envvar = getenv ("HOME")) == 0) {
281 string path = string_compose("%1/.%2/rdf", envvar, domain);
282 presets = scanner (path, rdf_filter, 0, false, true);
285 for (x = presets->begin(); x != presets->end (); ++x) {
286 string file = "file:" + **x;
287 if (lrdf_read_file(file.c_str())) {
288 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
292 vector_delete (presets);
298 PluginManager::add_lrdf_data (const string &path)
302 vector<string *>* rdf_files;
303 vector<string *>::iterator x;
305 rdf_files = scanner (path, rdf_filter, 0, false, true);
308 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
309 const string uri(string("file://") + **x);
311 if (lrdf_read_file(uri.c_str())) {
312 warning << "Could not parse rdf file: " << uri << endmsg;
316 vector_delete (rdf_files);
322 PluginManager::ladspa_discover (string path)
324 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
326 Glib::Module module(path);
327 const LADSPA_Descriptor *descriptor;
328 LADSPA_Descriptor_Function dfunc;
332 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
333 path, Glib::Module::get_last_error()) << endmsg;
338 if (!module.get_symbol("ladspa_descriptor", func)) {
339 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
340 error << Glib::Module::get_last_error() << endmsg;
344 dfunc = (LADSPA_Descriptor_Function)func;
346 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
348 for (uint32_t i = 0; ; ++i) {
349 if ((descriptor = dfunc (i)) == 0) {
353 if (!ladspa_plugin_whitelist.empty()) {
354 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
359 PluginInfoPtr info(new LadspaPluginInfo);
360 info->name = descriptor->Name;
361 info->category = get_ladspa_category(descriptor->UniqueID);
362 info->creator = descriptor->Maker;
365 info->n_inputs = ChanCount();
366 info->n_outputs = ChanCount();
367 info->type = ARDOUR::LADSPA;
370 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
371 info->unique_id = buf;
373 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
374 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
375 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
376 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
378 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
379 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
384 if(_ladspa_plugin_info->empty()){
385 _ladspa_plugin_info->push_back (info);
388 //Ensure that the plugin is not already in the plugin list.
392 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
393 if(0 == info->unique_id.compare((*i)->unique_id)){
399 _ladspa_plugin_info->push_back (info);
402 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
405 // GDB WILL NOT LIKE YOU IF YOU DO THIS
412 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 = const_cast<char*>(RDF_TYPE);
422 pattern.object_type = lrdf_uri;
424 lrdf_statement* matches1 = lrdf_matches (&pattern);
430 pattern.subject = matches1->object;
431 pattern.predicate = const_cast<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);
479 PluginManager::lv2_refresh ()
481 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
482 delete _lv2_plugin_info;
483 _lv2_plugin_info = LV2PluginInfo::discover();
487 #ifdef AUDIOUNIT_SUPPORT
489 PluginManager::au_refresh ()
491 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
492 delete _au_plugin_info;
493 _au_plugin_info = AUPluginInfo::discover();
498 #ifdef WINDOWS_VST_SUPPORT
501 PluginManager::windows_vst_refresh ()
503 if (_windows_vst_plugin_info) {
504 _windows_vst_plugin_info->clear ();
506 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
509 if (windows_vst_path.length() == 0) {
510 windows_vst_path = "/usr/local/lib/vst:/usr/lib/vst";
513 windows_vst_discover_from_path (windows_vst_path);
517 PluginManager::add_windows_vst_directory (string path)
519 if (windows_vst_discover_from_path (path) == 0) {
520 windows_vst_path += ':';
521 windows_vst_path += path;
527 static bool windows_vst_filter (const string& str, void *arg)
529 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
531 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
535 PluginManager::windows_vst_discover_from_path (string path)
538 vector<string *> *plugin_objects;
539 vector<string *>::iterator x;
542 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
544 plugin_objects = scanner (windows_vst_path, windows_vst_filter, 0, false, true);
546 if (plugin_objects) {
547 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
548 windows_vst_discover (**x);
551 vector_delete (plugin_objects);
558 PluginManager::windows_vst_discover (string path)
560 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
562 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()));
564 if (finfos->empty()) {
565 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
566 warning << "Cannot get Windows VST information from " << path << endmsg;
570 uint32_t discovered = 0;
571 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
575 if (!finfo->canProcessReplacing) {
576 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
577 finfo->name, PROGRAM_NAME)
582 PluginInfoPtr info (new WindowsVSTPluginInfo);
584 /* what a joke freeware VST is */
586 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
587 info->name = PBD::basename_nosuffix (path);
589 info->name = finfo->name;
593 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
594 info->unique_id = buf;
595 info->category = "VST";
597 info->creator = finfo->creator;
599 info->n_inputs.set_audio (finfo->numInputs);
600 info->n_outputs.set_audio (finfo->numOutputs);
601 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
602 info->type = ARDOUR::Windows_VST;
604 // TODO: check dup-IDs (lxvst AND windows vst)
605 bool duplicate = false;
607 if (!_windows_vst_plugin_info->empty()) {
608 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
609 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
610 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
618 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
619 _windows_vst_plugin_info->push_back (info);
624 vstfx_free_info_list (finfos);
625 return discovered > 0 ? 0 : -1;
628 #endif // WINDOWS_VST_SUPPORT
633 PluginManager::lxvst_refresh ()
635 if (_lxvst_plugin_info) {
636 _lxvst_plugin_info->clear ();
638 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
641 if (lxvst_path.length() == 0) {
642 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
643 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
644 "/usr/lib/vst:/usr/local/lib/vst";
647 lxvst_discover_from_path (lxvst_path);
651 PluginManager::add_lxvst_directory (string path)
653 if (lxvst_discover_from_path (path) == 0) {
661 static bool lxvst_filter (const string& str, void *)
663 /* Not a dotfile, has a prefix before a period, suffix is "so" */
665 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
669 PluginManager::lxvst_discover_from_path (string path)
672 vector<string *> *plugin_objects;
673 vector<string *>::iterator x;
680 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
682 plugin_objects = scanner (lxvst_path, lxvst_filter, 0, false, true);
684 if (plugin_objects) {
685 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
686 lxvst_discover (**x);
689 vector_delete (plugin_objects);
696 PluginManager::lxvst_discover (string path)
698 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
700 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()));
702 if (finfos->empty()) {
703 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
704 warning << "Cannot get Linux VST information from " << path << endmsg;
708 uint32_t discovered = 0;
709 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
713 if (!finfo->canProcessReplacing) {
714 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
715 finfo->name, PROGRAM_NAME)
720 PluginInfoPtr info(new LXVSTPluginInfo);
722 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
723 info->name = PBD::basename_nosuffix (path);
725 info->name = finfo->name;
729 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
730 info->unique_id = buf;
731 info->category = "linuxVSTs";
733 info->creator = finfo->creator;
735 info->n_inputs.set_audio (finfo->numInputs);
736 info->n_outputs.set_audio (finfo->numOutputs);
737 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
738 info->type = ARDOUR::LXVST;
740 /* Make sure we don't find the same plugin in more than one place along
741 the LXVST_PATH We can't use a simple 'find' because the path is included
742 in the PluginInfo, and that is the one thing we can be sure MUST be
743 different if a duplicate instance is found. So we just compare the type
744 and unique ID (which for some VSTs isn't actually unique...)
747 // TODO: check dup-IDs with windowsVST, too
748 bool duplicate = false;
749 if (!_lxvst_plugin_info->empty()) {
750 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
751 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
752 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
760 _lxvst_plugin_info->push_back (info);
765 vstfx_free_info_list (finfos);
766 return discovered > 0 ? 0 : -1;
769 #endif // LXVST_SUPPORT
772 PluginManager::PluginStatusType
773 PluginManager::get_status (const PluginInfoPtr& pi)
775 PluginStatus ps (pi->type, pi->unique_id);
776 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
777 if (i == statuses.end() ) {
785 PluginManager::save_statuses ()
788 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
790 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
796 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
808 ofs << "Windows-VST";
817 switch ((*i).status) {
830 ofs << (*i).unique_id;;
838 PluginManager::load_statuses ()
840 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
841 ifstream ifs (path.c_str());
851 PluginStatusType status;
868 /* rest of the line is the plugin ID */
870 ifs.getline (buf, sizeof (buf), '\n');
875 if (sstatus == "Normal") {
877 } else if (sstatus == "Favorite") {
879 } else if (sstatus == "Hidden") {
882 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
888 if (stype == "LADSPA") {
890 } else if (stype == "AudioUnit") {
892 } else if (stype == "LV2") {
894 } else if (stype == "Windows-VST") {
896 } else if (stype == "LXVST") {
899 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
905 strip_whitespace_edges (id);
906 set_status (type, id, status);
913 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
915 PluginStatus ps (t, id, status);
918 if (status == Normal) {
922 statuses.insert (ps);
925 ARDOUR::PluginInfoList&
926 PluginManager::windows_vst_plugin_info ()
928 #ifdef WINDOWS_VST_SUPPORT
929 if (!_windows_vst_plugin_info) {
930 windows_vst_refresh ();
932 return *_windows_vst_plugin_info;
934 return _empty_plugin_info;
938 ARDOUR::PluginInfoList&
939 PluginManager::lxvst_plugin_info ()
942 if (!_lxvst_plugin_info)
944 return *_lxvst_plugin_info;
946 return _empty_plugin_info;
950 ARDOUR::PluginInfoList&
951 PluginManager::ladspa_plugin_info ()
953 if (!_ladspa_plugin_info)
955 return *_ladspa_plugin_info;
958 ARDOUR::PluginInfoList&
959 PluginManager::lv2_plugin_info ()
962 if (!_lv2_plugin_info)
964 return *_lv2_plugin_info;
966 return _empty_plugin_info;
970 ARDOUR::PluginInfoList&
971 PluginManager::au_plugin_info ()
973 #ifdef AUDIOUNIT_SUPPORT
974 if (!_au_plugin_info)
976 return *_au_plugin_info;
978 return _empty_plugin_info;