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>
31 #include <pbd/gstdio_compat.h>
37 #ifdef WINDOWS_VST_SUPPORT
38 #include "ardour/vst_info_file.h"
40 #include "pbd/basename.h"
42 #endif // WINDOWS_VST_SUPPORT
45 #include "ardour/vst_info_file.h"
46 #include "ardour/linux_vst_support.h"
47 #include "pbd/basename.h"
49 #endif //LXVST_SUPPORT
51 #include <pbd/gstdio_compat.h>
52 #include <glibmm/miscutils.h>
53 #include <glibmm/pattern.h>
54 #include <glibmm/fileutils.h>
55 #include <glibmm/miscutils.h>
57 #include "pbd/whitespace.h"
58 #include "pbd/file_utils.h"
60 #include "ardour/debug.h"
61 #include "ardour/filesystem_paths.h"
62 #include "ardour/ladspa.h"
63 #include "ardour/ladspa_plugin.h"
64 #include "ardour/plugin.h"
65 #include "ardour/plugin_manager.h"
66 #include "ardour/rc_configuration.h"
68 #include "ardour/search_paths.h"
71 #include "ardour/lv2_plugin.h"
74 #ifdef WINDOWS_VST_SUPPORT
75 #include "ardour/windows_vst_plugin.h"
79 #include "ardour/lxvst_plugin.h"
82 #ifdef AUDIOUNIT_SUPPORT
83 #include "ardour/audio_unit.h"
84 #include <Carbon/Carbon.h>
87 #include "pbd/error.h"
88 #include "pbd/stl_delete.h"
92 #include "ardour/debug.h"
94 using namespace ARDOUR;
98 PluginManager* PluginManager::_instance = 0;
99 std::string PluginManager::scanner_bin_path = "";
102 PluginManager::instance()
105 _instance = new PluginManager;
110 PluginManager::PluginManager ()
111 : _windows_vst_plugin_info(0)
112 , _lxvst_plugin_info(0)
113 , _ladspa_plugin_info(0)
114 , _lv2_plugin_info(0)
116 , _cancel_scan(false)
117 , _cancel_timeout(false)
122 #if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT
123 // source-tree (ardev, etc)
124 PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst"));
126 #ifdef PLATFORM_WINDOWS
127 // on windows the .exe needs to be in the same folder with libardour.dll
128 vstsp += Glib::build_filename(windows_package_directory_path(), "bin");
130 // on Unices additional internal-use binaries are deployed to $libdir
131 vstsp += ARDOUR::ardour_dll_directory();
134 if (!PBD::find_file (vstsp,
135 #ifdef PLATFORM_WINDOWS
136 #ifdef DEBUGGABLE_SCANNER_APP
137 #if defined(DEBUG) || defined(_DEBUG)
138 "ardour-vst-scannerD.exe"
140 "ardour-vst-scannerRDC.exe"
143 "ardour-vst-scanner.exe"
148 , scanner_bin_path)) {
149 PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << vstsp.to_string() << endmsg;
155 if ((s = getenv ("LADSPA_RDF_PATH"))){
159 if (lrdf_path.length() == 0) {
160 lrdf_path = "/usr/local/share/ladspa/rdf:/usr/share/ladspa/rdf";
163 add_lrdf_data(lrdf_path);
164 add_ladspa_presets();
165 #ifdef WINDOWS_VST_SUPPORT
166 if (Config->get_use_windows_vst ()) {
167 add_windows_vst_presets ();
169 #endif /* WINDOWS_VST_SUPPORT */
172 if (Config->get_use_lxvst()) {
175 #endif /* Native LinuxVST support*/
177 if ((s = getenv ("VST_PATH"))) {
178 windows_vst_path = s;
179 } else if ((s = getenv ("VST_PLUGINS"))) {
180 windows_vst_path = s;
183 if (windows_vst_path.length() == 0) {
184 windows_vst_path = vst_search_path ();
187 if ((s = getenv ("LXVST_PATH"))) {
189 } else if ((s = getenv ("LXVST_PLUGINS"))) {
193 if (lxvst_path.length() == 0) {
194 lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
195 "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
196 "/usr/lib/vst:/usr/local/lib/vst";
199 /* first time setup, use 'default' path */
200 if (Config->get_plugin_path_lxvst() == X_("@default@")) {
201 Config->set_plugin_path_lxvst(get_default_lxvst_path());
203 if (Config->get_plugin_path_vst() == X_("@default@")) {
204 Config->set_plugin_path_vst(get_default_windows_vst_path());
207 if (_instance == 0) {
211 BootMessage (_("Discovering Plugins"));
215 PluginManager::~PluginManager()
217 if (getenv ("ARDOUR_RUNNING_UNDER_VALGRIND")) {
218 // don't bother, just exit quickly.
219 delete _windows_vst_plugin_info;
220 delete _lxvst_plugin_info;
221 delete _ladspa_plugin_info;
222 delete _lv2_plugin_info;
223 delete _au_plugin_info;
228 PluginManager::refresh (bool cache_only)
230 Glib::Threads::Mutex::Lock lm (_lock, Glib::Threads::TRY_LOCK);
236 DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
237 _cancel_scan = false;
239 BootMessage (_("Scanning LADSPA Plugins"));
242 BootMessage (_("Scanning LV2 Plugins"));
245 #ifdef WINDOWS_VST_SUPPORT
246 if (Config->get_use_windows_vst()) {
248 BootMessage (_("Scanning Windows VST Plugins"));
250 BootMessage (_("Discovering Windows VST Plugins"));
252 windows_vst_refresh (cache_only);
254 #endif // WINDOWS_VST_SUPPORT
257 if(Config->get_use_lxvst()) {
259 BootMessage (_("Scanning Linux VST Plugins"));
261 BootMessage (_("Discovering Linux VST Plugins"));
263 lxvst_refresh(cache_only);
265 #endif //Native linuxVST SUPPORT
267 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
269 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
270 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
272 if (g_file_get_contents(fn.c_str (), contents, NULL, NULL)) {
273 PBD::info << _("VST Blacklist:") << "\n" << bl << "-----" << endmsg;
280 #ifdef AUDIOUNIT_SUPPORT
282 BootMessage (_("Scanning AU Plugins"));
284 BootMessage (_("Discovering AU Plugins"));
286 au_refresh (cache_only);
289 BootMessage (_("Plugin Scan Complete..."));
290 PluginListChanged (); /* EMIT SIGNAL */
291 PluginScanMessage(X_("closeme"), "", false);
292 _cancel_scan = false;
296 PluginManager::cancel_plugin_scan ()
302 PluginManager::cancel_plugin_timeout ()
304 _cancel_timeout = true;
308 PluginManager::clear_vst_cache ()
310 #if 1 // clean old cache and error files. (remove this code after 4.3 or 5.0)
311 #ifdef WINDOWS_VST_SUPPORT
313 vector<string> fsi_files;
314 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_INFOFILE "$", true);
315 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
316 ::g_unlink(i->c_str());
320 vector<string> fsi_files;
321 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
322 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
323 ::g_unlink(i->c_str());
327 vector<string> fsi_files;
328 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.err$", true);
329 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
330 ::g_unlink(i->c_str());
337 vector<string> fsi_files;
338 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_INFOFILE "$", true);
339 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
340 ::g_unlink(i->c_str());
344 vector<string> fsi_files;
345 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
346 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
347 ::g_unlink(i->c_str());
351 vector<string> fsi_files;
352 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.err$", true);
353 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
354 ::g_unlink(i->c_str());
358 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
360 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_info");
361 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
362 PBD::remove_directory (dir);
366 #endif // old cache cleanup
368 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
370 string dn = Glib::build_filename (ARDOUR::user_cache_directory(), "vst");
371 vector<string> fsi_files;
372 find_files_matching_regex (fsi_files, dn, "\\" VST_EXT_INFOFILE "$", /* user cache is flat, no recursion */ false);
373 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
374 ::g_unlink(i->c_str());
381 PluginManager::clear_vst_blacklist ()
383 #if 1 // remove old blacklist files. (remove this code after 4.3 or 5.0)
385 #ifdef WINDOWS_VST_SUPPORT
387 vector<string> fsi_files;
388 find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_BLACKLIST "$", true);
389 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
390 ::g_unlink(i->c_str());
397 vector<string> fsi_files;
398 find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_BLACKLIST "$", true);
399 for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
400 ::g_unlink(i->c_str());
404 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
406 string dir = Glib::build_filename (ARDOUR::user_cache_directory(), "fst_blacklist");
407 if (Glib::file_test (dir, Glib::FILE_TEST_IS_DIR)) {
408 PBD::remove_directory (dir);
413 #endif // old blacklist cleanup
415 #if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT)
417 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST);
418 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
419 ::g_unlink (fn.c_str());
427 PluginManager::clear_au_cache ()
429 #ifdef AUDIOUNIT_SUPPORT
430 // AUPluginInfo::au_cache_path ()
431 string fn = Glib::build_filename (ARDOUR::user_config_directory(), "au_cache");
432 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
433 ::g_unlink(fn.c_str());
439 PluginManager::clear_au_blacklist ()
441 #ifdef AUDIOUNIT_SUPPORT
442 string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_blacklist.txt");
443 if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
444 ::g_unlink(fn.c_str());
450 PluginManager::ladspa_refresh ()
452 if (_ladspa_plugin_info) {
453 _ladspa_plugin_info->clear ();
455 _ladspa_plugin_info = new ARDOUR::PluginInfoList ();
458 /* allow LADSPA_PATH to augment, not override standard locations */
460 /* Only add standard locations to ladspa_path if it doesn't
461 * already contain them. Check for trailing G_DIR_SEPARATOR too.
464 vector<string> ladspa_modules;
466 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA: search along: [%1]\n", ladspa_search_path().to_string()));
468 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.so");
469 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dylib");
470 find_files_matching_pattern (ladspa_modules, ladspa_search_path (), "*.dll");
472 for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
473 ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
474 ladspa_discover (*i);
479 static bool rdf_filter (const string &str, void* /*arg*/)
481 return str[0] != '.' &&
482 ((str.find(".rdf") == (str.length() - 4)) ||
483 (str.find(".rdfs") == (str.length() - 5)) ||
484 (str.find(".n3") == (str.length() - 3)) ||
485 (str.find(".ttl") == (str.length() - 4)));
490 PluginManager::add_ladspa_presets()
492 add_presets ("ladspa");
496 PluginManager::add_windows_vst_presets()
498 add_presets ("windows-vst");
502 PluginManager::add_lxvst_presets()
504 add_presets ("lxvst");
508 PluginManager::add_presets(string domain)
511 vector<string> presets;
512 vector<string>::iterator x;
515 if ((envvar = getenv ("HOME")) == 0) {
519 string path = string_compose("%1/.%2/rdf", envvar, domain);
520 find_files_matching_filter (presets, path, rdf_filter, 0, false, true);
522 for (x = presets.begin(); x != presets.end (); ++x) {
523 string file = "file:" + *x;
524 if (lrdf_read_file(file.c_str())) {
525 warning << string_compose(_("Could not parse rdf file: %1"), *x) << endmsg;
533 PluginManager::add_lrdf_data (const string &path)
536 vector<string> rdf_files;
537 vector<string>::iterator x;
539 find_files_matching_filter (rdf_files, path, rdf_filter, 0, false, true);
541 for (x = rdf_files.begin(); x != rdf_files.end (); ++x) {
542 const string uri(string("file://") + *x);
544 if (lrdf_read_file(uri.c_str())) {
545 warning << "Could not parse rdf file: " << uri << endmsg;
552 PluginManager::ladspa_discover (string path)
554 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Checking for LADSPA plugin at %1\n", path));
556 Glib::Module module(path);
557 const LADSPA_Descriptor *descriptor;
558 LADSPA_Descriptor_Function dfunc;
562 error << string_compose(_("LADSPA: cannot load module \"%1\" (%2)"),
563 path, Glib::Module::get_last_error()) << endmsg;
568 if (!module.get_symbol("ladspa_descriptor", func)) {
569 error << string_compose(_("LADSPA: module \"%1\" has no descriptor function."), path) << endmsg;
570 error << Glib::Module::get_last_error() << endmsg;
574 dfunc = (LADSPA_Descriptor_Function)func;
576 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path));
578 for (uint32_t i = 0; ; ++i) {
579 if ((descriptor = dfunc (i)) == 0) {
583 if (!ladspa_plugin_whitelist.empty()) {
584 if (find (ladspa_plugin_whitelist.begin(), ladspa_plugin_whitelist.end(), descriptor->UniqueID) == ladspa_plugin_whitelist.end()) {
589 PluginInfoPtr info(new LadspaPluginInfo);
590 info->name = descriptor->Name;
591 info->category = get_ladspa_category(descriptor->UniqueID);
592 info->creator = descriptor->Maker;
595 info->n_inputs = ChanCount();
596 info->n_outputs = ChanCount();
597 info->type = ARDOUR::LADSPA;
600 snprintf (buf, sizeof (buf), "%lu", descriptor->UniqueID);
601 info->unique_id = buf;
603 for (uint32_t n=0; n < descriptor->PortCount; ++n) {
604 if ( LADSPA_IS_PORT_AUDIO (descriptor->PortDescriptors[n]) ) {
605 if ( LADSPA_IS_PORT_INPUT (descriptor->PortDescriptors[n]) ) {
606 info->n_inputs.set_audio(info->n_inputs.n_audio() + 1);
608 else if ( LADSPA_IS_PORT_OUTPUT (descriptor->PortDescriptors[n]) ) {
609 info->n_outputs.set_audio(info->n_outputs.n_audio() + 1);
614 if(_ladspa_plugin_info->empty()){
615 _ladspa_plugin_info->push_back (info);
618 //Ensure that the plugin is not already in the plugin list.
622 for (PluginInfoList::const_iterator i = _ladspa_plugin_info->begin(); i != _ladspa_plugin_info->end(); ++i) {
623 if(0 == info->unique_id.compare((*i)->unique_id)){
629 _ladspa_plugin_info->push_back (info);
632 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Found LADSPA plugin, name: %1, Inputs: %2, Outputs: %3\n", info->name, info->n_inputs, info->n_outputs));
635 // GDB WILL NOT LIKE YOU IF YOU DO THIS
642 PluginManager::get_ladspa_category (uint32_t plugin_id)
646 lrdf_statement pattern;
648 snprintf(buf, sizeof(buf), "%s%" PRIu32, LADSPA_BASE, plugin_id);
649 pattern.subject = buf;
650 pattern.predicate = const_cast<char*>(RDF_TYPE);
652 pattern.object_type = lrdf_uri;
654 lrdf_statement* matches1 = lrdf_matches (&pattern);
660 pattern.subject = matches1->object;
661 pattern.predicate = const_cast<char*>(LADSPA_BASE "hasLabel");
663 pattern.object_type = lrdf_literal;
665 lrdf_statement* matches2 = lrdf_matches (&pattern);
666 lrdf_free_statements(matches1);
672 string label = matches2->object;
673 lrdf_free_statements(matches2);
675 /* Kludge LADSPA class names to be singular and match LV2 class names.
676 This avoids duplicate plugin menus for every class, which is necessary
677 to make the plugin category menu at all usable, but is obviously a
680 In the short term, lrdf could be updated so the labels match and a new
681 release made. To support both specs, we should probably be mapping the
682 URIs to the same category in code and perhaps tweaking that hierarchy
683 dynamically to suit the user. Personally, I (drobilla) think that time
684 is better spent replacing the little-used LRDF.
686 In the longer term, we will abandon LRDF entirely in favour of LV2 and
687 use that class hierarchy. Aside from fixing this problem properly, that
688 will also allow for translated labels. SWH plugins have been LV2 for
689 ages; TAP needs porting. I don't know of anything else with LRDF data.
691 if (label == "Utilities") {
693 } else if (label == "Pitch shifters") {
694 return "Pitch Shifter";
695 } else if (label != "Dynamics" && label != "Chorus"
696 &&label[label.length() - 1] == 's'
697 && label[label.length() - 2] != 's') {
698 return label.substr(0, label.length() - 1);
709 PluginManager::lv2_refresh ()
711 DEBUG_TRACE (DEBUG::PluginManager, "LV2: refresh\n");
712 delete _lv2_plugin_info;
713 _lv2_plugin_info = LV2PluginInfo::discover();
717 #ifdef AUDIOUNIT_SUPPORT
719 PluginManager::au_refresh (bool cache_only)
721 DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
723 // disable automatic discovery in case we crash
724 bool discover_at_start = Config->get_discover_audio_units ();
725 Config->set_discover_audio_units (false);
726 Config->save_state();
728 delete _au_plugin_info;
729 _au_plugin_info = AUPluginInfo::discover(cache_only && !discover_at_start);
731 // successful scan re-enabled automatic discovery if it was set
732 Config->set_discover_audio_units (discover_at_start);
733 Config->save_state();
738 #ifdef WINDOWS_VST_SUPPORT
741 PluginManager::windows_vst_refresh (bool cache_only)
743 if (_windows_vst_plugin_info) {
744 _windows_vst_plugin_info->clear ();
746 _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
749 windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
752 static bool windows_vst_filter (const string& str, void * /*arg*/)
754 /* Not a dotfile, has a prefix before a period, suffix is "dll" */
755 return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
759 PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
761 vector<string> plugin_objects;
762 vector<string>::iterator x;
765 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path));
767 if (Config->get_verbose_plugin_scan()) {
768 info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
771 find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
773 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
774 ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
775 windows_vst_discover (*x, cache_only || cancelled());
778 if (Config->get_verbose_plugin_scan()) {
779 info << _("--- Windows VST plugins Scan Done") << endmsg;
786 PluginManager::windows_vst_discover (string path, bool cache_only)
788 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
790 if (Config->get_verbose_plugin_scan()) {
791 info << string_compose (_(" * %1 %2"), path, (cache_only ? _(" (cache only)") : "")) << endmsg;
794 _cancel_timeout = false;
795 vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
796 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
798 // TODO get extended error messae from vstfx_get_info_fst() e.g blacklisted, 32/64bit compat,
799 // .err file scanner output etc.
801 if (finfos->empty()) {
802 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
803 if (Config->get_verbose_plugin_scan()) {
804 info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
809 uint32_t discovered = 0;
810 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
814 if (!finfo->canProcessReplacing) {
815 warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
816 finfo->name, PROGRAM_NAME)
821 PluginInfoPtr info (new WindowsVSTPluginInfo);
823 /* what a joke freeware VST is */
825 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
826 info->name = PBD::basename_nosuffix (path);
828 info->name = finfo->name;
832 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
833 info->unique_id = buf;
834 info->category = "VST";
836 info->creator = finfo->creator;
838 info->n_inputs.set_audio (finfo->numInputs);
839 info->n_outputs.set_audio (finfo->numOutputs);
840 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
841 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
842 info->type = ARDOUR::Windows_VST;
844 // TODO: check dup-IDs (lxvst AND windows vst)
845 bool duplicate = false;
847 if (!_windows_vst_plugin_info->empty()) {
848 for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
849 if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
850 warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
858 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
859 _windows_vst_plugin_info->push_back (info);
861 if (Config->get_verbose_plugin_scan()) {
862 PBD::info << string_compose (_(" -> OK (VST Plugin \"%1\" was added)."), info->name) << endmsg;
867 vstfx_free_info_list (finfos);
868 return discovered > 0 ? 0 : -1;
871 #endif // WINDOWS_VST_SUPPORT
876 PluginManager::lxvst_refresh (bool cache_only)
878 if (_lxvst_plugin_info) {
879 _lxvst_plugin_info->clear ();
881 _lxvst_plugin_info = new ARDOUR::PluginInfoList();
884 lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
887 static bool lxvst_filter (const string& str, void *)
889 /* Not a dotfile, has a prefix before a period, suffix is "so" */
891 return str[0] != '.' && (str.length() > 3 && str.find (".so") == (str.length() - 3));
895 PluginManager::lxvst_discover_from_path (string path, bool cache_only)
897 vector<string> plugin_objects;
898 vector<string>::iterator x;
905 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
907 find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
909 for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
910 ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());
911 lxvst_discover (*x, cache_only || cancelled());
918 PluginManager::lxvst_discover (string path, bool cache_only)
920 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
922 _cancel_timeout = false;
923 vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
924 cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
926 if (finfos->empty()) {
927 DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
931 uint32_t discovered = 0;
932 for (vector<VSTInfo *>::iterator x = finfos->begin(); x != finfos->end(); ++x) {
936 if (!finfo->canProcessReplacing) {
937 warning << string_compose (_("linuxVST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
938 finfo->name, PROGRAM_NAME)
943 PluginInfoPtr info(new LXVSTPluginInfo);
945 if (!strcasecmp ("The Unnamed plugin", finfo->name)) {
946 info->name = PBD::basename_nosuffix (path);
948 info->name = finfo->name;
952 snprintf (buf, sizeof (buf), "%d", finfo->UniqueID);
953 info->unique_id = buf;
954 info->category = "linuxVSTs";
956 info->creator = finfo->creator;
958 info->n_inputs.set_audio (finfo->numInputs);
959 info->n_outputs.set_audio (finfo->numOutputs);
960 info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
961 info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
962 info->type = ARDOUR::LXVST;
964 /* Make sure we don't find the same plugin in more than one place along
965 the LXVST_PATH We can't use a simple 'find' because the path is included
966 in the PluginInfo, and that is the one thing we can be sure MUST be
967 different if a duplicate instance is found. So we just compare the type
968 and unique ID (which for some VSTs isn't actually unique...)
971 // TODO: check dup-IDs with windowsVST, too
972 bool duplicate = false;
973 if (!_lxvst_plugin_info->empty()) {
974 for (PluginInfoList::iterator i =_lxvst_plugin_info->begin(); i != _lxvst_plugin_info->end(); ++i) {
975 if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
976 warning << "Ignoring duplicate Linux VST plugin " << info->name << "\n";
984 _lxvst_plugin_info->push_back (info);
989 vstfx_free_info_list (finfos);
990 return discovered > 0 ? 0 : -1;
993 #endif // LXVST_SUPPORT
996 PluginManager::PluginStatusType
997 PluginManager::get_status (const PluginInfoPtr& pi)
999 PluginStatus ps (pi->type, pi->unique_id);
1000 PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps);
1001 if (i == statuses.end() ) {
1009 PluginManager::save_statuses ()
1011 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1014 for (PluginStatusList::iterator i = statuses.begin(); i != statuses.end(); ++i) {
1015 switch ((*i).type) {
1026 ofs << "Windows-VST";
1035 switch ((*i).status) {
1048 ofs << (*i).unique_id;;
1051 g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL);
1055 PluginManager::load_statuses ()
1057 std::string path = Glib::build_filename (user_config_directory(), "plugin_statuses");
1059 if (!g_file_get_contents (path.c_str(), &fbuf, NULL, NULL)) {
1062 stringstream ifs (fbuf);
1066 std::string sstatus;
1069 PluginStatusType status;
1086 /* rest of the line is the plugin ID */
1088 ifs.getline (buf, sizeof (buf), '\n');
1093 if (sstatus == "Normal") {
1095 } else if (sstatus == "Favorite") {
1097 } else if (sstatus == "Hidden") {
1100 error << string_compose (_("unknown plugin status type \"%1\" - all entries ignored"), sstatus)
1106 if (stype == "LADSPA") {
1108 } else if (stype == "AudioUnit") {
1110 } else if (stype == "LV2") {
1112 } else if (stype == "Windows-VST") {
1114 } else if (stype == "LXVST") {
1117 error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype)
1123 strip_whitespace_edges (id);
1124 set_status (type, id, status);
1129 PluginManager::set_status (PluginType t, string id, PluginStatusType status)
1131 PluginStatus ps (t, id, status);
1132 statuses.erase (ps);
1134 if (status == Normal) {
1138 statuses.insert (ps);
1141 ARDOUR::PluginInfoList&
1142 PluginManager::windows_vst_plugin_info ()
1144 #ifdef WINDOWS_VST_SUPPORT
1145 if (!_windows_vst_plugin_info) {
1146 windows_vst_refresh ();
1148 return *_windows_vst_plugin_info;
1150 return _empty_plugin_info;
1154 ARDOUR::PluginInfoList&
1155 PluginManager::lxvst_plugin_info ()
1157 #ifdef LXVST_SUPPORT
1158 assert(_lxvst_plugin_info);
1159 return *_lxvst_plugin_info;
1161 return _empty_plugin_info;
1165 ARDOUR::PluginInfoList&
1166 PluginManager::ladspa_plugin_info ()
1168 assert(_ladspa_plugin_info);
1169 return *_ladspa_plugin_info;
1172 ARDOUR::PluginInfoList&
1173 PluginManager::lv2_plugin_info ()
1176 assert(_lv2_plugin_info);
1177 return *_lv2_plugin_info;
1179 return _empty_plugin_info;
1183 ARDOUR::PluginInfoList&
1184 PluginManager::au_plugin_info ()
1186 #ifdef AUDIOUNIT_SUPPORT
1187 if (_au_plugin_info) {
1188 return *_au_plugin_info;
1191 return _empty_plugin_info;