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);
249 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
250 ::g_unlink(i->c_str());
258 vector<string> fsi_files;
259 fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsi$", true, true, -1, false);
260 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
261 ::g_unlink(i->c_str());
266 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
268 string personal = get_personal_vst_info_cache_dir();
270 vector<string> fsi_files;
271 fsi_files = scanner (personal, "\\.fsi$", true, true, -1, false);
272 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
273 ::g_unlink(i->c_str());
280 PluginManager::clear_vst_blacklist ()
282 #ifdef WINDOWS_VST_SUPPORT
285 vector<string> fsi_files;
287 fsi_files = scanner (Config->get_plugin_path_vst(), "\\.fsb$", true, true, -1, false);
288 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
289 ::g_unlink(i->c_str());
297 vector<string> fsi_files;
298 fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsb$", true, true, -1, false);
299 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
300 ::g_unlink(i->c_str());
305 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
307 string personal = get_personal_vst_blacklist_dir();
310 vector<string> fsi_files;
311 fsi_files = scanner (personal, "\\.fsb$", true, true, -1, false);
312 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
313 ::g_unlink(i->c_str());
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, false);
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);
400 for (x = presets.begin(); x != presets.end (); ++x) {
401 string file = "file:" + *x;
402 if (lrdf_read_file(file.c_str())) {
403 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
411 PluginManager::add_lrdf_data (const string &path)
415 vector<string> rdf_files;
416 vector<string>::iterator x;
418 rdf_files = scanner (path, rdf_filter, 0, false, true);
420 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
421 const string uri(string("file://") + *x);
423 if (lrdf_read_file(uri.c_str())) {
424 warning << "Could not parse rdf file: " << uri << endmsg;
431 PluginManager::ladspa_discover (string path)
433 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
435 Glib::Module module(path);
436 const LADSPA_Descriptor *descriptor;
437 LADSPA_Descriptor_Function dfunc;
441 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
442 path, Glib::Module::get_last_error()) << endmsg;
447 if (!module.get_symbol("ladspa_descriptor", func)) {
448 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
449 error << Glib::Module::get_last_error() << endmsg;
453 dfunc = (LADSPA_Descriptor_Function)func;
455 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
457 for (uint32_t i = 0; ; ++i) {
458 if ((descriptor = dfunc (i)) == 0) {
462 if (!ladspa_plugin_whitelist.empty()) {
463 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
468 PluginInfoPtr info(new LadspaPluginInfo);
469 info->name = descriptor->Name;
470 info->category = get_ladspa_category(descriptor->UniqueID);
471 info->creator = descriptor->Maker;
474 info->n_inputs = ChanCount();
475 info->n_outputs = ChanCount();
476 info->type = ARDOUR::LADSPA;
479 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
480 info->unique_id = buf;
482 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
483 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
484 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
485 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
487 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
488 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
493 if(_ladspa_plugin_info->empty()){
494 _ladspa_plugin_info->push_back (info);
497 //Ensure that the plugin is not already in the plugin list.
501 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
502 if(0 == info->unique_id.compare((*i)->unique_id)){
508 _ladspa_plugin_info->push_back (info);
511 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
514 // GDB WILL NOT LIKE YOU IF YOU DO THIS
521 PluginManager::get_ladspa_category (uint32_t plugin_id)
525 lrdf_statement pattern;
527 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
528 pattern.subject = buf;
529 pattern.predicate = const_cast<char*>(RDF_TYPE);
531 pattern.object_type = lrdf_uri;
533 lrdf_statement* matches1 = lrdf_matches (&pattern);
539 pattern.subject = matches1->object;
540 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
542 pattern.object_type = lrdf_literal;
544 lrdf_statement* matches2 = lrdf_matches (&pattern);
545 lrdf_free_statements(matches1);
551 string label = matches2->object;
552 lrdf_free_statements(matches2);
554 /* Kludge LADSPA class names to be singular and match LV2 class names.
555 This avoids duplicate plugin menus for every class, which is necessary
556 to make the plugin category menu at all usable, but is obviously a
559 In the short term, lrdf could be updated so the labels match and a new
560 release made. To support both specs, we should probably be mapping the
561 URIs to the same category in code and perhaps tweaking that hierarchy
562 dynamically to suit the user. Personally, I (drobilla) think that time
563 is better spent replacing the little-used LRDF.
565 In the longer term, we will abandon LRDF entirely in favour of LV2 and
566 use that class hierarchy. Aside from fixing this problem properly, that
567 will also allow for translated labels. SWH plugins have been LV2 for
568 ages; TAP needs porting. I don't know of anything else with LRDF data.
570 if (label == "Utilities") {
572 } else if (label == "Pitch shifters") {
573 return "Pitch Shifter";
574 } else if (label != "Dynamics" && label != "Chorus"
575 &&label[label.length() - 1] == 's'
576 && label[label.length() - 2] != 's') {
577 return label.substr(0, label.length() - 1);
588 PluginManager::lv2_refresh ()
590 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
591 delete _lv2_plugin_info;
592 _lv2_plugin_info = LV2PluginInfo::discover();
596 #ifdef AUDIOUNIT_SUPPORT
598 PluginManager::au_refresh ()
600 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
601 delete _au_plugin_info;
602 _au_plugin_info = AUPluginInfo::discover();
607 #ifdef WINDOWS_VST_SUPPORT
610 PluginManager::windows_vst_refresh (bool cache_only)
612 if (_windows_vst_plugin_info) {
613 _windows_vst_plugin_info->clear ();
615 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
618 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
621 static bool windows_vst_filter (const string& str, void * /*arg*/)
623 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
625 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
629 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
632 vector<string> plugin_objects;
633 vector<string>::iterator x;
636 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
638 plugin_objects = scanner (Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
640 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
641 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
642 windows_vst_discover (*x, cache_only || cancelled());
649 PluginManager::windows_vst_discover (string path, bool cache_only)
651 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
653 _cancel_timeout = false;
654 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
655 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
657 if (finfos->empty()) {
658 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
662 uint32_t discovered = 0;
663 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
667 if (!finfo->canProcessReplacing) {
668 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
669 finfo->name, PROGRAM_NAME)
674 PluginInfoPtr info (new WindowsVSTPluginInfo);
676 /* what a joke freeware VST is */
678 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
679 info->name = PBD::basename_nosuffix (path);
681 info->name = finfo->name;
685 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
686 info->unique_id = buf;
687 info->category = "VST";
689 info->creator = finfo->creator;
691 info->n_inputs.set_audio (finfo->numInputs);
692 info->n_outputs.set_audio (finfo->numOutputs);
693 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
694 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
695 info->type = ARDOUR::Windows_VST;
697 // TODO: check dup-IDs (lxvst AND windows vst)
698 bool duplicate = false;
700 if (!_windows_vst_plugin_info->empty()) {
701 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
702 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
703 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
711 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
712 _windows_vst_plugin_info->push_back (info);
717 vstfx_free_info_list (finfos);
718 return discovered > 0 ? 0 : -1;
721 #endif // WINDOWS_VST_SUPPORT
726 PluginManager::lxvst_refresh (bool cache_only)
728 if (_lxvst_plugin_info) {
729 _lxvst_plugin_info->clear ();
731 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
734 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
737 static bool lxvst_filter (const string& str, void *)
739 /* Not a dotfile, has a prefix before a period, suffix is "so" */
741 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
745 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
748 vector<string> plugin_objects;
749 vector<string>::iterator x;
756 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
758 plugin_objects = scanner (Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
760 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
761 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
762 lxvst_discover (*x, cache_only || cancelled());
769 PluginManager::lxvst_discover (string path, bool cache_only)
771 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
773 _cancel_timeout = false;
774 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
775 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
777 if (finfos->empty()) {
778 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
782 uint32_t discovered = 0;
783 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
787 if (!finfo->canProcessReplacing) {
788 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
789 finfo->name, PROGRAM_NAME)
794 PluginInfoPtr info(new LXVSTPluginInfo);
796 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
797 info->name = PBD::basename_nosuffix (path);
799 info->name = finfo->name;
803 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
804 info->unique_id = buf;
805 info->category = "linuxVSTs";
807 info->creator = finfo->creator;
809 info->n_inputs.set_audio (finfo->numInputs);
810 info->n_outputs.set_audio (finfo->numOutputs);
811 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
812 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
813 info->type = ARDOUR::LXVST;
815 /* Make sure we don't find the same plugin in more than one place along
816 the LXVST_PATH We can't use a simple 'find' because the path is included
817 in the PluginInfo, and that is the one thing we can be sure MUST be
818 different if a duplicate instance is found. So we just compare the type
819 and unique ID (which for some VSTs isn't actually unique...)
822 // TODO: check dup-IDs with windowsVST, too
823 bool duplicate = false;
824 if (!_lxvst_plugin_info->empty()) {
825 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
826 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
827 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
835 _lxvst_plugin_info->push_back (info);
840 vstfx_free_info_list (finfos);
841 return discovered > 0 ? 0 : -1;
844 #endif // LXVST_SUPPORT
847 PluginManager::PluginStatusType
848 PluginManager::get_status (const PluginInfoPtr& pi)
850 PluginStatus ps (pi->type, pi->unique_id);
851 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
852 if (i == statuses.end() ) {
860 PluginManager::save_statuses ()
863 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
865 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
871 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
883 ofs << "Windows-VST";
892 switch ((*i).status) {
905 ofs << (*i).unique_id;;
913 PluginManager::load_statuses ()
915 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
916 ifstream ifs (path.c_str());
926 PluginStatusType status;
943 /* rest of the line is the plugin ID */
945 ifs.getline (buf, sizeof (buf), '\n');
950 if (sstatus == "Normal") {
952 } else if (sstatus == "Favorite") {
954 } else if (sstatus == "Hidden") {
957 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
963 if (stype == "LADSPA") {
965 } else if (stype == "AudioUnit") {
967 } else if (stype == "LV2") {
969 } else if (stype == "Windows-VST") {
971 } else if (stype == "LXVST") {
974 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
980 strip_whitespace_edges (id);
981 set_status (type, id, status);
988 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
990 PluginStatus ps (t, id, status);
993 if (status == Normal) {
997 statuses.insert (ps);
1000 ARDOUR::PluginInfoList&
1001 PluginManager::windows_vst_plugin_info ()
1003 #ifdef WINDOWS_VST_SUPPORT
1004 if (!_windows_vst_plugin_info) {
1005 windows_vst_refresh ();
1007 return *_windows_vst_plugin_info;
1009 return _empty_plugin_info;
1013 ARDOUR::PluginInfoList&
1014 PluginManager::lxvst_plugin_info ()
1016 #ifdef LXVST_SUPPORT
1017 assert(_lxvst_plugin_info);
1018 return *_lxvst_plugin_info;
1020 return _empty_plugin_info;
1024 ARDOUR::PluginInfoList&
1025 PluginManager::ladspa_plugin_info ()
1027 assert(_ladspa_plugin_info);
1028 return *_ladspa_plugin_info;
1031 ARDOUR::PluginInfoList&
1032 PluginManager::lv2_plugin_info ()
1035 assert(_lv2_plugin_info);
1036 return *_lv2_plugin_info;
1038 return _empty_plugin_info;
1042 ARDOUR::PluginInfoList&
1043 PluginManager::au_plugin_info ()
1045 #ifdef AUDIOUNIT_SUPPORT
1046 assert(_au_plugin_info);
1047 return *_au_plugin_info;
1049 return _empty_plugin_info;