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 ((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 = g_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') {
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 (32-bit)");
836 rv = _("x64 (64-bit)");
839 rv = _("Native Architecture");
842 rv = _("Unknown Architecture");
846 assert (rv.length() > 0);
852 PluginManager::windows_vst_discover (string path, bool cache_only)
854 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
856 if (Config->get_verbose_plugin_scan()) {
858 info << string_compose (_(" * %1 (cache only)"), path) << endmsg;
860 info << string_compose (_(" * %1 - %2"), path, dll_info (path)) << endmsg;
864 _cancel_timeout = false;
865 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
866 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
868 // TODO get extended error messae from vstfx_get_info_fst() e.g blacklisted, 32/64bit compat,
869 // .err file scanner output etc.
871 if (finfos->empty()) {
872 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
873 if (Config->get_verbose_plugin_scan()) {
874 info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
879 uint32_t discovered = 0;
880 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
884 if (!finfo->canProcessReplacing) {
885 warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
886 finfo->name, PROGRAM_NAME)
891 PluginInfoPtr info (new WindowsVSTPluginInfo);
893 /* what a joke freeware VST is */
895 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
896 info->name = PBD::basename_nosuffix (path);
898 info->name = finfo->name;
902 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
903 info->unique_id = buf;
904 info->category = "VST";
906 info->creator = finfo->creator;
908 info->n_inputs.set_audio (finfo->numInputs);
909 info->n_outputs.set_audio (finfo->numOutputs);
910 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
911 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
912 info->type = ARDOUR::Windows_VST;
914 // TODO: check dup-IDs (lxvst AND windows vst)
915 bool duplicate = false;
917 if (!_windows_vst_plugin_info->empty()) {
918 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
919 if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
920 warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
928 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
929 _windows_vst_plugin_info->push_back (info);
931 if (Config->get_verbose_plugin_scan()) {
932 PBD::info << string_compose (_(" -> OK (VST Plugin \"%1\" was added)."), info->name) << endmsg;
937 vstfx_free_info_list (finfos);
938 return discovered > 0 ? 0 : -1;
941 #endif // WINDOWS_VST_SUPPORT
946 PluginManager::lxvst_refresh (bool cache_only)
948 if (_lxvst_plugin_info) {
949 _lxvst_plugin_info->clear ();
951 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
954 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
957 static bool lxvst_filter (const string& str, void *)
959 /* Not a dotfile, has a prefix before a period, suffix is "so" */
961 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
965 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
967 vector<string> plugin_objects;
968 vector<string>::iterator x;
975 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
977 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
979 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
980 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
981 lxvst_discover (*x, cache_only || cancelled());
988 PluginManager::lxvst_discover (string path, bool cache_only)
990 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
992 _cancel_timeout = false;
993 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
994 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
996 if (finfos->empty()) {
997 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
1001 uint32_t discovered = 0;
1002 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
1003 VSTInfo* finfo = *x;
1006 if (!finfo->canProcessReplacing) {
1007 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
1008 finfo->name, PROGRAM_NAME)
1013 PluginInfoPtr info(new LXVSTPluginInfo);
1015 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
1016 info->name = PBD::basename_nosuffix (path);
1018 info->name = finfo->name;
1022 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
1023 info->unique_id = buf;
1024 info->category = "linuxVSTs";
1026 info->creator = finfo->creator;
1028 info->n_inputs.set_audio (finfo->numInputs);
1029 info->n_outputs.set_audio (finfo->numOutputs);
1030 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
1031 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
1032 info->type = ARDOUR::LXVST;
1034 /* Make sure we don't find the same plugin in more than one place along
1035 the LXVST_PATH We can't use a simple 'find' because the path is included
1036 in the PluginInfo, and that is the one thing we can be sure MUST be
1037 different if a duplicate instance is found. So we just compare the type
1038 and unique ID (which for some VSTs isn't actually unique...)
1041 // TODO: check dup-IDs with windowsVST, too
1042 bool duplicate = false;
1043 if (!_lxvst_plugin_info->empty()) {
1044 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
1045 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
1046 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
1054 _lxvst_plugin_info->push_back (info);
1059 vstfx_free_info_list (finfos);
1060 return discovered > 0 ? 0 : -1;
1063 #endif // LXVST_SUPPORT
1066 PluginManager::PluginStatusType
1067 PluginManager::get_status (const PluginInfoPtr& pi)
1069 PluginStatus ps (pi->type, pi->unique_id);
1070 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
1071 if (i == statuses.end() ) {
1079 PluginManager::save_statuses ()
1081 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1084 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
1085 switch ((*i).type) {
1096 ofs << "Windows-VST";
1109 switch ((*i).status) {
1122 ofs << (*i).unique_id;;
1125 g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL);
1126 PluginStatusesChanged (); /* EMIT SIGNAL */
1130 PluginManager::load_statuses ()
1132 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1134 if (!g_file_get_contents (path.c_str(), &fbuf, NULL, NULL)) {
1137 stringstream ifs (fbuf);
1141 std::string sstatus;
1144 PluginStatusType status;
1161 /* rest of the line is the plugin ID */
1163 ifs.getline (buf, sizeof (buf), '\n');
1168 if (sstatus == "Normal") {
1170 } else if (sstatus == "Favorite") {
1172 } else if (sstatus == "Hidden") {
1175 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1181 if (stype == "LADSPA") {
1183 } else if (stype == "AudioUnit") {
1185 } else if (stype == "LV2") {
1187 } else if (stype == "Windows-VST") {
1189 } else if (stype == "LXVST") {
1192 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1198 strip_whitespace_edges (id);
1199 set_status (type, id, status);
1204 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1206 PluginStatus ps (t, id, status);
1207 statuses.erase (ps);
1209 if (status == Normal) {
1213 statuses.insert (ps);
1216 ARDOUR::PluginInfoList&
1217 PluginManager::windows_vst_plugin_info ()
1219 #ifdef WINDOWS_VST_SUPPORT
1220 if (!_windows_vst_plugin_info) {
1221 windows_vst_refresh ();
1223 return *_windows_vst_plugin_info;
1225 return _empty_plugin_info;
1229 ARDOUR::PluginInfoList&
1230 PluginManager::lxvst_plugin_info ()
1232 #ifdef LXVST_SUPPORT
1233 assert(_lxvst_plugin_info);
1234 return *_lxvst_plugin_info;
1236 return _empty_plugin_info;
1240 ARDOUR::PluginInfoList&
1241 PluginManager::ladspa_plugin_info ()
1243 assert(_ladspa_plugin_info);
1244 return *_ladspa_plugin_info;
1247 ARDOUR::PluginInfoList&
1248 PluginManager::lv2_plugin_info ()
1251 assert(_lv2_plugin_info);
1252 return *_lv2_plugin_info;
1254 return _empty_plugin_info;
1258 ARDOUR::PluginInfoList&
1259 PluginManager::au_plugin_info ()
1261 #ifdef AUDIOUNIT_SUPPORT
1262 if (_au_plugin_info) {
1263 return *_au_plugin_info;
1266 return _empty_plugin_info;