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 (PBD::Searchpath(scan_p),
120 #ifdef PLATFORM_WINDOWS
121 "ardour-vst-scanner.exe"
125 , scanner_bin_path)) {
126 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << scan_p << endmsg;
131 if ((s = getenv ("LADSPA_RDF_PATH"))){
135 if (lrdf_path.length() == 0) {
136 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
139 add_lrdf_data(lrdf_path);
140 add_ladspa_presets();
141 #ifdef WINDOWS_VST_SUPPORT
142 if (Config->get_use_windows_vst ()) {
143 add_windows_vst_presets ();
145 #endif /* WINDOWS_VST_SUPPORT */
148 if (Config->get_use_lxvst()) {
151 #endif /* Native LinuxVST support*/
153 if ((s = getenv ("VST_PATH"))) {
154 windows_vst_path = s;
155 } else if ((s = getenv ("VST_PLUGINS"))) {
156 windows_vst_path = s;
159 if (windows_vst_path.length() == 0) {
160 windows_vst_path = vst_search_path ();
163 if ((s = getenv ("LXVST_PATH"))) {
165 } else if ((s = getenv ("LXVST_PLUGINS"))) {
169 if (lxvst_path.length() == 0) {
170 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
171 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
172 "/usr/lib/vst:/usr/local/lib/vst";
175 /* first time setup, use 'default' path */
176 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
177 Config->set_plugin_path_lxvst(get_default_lxvst_path());
179 if (Config->get_plugin_path_vst() == X_("@default@")) {
180 Config->set_plugin_path_vst(get_default_windows_vst_path());
183 if (_instance == 0) {
187 BootMessage (_("Discovering Plugins"));
191 PluginManager::~PluginManager()
193 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
194 // don't bother, just exit quickly.
195 delete _windows_vst_plugin_info;
196 delete _lxvst_plugin_info;
197 delete _ladspa_plugin_info;
198 delete _lv2_plugin_info;
199 delete _au_plugin_info;
204 PluginManager::refresh (bool cache_only)
206 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
207 _cancel_scan = false;
209 BootMessage (_("Scanning LADSPA Plugins"));
212 BootMessage (_("Scanning LV2 Plugins"));
215 #ifdef WINDOWS_VST_SUPPORT
216 if (Config->get_use_windows_vst()) {
217 BootMessage (_("Scanning Windows VST Plugins"));
218 windows_vst_refresh (cache_only);
220 #endif // WINDOWS_VST_SUPPORT
223 if(Config->get_use_lxvst()) {
224 BootMessage (_("Scanning Linux VST Plugins"));
225 lxvst_refresh(cache_only);
227 #endif //Native linuxVST SUPPORT
229 #ifdef AUDIOUNIT_SUPPORT
230 BootMessage (_("Scanning AU Plugins"));
234 BootMessage (_("Plugin Scan Complete..."));
235 PluginListChanged (); /* EMIT SIGNAL */
236 PluginScanMessage(X_("closeme"), "", false);
237 _cancel_scan = false;
241 PluginManager::cancel_plugin_scan ()
247 PluginManager::cancel_plugin_timeout ()
249 _cancel_timeout = true;
253 PluginManager::clear_vst_cache ()
255 // see also libs/ardour/vst_info_file.cc - vstfx_infofile_path()
256 #ifdef WINDOWS_VST_SUPPORT
258 vector<string> fsi_files;
259 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$");
260 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
261 ::g_unlink(i->c_str());
268 vector<string> fsi_files;
269 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$");
270 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
271 ::g_unlink(i->c_str());
276 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
278 string personal = get_personal_vst_info_cache_dir();
279 vector<string> fsi_files;
280 find_files_matching_regex (fsi_files, personal, "\\.fsi$");
281 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
282 ::g_unlink(i->c_str());
289 PluginManager::clear_vst_blacklist ()
291 #ifdef WINDOWS_VST_SUPPORT
293 vector<string> fsi_files;
294 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsb$");
295 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
296 ::g_unlink(i->c_str());
303 vector<string> fsi_files;
304 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsb$");
305 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
306 ::g_unlink(i->c_str());
311 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
313 string personal = get_personal_vst_blacklist_dir();
315 vector<string> fsi_files;
316 find_files_matching_regex (fsi_files, personal, "\\.fsb$");
317 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
318 ::g_unlink(i->c_str());
325 PluginManager::ladspa_refresh ()
327 if (_ladspa_plugin_info) {
328 _ladspa_plugin_info->clear ();
330 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
333 /* allow LADSPA_PATH to augment, not override standard locations */
335 /* Only add standard locations to ladspa_path if it doesn't
336 * already contain them. Check for trailing G_DIR_SEPARATOR too.
339 vector<string> ladspa_modules;
341 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
343 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
344 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
345 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
347 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
348 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
349 ladspa_discover (*i);
353 static bool rdf_filter (const string &str, void* /*arg*/)
355 return str[0] != '.' &&
356 ((str.find(".rdf") == (str.length() - 4)) ||
357 (str.find(".rdfs") == (str.length() - 5)) ||
358 (str.find(".n3") == (str.length() - 3)) ||
359 (str.find(".ttl") == (str.length() - 4)));
363 PluginManager::add_ladspa_presets()
365 add_presets ("ladspa");
369 PluginManager::add_windows_vst_presets()
371 add_presets ("windows-vst");
375 PluginManager::add_lxvst_presets()
377 add_presets ("lxvst");
381 PluginManager::add_presets(string domain)
384 vector<string> presets;
385 vector<string>::iterator x;
388 if ((envvar = getenv ("HOME")) == 0) {
392 string path = string_compose("%1/.%2/rdf", envvar, domain);
393 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
395 for (x = presets.begin(); x != presets.end (); ++x) {
396 string file = "file:" + *x;
397 if (lrdf_read_file(file.c_str())) {
398 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
406 PluginManager::add_lrdf_data (const string &path)
409 vector<string> rdf_files;
410 vector<string>::iterator x;
412 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
414 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
415 const string uri(string("file://") + *x);
417 if (lrdf_read_file(uri.c_str())) {
418 warning << "Could not parse rdf file: " << uri << endmsg;
425 PluginManager::ladspa_discover (string path)
427 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
429 Glib::Module module(path);
430 const LADSPA_Descriptor *descriptor;
431 LADSPA_Descriptor_Function dfunc;
435 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
436 path, Glib::Module::get_last_error()) << endmsg;
441 if (!module.get_symbol("ladspa_descriptor", func)) {
442 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
443 error << Glib::Module::get_last_error() << endmsg;
447 dfunc = (LADSPA_Descriptor_Function)func;
449 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
451 for (uint32_t i = 0; ; ++i) {
452 if ((descriptor = dfunc (i)) == 0) {
456 if (!ladspa_plugin_whitelist.empty()) {
457 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
462 PluginInfoPtr info(new LadspaPluginInfo);
463 info->name = descriptor->Name;
464 info->category = get_ladspa_category(descriptor->UniqueID);
465 info->creator = descriptor->Maker;
468 info->n_inputs = ChanCount();
469 info->n_outputs = ChanCount();
470 info->type = ARDOUR::LADSPA;
473 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
474 info->unique_id = buf;
476 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
477 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
478 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
479 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
481 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
482 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
487 if(_ladspa_plugin_info->empty()){
488 _ladspa_plugin_info->push_back (info);
491 //Ensure that the plugin is not already in the plugin list.
495 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
496 if(0 == info->unique_id.compare((*i)->unique_id)){
502 _ladspa_plugin_info->push_back (info);
505 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
508 // GDB WILL NOT LIKE YOU IF YOU DO THIS
515 PluginManager::get_ladspa_category (uint32_t plugin_id)
519 lrdf_statement pattern;
521 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
522 pattern.subject = buf;
523 pattern.predicate = const_cast<char*>(RDF_TYPE);
525 pattern.object_type = lrdf_uri;
527 lrdf_statement* matches1 = lrdf_matches (&pattern);
533 pattern.subject = matches1->object;
534 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
536 pattern.object_type = lrdf_literal;
538 lrdf_statement* matches2 = lrdf_matches (&pattern);
539 lrdf_free_statements(matches1);
545 string label = matches2->object;
546 lrdf_free_statements(matches2);
548 /* Kludge LADSPA class names to be singular and match LV2 class names.
549 This avoids duplicate plugin menus for every class, which is necessary
550 to make the plugin category menu at all usable, but is obviously a
553 In the short term, lrdf could be updated so the labels match and a new
554 release made. To support both specs, we should probably be mapping the
555 URIs to the same category in code and perhaps tweaking that hierarchy
556 dynamically to suit the user. Personally, I (drobilla) think that time
557 is better spent replacing the little-used LRDF.
559 In the longer term, we will abandon LRDF entirely in favour of LV2 and
560 use that class hierarchy. Aside from fixing this problem properly, that
561 will also allow for translated labels. SWH plugins have been LV2 for
562 ages; TAP needs porting. I don't know of anything else with LRDF data.
564 if (label == "Utilities") {
566 } else if (label == "Pitch shifters") {
567 return "Pitch Shifter";
568 } else if (label != "Dynamics" && label != "Chorus"
569 &&label[label.length() - 1] == 's'
570 && label[label.length() - 2] != 's') {
571 return label.substr(0, label.length() - 1);
582 PluginManager::lv2_refresh ()
584 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
585 delete _lv2_plugin_info;
586 _lv2_plugin_info = LV2PluginInfo::discover();
590 #ifdef AUDIOUNIT_SUPPORT
592 PluginManager::au_refresh ()
594 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
595 delete _au_plugin_info;
596 _au_plugin_info = AUPluginInfo::discover();
601 #ifdef WINDOWS_VST_SUPPORT
604 PluginManager::windows_vst_refresh (bool cache_only)
606 if (_windows_vst_plugin_info) {
607 _windows_vst_plugin_info->clear ();
609 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
612 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
615 static bool windows_vst_filter (const string& str, void * /*arg*/)
617 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
619 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
623 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
625 vector<string> plugin_objects;
626 vector<string>::iterator x;
629 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
631 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
633 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
634 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
635 windows_vst_discover (*x, cache_only || cancelled());
642 PluginManager::windows_vst_discover (string path, bool cache_only)
644 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
646 _cancel_timeout = false;
647 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
648 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
650 if (finfos->empty()) {
651 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
655 uint32_t discovered = 0;
656 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
660 if (!finfo->canProcessReplacing) {
661 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
662 finfo->name, PROGRAM_NAME)
667 PluginInfoPtr info (new WindowsVSTPluginInfo);
669 /* what a joke freeware VST is */
671 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
672 info->name = PBD::basename_nosuffix (path);
674 info->name = finfo->name;
678 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
679 info->unique_id = buf;
680 info->category = "VST";
682 info->creator = finfo->creator;
684 info->n_inputs.set_audio (finfo->numInputs);
685 info->n_outputs.set_audio (finfo->numOutputs);
686 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
687 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
688 info->type = ARDOUR::Windows_VST;
690 // TODO: check dup-IDs (lxvst AND windows vst)
691 bool duplicate = false;
693 if (!_windows_vst_plugin_info->empty()) {
694 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
695 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
696 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
704 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
705 _windows_vst_plugin_info->push_back (info);
710 vstfx_free_info_list (finfos);
711 return discovered > 0 ? 0 : -1;
714 #endif // WINDOWS_VST_SUPPORT
719 PluginManager::lxvst_refresh (bool cache_only)
721 if (_lxvst_plugin_info) {
722 _lxvst_plugin_info->clear ();
724 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
727 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
730 static bool lxvst_filter (const string& str, void *)
732 /* Not a dotfile, has a prefix before a period, suffix is "so" */
734 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
738 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
740 vector<string> plugin_objects;
741 vector<string>::iterator x;
748 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
750 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
752 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
753 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
754 lxvst_discover (*x, cache_only || cancelled());
761 PluginManager::lxvst_discover (string path, bool cache_only)
763 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
765 _cancel_timeout = false;
766 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
767 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
769 if (finfos->empty()) {
770 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
774 uint32_t discovered = 0;
775 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
779 if (!finfo->canProcessReplacing) {
780 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
781 finfo->name, PROGRAM_NAME)
786 PluginInfoPtr info(new LXVSTPluginInfo);
788 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
789 info->name = PBD::basename_nosuffix (path);
791 info->name = finfo->name;
795 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
796 info->unique_id = buf;
797 info->category = "linuxVSTs";
799 info->creator = finfo->creator;
801 info->n_inputs.set_audio (finfo->numInputs);
802 info->n_outputs.set_audio (finfo->numOutputs);
803 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
804 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
805 info->type = ARDOUR::LXVST;
807 /* Make sure we don't find the same plugin in more than one place along
808 the LXVST_PATH We can't use a simple 'find' because the path is included
809 in the PluginInfo, and that is the one thing we can be sure MUST be
810 different if a duplicate instance is found. So we just compare the type
811 and unique ID (which for some VSTs isn't actually unique...)
814 // TODO: check dup-IDs with windowsVST, too
815 bool duplicate = false;
816 if (!_lxvst_plugin_info->empty()) {
817 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
818 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
819 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
827 _lxvst_plugin_info->push_back (info);
832 vstfx_free_info_list (finfos);
833 return discovered > 0 ? 0 : -1;
836 #endif // LXVST_SUPPORT
839 PluginManager::PluginStatusType
840 PluginManager::get_status (const PluginInfoPtr& pi)
842 PluginStatus ps (pi->type, pi->unique_id);
843 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
844 if (i == statuses.end() ) {
852 PluginManager::save_statuses ()
855 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
857 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
863 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
875 ofs << "Windows-VST";
884 switch ((*i).status) {
897 ofs << (*i).unique_id;;
905 PluginManager::load_statuses ()
907 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
908 ifstream ifs (path.c_str());
918 PluginStatusType status;
935 /* rest of the line is the plugin ID */
937 ifs.getline (buf, sizeof (buf), '\n');
942 if (sstatus == "Normal") {
944 } else if (sstatus == "Favorite") {
946 } else if (sstatus == "Hidden") {
949 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
955 if (stype == "LADSPA") {
957 } else if (stype == "AudioUnit") {
959 } else if (stype == "LV2") {
961 } else if (stype == "Windows-VST") {
963 } else if (stype == "LXVST") {
966 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
972 strip_whitespace_edges (id);
973 set_status (type, id, status);
980 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
982 PluginStatus ps (t, id, status);
985 if (status == Normal) {
989 statuses.insert (ps);
992 ARDOUR::PluginInfoList&
993 PluginManager::windows_vst_plugin_info ()
995 #ifdef WINDOWS_VST_SUPPORT
996 if (!_windows_vst_plugin_info) {
997 windows_vst_refresh ();
999 return *_windows_vst_plugin_info;
1001 return _empty_plugin_info;
1005 ARDOUR::PluginInfoList&
1006 PluginManager::lxvst_plugin_info ()
1008 #ifdef LXVST_SUPPORT
1009 assert(_lxvst_plugin_info);
1010 return *_lxvst_plugin_info;
1012 return _empty_plugin_info;
1016 ARDOUR::PluginInfoList&
1017 PluginManager::ladspa_plugin_info ()
1019 assert(_ladspa_plugin_info);
1020 return *_ladspa_plugin_info;
1023 ARDOUR::PluginInfoList&
1024 PluginManager::lv2_plugin_info ()
1027 assert(_lv2_plugin_info);
1028 return *_lv2_plugin_info;
1030 return _empty_plugin_info;
1034 ARDOUR::PluginInfoList&
1035 PluginManager::au_plugin_info ()
1037 #ifdef AUDIOUNIT_SUPPORT
1038 assert(_au_plugin_info);
1039 return *_au_plugin_info;
1041 return _empty_plugin_info;