2 Copyright (C) 2000-2006 Paul Davis
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "libardour-config.h"
26 #include <sys/types.h>
35 #ifdef WINDOWS_VST_SUPPORT
36 #include "ardour/vst_info_file.h"
38 #include "pbd/basename.h"
40 #endif // WINDOWS_VST_SUPPORT
43 #include "ardour/vst_info_file.h"
44 #include "ardour/linux_vst_support.h"
45 #include "pbd/basename.h"
47 #endif //LXVST_SUPPORT
49 #include <glib/gstdio.h>
50 #include <glibmm/miscutils.h>
51 #include <glibmm/pattern.h>
52 #include <glibmm/fileutils.h>
53 #include <glibmm/miscutils.h>
55 #include "pbd/whitespace.h"
56 #include "pbd/file_utils.h"
58 #include "ardour/debug.h"
59 #include "ardour/filesystem_paths.h"
60 #include "ardour/ladspa.h"
61 #include "ardour/ladspa_plugin.h"
62 #include "ardour/plugin.h"
63 #include "ardour/plugin_manager.h"
64 #include "ardour/rc_configuration.h"
66 #include "ardour/search_paths.h"
69 #include "ardour/lv2_plugin.h"
72 #ifdef WINDOWS_VST_SUPPORT
73 #include "ardour/windows_vst_plugin.h"
77 #include "ardour/lxvst_plugin.h"
80 #ifdef AUDIOUNIT_SUPPORT
81 #include "ardour/audio_unit.h"
82 #include <Carbon/Carbon.h>
85 #include "pbd/error.h"
86 #include "pbd/stl_delete.h"
90 #include "ardour/debug.h"
92 using namespace ARDOUR;
96 PluginManager* PluginManager::_instance = 0;
97 std::string PluginManager::scanner_bin_path = "";
100 PluginManager::instance()
103 _instance = new PluginManager;
108 PluginManager::PluginManager ()
109 : _windows_vst_plugin_info(0)
110 , _lxvst_plugin_info(0)
111 , _ladspa_plugin_info(0)
112 , _lv2_plugin_info(0)
114 , _cancel_scan(false)
115 , _cancel_timeout(false)
120 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
121 // source-tree (ardev, etc)
122 PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
124 #ifdef PLATFORM_WINDOWS
125 // on windows the .exe needs to be in the same folder with libardour.dll
126 vstsp += Glib::build_filename(g_win32_get_package_installation_directory_of_module (0), "bin");
128 // on Unices additional internal-use binaries are deployed to $libdir
129 vstsp += ARDOUR::ardour_dll_directory();
132 if (!PBD::find_file (vstsp,
133 #ifdef PLATFORM_WINDOWS
134 #ifdef DEBUGGABLE_SCANNER_APP
135 #if defined(DEBUG) || defined(_DEBUG)
136 "ardour-vst-scannerD.exe"
138 "ardour-vst-scannerRDC.exe"
141 "ardour-vst-scanner.exe"
146 , scanner_bin_path)) {
147 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << vstsp.to_string() << endmsg;
153 if ((s = getenv ("LADSPA_RDF_PATH"))){
157 if (lrdf_path.length() == 0) {
158 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
161 add_lrdf_data(lrdf_path);
162 add_ladspa_presets();
163 #ifdef WINDOWS_VST_SUPPORT
164 if (Config->get_use_windows_vst ()) {
165 add_windows_vst_presets ();
167 #endif /* WINDOWS_VST_SUPPORT */
170 if (Config->get_use_lxvst()) {
173 #endif /* Native LinuxVST support*/
175 if ((s = getenv ("VST_PATH"))) {
176 windows_vst_path = s;
177 } else if ((s = getenv ("VST_PLUGINS"))) {
178 windows_vst_path = s;
181 if (windows_vst_path.length() == 0) {
182 windows_vst_path = vst_search_path ();
185 if ((s = getenv ("LXVST_PATH"))) {
187 } else if ((s = getenv ("LXVST_PLUGINS"))) {
191 if (lxvst_path.length() == 0) {
192 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
193 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
194 "/usr/lib/vst:/usr/local/lib/vst";
197 /* first time setup, use 'default' path */
198 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
199 Config->set_plugin_path_lxvst(get_default_lxvst_path());
201 if (Config->get_plugin_path_vst() == X_("@default@")) {
202 Config->set_plugin_path_vst(get_default_windows_vst_path());
205 if (_instance == 0) {
209 BootMessage (_("Discovering Plugins"));
213 PluginManager::~PluginManager()
215 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
216 // don't bother, just exit quickly.
217 delete _windows_vst_plugin_info;
218 delete _lxvst_plugin_info;
219 delete _ladspa_plugin_info;
220 delete _lv2_plugin_info;
221 delete _au_plugin_info;
226 PluginManager::refresh (bool cache_only)
228 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
229 _cancel_scan = false;
231 BootMessage (_("Scanning LADSPA Plugins"));
234 BootMessage (_("Scanning LV2 Plugins"));
237 #ifdef WINDOWS_VST_SUPPORT
238 if (Config->get_use_windows_vst()) {
239 BootMessage (_("Scanning Windows VST Plugins"));
240 windows_vst_refresh (cache_only);
242 #endif // WINDOWS_VST_SUPPORT
245 if(Config->get_use_lxvst()) {
246 BootMessage (_("Scanning Linux VST Plugins"));
247 lxvst_refresh(cache_only);
249 #endif //Native linuxVST SUPPORT
251 #ifdef AUDIOUNIT_SUPPORT
252 BootMessage (_("Scanning AU Plugins"));
253 au_refresh (cache_only);
256 BootMessage (_("Plugin Scan Complete..."));
257 PluginListChanged (); /* EMIT SIGNAL */
258 PluginScanMessage(X_("closeme"), "", false);
259 _cancel_scan = false;
263 PluginManager::cancel_plugin_scan ()
269 PluginManager::cancel_plugin_timeout ()
271 _cancel_timeout = true;
275 PluginManager::clear_vst_cache ()
277 // see also libs/ardour/vst_info_file.cc - vstfx_infofile_path()
278 #ifdef WINDOWS_VST_SUPPORT
280 vector<string> fsi_files;
281 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
282 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
283 ::g_unlink(i->c_str());
290 vector<string> fsi_files;
291 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
292 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
293 ::g_unlink(i->c_str());
298 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
300 string personal = get_personal_vst_info_cache_dir();
301 vector<string> fsi_files;
302 find_files_matching_regex (fsi_files, personal, "\\.fsi$", /* user cache is flat, no recursion */ false);
303 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
304 ::g_unlink(i->c_str());
311 PluginManager::clear_vst_blacklist ()
313 #ifdef WINDOWS_VST_SUPPORT
315 vector<string> fsi_files;
316 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_BLACKLIST "$", true);
317 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
318 ::g_unlink(i->c_str());
325 vector<string> fsi_files;
326 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_BLACKLIST "$", true);
327 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
328 ::g_unlink(i->c_str());
333 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
335 string personal = get_personal_vst_blacklist_dir();
337 vector<string> fsi_files;
338 find_files_matching_regex (fsi_files, personal, "\\" VST_EXT_BLACKLIST "$", /* flat user cache */ false);
339 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
340 ::g_unlink(i->c_str());
347 PluginManager::clear_au_cache ()
349 #ifdef AUDIOUNIT_SUPPORT
350 // AUPluginInfo::au_cache_path ()
351 string fn = Glib::build_filename (ARDOUR::user_config_directory(), "au_cache");
352 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
353 ::g_unlink(fn.c_str());
359 PluginManager::clear_au_blacklist ()
361 #ifdef AUDIOUNIT_SUPPORT
362 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_blacklist.txt");
363 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
364 ::g_unlink(fn.c_str());
370 PluginManager::ladspa_refresh ()
372 if (_ladspa_plugin_info) {
373 _ladspa_plugin_info->clear ();
375 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
378 /* allow LADSPA_PATH to augment, not override standard locations */
380 /* Only add standard locations to ladspa_path if it doesn't
381 * already contain them. Check for trailing G_DIR_SEPARATOR too.
384 vector<string> ladspa_modules;
386 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
388 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
389 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
390 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
392 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
393 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
394 ladspa_discover (*i);
399 static bool rdf_filter (const string &str, void* /*arg*/)
401 return str[0] != '.' &&
402 ((str.find(".rdf") == (str.length() - 4)) ||
403 (str.find(".rdfs") == (str.length() - 5)) ||
404 (str.find(".n3") == (str.length() - 3)) ||
405 (str.find(".ttl") == (str.length() - 4)));
410 PluginManager::add_ladspa_presets()
412 add_presets ("ladspa");
416 PluginManager::add_windows_vst_presets()
418 add_presets ("windows-vst");
422 PluginManager::add_lxvst_presets()
424 add_presets ("lxvst");
428 PluginManager::add_presets(string domain)
431 vector<string> presets;
432 vector<string>::iterator x;
435 if ((envvar = getenv ("HOME")) == 0) {
439 string path = string_compose("%1/.%2/rdf", envvar, domain);
440 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
442 for (x = presets.begin(); x != presets.end (); ++x) {
443 string file = "file:" + *x;
444 if (lrdf_read_file(file.c_str())) {
445 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
453 PluginManager::add_lrdf_data (const string &path)
456 vector<string> rdf_files;
457 vector<string>::iterator x;
459 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
461 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
462 const string uri(string("file://") + *x);
464 if (lrdf_read_file(uri.c_str())) {
465 warning << "Could not parse rdf file: " << uri << endmsg;
472 PluginManager::ladspa_discover (string path)
474 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
476 Glib::Module module(path);
477 const LADSPA_Descriptor *descriptor;
478 LADSPA_Descriptor_Function dfunc;
482 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
483 path, Glib::Module::get_last_error()) << endmsg;
488 if (!module.get_symbol("ladspa_descriptor", func)) {
489 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
490 error << Glib::Module::get_last_error() << endmsg;
494 dfunc = (LADSPA_Descriptor_Function)func;
496 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
498 for (uint32_t i = 0; ; ++i) {
499 if ((descriptor = dfunc (i)) == 0) {
503 if (!ladspa_plugin_whitelist.empty()) {
504 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
509 PluginInfoPtr info(new LadspaPluginInfo);
510 info->name = descriptor->Name;
511 info->category = get_ladspa_category(descriptor->UniqueID);
512 info->creator = descriptor->Maker;
515 info->n_inputs = ChanCount();
516 info->n_outputs = ChanCount();
517 info->type = ARDOUR::LADSPA;
520 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
521 info->unique_id = buf;
523 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
524 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
525 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
526 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
528 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
529 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
534 if(_ladspa_plugin_info->empty()){
535 _ladspa_plugin_info->push_back (info);
538 //Ensure that the plugin is not already in the plugin list.
542 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
543 if(0 == info->unique_id.compare((*i)->unique_id)){
549 _ladspa_plugin_info->push_back (info);
552 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
555 // GDB WILL NOT LIKE YOU IF YOU DO THIS
562 PluginManager::get_ladspa_category (uint32_t plugin_id)
566 lrdf_statement pattern;
568 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
569 pattern.subject = buf;
570 pattern.predicate = const_cast<char*>(RDF_TYPE);
572 pattern.object_type = lrdf_uri;
574 lrdf_statement* matches1 = lrdf_matches (&pattern);
580 pattern.subject = matches1->object;
581 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
583 pattern.object_type = lrdf_literal;
585 lrdf_statement* matches2 = lrdf_matches (&pattern);
586 lrdf_free_statements(matches1);
592 string label = matches2->object;
593 lrdf_free_statements(matches2);
595 /* Kludge LADSPA class names to be singular and match LV2 class names.
596 This avoids duplicate plugin menus for every class, which is necessary
597 to make the plugin category menu at all usable, but is obviously a
600 In the short term, lrdf could be updated so the labels match and a new
601 release made. To support both specs, we should probably be mapping the
602 URIs to the same category in code and perhaps tweaking that hierarchy
603 dynamically to suit the user. Personally, I (drobilla) think that time
604 is better spent replacing the little-used LRDF.
606 In the longer term, we will abandon LRDF entirely in favour of LV2 and
607 use that class hierarchy. Aside from fixing this problem properly, that
608 will also allow for translated labels. SWH plugins have been LV2 for
609 ages; TAP needs porting. I don't know of anything else with LRDF data.
611 if (label == "Utilities") {
613 } else if (label == "Pitch shifters") {
614 return "Pitch Shifter";
615 } else if (label != "Dynamics" && label != "Chorus"
616 &&label[label.length() - 1] == 's'
617 && label[label.length() - 2] != 's') {
618 return label.substr(0, label.length() - 1);
629 PluginManager::lv2_refresh ()
631 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
632 delete _lv2_plugin_info;
633 _lv2_plugin_info = LV2PluginInfo::discover();
637 #ifdef AUDIOUNIT_SUPPORT
639 PluginManager::au_refresh (bool cache_only)
641 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
643 // disable automatic discovery in case we crash
644 bool discover_at_start = Config->get_discover_audio_units ();
645 Config->set_discover_audio_units (false);
646 Config->save_state();
648 delete _au_plugin_info;
649 _au_plugin_info = AUPluginInfo::discover(cache_only && !discover_at_start);
651 // successful scan re-enabled automatic discovery if it was set
652 Config->set_discover_audio_units (discover_at_start);
653 Config->save_state();
658 #ifdef WINDOWS_VST_SUPPORT
661 PluginManager::windows_vst_refresh (bool cache_only)
663 if (_windows_vst_plugin_info) {
664 _windows_vst_plugin_info->clear ();
666 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
669 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
672 static bool windows_vst_filter (const string& str, void * /*arg*/)
674 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
675 return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
679 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
681 vector<string> plugin_objects;
682 vector<string>::iterator x;
685 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path));
687 if (Config->get_verbose_plugin_scan()) {
688 info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
691 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
693 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
694 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
695 windows_vst_discover (*x, cache_only || cancelled());
698 if (Config->get_verbose_plugin_scan()) {
699 info << _("--- Windows VST plugins Scan Done") << endmsg;
706 PluginManager::windows_vst_discover (string path, bool cache_only)
708 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
710 if (Config->get_verbose_plugin_scan()) {
711 info << string_compose (_(" * %1 %2"), path, (cache_only ? _(" (cache only)") : "")) << endmsg;
714 _cancel_timeout = false;
715 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
716 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
718 // TODO get extended error messae from vstfx_get_info_fst() e.g blacklisted, 32/64bit compat,
719 // .err file scanner output etc.
721 if (finfos->empty()) {
722 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
723 if (Config->get_verbose_plugin_scan()) {
724 info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
729 uint32_t discovered = 0;
730 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
734 if (!finfo->canProcessReplacing) {
735 warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
736 finfo->name, PROGRAM_NAME)
741 PluginInfoPtr info (new WindowsVSTPluginInfo);
743 /* what a joke freeware VST is */
745 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
746 info->name = PBD::basename_nosuffix (path);
748 info->name = finfo->name;
752 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
753 info->unique_id = buf;
754 info->category = "VST";
756 info->creator = finfo->creator;
758 info->n_inputs.set_audio (finfo->numInputs);
759 info->n_outputs.set_audio (finfo->numOutputs);
760 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
761 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
762 info->type = ARDOUR::Windows_VST;
764 // TODO: check dup-IDs (lxvst AND windows vst)
765 bool duplicate = false;
767 if (!_windows_vst_plugin_info->empty()) {
768 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
769 if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
770 warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
778 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
779 _windows_vst_plugin_info->push_back (info);
781 if (Config->get_verbose_plugin_scan()) {
782 PBD::info << string_compose (_(" -> OK. (VST Plugin \"%1\" added)."), info->name) << endmsg;
787 vstfx_free_info_list (finfos);
788 return discovered > 0 ? 0 : -1;
791 #endif // WINDOWS_VST_SUPPORT
796 PluginManager::lxvst_refresh (bool cache_only)
798 if (_lxvst_plugin_info) {
799 _lxvst_plugin_info->clear ();
801 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
804 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
807 static bool lxvst_filter (const string& str, void *)
809 /* Not a dotfile, has a prefix before a period, suffix is "so" */
811 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
815 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
817 vector<string> plugin_objects;
818 vector<string>::iterator x;
825 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
827 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
829 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
830 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
831 lxvst_discover (*x, cache_only || cancelled());
838 PluginManager::lxvst_discover (string path, bool cache_only)
840 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
842 _cancel_timeout = false;
843 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
844 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
846 if (finfos->empty()) {
847 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
851 uint32_t discovered = 0;
852 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
856 if (!finfo->canProcessReplacing) {
857 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
858 finfo->name, PROGRAM_NAME)
863 PluginInfoPtr info(new LXVSTPluginInfo);
865 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
866 info->name = PBD::basename_nosuffix (path);
868 info->name = finfo->name;
872 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
873 info->unique_id = buf;
874 info->category = "linuxVSTs";
876 info->creator = finfo->creator;
878 info->n_inputs.set_audio (finfo->numInputs);
879 info->n_outputs.set_audio (finfo->numOutputs);
880 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
881 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
882 info->type = ARDOUR::LXVST;
884 /* Make sure we don't find the same plugin in more than one place along
885 the LXVST_PATH We can't use a simple 'find' because the path is included
886 in the PluginInfo, and that is the one thing we can be sure MUST be
887 different if a duplicate instance is found. So we just compare the type
888 and unique ID (which for some VSTs isn't actually unique...)
891 // TODO: check dup-IDs with windowsVST, too
892 bool duplicate = false;
893 if (!_lxvst_plugin_info->empty()) {
894 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
895 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
896 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
904 _lxvst_plugin_info->push_back (info);
909 vstfx_free_info_list (finfos);
910 return discovered > 0 ? 0 : -1;
913 #endif // LXVST_SUPPORT
916 PluginManager::PluginStatusType
917 PluginManager::get_status (const PluginInfoPtr& pi)
919 PluginStatus ps (pi->type, pi->unique_id);
920 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
921 if (i == statuses.end() ) {
929 PluginManager::save_statuses ()
932 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
934 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
940 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
952 ofs << "Windows-VST";
961 switch ((*i).status) {
974 ofs << (*i).unique_id;;
982 PluginManager::load_statuses ()
984 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
985 ifstream ifs (path.c_str());
995 PluginStatusType status;
1012 /* rest of the line is the plugin ID */
1014 ifs.getline (buf, sizeof (buf), '\n');
1019 if (sstatus == "Normal") {
1021 } else if (sstatus == "Favorite") {
1023 } else if (sstatus == "Hidden") {
1026 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1032 if (stype == "LADSPA") {
1034 } else if (stype == "AudioUnit") {
1036 } else if (stype == "LV2") {
1038 } else if (stype == "Windows-VST") {
1040 } else if (stype == "LXVST") {
1043 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1049 strip_whitespace_edges (id);
1050 set_status (type, id, status);
1057 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1059 PluginStatus ps (t, id, status);
1060 statuses.erase (ps);
1062 if (status == Normal) {
1066 statuses.insert (ps);
1069 ARDOUR::PluginInfoList&
1070 PluginManager::windows_vst_plugin_info ()
1072 #ifdef WINDOWS_VST_SUPPORT
1073 if (!_windows_vst_plugin_info) {
1074 windows_vst_refresh ();
1076 return *_windows_vst_plugin_info;
1078 return _empty_plugin_info;
1082 ARDOUR::PluginInfoList&
1083 PluginManager::lxvst_plugin_info ()
1085 #ifdef LXVST_SUPPORT
1086 assert(_lxvst_plugin_info);
1087 return *_lxvst_plugin_info;
1089 return _empty_plugin_info;
1093 ARDOUR::PluginInfoList&
1094 PluginManager::ladspa_plugin_info ()
1096 assert(_ladspa_plugin_info);
1097 return *_ladspa_plugin_info;
1100 ARDOUR::PluginInfoList&
1101 PluginManager::lv2_plugin_info ()
1104 assert(_lv2_plugin_info);
1105 return *_lv2_plugin_info;
1107 return _empty_plugin_info;
1111 ARDOUR::PluginInfoList&
1112 PluginManager::au_plugin_info ()
1114 #ifdef AUDIOUNIT_SUPPORT
1115 if (_au_plugin_info) {
1116 return *_au_plugin_info;
1119 return _empty_plugin_info;