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
58 #include <glibmm/miscutils.h>
59 #include <glibmm/pattern.h>
60 #include <glibmm/fileutils.h>
61 #include <glibmm/miscutils.h>
63 #include "pbd/whitespace.h"
64 #include "pbd/file_utils.h"
66 #include "ardour/debug.h"
67 #include "ardour/filesystem_paths.h"
68 #include "ardour/ladspa.h"
69 #include "ardour/ladspa_plugin.h"
70 #include "ardour/plugin.h"
71 #include "ardour/plugin_manager.h"
72 #include "ardour/rc_configuration.h"
74 #include "ardour/search_paths.h"
77 #include "ardour/lv2_plugin.h"
80 #ifdef WINDOWS_VST_SUPPORT
81 #include "ardour/windows_vst_plugin.h"
85 #include "ardour/lxvst_plugin.h"
88 #ifdef AUDIOUNIT_SUPPORT
89 #include "ardour/audio_unit.h"
90 #include <Carbon/Carbon.h>
93 #include "pbd/error.h"
94 #include "pbd/stl_delete.h"
98 #include "ardour/debug.h"
100 using namespace ARDOUR;
104 PluginManager* PluginManager::_instance = 0;
105 std::string PluginManager::scanner_bin_path = "";
108 PluginManager::instance()
111 _instance = new PluginManager;
116 PluginManager::PluginManager ()
117 : _windows_vst_plugin_info(0)
118 , _lxvst_plugin_info(0)
119 , _ladspa_plugin_info(0)
120 , _lv2_plugin_info(0)
122 , _cancel_scan(false)
123 , _cancel_timeout(false)
128 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
129 // source-tree (ardev, etc)
130 PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
132 #ifdef PLATFORM_WINDOWS
133 // on windows the .exe needs to be in the same folder with libardour.dll
134 vstsp += Glib::build_filename(windows_package_directory_path(), "bin");
136 // on Unices additional internal-use binaries are deployed to $libdir
137 vstsp += ARDOUR::ardour_dll_directory();
140 if (!PBD::find_file (vstsp,
141 #ifdef PLATFORM_WINDOWS
142 #ifdef DEBUGGABLE_SCANNER_APP
143 #if defined(DEBUG) || defined(_DEBUG)
144 "ardour-vst-scannerD.exe"
146 "ardour-vst-scannerRDC.exe"
149 "ardour-vst-scanner.exe"
154 , scanner_bin_path)) {
155 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << vstsp.to_string() << endmsg;
161 if ((s = getenv ("LADSPA_RDF_PATH"))){
165 if (lrdf_path.length() == 0) {
166 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
169 add_lrdf_data(lrdf_path);
170 add_ladspa_presets();
171 #ifdef WINDOWS_VST_SUPPORT
172 if (Config->get_use_windows_vst ()) {
173 add_windows_vst_presets ();
175 #endif /* WINDOWS_VST_SUPPORT */
178 if (Config->get_use_lxvst()) {
181 #endif /* Native LinuxVST support*/
183 if ((s = getenv ("VST_PATH"))) {
184 windows_vst_path = s;
185 } else if ((s = getenv ("VST_PLUGINS"))) {
186 windows_vst_path = s;
189 if (windows_vst_path.length() == 0) {
190 windows_vst_path = vst_search_path ();
193 if ((s = getenv ("LXVST_PATH"))) {
195 } else if ((s = getenv ("LXVST_PLUGINS"))) {
199 if (lxvst_path.length() == 0) {
200 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
201 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
202 "/usr/lib/vst:/usr/local/lib/vst";
205 /* first time setup, use 'default' path */
206 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
207 Config->set_plugin_path_lxvst(get_default_lxvst_path());
209 if (Config->get_plugin_path_vst() == X_("@default@")) {
210 Config->set_plugin_path_vst(get_default_windows_vst_path());
213 if (_instance == 0) {
217 BootMessage (_("Discovering Plugins"));
221 PluginManager::~PluginManager()
223 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
224 // don't bother, just exit quickly.
225 delete _windows_vst_plugin_info;
226 delete _lxvst_plugin_info;
227 delete _ladspa_plugin_info;
228 delete _lv2_plugin_info;
229 delete _au_plugin_info;
234 PluginManager::refresh (bool cache_only)
236 Glib::Threads::Mutex::Lock lm (_lock, Glib::Threads::TRY_LOCK);
242 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
243 _cancel_scan = false;
245 BootMessage (_("Scanning LADSPA Plugins"));
248 BootMessage (_("Scanning LV2 Plugins"));
251 #ifdef WINDOWS_VST_SUPPORT
252 if (Config->get_use_windows_vst()) {
254 BootMessage (_("Scanning Windows VST Plugins"));
256 BootMessage (_("Discovering Windows VST Plugins"));
258 windows_vst_refresh (cache_only);
260 #endif // WINDOWS_VST_SUPPORT
263 if(Config->get_use_lxvst()) {
265 BootMessage (_("Scanning Linux VST Plugins"));
267 BootMessage (_("Discovering Linux VST Plugins"));
269 lxvst_refresh(cache_only);
271 #endif //Native linuxVST SUPPORT
273 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
275 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
276 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
278 if (g_file_get_contents(fn.c_str (), &bl, NULL, NULL)) {
279 if (Config->get_verbose_plugin_scan()) {
280 PBD::info << _("VST Blacklist: ") << fn << "\n" << bl << "-----" << endmsg;
282 PBD::info << _("VST Blacklist:") << "\n" << bl << "-----" << endmsg;
290 #ifdef AUDIOUNIT_SUPPORT
292 BootMessage (_("Scanning AU Plugins"));
294 BootMessage (_("Discovering AU Plugins"));
296 au_refresh (cache_only);
299 BootMessage (_("Plugin Scan Complete..."));
300 PluginListChanged (); /* EMIT SIGNAL */
301 PluginScanMessage(X_("closeme"), "", false);
302 _cancel_scan = false;
306 PluginManager::cancel_plugin_scan ()
312 PluginManager::cancel_plugin_timeout ()
314 _cancel_timeout = true;
318 PluginManager::clear_vst_cache ()
320 #if 1 // clean old cache and error files. (remove this code after 4.3 or 5.0)
321 #ifdef WINDOWS_VST_SUPPORT
323 vector<string> fsi_files;
324 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_INFOFILE "$", true);
325 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
326 ::g_unlink(i->c_str());
330 vector<string> fsi_files;
331 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
332 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
333 ::g_unlink(i->c_str());
337 vector<string> fsi_files;
338 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.err$", true);
339 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
340 ::g_unlink(i->c_str());
347 vector<string> fsi_files;
348 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_INFOFILE "$", true);
349 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
350 ::g_unlink(i->c_str());
354 vector<string> fsi_files;
355 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
356 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
357 ::g_unlink(i->c_str());
361 vector<string> fsi_files;
362 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.err$", true);
363 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
364 ::g_unlink(i->c_str());
368 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
370 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_info");
371 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
372 PBD::remove_directory (dir);
376 #endif // old cache cleanup
378 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
380 string dn = Glib::build_filename (ARDOUR::user_cache_directory(), "vst");
381 vector<string> fsi_files;
382 find_files_matching_regex (fsi_files, dn, "\\" VST_EXT_INFOFILE "$", /* user cache is flat, no recursion */ false);
383 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
384 ::g_unlink(i->c_str());
391 PluginManager::clear_vst_blacklist ()
393 #if 1 // remove old blacklist files. (remove this code after 4.3 or 5.0)
395 #ifdef WINDOWS_VST_SUPPORT
397 vector<string> fsi_files;
398 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_BLACKLIST "$", true);
399 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
400 ::g_unlink(i->c_str());
407 vector<string> fsi_files;
408 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_BLACKLIST "$", true);
409 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
410 ::g_unlink(i->c_str());
414 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
416 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_blacklist");
417 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
418 PBD::remove_directory (dir);
423 #endif // old blacklist cleanup
425 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
427 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
428 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
429 ::g_unlink (fn.c_str());
437 PluginManager::clear_au_cache ()
439 #ifdef AUDIOUNIT_SUPPORT
440 AUPluginInfo::clear_cache ();
445 PluginManager::clear_au_blacklist ()
447 #ifdef AUDIOUNIT_SUPPORT
448 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_blacklist.txt");
449 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
450 ::g_unlink(fn.c_str());
456 PluginManager::ladspa_refresh ()
458 if (_ladspa_plugin_info) {
459 _ladspa_plugin_info->clear ();
461 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
464 /* allow LADSPA_PATH to augment, not override standard locations */
466 /* Only add standard locations to ladspa_path if it doesn't
467 * already contain them. Check for trailing G_DIR_SEPARATOR too.
470 vector<string> ladspa_modules;
472 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
474 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
475 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
476 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
478 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
479 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
480 ladspa_discover (*i);
485 static bool rdf_filter (const string &str, void* /*arg*/)
487 return str[0] != '.' &&
488 ((str.find(".rdf") == (str.length() - 4)) ||
489 (str.find(".rdfs") == (str.length() - 5)) ||
490 (str.find(".n3") == (str.length() - 3)) ||
491 (str.find(".ttl") == (str.length() - 4)));
496 PluginManager::add_ladspa_presets()
498 add_presets ("ladspa");
502 PluginManager::add_windows_vst_presets()
504 add_presets ("windows-vst");
508 PluginManager::add_lxvst_presets()
510 add_presets ("lxvst");
514 PluginManager::add_presets(string domain)
517 vector<string> presets;
518 vector<string>::iterator x;
521 if ((envvar = getenv ("HOME")) == 0) {
525 string path = string_compose("%1/.%2/rdf", envvar, domain);
526 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
528 for (x = presets.begin(); x != presets.end (); ++x) {
529 string file = "file:" + *x;
530 if (lrdf_read_file(file.c_str())) {
531 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
539 PluginManager::add_lrdf_data (const string &path)
542 vector<string> rdf_files;
543 vector<string>::iterator x;
545 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
547 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
548 const string uri(string("file://") + *x);
550 if (lrdf_read_file(uri.c_str())) {
551 warning << "Could not parse rdf file: " << uri << endmsg;
558 PluginManager::ladspa_discover (string path)
560 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
562 Glib::Module module(path);
563 const LADSPA_Descriptor *descriptor;
564 LADSPA_Descriptor_Function dfunc;
568 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
569 path, Glib::Module::get_last_error()) << endmsg;
574 if (!module.get_symbol("ladspa_descriptor", func)) {
575 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
576 error << Glib::Module::get_last_error() << endmsg;
580 dfunc = (LADSPA_Descriptor_Function)func;
582 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
584 for (uint32_t i = 0; ; ++i) {
585 /* if a ladspa plugin allocates memory here
586 * it is never free()ed (or plugin-dependent only when unloading).
587 * For some plugins memory allocated is incremental, we should
588 * avoid re-scanning plugins and file bug reports.
590 if ((descriptor = dfunc (i)) == 0) {
594 if (!ladspa_plugin_whitelist.empty()) {
595 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
600 PluginInfoPtr info(new LadspaPluginInfo);
601 info->name = descriptor->Name;
602 info->category = get_ladspa_category(descriptor->UniqueID);
603 info->creator = descriptor->Maker;
606 info->n_inputs = ChanCount();
607 info->n_outputs = ChanCount();
608 info->type = ARDOUR::LADSPA;
611 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
612 info->unique_id = buf;
614 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
615 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
616 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
617 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
619 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
620 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
625 if(_ladspa_plugin_info->empty()){
626 _ladspa_plugin_info->push_back (info);
629 //Ensure that the plugin is not already in the plugin list.
633 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
634 if(0 == info->unique_id.compare((*i)->unique_id)){
640 _ladspa_plugin_info->push_back (info);
643 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
646 // GDB WILL NOT LIKE YOU IF YOU DO THIS
653 PluginManager::get_ladspa_category (uint32_t plugin_id)
657 lrdf_statement pattern;
659 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
660 pattern.subject = buf;
661 pattern.predicate = const_cast<char*>(RDF_TYPE);
663 pattern.object_type = lrdf_uri;
665 lrdf_statement* matches1 = lrdf_matches (&pattern);
671 pattern.subject = matches1->object;
672 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
674 pattern.object_type = lrdf_literal;
676 lrdf_statement* matches2 = lrdf_matches (&pattern);
677 lrdf_free_statements(matches1);
683 string label = matches2->object;
684 lrdf_free_statements(matches2);
686 /* Kludge LADSPA class names to be singular and match LV2 class names.
687 This avoids duplicate plugin menus for every class, which is necessary
688 to make the plugin category menu at all usable, but is obviously a
691 In the short term, lrdf could be updated so the labels match and a new
692 release made. To support both specs, we should probably be mapping the
693 URIs to the same category in code and perhaps tweaking that hierarchy
694 dynamically to suit the user. Personally, I (drobilla) think that time
695 is better spent replacing the little-used LRDF.
697 In the longer term, we will abandon LRDF entirely in favour of LV2 and
698 use that class hierarchy. Aside from fixing this problem properly, that
699 will also allow for translated labels. SWH plugins have been LV2 for
700 ages; TAP needs porting. I don't know of anything else with LRDF data.
702 if (label == "Utilities") {
704 } else if (label == "Pitch shifters") {
705 return "Pitch Shifter";
706 } else if (label != "Dynamics" && label != "Chorus"
707 &&label[label.length() - 1] == 's'
708 && label[label.length() - 2] != 's') {
709 return label.substr(0, label.length() - 1);
720 PluginManager::lv2_refresh ()
722 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
723 delete _lv2_plugin_info;
724 _lv2_plugin_info = LV2PluginInfo::discover();
728 #ifdef AUDIOUNIT_SUPPORT
730 PluginManager::au_refresh (bool cache_only)
732 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
734 // disable automatic discovery in case we crash
735 bool discover_at_start = Config->get_discover_audio_units ();
736 Config->set_discover_audio_units (false);
737 Config->save_state();
739 delete _au_plugin_info;
740 _au_plugin_info = AUPluginInfo::discover(cache_only && !discover_at_start);
742 // successful scan re-enabled automatic discovery if it was set
743 Config->set_discover_audio_units (discover_at_start);
744 Config->save_state();
749 #ifdef WINDOWS_VST_SUPPORT
752 PluginManager::windows_vst_refresh (bool cache_only)
754 if (_windows_vst_plugin_info) {
755 _windows_vst_plugin_info->clear ();
757 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
760 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
763 static bool windows_vst_filter (const string& str, void * /*arg*/)
765 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
766 return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
770 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
772 vector<string> plugin_objects;
773 vector<string>::iterator x;
776 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path));
778 if (Config->get_verbose_plugin_scan()) {
779 info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
782 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
784 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
785 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
786 windows_vst_discover (*x, cache_only || cancelled());
789 if (Config->get_verbose_plugin_scan()) {
790 info << _("--- Windows VST plugins Scan Done") << endmsg;
796 static std::string dll_info (std::string path) {
800 off_t pe_hdr_off = 0;
802 int fd = g_open(path.c_str(), O_RDONLY, 0444);
805 return _("cannot open dll"); // TODO strerror()
808 if (68 != read (fd, buf, 68)) {
809 rv = _("invalid dll, file too small");
812 if (buf[0] != 'M' && buf[1] != 'Z') {
817 pe_hdr_off = *((int32_t*) &buf[60]);
818 if (pe_hdr_off !=lseek (fd, pe_hdr_off, SEEK_SET)) {
819 rv = _("cannot determine dll type");
822 if (6 != read (fd, buf, 6)) {
823 rv = _("cannot read dll PE header");
827 if (buf[0] != 'P' && buf[1] != 'E') {
828 rv = _("invalid dll PE header");
832 type = *((uint16_t*) &buf[4]);
835 rv = _("i386 (32-bit)");
841 rv = _("x64 (64-bit)");
844 rv = _("Native Architecture");
847 rv = _("Unknown Architecture");
851 assert (rv.length() > 0);
857 PluginManager::windows_vst_discover (string path, bool cache_only)
859 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
861 if (Config->get_verbose_plugin_scan()) {
863 info << string_compose (_(" * %1 (cache only)"), path) << endmsg;
865 info << string_compose (_(" * %1 - %2"), path, dll_info (path)) << endmsg;
869 _cancel_timeout = false;
870 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
871 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
873 // TODO get extended error messae from vstfx_get_info_fst() e.g blacklisted, 32/64bit compat,
874 // .err file scanner output etc.
876 if (finfos->empty()) {
877 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
878 if (Config->get_verbose_plugin_scan()) {
879 info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
884 uint32_t discovered = 0;
885 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
889 if (!finfo->canProcessReplacing) {
890 warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
891 finfo->name, PROGRAM_NAME)
896 PluginInfoPtr info (new WindowsVSTPluginInfo);
898 /* what a joke freeware VST is */
900 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
901 info->name = PBD::basename_nosuffix (path);
903 info->name = finfo->name;
907 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
908 info->unique_id = buf;
909 info->category = "VST";
911 info->creator = finfo->creator;
913 info->n_inputs.set_audio (finfo->numInputs);
914 info->n_outputs.set_audio (finfo->numOutputs);
915 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
916 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
917 info->type = ARDOUR::Windows_VST;
919 // TODO: check dup-IDs (lxvst AND windows vst)
920 bool duplicate = false;
922 if (!_windows_vst_plugin_info->empty()) {
923 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
924 if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
925 warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
933 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
934 _windows_vst_plugin_info->push_back (info);
936 if (Config->get_verbose_plugin_scan()) {
937 PBD::info << string_compose (_(" -> OK (VST Plugin \"%1\" was added)."), info->name) << endmsg;
942 vstfx_free_info_list (finfos);
943 return discovered > 0 ? 0 : -1;
946 #endif // WINDOWS_VST_SUPPORT
951 PluginManager::lxvst_refresh (bool cache_only)
953 if (_lxvst_plugin_info) {
954 _lxvst_plugin_info->clear ();
956 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
959 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
962 static bool lxvst_filter (const string& str, void *)
964 /* Not a dotfile, has a prefix before a period, suffix is "so" */
966 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
970 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
972 vector<string> plugin_objects;
973 vector<string>::iterator x;
980 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
982 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
984 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
985 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
986 lxvst_discover (*x, cache_only || cancelled());
993 PluginManager::lxvst_discover (string path, bool cache_only)
995 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
997 _cancel_timeout = false;
998 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
999 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
1001 if (finfos->empty()) {
1002 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
1006 uint32_t discovered = 0;
1007 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
1008 VSTInfo* finfo = *x;
1011 if (!finfo->canProcessReplacing) {
1012 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
1013 finfo->name, PROGRAM_NAME)
1018 PluginInfoPtr info(new LXVSTPluginInfo);
1020 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
1021 info->name = PBD::basename_nosuffix (path);
1023 info->name = finfo->name;
1027 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
1028 info->unique_id = buf;
1029 info->category = "linuxVSTs";
1031 info->creator = finfo->creator;
1033 info->n_inputs.set_audio (finfo->numInputs);
1034 info->n_outputs.set_audio (finfo->numOutputs);
1035 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
1036 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
1037 info->type = ARDOUR::LXVST;
1039 /* Make sure we don't find the same plugin in more than one place along
1040 the LXVST_PATH We can't use a simple 'find' because the path is included
1041 in the PluginInfo, and that is the one thing we can be sure MUST be
1042 different if a duplicate instance is found. So we just compare the type
1043 and unique ID (which for some VSTs isn't actually unique...)
1046 // TODO: check dup-IDs with windowsVST, too
1047 bool duplicate = false;
1048 if (!_lxvst_plugin_info->empty()) {
1049 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
1050 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
1051 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
1059 _lxvst_plugin_info->push_back (info);
1064 vstfx_free_info_list (finfos);
1065 return discovered > 0 ? 0 : -1;
1068 #endif // LXVST_SUPPORT
1071 PluginManager::PluginStatusType
1072 PluginManager::get_status (const PluginInfoPtr& pi)
1074 PluginStatus ps (pi->type, pi->unique_id);
1075 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
1076 if (i == statuses.end() ) {
1084 PluginManager::save_statuses ()
1086 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1089 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
1090 switch ((*i).type) {
1101 ofs << "Windows-VST";
1114 switch ((*i).status) {
1127 ofs << (*i).unique_id;;
1130 g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL);
1131 PluginStatusesChanged (); /* EMIT SIGNAL */
1135 PluginManager::load_statuses ()
1137 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1139 if (!g_file_get_contents (path.c_str(), &fbuf, NULL, NULL)) {
1142 stringstream ifs (fbuf);
1146 std::string sstatus;
1149 PluginStatusType status;
1166 /* rest of the line is the plugin ID */
1168 ifs.getline (buf, sizeof (buf), '\n');
1173 if (sstatus == "Normal") {
1175 } else if (sstatus == "Favorite") {
1177 } else if (sstatus == "Hidden") {
1180 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1186 if (stype == "LADSPA") {
1188 } else if (stype == "AudioUnit") {
1190 } else if (stype == "LV2") {
1192 } else if (stype == "Windows-VST") {
1194 } else if (stype == "LXVST") {
1197 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1203 strip_whitespace_edges (id);
1204 set_status (type, id, status);
1209 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1211 PluginStatus ps (t, id, status);
1212 statuses.erase (ps);
1214 if (status == Normal) {
1218 statuses.insert (ps);
1221 ARDOUR::PluginInfoList&
1222 PluginManager::windows_vst_plugin_info ()
1224 #ifdef WINDOWS_VST_SUPPORT
1225 if (!_windows_vst_plugin_info) {
1226 windows_vst_refresh ();
1228 return *_windows_vst_plugin_info;
1230 return _empty_plugin_info;
1234 ARDOUR::PluginInfoList&
1235 PluginManager::lxvst_plugin_info ()
1237 #ifdef LXVST_SUPPORT
1238 assert(_lxvst_plugin_info);
1239 return *_lxvst_plugin_info;
1241 return _empty_plugin_info;
1245 ARDOUR::PluginInfoList&
1246 PluginManager::ladspa_plugin_info ()
1248 assert(_ladspa_plugin_info);
1249 return *_ladspa_plugin_info;
1252 ARDOUR::PluginInfoList&
1253 PluginManager::lv2_plugin_info ()
1256 assert(_lv2_plugin_info);
1257 return *_lv2_plugin_info;
1259 return _empty_plugin_info;
1263 ARDOUR::PluginInfoList&
1264 PluginManager::au_plugin_info ()
1266 #ifdef AUDIOUNIT_SUPPORT
1267 if (_au_plugin_info) {
1268 return *_au_plugin_info;
1271 return _empty_plugin_info;