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>
31 #include "pbd/gstdio_compat.h"
37 #ifdef WINDOWS_VST_SUPPORT
38 #include "ardour/vst_info_file.h"
40 #include "pbd/basename.h"
49 #endif // WINDOWS_VST_SUPPORT
52 #include "ardour/vst_info_file.h"
53 #include "ardour/linux_vst_support.h"
54 #include "pbd/basename.h"
56 #endif //LXVST_SUPPORT
59 #include "ardour/vst_info_file.h"
60 #include "ardour/mac_vst_support.h"
61 #include "ardour/mac_vst_plugin.h"
62 #include "pbd/basename.h"
64 #endif //MACVST_SUPPORT
66 #include <glibmm/miscutils.h>
67 #include <glibmm/pattern.h>
68 #include <glibmm/fileutils.h>
69 #include <glibmm/miscutils.h>
71 #include "pbd/whitespace.h"
72 #include "pbd/file_utils.h"
74 #include "ardour/debug.h"
75 #include "ardour/filesystem_paths.h"
76 #include "ardour/ladspa.h"
77 #include "ardour/ladspa_plugin.h"
78 #include "ardour/luascripting.h"
79 #include "ardour/luaproc.h"
80 #include "ardour/plugin.h"
81 #include "ardour/plugin_manager.h"
82 #include "ardour/rc_configuration.h"
84 #include "ardour/search_paths.h"
87 #include "ardour/lv2_plugin.h"
90 #ifdef WINDOWS_VST_SUPPORT
91 #include "ardour/windows_vst_plugin.h"
95 #include "ardour/lxvst_plugin.h"
98 #ifdef AUDIOUNIT_SUPPORT
99 #include "ardour/audio_unit.h"
100 #include <Carbon/Carbon.h>
103 #include "pbd/error.h"
104 #include "pbd/stl_delete.h"
106 #include "pbd/i18n.h"
108 #include "ardour/debug.h"
110 using namespace ARDOUR;
114 PluginManager* PluginManager::_instance = 0;
115 std::string PluginManager::scanner_bin_path = "";
118 PluginManager::instance()
121 _instance = new PluginManager;
126 PluginManager::PluginManager ()
127 : _windows_vst_plugin_info(0)
128 , _lxvst_plugin_info(0)
129 , _mac_vst_plugin_info(0)
130 , _ladspa_plugin_info(0)
131 , _lv2_plugin_info(0)
133 , _lua_plugin_info(0)
134 , _cancel_scan(false)
135 , _cancel_timeout(false)
140 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT
141 // source-tree (ardev, etc)
142 PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
144 #ifdef PLATFORM_WINDOWS
145 // on windows the .exe needs to be in the same folder with libardour.dll
146 vstsp += Glib::build_filename(windows_package_directory_path(), "bin");
148 // on Unices additional internal-use binaries are deployed to $libdir
149 vstsp += ARDOUR::ardour_dll_directory();
152 if (!PBD::find_file (vstsp,
153 #ifdef PLATFORM_WINDOWS
154 #ifdef DEBUGGABLE_SCANNER_APP
155 #if defined(DEBUG) || defined(_DEBUG)
156 "ardour-vst-scannerD.exe"
158 "ardour-vst-scannerRDC.exe"
161 "ardour-vst-scanner.exe"
166 , scanner_bin_path)) {
167 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << vstsp.to_string() << endmsg;
173 if ((s = getenv ("LADSPA_RDF_PATH"))){
177 if (lrdf_path.length() == 0) {
178 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
181 add_lrdf_data(lrdf_path);
182 add_ladspa_presets();
183 #ifdef WINDOWS_VST_SUPPORT
184 if (Config->get_use_windows_vst ()) {
185 add_windows_vst_presets ();
187 #endif /* WINDOWS_VST_SUPPORT */
190 if (Config->get_use_lxvst()) {
193 #endif /* Native LinuxVST support*/
195 #ifdef MACVST_SUPPORT
196 if (Config->get_use_macvst ()) {
197 add_mac_vst_presets ();
201 if ((s = getenv ("VST_PATH"))) {
202 windows_vst_path = s;
203 } else if ((s = getenv ("VST_PLUGINS"))) {
204 windows_vst_path = s;
207 if (windows_vst_path.length() == 0) {
208 windows_vst_path = vst_search_path ();
211 if ((s = getenv ("LXVST_PATH"))) {
213 } else if ((s = getenv ("LXVST_PLUGINS"))) {
217 if (lxvst_path.length() == 0) {
218 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
219 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
220 "/usr/lib/vst:/usr/local/lib/vst";
223 /* first time setup, use 'default' path */
224 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
225 Config->set_plugin_path_lxvst(get_default_lxvst_path());
227 if (Config->get_plugin_path_vst() == X_("@default@")) {
228 Config->set_plugin_path_vst(get_default_windows_vst_path());
231 if (_instance == 0) {
235 BootMessage (_("Discovering Plugins"));
237 LuaScripting::instance().scripts_changed.connect_same_thread (lua_refresh_connection, boost::bind (&PluginManager::lua_refresh_cb, this));
241 PluginManager::~PluginManager()
243 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
244 // don't bother, just exit quickly.
245 delete _windows_vst_plugin_info;
246 delete _lxvst_plugin_info;
247 delete _mac_vst_plugin_info;
248 delete _ladspa_plugin_info;
249 delete _lv2_plugin_info;
250 delete _au_plugin_info;
251 delete _lua_plugin_info;
256 PluginManager::refresh (bool cache_only)
258 Glib::Threads::Mutex::Lock lm (_lock, Glib::Threads::TRY_LOCK);
264 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
265 _cancel_scan = false;
267 BootMessage (_("Scanning LADSPA Plugins"));
269 BootMessage (_("Scanning Lua DSP Processors"));
272 BootMessage (_("Scanning LV2 Plugins"));
275 #ifdef WINDOWS_VST_SUPPORT
276 if (Config->get_use_windows_vst()) {
278 BootMessage (_("Scanning Windows VST Plugins"));
280 BootMessage (_("Discovering Windows VST Plugins"));
282 windows_vst_refresh (cache_only);
284 #endif // WINDOWS_VST_SUPPORT
287 if(Config->get_use_lxvst()) {
289 BootMessage (_("Scanning Linux VST Plugins"));
291 BootMessage (_("Discovering Linux VST Plugins"));
293 lxvst_refresh(cache_only);
295 #endif //Native linuxVST SUPPORT
297 #ifdef MACVST_SUPPORT
298 if(Config->get_use_macvst ()) {
300 BootMessage (_("Scanning Mac VST Plugins"));
302 BootMessage (_("Discovering Mac VST Plugins"));
304 mac_vst_refresh (cache_only);
305 } else if (_mac_vst_plugin_info) {
306 _mac_vst_plugin_info->clear ();
308 _mac_vst_plugin_info = new ARDOUR::PluginInfoList();
310 #endif //Native Mac VST SUPPORT
312 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
314 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
315 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
317 if (g_file_get_contents(fn.c_str (), &bl, NULL, NULL)) {
318 if (Config->get_verbose_plugin_scan()) {
319 PBD::info << _("VST Blacklist: ") << fn << "\n" << bl << "-----" << endmsg;
321 PBD::info << _("VST Blacklist:") << "\n" << bl << "-----" << endmsg;
329 #ifdef AUDIOUNIT_SUPPORT
331 BootMessage (_("Scanning AU Plugins"));
333 BootMessage (_("Discovering AU Plugins"));
335 au_refresh (cache_only);
338 BootMessage (_("Plugin Scan Complete..."));
339 PluginListChanged (); /* EMIT SIGNAL */
340 PluginScanMessage(X_("closeme"), "", false);
341 _cancel_scan = false;
345 PluginManager::cancel_plugin_scan ()
351 PluginManager::cancel_plugin_timeout ()
353 _cancel_timeout = true;
357 PluginManager::clear_vst_cache ()
359 #if 1 // clean old cache and error files. (remove this code after 4.3 or 5.0)
360 #ifdef WINDOWS_VST_SUPPORT
362 vector<string> fsi_files;
363 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_INFOFILE "$", true);
364 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
365 ::g_unlink(i->c_str());
369 vector<string> fsi_files;
370 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
371 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
372 ::g_unlink(i->c_str());
376 vector<string> fsi_files;
377 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.err$", true);
378 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
379 ::g_unlink(i->c_str());
386 vector<string> fsi_files;
387 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_INFOFILE "$", true);
388 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
389 ::g_unlink(i->c_str());
393 vector<string> fsi_files;
394 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
395 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
396 ::g_unlink(i->c_str());
400 vector<string> fsi_files;
401 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.err$", true);
402 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
403 ::g_unlink(i->c_str());
407 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
409 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_info");
410 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
411 PBD::remove_directory (dir);
415 #endif // old cache cleanup
417 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
419 string dn = Glib::build_filename (ARDOUR::user_cache_directory(), "vst");
420 vector<string> fsi_files;
421 find_files_matching_regex (fsi_files, dn, "\\" VST_EXT_INFOFILE "$", /* user cache is flat, no recursion */ false);
422 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
423 ::g_unlink(i->c_str());
430 PluginManager::clear_vst_blacklist ()
432 #if 1 // remove old blacklist files. (remove this code after 4.3 or 5.0)
434 #ifdef WINDOWS_VST_SUPPORT
436 vector<string> fsi_files;
437 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_BLACKLIST "$", true);
438 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
439 ::g_unlink(i->c_str());
446 vector<string> fsi_files;
447 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_BLACKLIST "$", true);
448 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
449 ::g_unlink(i->c_str());
453 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
455 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_blacklist");
456 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
457 PBD::remove_directory (dir);
462 #endif // old blacklist cleanup
464 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT)
466 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
467 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
468 ::g_unlink (fn.c_str());
476 PluginManager::clear_au_cache ()
478 #ifdef AUDIOUNIT_SUPPORT
479 AUPluginInfo::clear_cache ();
484 PluginManager::clear_au_blacklist ()
486 #ifdef AUDIOUNIT_SUPPORT
487 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_blacklist.txt");
488 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
489 ::g_unlink(fn.c_str());
495 PluginManager::lua_refresh ()
497 if (_lua_plugin_info) {
498 _lua_plugin_info->clear ();
500 _lua_plugin_info = new ARDOUR::PluginInfoList ();
502 ARDOUR::LuaScriptList & _scripts (LuaScripting::instance ().scripts (LuaScriptInfo::DSP));
503 for (LuaScriptList::const_iterator s = _scripts.begin(); s != _scripts.end(); ++s) {
504 LuaPluginInfoPtr lpi (new LuaPluginInfo(*s));
505 _lua_plugin_info->push_back (lpi);
510 PluginManager::lua_refresh_cb ()
512 Glib::Threads::Mutex::Lock lm (_lock, Glib::Threads::TRY_LOCK);
517 PluginListChanged (); /* EMIT SIGNAL */
521 PluginManager::ladspa_refresh ()
523 if (_ladspa_plugin_info) {
524 _ladspa_plugin_info->clear ();
526 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
529 /* allow LADSPA_PATH to augment, not override standard locations */
531 /* Only add standard locations to ladspa_path if it doesn't
532 * already contain them. Check for trailing G_DIR_SEPARATOR too.
535 vector<string> ladspa_modules;
537 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
539 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
540 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
541 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
543 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
544 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
545 ladspa_discover (*i);
550 static bool rdf_filter (const string &str, void* /*arg*/)
552 return str[0] != '.' &&
553 ((str.find(".rdf") == (str.length() - 4)) ||
554 (str.find(".rdfs") == (str.length() - 5)) ||
555 (str.find(".n3") == (str.length() - 3)) ||
556 (str.find(".ttl") == (str.length() - 4)));
561 PluginManager::add_ladspa_presets()
563 add_presets ("ladspa");
567 PluginManager::add_windows_vst_presets()
569 add_presets ("windows-vst");
573 PluginManager::add_mac_vst_presets()
575 add_presets ("mac-vst");
579 PluginManager::add_lxvst_presets()
581 add_presets ("lxvst");
585 PluginManager::add_presets(string domain)
588 vector<string> presets;
589 vector<string>::iterator x;
592 if ((envvar = getenv ("HOME")) == 0) {
596 string path = string_compose("%1/.%2/rdf", envvar, domain);
597 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
599 for (x = presets.begin(); x != presets.end (); ++x) {
600 string file = "file:" + *x;
601 if (lrdf_read_file(file.c_str())) {
602 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
610 PluginManager::add_lrdf_data (const string &path)
613 vector<string> rdf_files;
614 vector<string>::iterator x;
616 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
618 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
619 const string uri(string("file://") + *x);
621 if (lrdf_read_file(uri.c_str())) {
622 warning << "Could not parse rdf file: " << uri << endmsg;
629 PluginManager::ladspa_discover (string path)
631 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
633 Glib::Module module(path);
634 const LADSPA_Descriptor *descriptor;
635 LADSPA_Descriptor_Function dfunc;
639 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
640 path, Glib::Module::get_last_error()) << endmsg;
645 if (!module.get_symbol("ladspa_descriptor", func)) {
646 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
647 error << Glib::Module::get_last_error() << endmsg;
651 dfunc = (LADSPA_Descriptor_Function)func;
653 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
655 for (uint32_t i = 0; ; ++i) {
656 /* if a ladspa plugin allocates memory here
657 * it is never free()ed (or plugin-dependent only when unloading).
658 * For some plugins memory allocated is incremental, we should
659 * avoid re-scanning plugins and file bug reports.
661 if ((descriptor = dfunc (i)) == 0) {
665 if (!ladspa_plugin_whitelist.empty()) {
666 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
671 PluginInfoPtr info(new LadspaPluginInfo);
672 info->name = descriptor->Name;
673 info->category = get_ladspa_category(descriptor->UniqueID);
674 info->creator = descriptor->Maker;
677 info->n_inputs = ChanCount();
678 info->n_outputs = ChanCount();
679 info->type = ARDOUR::LADSPA;
682 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
683 info->unique_id = buf;
685 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
686 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
687 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
688 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
690 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
691 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
696 if(_ladspa_plugin_info->empty()){
697 _ladspa_plugin_info->push_back (info);
700 //Ensure that the plugin is not already in the plugin list.
704 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
705 if(0 == info->unique_id.compare((*i)->unique_id)){
711 _ladspa_plugin_info->push_back (info);
714 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
717 // GDB WILL NOT LIKE YOU IF YOU DO THIS
724 PluginManager::get_ladspa_category (uint32_t plugin_id)
728 lrdf_statement pattern;
730 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
731 pattern.subject = buf;
732 pattern.predicate = const_cast<char*>(RDF_TYPE);
734 pattern.object_type = lrdf_uri;
736 lrdf_statement* matches1 = lrdf_matches (&pattern);
742 pattern.subject = matches1->object;
743 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
745 pattern.object_type = lrdf_literal;
747 lrdf_statement* matches2 = lrdf_matches (&pattern);
748 lrdf_free_statements(matches1);
754 string label = matches2->object;
755 lrdf_free_statements(matches2);
757 /* Kludge LADSPA class names to be singular and match LV2 class names.
758 This avoids duplicate plugin menus for every class, which is necessary
759 to make the plugin category menu at all usable, but is obviously a
762 In the short term, lrdf could be updated so the labels match and a new
763 release made. To support both specs, we should probably be mapping the
764 URIs to the same category in code and perhaps tweaking that hierarchy
765 dynamically to suit the user. Personally, I (drobilla) think that time
766 is better spent replacing the little-used LRDF.
768 In the longer term, we will abandon LRDF entirely in favour of LV2 and
769 use that class hierarchy. Aside from fixing this problem properly, that
770 will also allow for translated labels. SWH plugins have been LV2 for
771 ages; TAP needs porting. I don't know of anything else with LRDF data.
773 if (label == "Utilities") {
775 } else if (label == "Pitch shifters") {
776 return "Pitch Shifter";
777 } else if (label != "Dynamics" && label != "Chorus"
778 &&label[label.length() - 1] == 's'
779 && label[label.length() - 2] != 's') {
780 return label.substr(0, label.length() - 1);
791 PluginManager::lv2_refresh ()
793 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
794 delete _lv2_plugin_info;
795 _lv2_plugin_info = LV2PluginInfo::discover();
799 #ifdef AUDIOUNIT_SUPPORT
801 PluginManager::au_refresh (bool cache_only)
803 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
805 // disable automatic discovery in case we crash
806 bool discover_at_start = Config->get_discover_audio_units ();
807 Config->set_discover_audio_units (false);
808 Config->save_state();
810 delete _au_plugin_info;
811 _au_plugin_info = AUPluginInfo::discover(cache_only && !discover_at_start);
813 // successful scan re-enabled automatic discovery if it was set
814 Config->set_discover_audio_units (discover_at_start);
815 Config->save_state();
820 #ifdef WINDOWS_VST_SUPPORT
823 PluginManager::windows_vst_refresh (bool cache_only)
825 if (_windows_vst_plugin_info) {
826 _windows_vst_plugin_info->clear ();
828 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
831 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
834 static bool windows_vst_filter (const string& str, void * /*arg*/)
836 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
837 return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
841 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
843 vector<string> plugin_objects;
844 vector<string>::iterator x;
847 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path));
849 if (Session::get_disable_all_loaded_plugins ()) {
850 info << _("Disabled WindowsVST scan (safe mode)") << endmsg;
854 if (Config->get_verbose_plugin_scan()) {
855 info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
858 find_files_matching_filter (plugin_objects, path, windows_vst_filter, 0, false, true, true);
860 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
861 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
862 windows_vst_discover (*x, cache_only || cancelled());
865 if (Config->get_verbose_plugin_scan()) {
866 info << _("--- Windows VST plugins Scan Done") << endmsg;
872 static std::string dll_info (std::string path) {
876 off_t pe_hdr_off = 0;
878 int fd = g_open(path.c_str(), O_RDONLY, 0444);
881 return _("cannot open dll"); // TODO strerror()
884 if (68 != read (fd, buf, 68)) {
885 rv = _("invalid dll, file too small");
888 if (buf[0] != 'M' && buf[1] != 'Z') {
893 pe_hdr_off = *((int32_t*) &buf[60]);
894 if (pe_hdr_off !=lseek (fd, pe_hdr_off, SEEK_SET)) {
895 rv = _("cannot determine dll type");
898 if (6 != read (fd, buf, 6)) {
899 rv = _("cannot read dll PE header");
903 if (buf[0] != 'P' && buf[1] != 'E') {
904 rv = _("invalid dll PE header");
908 type = *((uint16_t*) &buf[4]);
911 rv = _("i386 (32-bit)");
917 rv = _("x64 (64-bit)");
920 rv = _("Native Architecture");
923 rv = _("Unknown Architecture");
927 assert (rv.length() > 0);
933 PluginManager::windows_vst_discover (string path, bool cache_only)
935 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
937 if (Config->get_verbose_plugin_scan()) {
939 info << string_compose (_(" * %1 (cache only)"), path) << endmsg;
941 info << string_compose (_(" * %1 - %2"), path, dll_info (path)) << endmsg;
945 _cancel_timeout = false;
946 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
947 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
949 // TODO get extended error messae from vstfx_get_info_fst() e.g blacklisted, 32/64bit compat,
950 // .err file scanner output etc.
952 if (finfos->empty()) {
953 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
954 if (Config->get_verbose_plugin_scan()) {
955 info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
960 uint32_t discovered = 0;
961 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
965 if (!finfo->canProcessReplacing) {
966 warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
967 finfo->name, PROGRAM_NAME)
972 PluginInfoPtr info (new WindowsVSTPluginInfo);
974 /* what a joke freeware VST is */
976 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
977 info->name = PBD::basename_nosuffix (path);
979 info->name = finfo->name;
983 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
984 info->unique_id = buf;
985 info->category = "VST";
987 info->creator = finfo->creator;
989 info->n_inputs.set_audio (finfo->numInputs);
990 info->n_outputs.set_audio (finfo->numOutputs);
991 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
992 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
993 info->type = ARDOUR::Windows_VST;
995 // TODO: check dup-IDs (lxvst AND windows vst)
996 bool duplicate = false;
998 if (!_windows_vst_plugin_info->empty()) {
999 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
1000 if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
1001 warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
1009 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
1010 _windows_vst_plugin_info->push_back (info);
1012 if (Config->get_verbose_plugin_scan()) {
1013 PBD::info << string_compose (_(" -> OK (VST Plugin \"%1\" was added)."), info->name) << endmsg;
1018 vstfx_free_info_list (finfos);
1019 return discovered > 0 ? 0 : -1;
1022 #endif // WINDOWS_VST_SUPPORT
1024 #ifdef MACVST_SUPPORT
1026 PluginManager::mac_vst_refresh (bool cache_only)
1028 if (_mac_vst_plugin_info) {
1029 _mac_vst_plugin_info->clear ();
1031 _mac_vst_plugin_info = new ARDOUR::PluginInfoList();
1034 mac_vst_discover_from_path ("~/Library/Audio/Plug-Ins/VST:/Library/Audio/Plug-Ins/VST", cache_only);
1037 static bool mac_vst_filter (const string& str, void *)
1039 if (!Glib::file_test (str, Glib::FILE_TEST_IS_DIR)) {
1042 string plist = Glib::build_filename (str, "Contents", "Info.plist");
1043 if (!Glib::file_test (plist, Glib::FILE_TEST_IS_REGULAR)) {
1046 return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".vst", str.substr(str.length() - 4));
1050 PluginManager::mac_vst_discover_from_path (string path, bool cache_only)
1052 vector<string> plugin_objects;
1053 vector<string>::iterator x;
1055 if (Session::get_disable_all_loaded_plugins ()) {
1056 info << _("Disabled MacVST scan (safe mode)") << endmsg;
1060 find_paths_matching_filter (plugin_objects, path, mac_vst_filter, 0, true, true, true);
1062 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
1063 ARDOUR::PluginScanMessage(_("MacVST"), *x, !cache_only && !cancelled());
1064 mac_vst_discover (*x, cache_only || cancelled());
1070 PluginManager::mac_vst_discover (string path, bool cache_only)
1072 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent MacVST plugin at %1\n", path));
1074 _cancel_timeout = false;
1076 vector<VSTInfo*>* finfos = vstfx_get_info_mac (const_cast<char *> (path.c_str()),
1077 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
1079 if (finfos->empty()) {
1080 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Mac VST information from '%1'\n", path));
1084 uint32_t discovered = 0;
1085 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
1086 VSTInfo* finfo = *x;
1089 if (!finfo->canProcessReplacing) {
1090 warning << string_compose (_("Mac VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
1091 finfo->name, PROGRAM_NAME)
1096 PluginInfoPtr info (new MacVSTPluginInfo);
1098 info->name = finfo->name;
1100 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
1101 info->unique_id = buf;
1102 info->category = "MacVST";
1104 info->creator = finfo->creator;
1106 info->n_inputs.set_audio (finfo->numInputs);
1107 info->n_outputs.set_audio (finfo->numOutputs);
1108 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
1109 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
1110 info->type = ARDOUR::MacVST;
1112 bool duplicate = false;
1113 if (!_mac_vst_plugin_info->empty()) {
1114 for (PluginInfoList::iterator i =_mac_vst_plugin_info->begin(); i != _mac_vst_plugin_info->end(); ++i) {
1115 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
1116 warning << "Ignoring duplicate Mac VST plugin " << info->name << "\n";
1124 _mac_vst_plugin_info->push_back (info);
1129 vstfx_free_info_list (finfos);
1130 return discovered > 0 ? 0 : -1;
1133 #endif // MAC_VST_SUPPORT
1135 #ifdef LXVST_SUPPORT
1138 PluginManager::lxvst_refresh (bool cache_only)
1140 if (_lxvst_plugin_info) {
1141 _lxvst_plugin_info->clear ();
1143 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
1146 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
1149 static bool lxvst_filter (const string& str, void *)
1151 /* Not a dotfile, has a prefix before a period, suffix is "so" */
1153 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
1157 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
1159 vector<string> plugin_objects;
1160 vector<string>::iterator x;
1163 if (Session::get_disable_all_loaded_plugins ()) {
1164 info << _("Disabled LinuxVST scan (safe mode)") << endmsg;
1172 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
1174 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
1176 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
1177 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
1178 lxvst_discover (*x, cache_only || cancelled());
1185 PluginManager::lxvst_discover (string path, bool cache_only)
1187 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
1189 _cancel_timeout = false;
1190 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
1191 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
1193 if (finfos->empty()) {
1194 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
1198 uint32_t discovered = 0;
1199 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
1200 VSTInfo* finfo = *x;
1203 if (!finfo->canProcessReplacing) {
1204 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
1205 finfo->name, PROGRAM_NAME)
1210 PluginInfoPtr info(new LXVSTPluginInfo);
1212 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
1213 info->name = PBD::basename_nosuffix (path);
1215 info->name = finfo->name;
1219 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
1220 info->unique_id = buf;
1221 info->category = "linuxVSTs";
1223 info->creator = finfo->creator;
1225 info->n_inputs.set_audio (finfo->numInputs);
1226 info->n_outputs.set_audio (finfo->numOutputs);
1227 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
1228 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
1229 info->type = ARDOUR::LXVST;
1231 /* Make sure we don't find the same plugin in more than one place along
1232 the LXVST_PATH We can't use a simple 'find' because the path is included
1233 in the PluginInfo, and that is the one thing we can be sure MUST be
1234 different if a duplicate instance is found. So we just compare the type
1235 and unique ID (which for some VSTs isn't actually unique...)
1238 // TODO: check dup-IDs with windowsVST, too
1239 bool duplicate = false;
1240 if (!_lxvst_plugin_info->empty()) {
1241 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
1242 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
1243 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
1251 _lxvst_plugin_info->push_back (info);
1256 vstfx_free_info_list (finfos);
1257 return discovered > 0 ? 0 : -1;
1260 #endif // LXVST_SUPPORT
1263 PluginManager::PluginStatusType
1264 PluginManager::get_status (const PluginInfoPtr& pi) const
1266 PluginStatus ps (pi->type, pi->unique_id);
1267 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
1268 if (i == statuses.end() ) {
1276 PluginManager::save_statuses ()
1278 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1281 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
1282 switch ((*i).type) {
1293 ofs << "Windows-VST";
1308 switch ((*i).status) {
1321 ofs << (*i).unique_id;;
1324 g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL);
1325 PluginStatusesChanged (); /* EMIT SIGNAL */
1329 PluginManager::load_statuses ()
1331 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1333 if (!g_file_get_contents (path.c_str(), &fbuf, NULL, NULL)) {
1336 stringstream ifs (fbuf);
1340 std::string sstatus;
1343 PluginStatusType status;
1360 /* rest of the line is the plugin ID */
1362 ifs.getline (buf, sizeof (buf), '\n');
1367 if (sstatus == "Normal") {
1369 } else if (sstatus == "Favorite") {
1371 } else if (sstatus == "Hidden") {
1374 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1380 if (stype == "LADSPA") {
1382 } else if (stype == "AudioUnit") {
1384 } else if (stype == "LV2") {
1386 } else if (stype == "Windows-VST") {
1388 } else if (stype == "LXVST") {
1390 } else if (stype == "MacVST") {
1392 } else if (stype == "Lua") {
1395 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1401 strip_whitespace_edges (id);
1402 set_status (type, id, status);
1407 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1409 PluginStatus ps (t, id, status);
1410 statuses.erase (ps);
1412 if (status == Normal) {
1416 statuses.insert (ps);
1419 const ARDOUR::PluginInfoList&
1420 PluginManager::windows_vst_plugin_info ()
1422 #ifdef WINDOWS_VST_SUPPORT
1423 if (!_windows_vst_plugin_info) {
1424 windows_vst_refresh ();
1426 return *_windows_vst_plugin_info;
1428 return _empty_plugin_info;
1432 const ARDOUR::PluginInfoList&
1433 PluginManager::mac_vst_plugin_info ()
1435 #ifdef MACVST_SUPPORT
1436 assert(_mac_vst_plugin_info);
1437 return *_mac_vst_plugin_info;
1439 return _empty_plugin_info;
1443 const ARDOUR::PluginInfoList&
1444 PluginManager::lxvst_plugin_info ()
1446 #ifdef LXVST_SUPPORT
1447 assert(_lxvst_plugin_info);
1448 return *_lxvst_plugin_info;
1450 return _empty_plugin_info;
1454 const ARDOUR::PluginInfoList&
1455 PluginManager::ladspa_plugin_info ()
1457 assert(_ladspa_plugin_info);
1458 return *_ladspa_plugin_info;
1461 const ARDOUR::PluginInfoList&
1462 PluginManager::lv2_plugin_info ()
1465 assert(_lv2_plugin_info);
1466 return *_lv2_plugin_info;
1468 return _empty_plugin_info;
1472 const ARDOUR::PluginInfoList&
1473 PluginManager::au_plugin_info ()
1475 #ifdef AUDIOUNIT_SUPPORT
1476 if (_au_plugin_info) {
1477 return *_au_plugin_info;
1480 return _empty_plugin_info;
1483 const ARDOUR::PluginInfoList&
1484 PluginManager::lua_plugin_info ()
1486 assert(_lua_plugin_info);
1487 return *_lua_plugin_info;