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(), "\\.fsb$", 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(), "\\.fsb$", 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, "\\.fsb$", /* 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");
642 if (cache_only && !Config->get_discover_audio_units ()) {
645 delete _au_plugin_info;
646 _au_plugin_info = AUPluginInfo::discover();
648 // disable automatic scan in case we crash
649 Config->set_discover_audio_units (false);
650 Config->save_state();
652 /* note: AU require a CAComponentDescription pointer provided by the OS.
653 * Ardour only caches port and i/o config. It can't just 'scan' without
654 * 'discovering' (like we do for VST).
656 * So in case discovery fails, we assume the worst: the Description
657 * is broken (malicious plugins) and even a simple 'scan' would always
658 * crash ardour on startup. Hence we disable Auto-Scan on start.
660 * If the crash happens at any later time (description is available),
661 * Ardour will blacklist the plugin in question -- unless
662 * the crash happens during realtime-run.
665 // successful scan re-enabled automatic discovery
666 Config->set_discover_audio_units (true);
667 Config->save_state();
672 #ifdef WINDOWS_VST_SUPPORT
675 PluginManager::windows_vst_refresh (bool cache_only)
677 if (_windows_vst_plugin_info) {
678 _windows_vst_plugin_info->clear ();
680 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
683 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
686 static bool windows_vst_filter (const string& str, void * /*arg*/)
688 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
689 return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
693 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
695 vector<string> plugin_objects;
696 vector<string>::iterator x;
699 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
701 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
703 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
704 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
705 windows_vst_discover (*x, cache_only || cancelled());
712 PluginManager::windows_vst_discover (string path, bool cache_only)
714 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
716 _cancel_timeout = false;
717 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
718 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
720 if (finfos->empty()) {
721 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
725 uint32_t discovered = 0;
726 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
730 if (!finfo->canProcessReplacing) {
731 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
732 finfo->name, PROGRAM_NAME)
737 PluginInfoPtr info (new WindowsVSTPluginInfo);
739 /* what a joke freeware VST is */
741 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
742 info->name = PBD::basename_nosuffix (path);
744 info->name = finfo->name;
748 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
749 info->unique_id = buf;
750 info->category = "VST";
752 info->creator = finfo->creator;
754 info->n_inputs.set_audio (finfo->numInputs);
755 info->n_outputs.set_audio (finfo->numOutputs);
756 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
757 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
758 info->type = ARDOUR::Windows_VST;
760 // TODO: check dup-IDs (lxvst AND windows vst)
761 bool duplicate = false;
763 if (!_windows_vst_plugin_info->empty()) {
764 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
765 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
766 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
774 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
775 _windows_vst_plugin_info->push_back (info);
780 vstfx_free_info_list (finfos);
781 return discovered > 0 ? 0 : -1;
784 #endif // WINDOWS_VST_SUPPORT
789 PluginManager::lxvst_refresh (bool cache_only)
791 if (_lxvst_plugin_info) {
792 _lxvst_plugin_info->clear ();
794 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
797 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
800 static bool lxvst_filter (const string& str, void *)
802 /* Not a dotfile, has a prefix before a period, suffix is "so" */
804 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
808 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
810 vector<string> plugin_objects;
811 vector<string>::iterator x;
818 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
820 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
822 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
823 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
824 lxvst_discover (*x, cache_only || cancelled());
831 PluginManager::lxvst_discover (string path, bool cache_only)
833 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
835 _cancel_timeout = false;
836 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
837 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
839 if (finfos->empty()) {
840 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
844 uint32_t discovered = 0;
845 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
849 if (!finfo->canProcessReplacing) {
850 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
851 finfo->name, PROGRAM_NAME)
856 PluginInfoPtr info(new LXVSTPluginInfo);
858 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
859 info->name = PBD::basename_nosuffix (path);
861 info->name = finfo->name;
865 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
866 info->unique_id = buf;
867 info->category = "linuxVSTs";
869 info->creator = finfo->creator;
871 info->n_inputs.set_audio (finfo->numInputs);
872 info->n_outputs.set_audio (finfo->numOutputs);
873 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
874 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
875 info->type = ARDOUR::LXVST;
877 /* Make sure we don't find the same plugin in more than one place along
878 the LXVST_PATH We can't use a simple 'find' because the path is included
879 in the PluginInfo, and that is the one thing we can be sure MUST be
880 different if a duplicate instance is found. So we just compare the type
881 and unique ID (which for some VSTs isn't actually unique...)
884 // TODO: check dup-IDs with windowsVST, too
885 bool duplicate = false;
886 if (!_lxvst_plugin_info->empty()) {
887 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
888 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
889 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
897 _lxvst_plugin_info->push_back (info);
902 vstfx_free_info_list (finfos);
903 return discovered > 0 ? 0 : -1;
906 #endif // LXVST_SUPPORT
909 PluginManager::PluginStatusType
910 PluginManager::get_status (const PluginInfoPtr& pi)
912 PluginStatus ps (pi->type, pi->unique_id);
913 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
914 if (i == statuses.end() ) {
922 PluginManager::save_statuses ()
925 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
927 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
933 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
945 ofs << "Windows-VST";
954 switch ((*i).status) {
967 ofs << (*i).unique_id;;
975 PluginManager::load_statuses ()
977 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
978 ifstream ifs (path.c_str());
988 PluginStatusType status;
1005 /* rest of the line is the plugin ID */
1007 ifs.getline (buf, sizeof (buf), '\n');
1012 if (sstatus == "Normal") {
1014 } else if (sstatus == "Favorite") {
1016 } else if (sstatus == "Hidden") {
1019 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1025 if (stype == "LADSPA") {
1027 } else if (stype == "AudioUnit") {
1029 } else if (stype == "LV2") {
1031 } else if (stype == "Windows-VST") {
1033 } else if (stype == "LXVST") {
1036 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1042 strip_whitespace_edges (id);
1043 set_status (type, id, status);
1050 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1052 PluginStatus ps (t, id, status);
1053 statuses.erase (ps);
1055 if (status == Normal) {
1059 statuses.insert (ps);
1062 ARDOUR::PluginInfoList&
1063 PluginManager::windows_vst_plugin_info ()
1065 #ifdef WINDOWS_VST_SUPPORT
1066 if (!_windows_vst_plugin_info) {
1067 windows_vst_refresh ();
1069 return *_windows_vst_plugin_info;
1071 return _empty_plugin_info;
1075 ARDOUR::PluginInfoList&
1076 PluginManager::lxvst_plugin_info ()
1078 #ifdef LXVST_SUPPORT
1079 assert(_lxvst_plugin_info);
1080 return *_lxvst_plugin_info;
1082 return _empty_plugin_info;
1086 ARDOUR::PluginInfoList&
1087 PluginManager::ladspa_plugin_info ()
1089 assert(_ladspa_plugin_info);
1090 return *_ladspa_plugin_info;
1093 ARDOUR::PluginInfoList&
1094 PluginManager::lv2_plugin_info ()
1097 assert(_lv2_plugin_info);
1098 return *_lv2_plugin_info;
1100 return _empty_plugin_info;
1104 ARDOUR::PluginInfoList&
1105 PluginManager::au_plugin_info ()
1107 #ifdef AUDIOUNIT_SUPPORT
1108 if (_au_plugin_info) {
1109 return *_au_plugin_info;
1112 return _empty_plugin_info;