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/ladspa_search_path.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)
118 if (!PBD::find_file_in_search_path (
119 PBD::Searchpath(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst")),
120 "ardour-vst-scanner", scanner_bin_path)) {
121 PBD::warning << "VST scanner app not found.'" << 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 ((s = getenv ("LXVST_PATH"))) {
156 } else if ((s = getenv ("LXVST_PLUGINS"))) {
160 if (_instance == 0) {
164 /* the plugin manager is constructed too early to use Profile */
166 if (getenv ("ARDOUR_SAE")) {
167 ladspa_plugin_whitelist.push_back (1203); // single band parametric
168 ladspa_plugin_whitelist.push_back (1772); // caps compressor
169 ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter
170 ladspa_plugin_whitelist.push_back (1075); // simple RMS expander
171 ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s)
172 ladspa_plugin_whitelist.push_back (1216); // gverb
173 ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter
176 BootMessage (_("Discovering Plugins"));
180 PluginManager::~PluginManager()
186 PluginManager::refresh (bool cache_only)
188 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
189 BootMessage (_("Discovering Plugins"));
195 #ifdef WINDOWS_VST_SUPPORT
196 if (Config->get_use_windows_vst()) {
197 windows_vst_refresh ();
199 #endif // WINDOWS_VST_SUPPORT
202 if(Config->get_use_lxvst()) {
205 #endif //Native linuxVST SUPPORT
207 #ifdef AUDIOUNIT_SUPPORT
211 PluginListChanged (); /* EMIT SIGNAL */
212 PluginScanMessage(X_("closeme"), "");
216 PluginManager::cancel_plugin_scan ()
222 PluginManager::clear_vst_cache ()
224 // see also libs/ardour/vst_info_file.cc - vstfx_infofile_path()
225 #ifdef WINDOWS_VST_SUPPORT
228 vector<string *> *fsi_files;
230 fsi_files = scanner (windows_vst_path, "\\.fsi$", true, true, -1, false);
232 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
233 ::g_unlink((*i)->c_str());
236 vector_delete(fsi_files);
243 vector<string *> *fsi_files;
244 fsi_files = scanner (lxvst_path, "\\.fsi$", true, true, -1, false);
246 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
247 ::g_unlink((*i)->c_str());
250 vector_delete(fsi_files);
254 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
256 string personal = get_personal_vst_info_cache_dir();
258 vector<string *> *fsi_files;
259 fsi_files = scanner (personal, "\\.fsi$", true, true, -1, false);
261 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
262 ::g_unlink((*i)->c_str());
265 vector_delete(fsi_files);
271 PluginManager::clear_vst_blacklist ()
273 #ifdef WINDOWS_VST_SUPPORT
276 vector<string *> *fsi_files;
278 fsi_files = scanner (windows_vst_path, "\\.fsb$", true, true, -1, false);
280 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
281 ::g_unlink((*i)->c_str());
284 vector_delete(fsi_files);
291 vector<string *> *fsi_files;
292 fsi_files = scanner (lxvst_path, "\\.fsb$", true, true, -1, false);
294 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
295 ::g_unlink((*i)->c_str());
298 vector_delete(fsi_files);
302 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
304 string personal = get_personal_vst_blacklist_dir();
307 vector<string *> *fsi_files;
308 fsi_files = scanner (personal, "\\.fsb$", true, true, -1, false);
310 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
311 ::g_unlink((*i)->c_str());
314 vector_delete(fsi_files);
320 PluginManager::ladspa_refresh ()
322 if (_ladspa_plugin_info) {
323 _ladspa_plugin_info->clear ();
325 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
328 /* allow LADSPA_PATH to augment, not override standard locations */
330 /* Only add standard locations to ladspa_path if it doesn't
331 * already contain them. Check for trailing G_DIR_SEPARATOR too.
334 vector<string> ladspa_modules;
336 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
338 Glib::PatternSpec so_extension_pattern("*.so");
339 Glib::PatternSpec dylib_extension_pattern("*.dylib");
340 Glib::PatternSpec dll_extension_pattern("*.dll");
342 find_matching_files_in_search_path (ladspa_search_path (),
343 so_extension_pattern, ladspa_modules);
345 find_matching_files_in_search_path (ladspa_search_path (),
346 dylib_extension_pattern, ladspa_modules);
348 find_matching_files_in_search_path (ladspa_search_path (),
349 dll_extension_pattern, ladspa_modules);
351 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
352 ARDOUR::PluginScanMessage(_("LADSPA"), *i);
353 ladspa_discover (*i);
357 static bool rdf_filter (const string &str, void* /*arg*/)
359 return str[0] != '.' &&
360 ((str.find(".rdf") == (str.length() - 4)) ||
361 (str.find(".rdfs") == (str.length() - 5)) ||
362 (str.find(".n3") == (str.length() - 3)) ||
363 (str.find(".ttl") == (str.length() - 4)));
367 PluginManager::add_ladspa_presets()
369 add_presets ("ladspa");
373 PluginManager::add_windows_vst_presets()
375 add_presets ("windows-vst");
379 PluginManager::add_lxvst_presets()
381 add_presets ("lxvst");
385 PluginManager::add_presets(string domain)
389 vector<string *> *presets;
390 vector<string *>::iterator x;
393 if ((envvar = getenv ("HOME")) == 0) {
397 string path = string_compose("%1/.%2/rdf", envvar, domain);
398 presets = scanner (path, rdf_filter, 0, false, true);
401 for (x = presets->begin(); x != presets->end (); ++x) {
402 string file = "file:" + **x;
403 if (lrdf_read_file(file.c_str())) {
404 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
408 vector_delete (presets);
414 PluginManager::add_lrdf_data (const string &path)
418 vector<string *>* rdf_files;
419 vector<string *>::iterator x;
421 rdf_files = scanner (path, rdf_filter, 0, false, true);
424 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
425 const string uri(string("file://") + **x);
427 if (lrdf_read_file(uri.c_str())) {
428 warning << "Could not parse rdf file: " << uri << endmsg;
432 vector_delete (rdf_files);
438 PluginManager::ladspa_discover (string path)
440 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
442 Glib::Module module(path);
443 const LADSPA_Descriptor *descriptor;
444 LADSPA_Descriptor_Function dfunc;
448 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
449 path, Glib::Module::get_last_error()) << endmsg;
454 if (!module.get_symbol("ladspa_descriptor", func)) {
455 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
456 error << Glib::Module::get_last_error() << endmsg;
460 dfunc = (LADSPA_Descriptor_Function)func;
462 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
464 for (uint32_t i = 0; ; ++i) {
465 if ((descriptor = dfunc (i)) == 0) {
469 if (!ladspa_plugin_whitelist.empty()) {
470 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
475 PluginInfoPtr info(new LadspaPluginInfo);
476 info->name = descriptor->Name;
477 info->category = get_ladspa_category(descriptor->UniqueID);
478 info->creator = descriptor->Maker;
481 info->n_inputs = ChanCount();
482 info->n_outputs = ChanCount();
483 info->type = ARDOUR::LADSPA;
486 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
487 info->unique_id = buf;
489 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
490 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
491 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
492 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
494 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
495 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
500 if(_ladspa_plugin_info->empty()){
501 _ladspa_plugin_info->push_back (info);
504 //Ensure that the plugin is not already in the plugin list.
508 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
509 if(0 == info->unique_id.compare((*i)->unique_id)){
515 _ladspa_plugin_info->push_back (info);
518 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
521 // GDB WILL NOT LIKE YOU IF YOU DO THIS
528 PluginManager::get_ladspa_category (uint32_t plugin_id)
532 lrdf_statement pattern;
534 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
535 pattern.subject = buf;
536 pattern.predicate = const_cast<char*>(RDF_TYPE);
538 pattern.object_type = lrdf_uri;
540 lrdf_statement* matches1 = lrdf_matches (&pattern);
546 pattern.subject = matches1->object;
547 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
549 pattern.object_type = lrdf_literal;
551 lrdf_statement* matches2 = lrdf_matches (&pattern);
552 lrdf_free_statements(matches1);
558 string label = matches2->object;
559 lrdf_free_statements(matches2);
561 /* Kludge LADSPA class names to be singular and match LV2 class names.
562 This avoids duplicate plugin menus for every class, which is necessary
563 to make the plugin category menu at all usable, but is obviously a
566 In the short term, lrdf could be updated so the labels match and a new
567 release made. To support both specs, we should probably be mapping the
568 URIs to the same category in code and perhaps tweaking that hierarchy
569 dynamically to suit the user. Personally, I (drobilla) think that time
570 is better spent replacing the little-used LRDF.
572 In the longer term, we will abandon LRDF entirely in favour of LV2 and
573 use that class hierarchy. Aside from fixing this problem properly, that
574 will also allow for translated labels. SWH plugins have been LV2 for
575 ages; TAP needs porting. I don't know of anything else with LRDF data.
577 if (label == "Utilities") {
579 } else if (label == "Pitch shifters") {
580 return "Pitch Shifter";
581 } else if (label != "Dynamics" && label != "Chorus"
582 &&label[label.length() - 1] == 's'
583 && label[label.length() - 2] != 's') {
584 return label.substr(0, label.length() - 1);
595 PluginManager::lv2_refresh ()
597 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
598 delete _lv2_plugin_info;
599 _lv2_plugin_info = LV2PluginInfo::discover();
603 #ifdef AUDIOUNIT_SUPPORT
605 PluginManager::au_refresh ()
607 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
608 delete _au_plugin_info;
609 _au_plugin_info = AUPluginInfo::discover();
614 #ifdef WINDOWS_VST_SUPPORT
617 PluginManager::windows_vst_refresh (bool cache_only)
619 if (_windows_vst_plugin_info) {
620 _windows_vst_plugin_info->clear ();
622 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
625 if (windows_vst_path.length() == 0) {
626 windows_vst_path = "/usr/local/lib/vst:/usr/lib/vst";
629 windows_vst_discover_from_path (windows_vst_path, cache_only);
633 PluginManager::add_windows_vst_directory (string path)
635 if (windows_vst_discover_from_path (path) == 0) {
636 windows_vst_path += ':';
637 windows_vst_path += path;
643 static bool windows_vst_filter (const string& str, void * /*arg*/)
645 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
647 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
651 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
654 vector<string *> *plugin_objects;
655 vector<string *>::iterator x;
658 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
660 plugin_objects = scanner (windows_vst_path, windows_vst_filter, 0, false, true);
662 if (plugin_objects) {
663 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
664 ARDOUR::PluginScanMessage(_("VST"), **x);
665 windows_vst_discover (**x, cache_only);
668 vector_delete (plugin_objects);
675 PluginManager::windows_vst_discover (string path, bool cache_only)
677 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
679 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
680 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
682 if (finfos->empty()) {
683 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
687 uint32_t discovered = 0;
688 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
692 if (!finfo->canProcessReplacing) {
693 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
694 finfo->name, PROGRAM_NAME)
699 PluginInfoPtr info (new WindowsVSTPluginInfo);
701 /* what a joke freeware VST is */
703 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
704 info->name = PBD::basename_nosuffix (path);
706 info->name = finfo->name;
710 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
711 info->unique_id = buf;
712 info->category = "VST";
714 info->creator = finfo->creator;
716 info->n_inputs.set_audio (finfo->numInputs);
717 info->n_outputs.set_audio (finfo->numOutputs);
718 info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
719 info->type = ARDOUR::Windows_VST;
721 // TODO: check dup-IDs (lxvst AND windows vst)
722 bool duplicate = false;
724 if (!_windows_vst_plugin_info->empty()) {
725 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
726 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
727 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
735 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
736 _windows_vst_plugin_info->push_back (info);
741 vstfx_free_info_list (finfos);
742 return discovered > 0 ? 0 : -1;
745 #endif // WINDOWS_VST_SUPPORT
750 PluginManager::lxvst_refresh (bool cache_only)
752 if (_lxvst_plugin_info) {
753 _lxvst_plugin_info->clear ();
755 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
758 if (lxvst_path.length() == 0) {
759 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
760 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
761 "/usr/lib/vst:/usr/local/lib/vst";
764 lxvst_discover_from_path (lxvst_path, cache_only);
768 PluginManager::add_lxvst_directory (string path)
770 if (lxvst_discover_from_path (path) == 0) {
778 static bool lxvst_filter (const string& str, void *)
780 /* Not a dotfile, has a prefix before a period, suffix is "so" */
782 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
786 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
789 vector<string *> *plugin_objects;
790 vector<string *>::iterator x;
797 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
799 plugin_objects = scanner (lxvst_path, lxvst_filter, 0, false, true);
801 if (plugin_objects) {
802 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
803 ARDOUR::PluginScanMessage(_("LXVST"), **x);
804 lxvst_discover (**x, cache_only);
807 vector_delete (plugin_objects);
814 PluginManager::lxvst_discover (string path, bool cache_only)
816 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
818 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
819 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
821 if (finfos->empty()) {
822 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
826 uint32_t discovered = 0;
827 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
831 if (!finfo->canProcessReplacing) {
832 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
833 finfo->name, PROGRAM_NAME)
838 PluginInfoPtr info(new LXVSTPluginInfo);
840 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
841 info->name = PBD::basename_nosuffix (path);
843 info->name = finfo->name;
847 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
848 info->unique_id = buf;
849 info->category = "linuxVSTs";
851 info->creator = finfo->creator;
853 info->n_inputs.set_audio (finfo->numInputs);
854 info->n_outputs.set_audio (finfo->numOutputs);
855 info->n_inputs.set_midi (finfo->wantMidi ? 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 if (!_lxvst_plugin_info)
1062 return *_lxvst_plugin_info;
1064 return _empty_plugin_info;
1068 ARDOUR::PluginInfoList&
1069 PluginManager::ladspa_plugin_info ()
1071 if (!_ladspa_plugin_info)
1073 return *_ladspa_plugin_info;
1076 ARDOUR::PluginInfoList&
1077 PluginManager::lv2_plugin_info ()
1080 if (!_lv2_plugin_info)
1082 return *_lv2_plugin_info;
1084 return _empty_plugin_info;
1088 ARDOUR::PluginInfoList&
1089 PluginManager::au_plugin_info ()
1091 #ifdef AUDIOUNIT_SUPPORT
1092 if (!_au_plugin_info)
1094 return *_au_plugin_info;
1096 return _empty_plugin_info;