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/whitespace.h"
54 #include "pbd/file_utils.h"
56 #include "ardour/debug.h"
57 #include "ardour/filesystem_paths.h"
58 #include "ardour/ladspa.h"
59 #include "ardour/ladspa_plugin.h"
60 #include "ardour/plugin.h"
61 #include "ardour/plugin_manager.h"
62 #include "ardour/rc_configuration.h"
64 #include "ardour/search_paths.h"
67 #include "ardour/lv2_plugin.h"
70 #ifdef WINDOWS_VST_SUPPORT
71 #include "ardour/windows_vst_plugin.h"
75 #include "ardour/lxvst_plugin.h"
78 #ifdef AUDIOUNIT_SUPPORT
79 #include "ardour/audio_unit.h"
80 #include <Carbon/Carbon.h>
83 #include "pbd/error.h"
84 #include "pbd/stl_delete.h"
88 #include "ardour/debug.h"
90 using namespace ARDOUR;
94 PluginManager* PluginManager::_instance = 0;
95 std::string PluginManager::scanner_bin_path = "";
98 PluginManager::instance()
101 _instance = new PluginManager;
106 PluginManager::PluginManager ()
107 : _windows_vst_plugin_info(0)
108 , _lxvst_plugin_info(0)
109 , _ladspa_plugin_info(0)
110 , _lv2_plugin_info(0)
112 , _cancel_scan(false)
113 , _cancel_timeout(false)
118 string scan_p = Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst");
119 if (!PBD::find_file_in_search_path ( PBD::Searchpath(scan_p), "ardour-vst-scanner", scanner_bin_path)) {
120 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << scan_p << endmsg;
125 if ((s = getenv ("LADSPA_RDF_PATH"))){
129 if (lrdf_path.length() == 0) {
130 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
133 add_lrdf_data(lrdf_path);
134 add_ladspa_presets();
135 #ifdef WINDOWS_VST_SUPPORT
136 if (Config->get_use_windows_vst ()) {
137 add_windows_vst_presets ();
139 #endif /* WINDOWS_VST_SUPPORT */
142 if (Config->get_use_lxvst()) {
145 #endif /* Native LinuxVST support*/
147 if ((s = getenv ("VST_PATH"))) {
148 windows_vst_path = s;
149 } else if ((s = getenv ("VST_PLUGINS"))) {
150 windows_vst_path = s;
153 if (windows_vst_path.length() == 0) {
154 windows_vst_path = vst_search_path ();
157 if ((s = getenv ("LXVST_PATH"))) {
159 } else if ((s = getenv ("LXVST_PLUGINS"))) {
163 if (lxvst_path.length() == 0) {
164 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
165 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
166 "/usr/lib/vst:/usr/local/lib/vst";
169 /* first time setup, use 'default' path */
170 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
171 Config->set_plugin_path_lxvst(get_default_lxvst_path());
173 if (Config->get_plugin_path_vst() == X_("@default@")) {
174 Config->set_plugin_path_vst(get_default_windows_vst_path());
177 if (_instance == 0) {
181 BootMessage (_("Discovering Plugins"));
185 PluginManager::~PluginManager()
190 PluginManager::refresh (bool cache_only)
192 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
193 _cancel_scan = false;
195 BootMessage (_("Scanning LADSPA Plugins"));
198 BootMessage (_("Scanning LV2 Plugins"));
201 #ifdef WINDOWS_VST_SUPPORT
202 if (Config->get_use_windows_vst()) {
203 BootMessage (_("Scanning Windows VST Plugins"));
204 windows_vst_refresh (cache_only);
206 #endif // WINDOWS_VST_SUPPORT
209 if(Config->get_use_lxvst()) {
210 BootMessage (_("Scanning Linux VST Plugins"));
211 lxvst_refresh(cache_only);
213 #endif //Native linuxVST SUPPORT
215 #ifdef AUDIOUNIT_SUPPORT
216 BootMessage (_("Scanning AU Plugins"));
220 BootMessage (_("Plugin Scan Complete..."));
221 PluginListChanged (); /* EMIT SIGNAL */
222 PluginScanMessage(X_("closeme"), "", false);
223 _cancel_scan = false;
227 PluginManager::cancel_plugin_scan ()
233 PluginManager::cancel_plugin_timeout ()
235 _cancel_timeout = true;
239 PluginManager::clear_vst_cache ()
241 // see also libs/ardour/vst_info_file.cc - vstfx_infofile_path()
242 #ifdef WINDOWS_VST_SUPPORT
244 vector<string> fsi_files;
245 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.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());
254 vector<string> fsi_files;
255 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true, true, -1, false);
256 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
257 ::g_unlink(i->c_str());
262 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
264 string personal = get_personal_vst_info_cache_dir();
265 vector<string> fsi_files;
266 find_files_matching_regex (fsi_files, personal, "\\.fsi$", true, true, -1, false);
267 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
268 ::g_unlink(i->c_str());
275 PluginManager::clear_vst_blacklist ()
277 #ifdef WINDOWS_VST_SUPPORT
279 vector<string> fsi_files;
280 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsb$", true, true, -1, false);
281 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
282 ::g_unlink(i->c_str());
289 vector<string> fsi_files;
290 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsb$", true, true, -1, false);
291 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
292 ::g_unlink(i->c_str());
297 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
299 string personal = get_personal_vst_blacklist_dir();
301 vector<string> fsi_files;
302 find_files_matching_regex (fsi_files, personal, "\\.fsb$", true, true, -1, false);
303 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
304 ::g_unlink(i->c_str());
311 PluginManager::ladspa_refresh ()
313 if (_ladspa_plugin_info) {
314 _ladspa_plugin_info->clear ();
316 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
319 /* allow LADSPA_PATH to augment, not override standard locations */
321 /* Only add standard locations to ladspa_path if it doesn't
322 * already contain them. Check for trailing G_DIR_SEPARATOR too.
325 vector<string> ladspa_modules;
327 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
329 Glib::PatternSpec so_extension_pattern("*.so");
330 Glib::PatternSpec dylib_extension_pattern("*.dylib");
331 Glib::PatternSpec dll_extension_pattern("*.dll");
333 find_matching_files_in_search_path (ladspa_search_path (),
334 so_extension_pattern, ladspa_modules);
336 find_matching_files_in_search_path (ladspa_search_path (),
337 dylib_extension_pattern, ladspa_modules);
339 find_matching_files_in_search_path (ladspa_search_path (),
340 dll_extension_pattern, ladspa_modules);
342 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
343 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
344 ladspa_discover (*i);
348 static bool rdf_filter (const string &str, void* /*arg*/)
350 return str[0] != '.' &&
351 ((str.find(".rdf") == (str.length() - 4)) ||
352 (str.find(".rdfs") == (str.length() - 5)) ||
353 (str.find(".n3") == (str.length() - 3)) ||
354 (str.find(".ttl") == (str.length() - 4)));
358 PluginManager::add_ladspa_presets()
360 add_presets ("ladspa");
364 PluginManager::add_windows_vst_presets()
366 add_presets ("windows-vst");
370 PluginManager::add_lxvst_presets()
372 add_presets ("lxvst");
376 PluginManager::add_presets(string domain)
379 vector<string> presets;
380 vector<string>::iterator x;
383 if ((envvar = getenv ("HOME")) == 0) {
387 string path = string_compose("%1/.%2/rdf", envvar, domain);
388 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
390 for (x = presets.begin(); x != presets.end (); ++x) {
391 string file = "file:" + *x;
392 if (lrdf_read_file(file.c_str())) {
393 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
401 PluginManager::add_lrdf_data (const string &path)
404 vector<string> rdf_files;
405 vector<string>::iterator x;
407 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
409 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
410 const string uri(string("file://") + *x);
412 if (lrdf_read_file(uri.c_str())) {
413 warning << "Could not parse rdf file: " << uri << endmsg;
420 PluginManager::ladspa_discover (string path)
422 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
424 Glib::Module module(path);
425 const LADSPA_Descriptor *descriptor;
426 LADSPA_Descriptor_Function dfunc;
430 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
431 path, Glib::Module::get_last_error()) << endmsg;
436 if (!module.get_symbol("ladspa_descriptor", func)) {
437 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
438 error << Glib::Module::get_last_error() << endmsg;
442 dfunc = (LADSPA_Descriptor_Function)func;
444 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
446 for (uint32_t i = 0; ; ++i) {
447 if ((descriptor = dfunc (i)) == 0) {
451 if (!ladspa_plugin_whitelist.empty()) {
452 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
457 PluginInfoPtr info(new LadspaPluginInfo);
458 info->name = descriptor->Name;
459 info->category = get_ladspa_category(descriptor->UniqueID);
460 info->creator = descriptor->Maker;
463 info->n_inputs = ChanCount();
464 info->n_outputs = ChanCount();
465 info->type = ARDOUR::LADSPA;
468 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
469 info->unique_id = buf;
471 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
472 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
473 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
474 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
476 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
477 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
482 if(_ladspa_plugin_info->empty()){
483 _ladspa_plugin_info->push_back (info);
486 //Ensure that the plugin is not already in the plugin list.
490 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
491 if(0 == info->unique_id.compare((*i)->unique_id)){
497 _ladspa_plugin_info->push_back (info);
500 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
503 // GDB WILL NOT LIKE YOU IF YOU DO THIS
510 PluginManager::get_ladspa_category (uint32_t plugin_id)
514 lrdf_statement pattern;
516 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
517 pattern.subject = buf;
518 pattern.predicate = const_cast<char*>(RDF_TYPE);
520 pattern.object_type = lrdf_uri;
522 lrdf_statement* matches1 = lrdf_matches (&pattern);
528 pattern.subject = matches1->object;
529 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
531 pattern.object_type = lrdf_literal;
533 lrdf_statement* matches2 = lrdf_matches (&pattern);
534 lrdf_free_statements(matches1);
540 string label = matches2->object;
541 lrdf_free_statements(matches2);
543 /* Kludge LADSPA class names to be singular and match LV2 class names.
544 This avoids duplicate plugin menus for every class, which is necessary
545 to make the plugin category menu at all usable, but is obviously a
548 In the short term, lrdf could be updated so the labels match and a new
549 release made. To support both specs, we should probably be mapping the
550 URIs to the same category in code and perhaps tweaking that hierarchy
551 dynamically to suit the user. Personally, I (drobilla) think that time
552 is better spent replacing the little-used LRDF.
554 In the longer term, we will abandon LRDF entirely in favour of LV2 and
555 use that class hierarchy. Aside from fixing this problem properly, that
556 will also allow for translated labels. SWH plugins have been LV2 for
557 ages; TAP needs porting. I don't know of anything else with LRDF data.
559 if (label == "Utilities") {
561 } else if (label == "Pitch shifters") {
562 return "Pitch Shifter";
563 } else if (label != "Dynamics" && label != "Chorus"
564 &&label[label.length() - 1] == 's'
565 && label[label.length() - 2] != 's') {
566 return label.substr(0, label.length() - 1);
577 PluginManager::lv2_refresh ()
579 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
580 delete _lv2_plugin_info;
581 _lv2_plugin_info = LV2PluginInfo::discover();
585 #ifdef AUDIOUNIT_SUPPORT
587 PluginManager::au_refresh ()
589 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
590 delete _au_plugin_info;
591 _au_plugin_info = AUPluginInfo::discover();
596 #ifdef WINDOWS_VST_SUPPORT
599 PluginManager::windows_vst_refresh (bool cache_only)
601 if (_windows_vst_plugin_info) {
602 _windows_vst_plugin_info->clear ();
604 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
607 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
610 static bool windows_vst_filter (const string& str, void * /*arg*/)
612 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
614 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
618 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
620 vector<string> plugin_objects;
621 vector<string>::iterator x;
624 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
626 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
628 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
629 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
630 windows_vst_discover (*x, cache_only || cancelled());
637 PluginManager::windows_vst_discover (string path, bool cache_only)
639 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
641 _cancel_timeout = false;
642 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
643 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
645 if (finfos->empty()) {
646 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
650 uint32_t discovered = 0;
651 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
655 if (!finfo->canProcessReplacing) {
656 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
657 finfo->name, PROGRAM_NAME)
662 PluginInfoPtr info (new WindowsVSTPluginInfo);
664 /* what a joke freeware VST is */
666 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
667 info->name = PBD::basename_nosuffix (path);
669 info->name = finfo->name;
673 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
674 info->unique_id = buf;
675 info->category = "VST";
677 info->creator = finfo->creator;
679 info->n_inputs.set_audio (finfo->numInputs);
680 info->n_outputs.set_audio (finfo->numOutputs);
681 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
682 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
683 info->type = ARDOUR::Windows_VST;
685 // TODO: check dup-IDs (lxvst AND windows vst)
686 bool duplicate = false;
688 if (!_windows_vst_plugin_info->empty()) {
689 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
690 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
691 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
699 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
700 _windows_vst_plugin_info->push_back (info);
705 vstfx_free_info_list (finfos);
706 return discovered > 0 ? 0 : -1;
709 #endif // WINDOWS_VST_SUPPORT
714 PluginManager::lxvst_refresh (bool cache_only)
716 if (_lxvst_plugin_info) {
717 _lxvst_plugin_info->clear ();
719 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
722 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
725 static bool lxvst_filter (const string& str, void *)
727 /* Not a dotfile, has a prefix before a period, suffix is "so" */
729 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
733 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
735 vector<string> plugin_objects;
736 vector<string>::iterator x;
743 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
745 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
747 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
748 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
749 lxvst_discover (*x, cache_only || cancelled());
756 PluginManager::lxvst_discover (string path, bool cache_only)
758 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
760 _cancel_timeout = false;
761 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
762 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
764 if (finfos->empty()) {
765 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
769 uint32_t discovered = 0;
770 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
774 if (!finfo->canProcessReplacing) {
775 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
776 finfo->name, PROGRAM_NAME)
781 PluginInfoPtr info(new LXVSTPluginInfo);
783 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
784 info->name = PBD::basename_nosuffix (path);
786 info->name = finfo->name;
790 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
791 info->unique_id = buf;
792 info->category = "linuxVSTs";
794 info->creator = finfo->creator;
796 info->n_inputs.set_audio (finfo->numInputs);
797 info->n_outputs.set_audio (finfo->numOutputs);
798 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
799 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
800 info->type = ARDOUR::LXVST;
802 /* Make sure we don't find the same plugin in more than one place along
803 the LXVST_PATH We can't use a simple 'find' because the path is included
804 in the PluginInfo, and that is the one thing we can be sure MUST be
805 different if a duplicate instance is found. So we just compare the type
806 and unique ID (which for some VSTs isn't actually unique...)
809 // TODO: check dup-IDs with windowsVST, too
810 bool duplicate = false;
811 if (!_lxvst_plugin_info->empty()) {
812 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
813 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
814 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
822 _lxvst_plugin_info->push_back (info);
827 vstfx_free_info_list (finfos);
828 return discovered > 0 ? 0 : -1;
831 #endif // LXVST_SUPPORT
834 PluginManager::PluginStatusType
835 PluginManager::get_status (const PluginInfoPtr& pi)
837 PluginStatus ps (pi->type, pi->unique_id);
838 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
839 if (i == statuses.end() ) {
847 PluginManager::save_statuses ()
850 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
852 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
858 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
870 ofs << "Windows-VST";
879 switch ((*i).status) {
892 ofs << (*i).unique_id;;
900 PluginManager::load_statuses ()
902 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
903 ifstream ifs (path.c_str());
913 PluginStatusType status;
930 /* rest of the line is the plugin ID */
932 ifs.getline (buf, sizeof (buf), '\n');
937 if (sstatus == "Normal") {
939 } else if (sstatus == "Favorite") {
941 } else if (sstatus == "Hidden") {
944 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
950 if (stype == "LADSPA") {
952 } else if (stype == "AudioUnit") {
954 } else if (stype == "LV2") {
956 } else if (stype == "Windows-VST") {
958 } else if (stype == "LXVST") {
961 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
967 strip_whitespace_edges (id);
968 set_status (type, id, status);
975 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
977 PluginStatus ps (t, id, status);
980 if (status == Normal) {
984 statuses.insert (ps);
987 ARDOUR::PluginInfoList&
988 PluginManager::windows_vst_plugin_info ()
990 #ifdef WINDOWS_VST_SUPPORT
991 if (!_windows_vst_plugin_info) {
992 windows_vst_refresh ();
994 return *_windows_vst_plugin_info;
996 return _empty_plugin_info;
1000 ARDOUR::PluginInfoList&
1001 PluginManager::lxvst_plugin_info ()
1003 #ifdef LXVST_SUPPORT
1004 assert(_lxvst_plugin_info);
1005 return *_lxvst_plugin_info;
1007 return _empty_plugin_info;
1011 ARDOUR::PluginInfoList&
1012 PluginManager::ladspa_plugin_info ()
1014 assert(_ladspa_plugin_info);
1015 return *_ladspa_plugin_info;
1018 ARDOUR::PluginInfoList&
1019 PluginManager::lv2_plugin_info ()
1022 assert(_lv2_plugin_info);
1023 return *_lv2_plugin_info;
1025 return _empty_plugin_info;
1029 ARDOUR::PluginInfoList&
1030 PluginManager::au_plugin_info ()
1032 #ifdef AUDIOUNIT_SUPPORT
1033 assert(_au_plugin_info);
1034 return *_au_plugin_info;
1036 return _empty_plugin_info;