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 if (!PBD::find_file_in_search_path (
120 PBD::Searchpath(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst")),
121 "ardour-vst-scanner", scanner_bin_path)) {
122 PBD::warning << "VST scanner app not found.'" << endmsg;
127 if ((s = getenv ("LADSPA_RDF_PATH"))){
131 if (lrdf_path.length() == 0) {
132 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
135 add_lrdf_data(lrdf_path);
136 add_ladspa_presets();
137 #ifdef WINDOWS_VST_SUPPORT
138 if (Config->get_use_windows_vst ()) {
139 add_windows_vst_presets ();
141 #endif /* WINDOWS_VST_SUPPORT */
144 if (Config->get_use_lxvst()) {
147 #endif /* Native LinuxVST support*/
149 if ((s = getenv ("VST_PATH"))) {
150 windows_vst_path = s;
151 } else if ((s = getenv ("VST_PLUGINS"))) {
152 windows_vst_path = s;
155 if (windows_vst_path.length() == 0) {
156 windows_vst_path = vst_search_path ();
159 if ((s = getenv ("LXVST_PATH"))) {
161 } else if ((s = getenv ("LXVST_PLUGINS"))) {
165 if (lxvst_path.length() == 0) {
166 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
167 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
168 "/usr/lib/vst:/usr/local/lib/vst";
171 /* first time setup, use 'default' path */
172 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
173 Config->set_plugin_path_lxvst(get_default_lxvst_path());
175 if (Config->get_plugin_path_vst() == X_("@default@")) {
176 Config->set_plugin_path_vst(get_default_windows_vst_path());
179 if (_instance == 0) {
183 BootMessage (_("Discovering Plugins"));
187 PluginManager::~PluginManager()
192 PluginManager::refresh (bool cache_only)
194 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
195 _cancel_scan = false;
197 BootMessage (_("Scanning LADSPA Plugins"));
200 BootMessage (_("Scanning LV2 Plugins"));
203 #ifdef WINDOWS_VST_SUPPORT
204 if (Config->get_use_windows_vst()) {
205 BootMessage (_("Scanning Windows VST Plugins"));
206 windows_vst_refresh (cache_only);
208 #endif // WINDOWS_VST_SUPPORT
211 if(Config->get_use_lxvst()) {
212 BootMessage (_("Scanning Linux VST Plugins"));
213 lxvst_refresh(cache_only);
215 #endif //Native linuxVST SUPPORT
217 #ifdef AUDIOUNIT_SUPPORT
218 BootMessage (_("Scanning AU Plugins"));
222 BootMessage (_("Plugin Scan Complete..."));
223 PluginListChanged (); /* EMIT SIGNAL */
224 PluginScanMessage(X_("closeme"), "", false);
225 _cancel_scan = false;
229 PluginManager::cancel_plugin_scan ()
235 PluginManager::cancel_plugin_timeout ()
237 _cancel_timeout = true;
241 PluginManager::clear_vst_cache ()
243 // see also libs/ardour/vst_info_file.cc - vstfx_infofile_path()
244 #ifdef WINDOWS_VST_SUPPORT
247 vector<string *> *fsi_files;
249 fsi_files = scanner (Config->get_plugin_path_vst(), "\\.fsi$", true, true, -1, false);
251 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
252 ::g_unlink((*i)->c_str());
255 vector_delete(fsi_files);
262 vector<string *> *fsi_files;
263 fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsi$", true, true, -1, false);
265 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
266 ::g_unlink((*i)->c_str());
269 vector_delete(fsi_files);
273 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
275 string personal = get_personal_vst_info_cache_dir();
277 vector<string *> *fsi_files;
278 fsi_files = scanner (personal, "\\.fsi$", 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);
290 PluginManager::clear_vst_blacklist ()
292 #ifdef WINDOWS_VST_SUPPORT
295 vector<string *> *fsi_files;
297 fsi_files = scanner (Config->get_plugin_path_vst(), "\\.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());
303 vector_delete(fsi_files);
310 vector<string *> *fsi_files;
311 fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsb$", true, true, -1, false);
313 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
314 ::g_unlink((*i)->c_str());
317 vector_delete(fsi_files);
321 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
323 string personal = get_personal_vst_blacklist_dir();
326 vector<string *> *fsi_files;
327 fsi_files = scanner (personal, "\\.fsb$", true, true, -1, false);
329 for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
330 ::g_unlink((*i)->c_str());
333 vector_delete(fsi_files);
339 PluginManager::ladspa_refresh ()
341 if (_ladspa_plugin_info) {
342 _ladspa_plugin_info->clear ();
344 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
347 /* allow LADSPA_PATH to augment, not override standard locations */
349 /* Only add standard locations to ladspa_path if it doesn't
350 * already contain them. Check for trailing G_DIR_SEPARATOR too.
353 vector<string> ladspa_modules;
355 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
357 Glib::PatternSpec so_extension_pattern("*.so");
358 Glib::PatternSpec dylib_extension_pattern("*.dylib");
359 Glib::PatternSpec dll_extension_pattern("*.dll");
361 find_matching_files_in_search_path (ladspa_search_path (),
362 so_extension_pattern, ladspa_modules);
364 find_matching_files_in_search_path (ladspa_search_path (),
365 dylib_extension_pattern, ladspa_modules);
367 find_matching_files_in_search_path (ladspa_search_path (),
368 dll_extension_pattern, ladspa_modules);
370 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
371 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
372 ladspa_discover (*i);
376 static bool rdf_filter (const string &str, void* /*arg*/)
378 return str[0] != '.' &&
379 ((str.find(".rdf") == (str.length() - 4)) ||
380 (str.find(".rdfs") == (str.length() - 5)) ||
381 (str.find(".n3") == (str.length() - 3)) ||
382 (str.find(".ttl") == (str.length() - 4)));
386 PluginManager::add_ladspa_presets()
388 add_presets ("ladspa");
392 PluginManager::add_windows_vst_presets()
394 add_presets ("windows-vst");
398 PluginManager::add_lxvst_presets()
400 add_presets ("lxvst");
404 PluginManager::add_presets(string domain)
408 vector<string *> *presets;
409 vector<string *>::iterator x;
412 if ((envvar = getenv ("HOME")) == 0) {
416 string path = string_compose("%1/.%2/rdf", envvar, domain);
417 presets = scanner (path, rdf_filter, 0, false, true);
420 for (x = presets->begin(); x != presets->end (); ++x) {
421 string file = "file:" + **x;
422 if (lrdf_read_file(file.c_str())) {
423 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
427 vector_delete (presets);
433 PluginManager::add_lrdf_data (const string &path)
437 vector<string *>* rdf_files;
438 vector<string *>::iterator x;
440 rdf_files = scanner (path, rdf_filter, 0, false, true);
443 for (x = rdf_files->begin(); x != rdf_files->end (); ++x) {
444 const string uri(string("file://") + **x);
446 if (lrdf_read_file(uri.c_str())) {
447 warning << "Could not parse rdf file: " << uri << endmsg;
451 vector_delete (rdf_files);
457 PluginManager::ladspa_discover (string path)
459 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
461 Glib::Module module(path);
462 const LADSPA_Descriptor *descriptor;
463 LADSPA_Descriptor_Function dfunc;
467 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
468 path, Glib::Module::get_last_error()) << endmsg;
473 if (!module.get_symbol("ladspa_descriptor", func)) {
474 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
475 error << Glib::Module::get_last_error() << endmsg;
479 dfunc = (LADSPA_Descriptor_Function)func;
481 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
483 for (uint32_t i = 0; ; ++i) {
484 if ((descriptor = dfunc (i)) == 0) {
488 if (!ladspa_plugin_whitelist.empty()) {
489 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
494 PluginInfoPtr info(new LadspaPluginInfo);
495 info->name = descriptor->Name;
496 info->category = get_ladspa_category(descriptor->UniqueID);
497 info->creator = descriptor->Maker;
500 info->n_inputs = ChanCount();
501 info->n_outputs = ChanCount();
502 info->type = ARDOUR::LADSPA;
505 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
506 info->unique_id = buf;
508 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
509 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
510 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
511 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
513 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
514 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
519 if(_ladspa_plugin_info->empty()){
520 _ladspa_plugin_info->push_back (info);
523 //Ensure that the plugin is not already in the plugin list.
527 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
528 if(0 == info->unique_id.compare((*i)->unique_id)){
534 _ladspa_plugin_info->push_back (info);
537 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
540 // GDB WILL NOT LIKE YOU IF YOU DO THIS
547 PluginManager::get_ladspa_category (uint32_t plugin_id)
551 lrdf_statement pattern;
553 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
554 pattern.subject = buf;
555 pattern.predicate = const_cast<char*>(RDF_TYPE);
557 pattern.object_type = lrdf_uri;
559 lrdf_statement* matches1 = lrdf_matches (&pattern);
565 pattern.subject = matches1->object;
566 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
568 pattern.object_type = lrdf_literal;
570 lrdf_statement* matches2 = lrdf_matches (&pattern);
571 lrdf_free_statements(matches1);
577 string label = matches2->object;
578 lrdf_free_statements(matches2);
580 /* Kludge LADSPA class names to be singular and match LV2 class names.
581 This avoids duplicate plugin menus for every class, which is necessary
582 to make the plugin category menu at all usable, but is obviously a
585 In the short term, lrdf could be updated so the labels match and a new
586 release made. To support both specs, we should probably be mapping the
587 URIs to the same category in code and perhaps tweaking that hierarchy
588 dynamically to suit the user. Personally, I (drobilla) think that time
589 is better spent replacing the little-used LRDF.
591 In the longer term, we will abandon LRDF entirely in favour of LV2 and
592 use that class hierarchy. Aside from fixing this problem properly, that
593 will also allow for translated labels. SWH plugins have been LV2 for
594 ages; TAP needs porting. I don't know of anything else with LRDF data.
596 if (label == "Utilities") {
598 } else if (label == "Pitch shifters") {
599 return "Pitch Shifter";
600 } else if (label != "Dynamics" && label != "Chorus"
601 &&label[label.length() - 1] == 's'
602 && label[label.length() - 2] != 's') {
603 return label.substr(0, label.length() - 1);
614 PluginManager::lv2_refresh ()
616 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
617 delete _lv2_plugin_info;
618 _lv2_plugin_info = LV2PluginInfo::discover();
622 #ifdef AUDIOUNIT_SUPPORT
624 PluginManager::au_refresh ()
626 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
627 delete _au_plugin_info;
628 _au_plugin_info = AUPluginInfo::discover();
633 #ifdef WINDOWS_VST_SUPPORT
636 PluginManager::windows_vst_refresh (bool cache_only)
638 if (_windows_vst_plugin_info) {
639 _windows_vst_plugin_info->clear ();
641 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
644 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
647 static bool windows_vst_filter (const string& str, void * /*arg*/)
649 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
651 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
655 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
658 vector<string *> *plugin_objects;
659 vector<string *>::iterator x;
662 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
664 plugin_objects = scanner (Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
666 if (plugin_objects) {
667 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
668 ARDOUR::PluginScanMessage(_("VST"), **x, !cache_only && !cancelled());
669 windows_vst_discover (**x, cache_only || cancelled());
672 vector_delete (plugin_objects);
679 PluginManager::windows_vst_discover (string path, bool cache_only)
681 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
683 _cancel_timeout = false;
684 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
685 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
687 if (finfos->empty()) {
688 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
692 uint32_t discovered = 0;
693 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
697 if (!finfo->canProcessReplacing) {
698 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
699 finfo->name, PROGRAM_NAME)
704 PluginInfoPtr info (new WindowsVSTPluginInfo);
706 /* what a joke freeware VST is */
708 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
709 info->name = PBD::basename_nosuffix (path);
711 info->name = finfo->name;
715 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
716 info->unique_id = buf;
717 info->category = "VST";
719 info->creator = finfo->creator;
721 info->n_inputs.set_audio (finfo->numInputs);
722 info->n_outputs.set_audio (finfo->numOutputs);
723 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
724 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
725 info->type = ARDOUR::Windows_VST;
727 // TODO: check dup-IDs (lxvst AND windows vst)
728 bool duplicate = false;
730 if (!_windows_vst_plugin_info->empty()) {
731 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
732 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
733 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
741 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
742 _windows_vst_plugin_info->push_back (info);
747 vstfx_free_info_list (finfos);
748 return discovered > 0 ? 0 : -1;
751 #endif // WINDOWS_VST_SUPPORT
756 PluginManager::lxvst_refresh (bool cache_only)
758 if (_lxvst_plugin_info) {
759 _lxvst_plugin_info->clear ();
761 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
764 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
767 static bool lxvst_filter (const string& str, void *)
769 /* Not a dotfile, has a prefix before a period, suffix is "so" */
771 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
775 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
778 vector<string *> *plugin_objects;
779 vector<string *>::iterator x;
786 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
788 plugin_objects = scanner (Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
790 if (plugin_objects) {
791 for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
792 ARDOUR::PluginScanMessage(_("LXVST"), **x, !cache_only && !cancelled());
793 lxvst_discover (**x, cache_only || cancelled());
796 vector_delete (plugin_objects);
803 PluginManager::lxvst_discover (string path, bool cache_only)
805 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
807 _cancel_timeout = false;
808 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
809 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
811 if (finfos->empty()) {
812 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
816 uint32_t discovered = 0;
817 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
821 if (!finfo->canProcessReplacing) {
822 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
823 finfo->name, PROGRAM_NAME)
828 PluginInfoPtr info(new LXVSTPluginInfo);
830 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
831 info->name = PBD::basename_nosuffix (path);
833 info->name = finfo->name;
837 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
838 info->unique_id = buf;
839 info->category = "linuxVSTs";
841 info->creator = finfo->creator;
843 info->n_inputs.set_audio (finfo->numInputs);
844 info->n_outputs.set_audio (finfo->numOutputs);
845 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
846 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
847 info->type = ARDOUR::LXVST;
849 /* Make sure we don't find the same plugin in more than one place along
850 the LXVST_PATH We can't use a simple 'find' because the path is included
851 in the PluginInfo, and that is the one thing we can be sure MUST be
852 different if a duplicate instance is found. So we just compare the type
853 and unique ID (which for some VSTs isn't actually unique...)
856 // TODO: check dup-IDs with windowsVST, too
857 bool duplicate = false;
858 if (!_lxvst_plugin_info->empty()) {
859 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
860 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
861 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
869 _lxvst_plugin_info->push_back (info);
874 vstfx_free_info_list (finfos);
875 return discovered > 0 ? 0 : -1;
878 #endif // LXVST_SUPPORT
881 PluginManager::PluginStatusType
882 PluginManager::get_status (const PluginInfoPtr& pi)
884 PluginStatus ps (pi->type, pi->unique_id);
885 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
886 if (i == statuses.end() ) {
894 PluginManager::save_statuses ()
897 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
899 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
905 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
917 ofs << "Windows-VST";
926 switch ((*i).status) {
939 ofs << (*i).unique_id;;
947 PluginManager::load_statuses ()
949 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
950 ifstream ifs (path.c_str());
960 PluginStatusType status;
977 /* rest of the line is the plugin ID */
979 ifs.getline (buf, sizeof (buf), '\n');
984 if (sstatus == "Normal") {
986 } else if (sstatus == "Favorite") {
988 } else if (sstatus == "Hidden") {
991 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
997 if (stype == "LADSPA") {
999 } else if (stype == "AudioUnit") {
1001 } else if (stype == "LV2") {
1003 } else if (stype == "Windows-VST") {
1005 } else if (stype == "LXVST") {
1008 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1014 strip_whitespace_edges (id);
1015 set_status (type, id, status);
1022 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1024 PluginStatus ps (t, id, status);
1025 statuses.erase (ps);
1027 if (status == Normal) {
1031 statuses.insert (ps);
1034 ARDOUR::PluginInfoList&
1035 PluginManager::windows_vst_plugin_info ()
1037 #ifdef WINDOWS_VST_SUPPORT
1038 if (!_windows_vst_plugin_info) {
1039 windows_vst_refresh ();
1041 return *_windows_vst_plugin_info;
1043 return _empty_plugin_info;
1047 ARDOUR::PluginInfoList&
1048 PluginManager::lxvst_plugin_info ()
1050 #ifdef LXVST_SUPPORT
1051 assert(_lxvst_plugin_info);
1052 return *_lxvst_plugin_info;
1054 return _empty_plugin_info;
1058 ARDOUR::PluginInfoList&
1059 PluginManager::ladspa_plugin_info ()
1061 assert(_ladspa_plugin_info);
1062 return *_ladspa_plugin_info;
1065 ARDOUR::PluginInfoList&
1066 PluginManager::lv2_plugin_info ()
1069 assert(_lv2_plugin_info);
1070 return *_lv2_plugin_info;
1072 return _empty_plugin_info;
1076 ARDOUR::PluginInfoList&
1077 PluginManager::au_plugin_info ()
1079 #ifdef AUDIOUNIT_SUPPORT
1080 assert(_au_plugin_info);
1081 return *_au_plugin_info;
1083 return _empty_plugin_info;