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>
53 #include "pbd/pathscanner.h"
54 #include "pbd/whitespace.h"
55 #include "pbd/file_utils.h"
57 #include "ardour/debug.h"
58 #include "ardour/filesystem_paths.h"
59 #include "ardour/ladspa.h"
60 #include "ardour/ladspa_plugin.h"
61 #include "ardour/plugin.h"
62 #include "ardour/plugin_manager.h"
63 #include "ardour/rc_configuration.h"
65 #include "ardour/search_paths.h"
68 #include "ardour/lv2_plugin.h"
71 #ifdef WINDOWS_VST_SUPPORT
72 #include "ardour/windows_vst_plugin.h"
76 #include "ardour/lxvst_plugin.h"
79 #ifdef AUDIOUNIT_SUPPORT
80 #include "ardour/audio_unit.h"
81 #include <Carbon/Carbon.h>
84 #include "pbd/error.h"
85 #include "pbd/stl_delete.h"
89 #include "ardour/debug.h"
91 using namespace ARDOUR;
95 PluginManager* PluginManager::_instance = 0;
96 std::string PluginManager::scanner_bin_path = "";
99 PluginManager::instance()
102 _instance = new PluginManager;
107 PluginManager::PluginManager ()
108 : _windows_vst_plugin_info(0)
109 , _lxvst_plugin_info(0)
110 , _ladspa_plugin_info(0)
111 , _lv2_plugin_info(0)
113 , _cancel_scan(false)
114 , _cancel_timeout(false)
119 string scan_p = Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst");
120 if (!PBD::find_file_in_search_path ( PBD::Searchpath(scan_p), "ardour-vst-scanner", scanner_bin_path)) {
121 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << scan_p << endmsg;
126 if ((s = getenv ("LADSPA_RDF_PATH"))){
130 if (lrdf_path.length() == 0) {
131 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
134 add_lrdf_data(lrdf_path);
135 add_ladspa_presets();
136 #ifdef WINDOWS_VST_SUPPORT
137 if (Config->get_use_windows_vst ()) {
138 add_windows_vst_presets ();
140 #endif /* WINDOWS_VST_SUPPORT */
143 if (Config->get_use_lxvst()) {
146 #endif /* Native LinuxVST support*/
148 if ((s = getenv ("VST_PATH"))) {
149 windows_vst_path = s;
150 } else if ((s = getenv ("VST_PLUGINS"))) {
151 windows_vst_path = s;
154 if (windows_vst_path.length() == 0) {
155 windows_vst_path = vst_search_path ();
158 if ((s = getenv ("LXVST_PATH"))) {
160 } else if ((s = getenv ("LXVST_PLUGINS"))) {
164 if (lxvst_path.length() == 0) {
165 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
166 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
167 "/usr/lib/vst:/usr/local/lib/vst";
170 /* first time setup, use 'default' path */
171 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
172 Config->set_plugin_path_lxvst(get_default_lxvst_path());
174 if (Config->get_plugin_path_vst() == X_("@default@")) {
175 Config->set_plugin_path_vst(get_default_windows_vst_path());
178 if (_instance == 0) {
182 BootMessage (_("Discovering Plugins"));
186 PluginManager::~PluginManager()
191 PluginManager::refresh (bool cache_only)
193 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
194 _cancel_scan = false;
196 BootMessage (_("Scanning LADSPA Plugins"));
199 BootMessage (_("Scanning LV2 Plugins"));
202 #ifdef WINDOWS_VST_SUPPORT
203 if (Config->get_use_windows_vst()) {
204 BootMessage (_("Scanning Windows VST Plugins"));
205 windows_vst_refresh (cache_only);
207 #endif // WINDOWS_VST_SUPPORT
210 if(Config->get_use_lxvst()) {
211 BootMessage (_("Scanning Linux VST Plugins"));
212 lxvst_refresh(cache_only);
214 #endif //Native linuxVST SUPPORT
216 #ifdef AUDIOUNIT_SUPPORT
217 BootMessage (_("Scanning AU Plugins"));
221 BootMessage (_("Plugin Scan Complete..."));
222 PluginListChanged (); /* EMIT SIGNAL */
223 PluginScanMessage(X_("closeme"), "", false);
224 _cancel_scan = false;
228 PluginManager::cancel_plugin_scan ()
234 PluginManager::cancel_plugin_timeout ()
236 _cancel_timeout = true;
240 PluginManager::clear_vst_cache ()
242 // see also libs/ardour/vst_info_file.cc - vstfx_infofile_path()
243 #ifdef WINDOWS_VST_SUPPORT
246 vector<string *> *fsi_files;
248 fsi_files = scanner (Config->get_plugin_path_vst(), "\\.fsi$", true, true, -1, false);
250 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
251 ::g_unlink((*i)->c_str());
254 vector_delete(fsi_files);
262 vector<string *> *fsi_files;
263 fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsi$", true, true, -1, false);
265 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
266 ::g_unlink((*i)->c_str());
269 vector_delete(fsi_files);
274 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
276 string personal = get_personal_vst_info_cache_dir();
278 vector<string *> *fsi_files;
279 fsi_files = scanner (personal, "\\.fsi$", true, true, -1, false);
281 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
282 ::g_unlink((*i)->c_str());
285 vector_delete(fsi_files);
292 PluginManager::clear_vst_blacklist ()
294 #ifdef WINDOWS_VST_SUPPORT
297 vector<string *> *fsi_files;
299 fsi_files = scanner (Config->get_plugin_path_vst(), "\\.fsb$", true, true, -1, false);
301 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
302 ::g_unlink((*i)->c_str());
305 vector_delete(fsi_files);
313 vector<string *> *fsi_files;
314 fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsb$", true, true, -1, false);
316 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
317 ::g_unlink((*i)->c_str());
320 vector_delete(fsi_files);
325 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
327 string personal = get_personal_vst_blacklist_dir();
330 vector<string *> *fsi_files;
331 fsi_files = scanner (personal, "\\.fsb$", true, true, -1, false);
333 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
334 ::g_unlink((*i)->c_str());
337 vector_delete(fsi_files);
344 PluginManager::ladspa_refresh ()
346 if (_ladspa_plugin_info) {
347 _ladspa_plugin_info->clear ();
349 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
352 /* allow LADSPA_PATH to augment, not override standard locations */
354 /* Only add standard locations to ladspa_path if it doesn't
355 * already contain them. Check for trailing G_DIR_SEPARATOR too.
358 vector<string> ladspa_modules;
360 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
362 Glib::PatternSpec so_extension_pattern("*.so");
363 Glib::PatternSpec dylib_extension_pattern("*.dylib");
364 Glib::PatternSpec dll_extension_pattern("*.dll");
366 find_matching_files_in_search_path (ladspa_search_path (),
367 so_extension_pattern, ladspa_modules);
369 find_matching_files_in_search_path (ladspa_search_path (),
370 dylib_extension_pattern, ladspa_modules);
372 find_matching_files_in_search_path (ladspa_search_path (),
373 dll_extension_pattern, ladspa_modules);
375 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
376 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
377 ladspa_discover (*i);
381 static bool rdf_filter (const string &str, void* /*arg*/)
383 return str[0] != '.' &&
384 ((str.find(".rdf") == (str.length() - 4)) ||
385 (str.find(".rdfs") == (str.length() - 5)) ||
386 (str.find(".n3") == (str.length() - 3)) ||
387 (str.find(".ttl") == (str.length() - 4)));
391 PluginManager::add_ladspa_presets()
393 add_presets ("ladspa");
397 PluginManager::add_windows_vst_presets()
399 add_presets ("windows-vst");
403 PluginManager::add_lxvst_presets()
405 add_presets ("lxvst");
409 PluginManager::add_presets(string domain)
413 vector<string *> *presets;
414 vector<string *>::iterator x;
417 if ((envvar = getenv ("HOME")) == 0) {
421 string path = string_compose("%1/.%2/rdf", envvar, domain);
422 presets = scanner (path, rdf_filter, 0, false, true);
425 for (x = presets->begin(); x != presets->end (); ++x) {
426 string file = "file:" + **x;
427 if (lrdf_read_file(file.c_str())) {
428 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
432 vector_delete (presets);
439 PluginManager::add_lrdf_data (const string &path)
443 vector<string *>* rdf_files;
444 vector<string *>::iterator x;
446 rdf_files = scanner (path, rdf_filter, 0, false, true);
449 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
450 const string uri(string("file://") + **x);
452 if (lrdf_read_file(uri.c_str())) {
453 warning << "Could not parse rdf file: " << uri << endmsg;
457 vector_delete (rdf_files);
464 PluginManager::ladspa_discover (string path)
466 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
468 Glib::Module module(path);
469 const LADSPA_Descriptor *descriptor;
470 LADSPA_Descriptor_Function dfunc;
474 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
475 path, Glib::Module::get_last_error()) << endmsg;
480 if (!module.get_symbol("ladspa_descriptor", func)) {
481 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
482 error << Glib::Module::get_last_error() << endmsg;
486 dfunc = (LADSPA_Descriptor_Function)func;
488 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
490 for (uint32_t i = 0; ; ++i) {
491 if ((descriptor = dfunc (i)) == 0) {
495 if (!ladspa_plugin_whitelist.empty()) {
496 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
501 PluginInfoPtr info(new LadspaPluginInfo);
502 info->name = descriptor->Name;
503 info->category = get_ladspa_category(descriptor->UniqueID);
504 info->creator = descriptor->Maker;
507 info->n_inputs = ChanCount();
508 info->n_outputs = ChanCount();
509 info->type = ARDOUR::LADSPA;
512 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
513 info->unique_id = buf;
515 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
516 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
517 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
518 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
520 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
521 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
526 if(_ladspa_plugin_info->empty()){
527 _ladspa_plugin_info->push_back (info);
530 //Ensure that the plugin is not already in the plugin list.
534 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
535 if(0 == info->unique_id.compare((*i)->unique_id)){
541 _ladspa_plugin_info->push_back (info);
544 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
547 // GDB WILL NOT LIKE YOU IF YOU DO THIS
554 PluginManager::get_ladspa_category (uint32_t plugin_id)
558 lrdf_statement pattern;
560 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
561 pattern.subject = buf;
562 pattern.predicate = const_cast<char*>(RDF_TYPE);
564 pattern.object_type = lrdf_uri;
566 lrdf_statement* matches1 = lrdf_matches (&pattern);
572 pattern.subject = matches1->object;
573 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
575 pattern.object_type = lrdf_literal;
577 lrdf_statement* matches2 = lrdf_matches (&pattern);
578 lrdf_free_statements(matches1);
584 string label = matches2->object;
585 lrdf_free_statements(matches2);
587 /* Kludge LADSPA class names to be singular and match LV2 class names.
588 This avoids duplicate plugin menus for every class, which is necessary
589 to make the plugin category menu at all usable, but is obviously a
592 In the short term, lrdf could be updated so the labels match and a new
593 release made. To support both specs, we should probably be mapping the
594 URIs to the same category in code and perhaps tweaking that hierarchy
595 dynamically to suit the user. Personally, I (drobilla) think that time
596 is better spent replacing the little-used LRDF.
598 In the longer term, we will abandon LRDF entirely in favour of LV2 and
599 use that class hierarchy. Aside from fixing this problem properly, that
600 will also allow for translated labels. SWH plugins have been LV2 for
601 ages; TAP needs porting. I don't know of anything else with LRDF data.
603 if (label == "Utilities") {
605 } else if (label == "Pitch shifters") {
606 return "Pitch Shifter";
607 } else if (label != "Dynamics" && label != "Chorus"
608 &&label[label.length() - 1] == 's'
609 && label[label.length() - 2] != 's') {
610 return label.substr(0, label.length() - 1);
621 PluginManager::lv2_refresh ()
623 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
624 delete _lv2_plugin_info;
625 _lv2_plugin_info = LV2PluginInfo::discover();
629 #ifdef AUDIOUNIT_SUPPORT
631 PluginManager::au_refresh ()
633 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
634 delete _au_plugin_info;
635 _au_plugin_info = AUPluginInfo::discover();
640 #ifdef WINDOWS_VST_SUPPORT
643 PluginManager::windows_vst_refresh (bool cache_only)
645 if (_windows_vst_plugin_info) {
646 _windows_vst_plugin_info->clear ();
648 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
651 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
654 static bool windows_vst_filter (const string& str, void * /*arg*/)
656 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
658 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
662 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
665 vector<string *> *plugin_objects;
666 vector<string *>::iterator x;
669 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
671 plugin_objects = scanner (Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
673 if (plugin_objects) {
674 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
675 ARDOUR::PluginScanMessage(_("VST"), **x, !cache_only && !cancelled());
676 windows_vst_discover (**x, cache_only || cancelled());
679 vector_delete (plugin_objects);
680 delete (plugin_objects);
687 PluginManager::windows_vst_discover (string path, bool cache_only)
689 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
691 _cancel_timeout = false;
692 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
693 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
695 if (finfos->empty()) {
696 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
700 uint32_t discovered = 0;
701 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
705 if (!finfo->canProcessReplacing) {
706 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
707 finfo->name, PROGRAM_NAME)
712 PluginInfoPtr info (new WindowsVSTPluginInfo);
714 /* what a joke freeware VST is */
716 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
717 info->name = PBD::basename_nosuffix (path);
719 info->name = finfo->name;
723 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
724 info->unique_id = buf;
725 info->category = "VST";
727 info->creator = finfo->creator;
729 info->n_inputs.set_audio (finfo->numInputs);
730 info->n_outputs.set_audio (finfo->numOutputs);
731 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
732 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
733 info->type = ARDOUR::Windows_VST;
735 // TODO: check dup-IDs (lxvst AND windows vst)
736 bool duplicate = false;
738 if (!_windows_vst_plugin_info->empty()) {
739 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
740 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
741 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
749 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
750 _windows_vst_plugin_info->push_back (info);
755 vstfx_free_info_list (finfos);
756 return discovered > 0 ? 0 : -1;
759 #endif // WINDOWS_VST_SUPPORT
764 PluginManager::lxvst_refresh (bool cache_only)
766 if (_lxvst_plugin_info) {
767 _lxvst_plugin_info->clear ();
769 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
772 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
775 static bool lxvst_filter (const string& str, void *)
777 /* Not a dotfile, has a prefix before a period, suffix is "so" */
779 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
783 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
786 vector<string *> *plugin_objects;
787 vector<string *>::iterator x;
794 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
796 plugin_objects = scanner (Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
798 if (plugin_objects) {
799 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
800 ARDOUR::PluginScanMessage(_("LXVST"), **x, !cache_only && !cancelled());
801 lxvst_discover (**x, cache_only || cancelled());
804 vector_delete (plugin_objects);
805 delete (plugin_objects);
812 PluginManager::lxvst_discover (string path, bool cache_only)
814 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
816 _cancel_timeout = false;
817 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
818 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
820 if (finfos->empty()) {
821 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
825 uint32_t discovered = 0;
826 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
830 if (!finfo->canProcessReplacing) {
831 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
832 finfo->name, PROGRAM_NAME)
837 PluginInfoPtr info(new LXVSTPluginInfo);
839 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
840 info->name = PBD::basename_nosuffix (path);
842 info->name = finfo->name;
846 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
847 info->unique_id = buf;
848 info->category = "linuxVSTs";
850 info->creator = finfo->creator;
852 info->n_inputs.set_audio (finfo->numInputs);
853 info->n_outputs.set_audio (finfo->numOutputs);
854 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
855 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
856 info->type = ARDOUR::LXVST;
858 /* Make sure we don't find the same plugin in more than one place along
859 the LXVST_PATH We can't use a simple 'find' because the path is included
860 in the PluginInfo, and that is the one thing we can be sure MUST be
861 different if a duplicate instance is found. So we just compare the type
862 and unique ID (which for some VSTs isn't actually unique...)
865 // TODO: check dup-IDs with windowsVST, too
866 bool duplicate = false;
867 if (!_lxvst_plugin_info->empty()) {
868 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
869 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
870 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
878 _lxvst_plugin_info->push_back (info);
883 vstfx_free_info_list (finfos);
884 return discovered > 0 ? 0 : -1;
887 #endif // LXVST_SUPPORT
890 PluginManager::PluginStatusType
891 PluginManager::get_status (const PluginInfoPtr& pi)
893 PluginStatus ps (pi->type, pi->unique_id);
894 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
895 if (i == statuses.end() ) {
903 PluginManager::save_statuses ()
906 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
908 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
914 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
926 ofs << "Windows-VST";
935 switch ((*i).status) {
948 ofs << (*i).unique_id;;
956 PluginManager::load_statuses ()
958 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
959 ifstream ifs (path.c_str());
969 PluginStatusType status;
986 /* rest of the line is the plugin ID */
988 ifs.getline (buf, sizeof (buf), '\n');
993 if (sstatus == "Normal") {
995 } else if (sstatus == "Favorite") {
997 } else if (sstatus == "Hidden") {
1000 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1006 if (stype == "LADSPA") {
1008 } else if (stype == "AudioUnit") {
1010 } else if (stype == "LV2") {
1012 } else if (stype == "Windows-VST") {
1014 } else if (stype == "LXVST") {
1017 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1023 strip_whitespace_edges (id);
1024 set_status (type, id, status);
1031 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1033 PluginStatus ps (t, id, status);
1034 statuses.erase (ps);
1036 if (status == Normal) {
1040 statuses.insert (ps);
1043 ARDOUR::PluginInfoList&
1044 PluginManager::windows_vst_plugin_info ()
1046 #ifdef WINDOWS_VST_SUPPORT
1047 if (!_windows_vst_plugin_info) {
1048 windows_vst_refresh ();
1050 return *_windows_vst_plugin_info;
1052 return _empty_plugin_info;
1056 ARDOUR::PluginInfoList&
1057 PluginManager::lxvst_plugin_info ()
1059 #ifdef LXVST_SUPPORT
1060 assert(_lxvst_plugin_info);
1061 return *_lxvst_plugin_info;
1063 return _empty_plugin_info;
1067 ARDOUR::PluginInfoList&
1068 PluginManager::ladspa_plugin_info ()
1070 assert(_ladspa_plugin_info);
1071 return *_ladspa_plugin_info;
1074 ARDOUR::PluginInfoList&
1075 PluginManager::lv2_plugin_info ()
1078 assert(_lv2_plugin_info);
1079 return *_lv2_plugin_info;
1081 return _empty_plugin_info;
1085 ARDOUR::PluginInfoList&
1086 PluginManager::au_plugin_info ()
1088 #ifdef AUDIOUNIT_SUPPORT
1089 assert(_au_plugin_info);
1090 return *_au_plugin_info;
1092 return _empty_plugin_info;