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), "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$");
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$");
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$");
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$");
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$");
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$");
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 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
330 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
331 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
333 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
334 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
335 ladspa_discover (*i);
339 static bool rdf_filter (const string &str, void* /*arg*/)
341 return str[0] != '.' &&
342 ((str.find(".rdf") == (str.length() - 4)) ||
343 (str.find(".rdfs") == (str.length() - 5)) ||
344 (str.find(".n3") == (str.length() - 3)) ||
345 (str.find(".ttl") == (str.length() - 4)));
349 PluginManager::add_ladspa_presets()
351 add_presets ("ladspa");
355 PluginManager::add_windows_vst_presets()
357 add_presets ("windows-vst");
361 PluginManager::add_lxvst_presets()
363 add_presets ("lxvst");
367 PluginManager::add_presets(string domain)
370 vector<string> presets;
371 vector<string>::iterator x;
374 if ((envvar = getenv ("HOME")) == 0) {
378 string path = string_compose("%1/.%2/rdf", envvar, domain);
379 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
381 for (x = presets.begin(); x != presets.end (); ++x) {
382 string file = "file:" + *x;
383 if (lrdf_read_file(file.c_str())) {
384 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
392 PluginManager::add_lrdf_data (const string &path)
395 vector<string> rdf_files;
396 vector<string>::iterator x;
398 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
400 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
401 const string uri(string("file://") + *x);
403 if (lrdf_read_file(uri.c_str())) {
404 warning << "Could not parse rdf file: " << uri << endmsg;
411 PluginManager::ladspa_discover (string path)
413 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
415 Glib::Module module(path);
416 const LADSPA_Descriptor *descriptor;
417 LADSPA_Descriptor_Function dfunc;
421 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
422 path, Glib::Module::get_last_error()) << endmsg;
427 if (!module.get_symbol("ladspa_descriptor", func)) {
428 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
429 error << Glib::Module::get_last_error() << endmsg;
433 dfunc = (LADSPA_Descriptor_Function)func;
435 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
437 for (uint32_t i = 0; ; ++i) {
438 if ((descriptor = dfunc (i)) == 0) {
442 if (!ladspa_plugin_whitelist.empty()) {
443 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
448 PluginInfoPtr info(new LadspaPluginInfo);
449 info->name = descriptor->Name;
450 info->category = get_ladspa_category(descriptor->UniqueID);
451 info->creator = descriptor->Maker;
454 info->n_inputs = ChanCount();
455 info->n_outputs = ChanCount();
456 info->type = ARDOUR::LADSPA;
459 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
460 info->unique_id = buf;
462 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
463 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
464 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
465 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
467 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
468 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
473 if(_ladspa_plugin_info->empty()){
474 _ladspa_plugin_info->push_back (info);
477 //Ensure that the plugin is not already in the plugin list.
481 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
482 if(0 == info->unique_id.compare((*i)->unique_id)){
488 _ladspa_plugin_info->push_back (info);
491 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
494 // GDB WILL NOT LIKE YOU IF YOU DO THIS
501 PluginManager::get_ladspa_category (uint32_t plugin_id)
505 lrdf_statement pattern;
507 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
508 pattern.subject = buf;
509 pattern.predicate = const_cast<char*>(RDF_TYPE);
511 pattern.object_type = lrdf_uri;
513 lrdf_statement* matches1 = lrdf_matches (&pattern);
519 pattern.subject = matches1->object;
520 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
522 pattern.object_type = lrdf_literal;
524 lrdf_statement* matches2 = lrdf_matches (&pattern);
525 lrdf_free_statements(matches1);
531 string label = matches2->object;
532 lrdf_free_statements(matches2);
534 /* Kludge LADSPA class names to be singular and match LV2 class names.
535 This avoids duplicate plugin menus for every class, which is necessary
536 to make the plugin category menu at all usable, but is obviously a
539 In the short term, lrdf could be updated so the labels match and a new
540 release made. To support both specs, we should probably be mapping the
541 URIs to the same category in code and perhaps tweaking that hierarchy
542 dynamically to suit the user. Personally, I (drobilla) think that time
543 is better spent replacing the little-used LRDF.
545 In the longer term, we will abandon LRDF entirely in favour of LV2 and
546 use that class hierarchy. Aside from fixing this problem properly, that
547 will also allow for translated labels. SWH plugins have been LV2 for
548 ages; TAP needs porting. I don't know of anything else with LRDF data.
550 if (label == "Utilities") {
552 } else if (label == "Pitch shifters") {
553 return "Pitch Shifter";
554 } else if (label != "Dynamics" && label != "Chorus"
555 &&label[label.length() - 1] == 's'
556 && label[label.length() - 2] != 's') {
557 return label.substr(0, label.length() - 1);
568 PluginManager::lv2_refresh ()
570 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
571 delete _lv2_plugin_info;
572 _lv2_plugin_info = LV2PluginInfo::discover();
576 #ifdef AUDIOUNIT_SUPPORT
578 PluginManager::au_refresh ()
580 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
581 delete _au_plugin_info;
582 _au_plugin_info = AUPluginInfo::discover();
587 #ifdef WINDOWS_VST_SUPPORT
590 PluginManager::windows_vst_refresh (bool cache_only)
592 if (_windows_vst_plugin_info) {
593 _windows_vst_plugin_info->clear ();
595 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
598 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
601 static bool windows_vst_filter (const string& str, void * /*arg*/)
603 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
605 return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
609 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
611 vector<string> plugin_objects;
612 vector<string>::iterator x;
615 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
617 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
619 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
620 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
621 windows_vst_discover (*x, cache_only || cancelled());
628 PluginManager::windows_vst_discover (string path, bool cache_only)
630 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
632 _cancel_timeout = false;
633 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
634 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
636 if (finfos->empty()) {
637 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
641 uint32_t discovered = 0;
642 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
646 if (!finfo->canProcessReplacing) {
647 warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
648 finfo->name, PROGRAM_NAME)
653 PluginInfoPtr info (new WindowsVSTPluginInfo);
655 /* what a joke freeware VST is */
657 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
658 info->name = PBD::basename_nosuffix (path);
660 info->name = finfo->name;
664 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
665 info->unique_id = buf;
666 info->category = "VST";
668 info->creator = finfo->creator;
670 info->n_inputs.set_audio (finfo->numInputs);
671 info->n_outputs.set_audio (finfo->numOutputs);
672 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
673 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
674 info->type = ARDOUR::Windows_VST;
676 // TODO: check dup-IDs (lxvst AND windows vst)
677 bool duplicate = false;
679 if (!_windows_vst_plugin_info->empty()) {
680 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
681 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
682 warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
690 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
691 _windows_vst_plugin_info->push_back (info);
696 vstfx_free_info_list (finfos);
697 return discovered > 0 ? 0 : -1;
700 #endif // WINDOWS_VST_SUPPORT
705 PluginManager::lxvst_refresh (bool cache_only)
707 if (_lxvst_plugin_info) {
708 _lxvst_plugin_info->clear ();
710 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
713 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
716 static bool lxvst_filter (const string& str, void *)
718 /* Not a dotfile, has a prefix before a period, suffix is "so" */
720 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
724 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
726 vector<string> plugin_objects;
727 vector<string>::iterator x;
734 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
736 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
738 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
739 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
740 lxvst_discover (*x, cache_only || cancelled());
747 PluginManager::lxvst_discover (string path, bool cache_only)
749 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
751 _cancel_timeout = false;
752 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
753 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
755 if (finfos->empty()) {
756 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
760 uint32_t discovered = 0;
761 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
765 if (!finfo->canProcessReplacing) {
766 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
767 finfo->name, PROGRAM_NAME)
772 PluginInfoPtr info(new LXVSTPluginInfo);
774 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
775 info->name = PBD::basename_nosuffix (path);
777 info->name = finfo->name;
781 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
782 info->unique_id = buf;
783 info->category = "linuxVSTs";
785 info->creator = finfo->creator;
787 info->n_inputs.set_audio (finfo->numInputs);
788 info->n_outputs.set_audio (finfo->numOutputs);
789 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
790 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
791 info->type = ARDOUR::LXVST;
793 /* Make sure we don't find the same plugin in more than one place along
794 the LXVST_PATH We can't use a simple 'find' because the path is included
795 in the PluginInfo, and that is the one thing we can be sure MUST be
796 different if a duplicate instance is found. So we just compare the type
797 and unique ID (which for some VSTs isn't actually unique...)
800 // TODO: check dup-IDs with windowsVST, too
801 bool duplicate = false;
802 if (!_lxvst_plugin_info->empty()) {
803 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
804 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
805 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
813 _lxvst_plugin_info->push_back (info);
818 vstfx_free_info_list (finfos);
819 return discovered > 0 ? 0 : -1;
822 #endif // LXVST_SUPPORT
825 PluginManager::PluginStatusType
826 PluginManager::get_status (const PluginInfoPtr& pi)
828 PluginStatus ps (pi->type, pi->unique_id);
829 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
830 if (i == statuses.end() ) {
838 PluginManager::save_statuses ()
841 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
843 ofs.open (path.c_str(), ios_base::openmode (ios::out|ios::trunc));
849 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
861 ofs << "Windows-VST";
870 switch ((*i).status) {
883 ofs << (*i).unique_id;;
891 PluginManager::load_statuses ()
893 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
894 ifstream ifs (path.c_str());
904 PluginStatusType status;
921 /* rest of the line is the plugin ID */
923 ifs.getline (buf, sizeof (buf), '\n');
928 if (sstatus == "Normal") {
930 } else if (sstatus == "Favorite") {
932 } else if (sstatus == "Hidden") {
935 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
941 if (stype == "LADSPA") {
943 } else if (stype == "AudioUnit") {
945 } else if (stype == "LV2") {
947 } else if (stype == "Windows-VST") {
949 } else if (stype == "LXVST") {
952 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
958 strip_whitespace_edges (id);
959 set_status (type, id, status);
966 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
968 PluginStatus ps (t, id, status);
971 if (status == Normal) {
975 statuses.insert (ps);
978 ARDOUR::PluginInfoList&
979 PluginManager::windows_vst_plugin_info ()
981 #ifdef WINDOWS_VST_SUPPORT
982 if (!_windows_vst_plugin_info) {
983 windows_vst_refresh ();
985 return *_windows_vst_plugin_info;
987 return _empty_plugin_info;
991 ARDOUR::PluginInfoList&
992 PluginManager::lxvst_plugin_info ()
995 assert(_lxvst_plugin_info);
996 return *_lxvst_plugin_info;
998 return _empty_plugin_info;
1002 ARDOUR::PluginInfoList&
1003 PluginManager::ladspa_plugin_info ()
1005 assert(_ladspa_plugin_info);
1006 return *_ladspa_plugin_info;
1009 ARDOUR::PluginInfoList&
1010 PluginManager::lv2_plugin_info ()
1013 assert(_lv2_plugin_info);
1014 return *_lv2_plugin_info;
1016 return _empty_plugin_info;
1020 ARDOUR::PluginInfoList&
1021 PluginManager::au_plugin_info ()
1023 #ifdef AUDIOUNIT_SUPPORT
1024 assert(_au_plugin_info);
1025 return *_au_plugin_info;
1027 return _empty_plugin_info;