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 PBD::info << _("VST Blacklist:") << "\n" << bl << "-----" << endmsg;
286 #ifdef AUDIOUNIT_SUPPORT
288 BootMessage (_("Scanning AU Plugins"));
290 BootMessage (_("Discovering AU Plugins"));
292 au_refresh (cache_only);
295 BootMessage (_("Plugin Scan Complete..."));
296 PluginListChanged (); /* EMIT SIGNAL */
297 PluginScanMessage(X_("closeme"), "", false);
298 _cancel_scan = false;
302 PluginManager::cancel_plugin_scan ()
308 PluginManager::cancel_plugin_timeout ()
310 _cancel_timeout = true;
314 PluginManager::clear_vst_cache ()
316 #if 1 // clean old cache and error files. (remove this code after 4.3 or 5.0)
317 #ifdef WINDOWS_VST_SUPPORT
319 vector<string> fsi_files;
320 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_INFOFILE "$", true);
321 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
322 ::g_unlink(i->c_str());
326 vector<string> fsi_files;
327 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
328 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
329 ::g_unlink(i->c_str());
333 vector<string> fsi_files;
334 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.err$", true);
335 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
336 ::g_unlink(i->c_str());
343 vector<string> fsi_files;
344 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_INFOFILE "$", true);
345 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
346 ::g_unlink(i->c_str());
350 vector<string> fsi_files;
351 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
352 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
353 ::g_unlink(i->c_str());
357 vector<string> fsi_files;
358 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.err$", true);
359 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
360 ::g_unlink(i->c_str());
364 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
366 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_info");
367 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
368 PBD::remove_directory (dir);
372 #endif // old cache cleanup
374 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
376 string dn = Glib::build_filename (ARDOUR::user_cache_directory(), "vst");
377 vector<string> fsi_files;
378 find_files_matching_regex (fsi_files, dn, "\\" VST_EXT_INFOFILE "$", /* user cache is flat, no recursion */ false);
379 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
380 ::g_unlink(i->c_str());
387 PluginManager::clear_vst_blacklist ()
389 #if 1 // remove old blacklist files. (remove this code after 4.3 or 5.0)
391 #ifdef WINDOWS_VST_SUPPORT
393 vector<string> fsi_files;
394 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_BLACKLIST "$", true);
395 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
396 ::g_unlink(i->c_str());
403 vector<string> fsi_files;
404 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_BLACKLIST "$", true);
405 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
406 ::g_unlink(i->c_str());
410 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
412 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_blacklist");
413 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
414 PBD::remove_directory (dir);
419 #endif // old blacklist cleanup
421 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
423 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
424 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
425 ::g_unlink (fn.c_str());
433 PluginManager::clear_au_cache ()
435 #ifdef AUDIOUNIT_SUPPORT
436 // AUPluginInfo::au_cache_path ()
437 string fn = Glib::build_filename (ARDOUR::user_config_directory(), "au_cache");
438 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
439 ::g_unlink(fn.c_str());
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 ((descriptor = dfunc (i)) == 0) {
589 if (!ladspa_plugin_whitelist.empty()) {
590 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
595 PluginInfoPtr info(new LadspaPluginInfo);
596 info->name = descriptor->Name;
597 info->category = get_ladspa_category(descriptor->UniqueID);
598 info->creator = descriptor->Maker;
601 info->n_inputs = ChanCount();
602 info->n_outputs = ChanCount();
603 info->type = ARDOUR::LADSPA;
606 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
607 info->unique_id = buf;
609 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
610 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
611 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
612 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
614 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
615 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
620 if(_ladspa_plugin_info->empty()){
621 _ladspa_plugin_info->push_back (info);
624 //Ensure that the plugin is not already in the plugin list.
628 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
629 if(0 == info->unique_id.compare((*i)->unique_id)){
635 _ladspa_plugin_info->push_back (info);
638 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
641 // GDB WILL NOT LIKE YOU IF YOU DO THIS
648 PluginManager::get_ladspa_category (uint32_t plugin_id)
652 lrdf_statement pattern;
654 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
655 pattern.subject = buf;
656 pattern.predicate = const_cast<char*>(RDF_TYPE);
658 pattern.object_type = lrdf_uri;
660 lrdf_statement* matches1 = lrdf_matches (&pattern);
666 pattern.subject = matches1->object;
667 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
669 pattern.object_type = lrdf_literal;
671 lrdf_statement* matches2 = lrdf_matches (&pattern);
672 lrdf_free_statements(matches1);
678 string label = matches2->object;
679 lrdf_free_statements(matches2);
681 /* Kludge LADSPA class names to be singular and match LV2 class names.
682 This avoids duplicate plugin menus for every class, which is necessary
683 to make the plugin category menu at all usable, but is obviously a
686 In the short term, lrdf could be updated so the labels match and a new
687 release made. To support both specs, we should probably be mapping the
688 URIs to the same category in code and perhaps tweaking that hierarchy
689 dynamically to suit the user. Personally, I (drobilla) think that time
690 is better spent replacing the little-used LRDF.
692 In the longer term, we will abandon LRDF entirely in favour of LV2 and
693 use that class hierarchy. Aside from fixing this problem properly, that
694 will also allow for translated labels. SWH plugins have been LV2 for
695 ages; TAP needs porting. I don't know of anything else with LRDF data.
697 if (label == "Utilities") {
699 } else if (label == "Pitch shifters") {
700 return "Pitch Shifter";
701 } else if (label != "Dynamics" && label != "Chorus"
702 &&label[label.length() - 1] == 's'
703 && label[label.length() - 2] != 's') {
704 return label.substr(0, label.length() - 1);
715 PluginManager::lv2_refresh ()
717 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
718 delete _lv2_plugin_info;
719 _lv2_plugin_info = LV2PluginInfo::discover();
723 #ifdef AUDIOUNIT_SUPPORT
725 PluginManager::au_refresh (bool cache_only)
727 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
729 // disable automatic discovery in case we crash
730 bool discover_at_start = Config->get_discover_audio_units ();
731 Config->set_discover_audio_units (false);
732 Config->save_state();
734 delete _au_plugin_info;
735 _au_plugin_info = AUPluginInfo::discover(cache_only && !discover_at_start);
737 // successful scan re-enabled automatic discovery if it was set
738 Config->set_discover_audio_units (discover_at_start);
739 Config->save_state();
744 #ifdef WINDOWS_VST_SUPPORT
747 PluginManager::windows_vst_refresh (bool cache_only)
749 if (_windows_vst_plugin_info) {
750 _windows_vst_plugin_info->clear ();
752 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
755 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
758 static bool windows_vst_filter (const string& str, void * /*arg*/)
760 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
761 return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
765 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
767 vector<string> plugin_objects;
768 vector<string>::iterator x;
771 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path));
773 if (Config->get_verbose_plugin_scan()) {
774 info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
777 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
779 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
780 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
781 windows_vst_discover (*x, cache_only || cancelled());
784 if (Config->get_verbose_plugin_scan()) {
785 info << _("--- Windows VST plugins Scan Done") << endmsg;
791 static std::string dll_info (std::string path) {
795 off_t pe_hdr_off = 0;
797 int fd = open(path.c_str(), O_RDONLY, 0444);
800 return _("- cannot open dll"); // TODO strerror()
803 if (68 != read (fd, buf, 68)) {
804 rv = _("- invalid dll, file too small");
807 if (buf[0] != 'M' && buf[1] != 'Z') {
808 rv = _("- not a dll");
812 pe_hdr_off = *((int32_t*) &buf[60]);
813 if (pe_hdr_off !=lseek (fd, pe_hdr_off, SEEK_SET)) {
814 rv = _("- cannot determine dll type");
817 if (6 != read (fd, buf, 6)) {
818 rv = _("- cannot read dll PE header");
822 if (buf[0] != 'P' && buf[1] != 'E') {
823 rv = _("- invalid dll PE header");
827 type = *((uint16_t*) &buf[4]);
830 rv = _("- i386 (32bit)");
836 rv = _("- x64 (64bit)");
839 rv = _("- Native Architecture");
842 rv = _("- Unknown Architecture");
851 PluginManager::windows_vst_discover (string path, bool cache_only)
853 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
855 if (Config->get_verbose_plugin_scan()) {
856 info << string_compose (_(" * %1 %2 %3"), path, (cache_only ? _(" (cache only)") : "", dll_info (path))) << endmsg;
859 _cancel_timeout = false;
860 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
861 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
863 // TODO get extended error messae from vstfx_get_info_fst() e.g blacklisted, 32/64bit compat,
864 // .err file scanner output etc.
866 if (finfos->empty()) {
867 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
868 if (Config->get_verbose_plugin_scan()) {
869 info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
874 uint32_t discovered = 0;
875 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
879 if (!finfo->canProcessReplacing) {
880 warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
881 finfo->name, PROGRAM_NAME)
886 PluginInfoPtr info (new WindowsVSTPluginInfo);
888 /* what a joke freeware VST is */
890 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
891 info->name = PBD::basename_nosuffix (path);
893 info->name = finfo->name;
897 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
898 info->unique_id = buf;
899 info->category = "VST";
901 info->creator = finfo->creator;
903 info->n_inputs.set_audio (finfo->numInputs);
904 info->n_outputs.set_audio (finfo->numOutputs);
905 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
906 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
907 info->type = ARDOUR::Windows_VST;
909 // TODO: check dup-IDs (lxvst AND windows vst)
910 bool duplicate = false;
912 if (!_windows_vst_plugin_info->empty()) {
913 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
914 if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
915 warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
923 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
924 _windows_vst_plugin_info->push_back (info);
926 if (Config->get_verbose_plugin_scan()) {
927 PBD::info << string_compose (_(" -> OK (VST Plugin \"%1\" was added)."), info->name) << endmsg;
932 vstfx_free_info_list (finfos);
933 return discovered > 0 ? 0 : -1;
936 #endif // WINDOWS_VST_SUPPORT
941 PluginManager::lxvst_refresh (bool cache_only)
943 if (_lxvst_plugin_info) {
944 _lxvst_plugin_info->clear ();
946 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
949 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
952 static bool lxvst_filter (const string& str, void *)
954 /* Not a dotfile, has a prefix before a period, suffix is "so" */
956 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
960 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
962 vector<string> plugin_objects;
963 vector<string>::iterator x;
970 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
972 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
974 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
975 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
976 lxvst_discover (*x, cache_only || cancelled());
983 PluginManager::lxvst_discover (string path, bool cache_only)
985 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
987 _cancel_timeout = false;
988 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
989 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
991 if (finfos->empty()) {
992 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
996 uint32_t discovered = 0;
997 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
1001 if (!finfo->canProcessReplacing) {
1002 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
1003 finfo->name, PROGRAM_NAME)
1008 PluginInfoPtr info(new LXVSTPluginInfo);
1010 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
1011 info->name = PBD::basename_nosuffix (path);
1013 info->name = finfo->name;
1017 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
1018 info->unique_id = buf;
1019 info->category = "linuxVSTs";
1021 info->creator = finfo->creator;
1023 info->n_inputs.set_audio (finfo->numInputs);
1024 info->n_outputs.set_audio (finfo->numOutputs);
1025 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
1026 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
1027 info->type = ARDOUR::LXVST;
1029 /* Make sure we don't find the same plugin in more than one place along
1030 the LXVST_PATH We can't use a simple 'find' because the path is included
1031 in the PluginInfo, and that is the one thing we can be sure MUST be
1032 different if a duplicate instance is found. So we just compare the type
1033 and unique ID (which for some VSTs isn't actually unique...)
1036 // TODO: check dup-IDs with windowsVST, too
1037 bool duplicate = false;
1038 if (!_lxvst_plugin_info->empty()) {
1039 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
1040 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
1041 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
1049 _lxvst_plugin_info->push_back (info);
1054 vstfx_free_info_list (finfos);
1055 return discovered > 0 ? 0 : -1;
1058 #endif // LXVST_SUPPORT
1061 PluginManager::PluginStatusType
1062 PluginManager::get_status (const PluginInfoPtr& pi)
1064 PluginStatus ps (pi->type, pi->unique_id);
1065 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
1066 if (i == statuses.end() ) {
1074 PluginManager::save_statuses ()
1076 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1079 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
1080 switch ((*i).type) {
1091 ofs << "Windows-VST";
1100 switch ((*i).status) {
1113 ofs << (*i).unique_id;;
1116 g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL);
1120 PluginManager::load_statuses ()
1122 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1124 if (!g_file_get_contents (path.c_str(), &fbuf, NULL, NULL)) {
1127 stringstream ifs (fbuf);
1131 std::string sstatus;
1134 PluginStatusType status;
1151 /* rest of the line is the plugin ID */
1153 ifs.getline (buf, sizeof (buf), '\n');
1158 if (sstatus == "Normal") {
1160 } else if (sstatus == "Favorite") {
1162 } else if (sstatus == "Hidden") {
1165 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1171 if (stype == "LADSPA") {
1173 } else if (stype == "AudioUnit") {
1175 } else if (stype == "LV2") {
1177 } else if (stype == "Windows-VST") {
1179 } else if (stype == "LXVST") {
1182 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1188 strip_whitespace_edges (id);
1189 set_status (type, id, status);
1194 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1196 PluginStatus ps (t, id, status);
1197 statuses.erase (ps);
1199 if (status == Normal) {
1203 statuses.insert (ps);
1206 ARDOUR::PluginInfoList&
1207 PluginManager::windows_vst_plugin_info ()
1209 #ifdef WINDOWS_VST_SUPPORT
1210 if (!_windows_vst_plugin_info) {
1211 windows_vst_refresh ();
1213 return *_windows_vst_plugin_info;
1215 return _empty_plugin_info;
1219 ARDOUR::PluginInfoList&
1220 PluginManager::lxvst_plugin_info ()
1222 #ifdef LXVST_SUPPORT
1223 assert(_lxvst_plugin_info);
1224 return *_lxvst_plugin_info;
1226 return _empty_plugin_info;
1230 ARDOUR::PluginInfoList&
1231 PluginManager::ladspa_plugin_info ()
1233 assert(_ladspa_plugin_info);
1234 return *_ladspa_plugin_info;
1237 ARDOUR::PluginInfoList&
1238 PluginManager::lv2_plugin_info ()
1241 assert(_lv2_plugin_info);
1242 return *_lv2_plugin_info;
1244 return _empty_plugin_info;
1248 ARDOUR::PluginInfoList&
1249 PluginManager::au_plugin_info ()
1251 #ifdef AUDIOUNIT_SUPPORT
1252 if (_au_plugin_info) {
1253 return *_au_plugin_info;
1256 return _empty_plugin_info;