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 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
119 PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
120 #ifdef PLATFORM_WINDOWS
121 vstsp += Glib::build_filename(g_win32_get_package_installation_directory_of_module (0), "bin");
123 vstsp += Glib::getenv("PATH");
125 if (!PBD::find_file (vstsp,
126 #ifdef PLATFORM_WINDOWS
127 "ardour-vst-scanner.exe"
131 , scanner_bin_path)) {
132 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << vstsp.to_string() << endmsg;
138 if ((s = getenv ("LADSPA_RDF_PATH"))){
142 if (lrdf_path.length() == 0) {
143 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
146 add_lrdf_data(lrdf_path);
147 add_ladspa_presets();
148 #ifdef WINDOWS_VST_SUPPORT
149 if (Config->get_use_windows_vst ()) {
150 add_windows_vst_presets ();
152 #endif /* WINDOWS_VST_SUPPORT */
155 if (Config->get_use_lxvst()) {
158 #endif /* Native LinuxVST support*/
160 if ((s = getenv ("VST_PATH"))) {
161 windows_vst_path = s;
162 } else if ((s = getenv ("VST_PLUGINS"))) {
163 windows_vst_path = s;
166 if (windows_vst_path.length() == 0) {
167 windows_vst_path = vst_search_path ();
170 if ((s = getenv ("LXVST_PATH"))) {
172 } else if ((s = getenv ("LXVST_PLUGINS"))) {
176 if (lxvst_path.length() == 0) {
177 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
178 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
179 "/usr/lib/vst:/usr/local/lib/vst";
182 /* first time setup, use 'default' path */
183 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
184 Config->set_plugin_path_lxvst(get_default_lxvst_path());
186 if (Config->get_plugin_path_vst() == X_("@default@")) {
187 Config->set_plugin_path_vst(get_default_windows_vst_path());
190 if (_instance == 0) {
194 BootMessage (_("Discovering Plugins"));
198 PluginManager::~PluginManager()
200 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
201 // don't bother, just exit quickly.
202 delete _windows_vst_plugin_info;
203 delete _lxvst_plugin_info;
204 delete _ladspa_plugin_info;
205 delete _lv2_plugin_info;
206 delete _au_plugin_info;
211 PluginManager::refresh (bool cache_only)
213 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
214 _cancel_scan = false;
216 BootMessage (_("Scanning LADSPA Plugins"));
219 BootMessage (_("Scanning LV2 Plugins"));
222 #ifdef WINDOWS_VST_SUPPORT
223 if (Config->get_use_windows_vst()) {
224 BootMessage (_("Scanning Windows VST Plugins"));
225 windows_vst_refresh (cache_only);
227 #endif // WINDOWS_VST_SUPPORT
230 if(Config->get_use_lxvst()) {
231 BootMessage (_("Scanning Linux VST Plugins"));
232 lxvst_refresh(cache_only);
234 #endif //Native linuxVST SUPPORT
236 #ifdef AUDIOUNIT_SUPPORT
237 BootMessage (_("Scanning AU Plugins"));
241 BootMessage (_("Plugin Scan Complete..."));
242 PluginListChanged (); /* EMIT SIGNAL */
243 PluginScanMessage(X_("closeme"), "", false);
244 _cancel_scan = false;
248 PluginManager::cancel_plugin_scan ()
254 PluginManager::cancel_plugin_timeout ()
256 _cancel_timeout = true;
260 PluginManager::clear_vst_cache ()
262 // see also libs/ardour/vst_info_file.cc - vstfx_infofile_path()
263 #ifdef WINDOWS_VST_SUPPORT
265 vector<string> fsi_files;
266 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$");
267 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
268 ::g_unlink(i->c_str());
275 vector<string> fsi_files;
276 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$");
277 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
278 ::g_unlink(i->c_str());
283 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
285 string personal = get_personal_vst_info_cache_dir();
286 vector<string> fsi_files;
287 find_files_matching_regex (fsi_files, personal, "\\.fsi$");
288 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
289 ::g_unlink(i->c_str());
296 PluginManager::clear_vst_blacklist ()
298 #ifdef WINDOWS_VST_SUPPORT
300 vector<string> fsi_files;
301 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsb$");
302 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
303 ::g_unlink(i->c_str());
310 vector<string> fsi_files;
311 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsb$");
312 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
313 ::g_unlink(i->c_str());
318 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
320 string personal = get_personal_vst_blacklist_dir();
322 vector<string> fsi_files;
323 find_files_matching_regex (fsi_files, personal, "\\.fsb$");
324 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
325 ::g_unlink(i->c_str());
332 PluginManager::ladspa_refresh ()
334 if (_ladspa_plugin_info) {
335 _ladspa_plugin_info->clear ();
337 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
340 /* allow LADSPA_PATH to augment, not override standard locations */
342 /* Only add standard locations to ladspa_path if it doesn't
343 * already contain them. Check for trailing G_DIR_SEPARATOR too.
346 vector<string> ladspa_modules;
348 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
350 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
351 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
352 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
354 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
355 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
356 ladspa_discover (*i);
360 static bool rdf_filter (const string &str, void* /*arg*/)
362 return str[0] != '.' &&
363 ((str.find(".rdf") == (str.length() - 4)) ||
364 (str.find(".rdfs") == (str.length() - 5)) ||
365 (str.find(".n3") == (str.length() - 3)) ||
366 (str.find(".ttl") == (str.length() - 4)));
370 PluginManager::add_ladspa_presets()
372 add_presets ("ladspa");
376 PluginManager::add_windows_vst_presets()
378 add_presets ("windows-vst");
382 PluginManager::add_lxvst_presets()
384 add_presets ("lxvst");
388 PluginManager::add_presets(string domain)
391 vector<string> presets;
392 vector<string>::iterator x;
395 if ((envvar = getenv ("HOME")) == 0) {
399 string path = string_compose("%1/.%2/rdf", envvar, domain);
400 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
402 for (x = presets.begin(); x != presets.end (); ++x) {
403 string file = "file:" + *x;
404 if (lrdf_read_file(file.c_str())) {
405 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
413 PluginManager::add_lrdf_data (const string &path)
416 vector<string> rdf_files;
417 vector<string>::iterator x;
419 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
421 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
422 const string uri(string("file://") + *x);
424 if (lrdf_read_file(uri.c_str())) {
425 warning << "Could not parse rdf file: " << uri << endmsg;
432 PluginManager::ladspa_discover (string path)
434 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
436 Glib::Module module(path);
437 const LADSPA_Descriptor *descriptor;
438 LADSPA_Descriptor_Function dfunc;
442 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
443 path, Glib::Module::get_last_error()) << endmsg;
448 if (!module.get_symbol("ladspa_descriptor", func)) {
449 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
450 error << Glib::Module::get_last_error() << endmsg;
454 dfunc = (LADSPA_Descriptor_Function)func;
456 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
458 for (uint32_t i = 0; ; ++i) {
459 if ((descriptor = dfunc (i)) == 0) {
463 if (!ladspa_plugin_whitelist.empty()) {
464 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
469 PluginInfoPtr info(new LadspaPluginInfo);
470 info->name = descriptor->Name;
471 info->category = get_ladspa_category(descriptor->UniqueID);
472 info->creator = descriptor->Maker;
475 info->n_inputs = ChanCount();
476 info->n_outputs = ChanCount();
477 info->type = ARDOUR::LADSPA;
480 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
481 info->unique_id = buf;
483 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
484 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
485 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
486 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
488 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
489 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
494 if(_ladspa_plugin_info->empty()){
495 _ladspa_plugin_info->push_back (info);
498 //Ensure that the plugin is not already in the plugin list.
502 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
503 if(0 == info->unique_id.compare((*i)->unique_id)){
509 _ladspa_plugin_info->push_back (info);
512 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
515 // GDB WILL NOT LIKE YOU IF YOU DO THIS
522 PluginManager::get_ladspa_category (uint32_t plugin_id)
526 lrdf_statement pattern;
528 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
529 pattern.subject = buf;
530 pattern.predicate = const_cast<char*>(RDF_TYPE);
532 pattern.object_type = lrdf_uri;
534 lrdf_statement* matches1 = lrdf_matches (&pattern);
540 pattern.subject = matches1->object;
541 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
543 pattern.object_type = lrdf_literal;
545 lrdf_statement* matches2 = lrdf_matches (&pattern);
546 lrdf_free_statements(matches1);
552 string label = matches2->object;
553 lrdf_free_statements(matches2);
555 /* Kludge LADSPA class names to be singular and match LV2 class names.
556 This avoids duplicate plugin menus for every class, which is necessary
557 to make the plugin category menu at all usable, but is obviously a
560 In the short term, lrdf could be updated so the labels match and a new
561 release made. To support both specs, we should probably be mapping the
562 URIs to the same category in code and perhaps tweaking that hierarchy
563 dynamically to suit the user. Personally, I (drobilla) think that time
564 is better spent replacing the little-used LRDF.
566 In the longer term, we will abandon LRDF entirely in favour of LV2 and
567 use that class hierarchy. Aside from fixing this problem properly, that
568 will also allow for translated labels. SWH plugins have been LV2 for
569 ages; TAP needs porting. I don't know of anything else with LRDF data.
571 if (label == "Utilities") {
573 } else if (label == "Pitch shifters") {
574 return "Pitch Shifter";
575 } else if (label != "Dynamics" && label != "Chorus"
576 &&label[label.length() - 1] == 's'
577 && label[label.length() - 2] != 's') {
578 return label.substr(0, label.length() - 1);
589 PluginManager::lv2_refresh ()
591 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
592 delete _lv2_plugin_info;
593 _lv2_plugin_info = LV2PluginInfo::discover();
597 #ifdef AUDIOUNIT_SUPPORT
599 PluginManager::au_refresh ()
601 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
602 delete _au_plugin_info;
603 _au_plugin_info = AUPluginInfo::discover();
608 #ifdef WINDOWS_VST_SUPPORT
611 PluginManager::windows_vst_refresh (bool cache_only)
613 if (_windows_vst_plugin_info) {
614 _windows_vst_plugin_info->clear ();
616 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
619 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
622 static bool windows_vst_filter (const string& str, void * /*arg*/)
624 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
626 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
630 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 find_files_matching_filter (plugin_objects, 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)
747 vector<string> plugin_objects;
748 vector<string>::iterator x;
755 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
757 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
759 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
760 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
761 lxvst_discover (*x, cache_only || cancelled());
768 PluginManager::lxvst_discover (string path, bool cache_only)
770 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
772 _cancel_timeout = false;
773 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
774 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
776 if (finfos->empty()) {
777 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
781 uint32_t discovered = 0;
782 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
786 if (!finfo->canProcessReplacing) {
787 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
788 finfo->name, PROGRAM_NAME)
793 PluginInfoPtr info(new LXVSTPluginInfo);
795 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
796 info->name = PBD::basename_nosuffix (path);
798 info->name = finfo->name;
802 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
803 info->unique_id = buf;
804 info->category = "linuxVSTs";
806 info->creator = finfo->creator;
808 info->n_inputs.set_audio (finfo->numInputs);
809 info->n_outputs.set_audio (finfo->numOutputs);
810 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
811 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
812 info->type = ARDOUR::LXVST;
814 /* Make sure we don't find the same plugin in more than one place along
815 the LXVST_PATH We can't use a simple 'find' because the path is included
816 in the PluginInfo, and that is the one thing we can be sure MUST be
817 different if a duplicate instance is found. So we just compare the type
818 and unique ID (which for some VSTs isn't actually unique...)
821 // TODO: check dup-IDs with windowsVST, too
822 bool duplicate = false;
823 if (!_lxvst_plugin_info->empty()) {
824 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
825 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
826 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
834 _lxvst_plugin_info->push_back (info);
839 vstfx_free_info_list (finfos);
840 return discovered > 0 ? 0 : -1;
843 #endif // LXVST_SUPPORT
846 PluginManager::PluginStatusType
847 PluginManager::get_status (const PluginInfoPtr& pi)
849 PluginStatus ps (pi->type, pi->unique_id);
850 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
851 if (i == statuses.end() ) {
859 PluginManager::save_statuses ()
862 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
864 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
870 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
882 ofs << "Windows-VST";
891 switch ((*i).status) {
904 ofs << (*i).unique_id;;
912 PluginManager::load_statuses ()
914 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
915 ifstream ifs (path.c_str());
925 PluginStatusType status;
942 /* rest of the line is the plugin ID */
944 ifs.getline (buf, sizeof (buf), '\n');
949 if (sstatus == "Normal") {
951 } else if (sstatus == "Favorite") {
953 } else if (sstatus == "Hidden") {
956 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
962 if (stype == "LADSPA") {
964 } else if (stype == "AudioUnit") {
966 } else if (stype == "LV2") {
968 } else if (stype == "Windows-VST") {
970 } else if (stype == "LXVST") {
973 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
979 strip_whitespace_edges (id);
980 set_status (type, id, status);
987 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
989 PluginStatus ps (t, id, status);
992 if (status == Normal) {
996 statuses.insert (ps);
999 ARDOUR::PluginInfoList&
1000 PluginManager::windows_vst_plugin_info ()
1002 #ifdef WINDOWS_VST_SUPPORT
1003 if (!_windows_vst_plugin_info) {
1004 windows_vst_refresh ();
1006 return *_windows_vst_plugin_info;
1008 return _empty_plugin_info;
1012 ARDOUR::PluginInfoList&
1013 PluginManager::lxvst_plugin_info ()
1015 #ifdef LXVST_SUPPORT
1016 assert(_lxvst_plugin_info);
1017 return *_lxvst_plugin_info;
1019 return _empty_plugin_info;
1023 ARDOUR::PluginInfoList&
1024 PluginManager::ladspa_plugin_info ()
1026 assert(_ladspa_plugin_info);
1027 return *_ladspa_plugin_info;
1030 ARDOUR::PluginInfoList&
1031 PluginManager::lv2_plugin_info ()
1034 assert(_lv2_plugin_info);
1035 return *_lv2_plugin_info;
1037 return _empty_plugin_info;
1041 ARDOUR::PluginInfoList&
1042 PluginManager::au_plugin_info ()
1044 #ifdef AUDIOUNIT_SUPPORT
1045 assert(_au_plugin_info);
1046 return *_au_plugin_info;
1048 return _empty_plugin_info;