Post-export hook tweaks
[ardour.git] / libs / ardour / plugin_manager.cc
index cfdfc6af7f2ca55aa8733711d5db054c8a20966f..7c3eae538f9531fa9e17b20a2a796c2ebb4b3c6b 100644 (file)
@@ -62,7 +62,7 @@
 #include "ardour/plugin_manager.h"
 #include "ardour/rc_configuration.h"
 
-#include "ardour/ladspa_search_path.h"
+#include "ardour/search_paths.h"
 
 #ifdef LV2_SUPPORT
 #include "ardour/lv2_plugin.h"
@@ -93,6 +93,7 @@ using namespace PBD;
 using namespace std;
 
 PluginManager* PluginManager::_instance = 0;
+std::string PluginManager::scanner_bin_path = "";
 
 PluginManager&
 PluginManager::instance()
@@ -109,11 +110,17 @@ PluginManager::PluginManager ()
        , _ladspa_plugin_info(0)
        , _lv2_plugin_info(0)
        , _au_plugin_info(0)
-       , cancel_scan(false)
+       , _cancel_scan(false)
+       , _cancel_timeout(false)
 {
        char* s;
        string lrdf_path;
 
+       string  scan_p = Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst");
+       if (!PBD::find_file_in_search_path ( PBD::Searchpath(scan_p), "ardour-vst-scanner", scanner_bin_path)) {
+               PBD::warning << "VST scanner app (ardour-vst-scanner) not found in path " << scan_p <<  endmsg;
+       }
+
        load_statuses ();
 
        if ((s = getenv ("LADSPA_RDF_PATH"))){
@@ -144,26 +151,32 @@ PluginManager::PluginManager ()
                windows_vst_path = s;
        }
 
+       if (windows_vst_path.length() == 0) {
+               windows_vst_path = vst_search_path ();
+       }
+
        if ((s = getenv ("LXVST_PATH"))) {
                lxvst_path = s;
        } else if ((s = getenv ("LXVST_PLUGINS"))) {
                lxvst_path = s;
        }
 
-       if (_instance == 0) {
-               _instance = this;
+       if (lxvst_path.length() == 0) {
+               lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
+                       "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
+                       "/usr/lib/vst:/usr/local/lib/vst";
        }
 
-       /* the plugin manager is constructed too early to use Profile */
+       /* first time setup, use 'default' path */
+       if (Config->get_plugin_path_lxvst() == X_("@default@")) {
+               Config->set_plugin_path_lxvst(get_default_lxvst_path());
+       }
+       if (Config->get_plugin_path_vst() == X_("@default@")) {
+               Config->set_plugin_path_vst(get_default_windows_vst_path());
+       }
 
-       if (getenv ("ARDOUR_SAE")) {
-               ladspa_plugin_whitelist.push_back (1203); // single band parametric
-               ladspa_plugin_whitelist.push_back (1772); // caps compressor
-               ladspa_plugin_whitelist.push_back (1913); // fast lookahead limiter
-               ladspa_plugin_whitelist.push_back (1075); // simple RMS expander
-               ladspa_plugin_whitelist.push_back (1061); // feedback delay line (max 5s)
-               ladspa_plugin_whitelist.push_back (1216); // gverb
-               ladspa_plugin_whitelist.push_back (2150); // tap pitch shifter
+       if (_instance == 0) {
+               _instance = this;
        }
 
        BootMessage (_("Discovering Plugins"));
@@ -174,41 +187,53 @@ PluginManager::~PluginManager()
 {
 }
 
-
 void
-PluginManager::refresh ()
+PluginManager::refresh (bool cache_only)
 {
        DEBUG_TRACE (DEBUG::PluginManager, "PluginManager::refresh\n");
-       BootMessage (_("Discovering Plugins"));
+       _cancel_scan = false;
 
+       BootMessage (_("Scanning LADSPA Plugins"));
        ladspa_refresh ();
 #ifdef LV2_SUPPORT
+       BootMessage (_("Scanning LV2 Plugins"));
        lv2_refresh ();
 #endif
 #ifdef WINDOWS_VST_SUPPORT
        if (Config->get_use_windows_vst()) {
-               windows_vst_refresh ();
+               BootMessage (_("Scanning Windows VST Plugins"));
+               windows_vst_refresh (cache_only);
        }
 #endif // WINDOWS_VST_SUPPORT
 
 #ifdef LXVST_SUPPORT
        if(Config->get_use_lxvst()) {
-               lxvst_refresh();
+               BootMessage (_("Scanning Linux VST Plugins"));
+               lxvst_refresh(cache_only);
        }
 #endif //Native linuxVST SUPPORT
 
 #ifdef AUDIOUNIT_SUPPORT
+       BootMessage (_("Scanning AU Plugins"));
        au_refresh ();
 #endif
 
+       BootMessage (_("Plugin Scan Complete..."));
        PluginListChanged (); /* EMIT SIGNAL */
-       PluginScanMessage(X_("closeme"), "");
+       PluginScanMessage(X_("closeme"), "", false);
+       _cancel_scan = false;
 }
 
 void
 PluginManager::cancel_plugin_scan ()
 {
-       // TODO
+       _cancel_scan = true;
+}
+
+void
+PluginManager::cancel_plugin_timeout ()
+{
+       _cancel_timeout = true;
 }
 
 void
@@ -220,7 +245,7 @@ PluginManager::clear_vst_cache ()
                PathScanner scanner;
                vector<string *> *fsi_files;
 
-               fsi_files = scanner (windows_vst_path, "\\.fsi$", true, true, -1, false);
+               fsi_files = scanner (Config->get_plugin_path_vst(), "\\.fsi$", true, true, -1, false);
                if (fsi_files) {
                        for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
                                ::g_unlink((*i)->c_str());
@@ -234,7 +259,7 @@ PluginManager::clear_vst_cache ()
        {
                PathScanner scanner;
                vector<string *> *fsi_files;
-               fsi_files = scanner (lxvst_path, "\\.fsi$", true, true, -1, false);
+               fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsi$", true, true, -1, false);
                if (fsi_files) {
                        for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
                                ::g_unlink((*i)->c_str());
@@ -268,7 +293,7 @@ PluginManager::clear_vst_blacklist ()
                PathScanner scanner;
                vector<string *> *fsi_files;
 
-               fsi_files = scanner (windows_vst_path, "\\.fsb$", true, true, -1, false);
+               fsi_files = scanner (Config->get_plugin_path_vst(), "\\.fsb$", true, true, -1, false);
                if (fsi_files) {
                        for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
                                ::g_unlink((*i)->c_str());
@@ -282,7 +307,7 @@ PluginManager::clear_vst_blacklist ()
        {
                PathScanner scanner;
                vector<string *> *fsi_files;
-               fsi_files = scanner (lxvst_path, "\\.fsb$", true, true, -1, false);
+               fsi_files = scanner (Config->get_plugin_path_lxvst(), "\\.fsb$", true, true, -1, false);
                if (fsi_files) {
                        for (vector<string *>::iterator i = fsi_files->begin(); i != fsi_files->end (); ++i) {
                                ::g_unlink((*i)->c_str());
@@ -342,7 +367,7 @@ PluginManager::ladspa_refresh ()
                                            dll_extension_pattern, ladspa_modules);
 
        for (vector<std::string>::iterator i = ladspa_modules.begin(); i != ladspa_modules.end(); ++i) {
-               ARDOUR::PluginScanMessage(_("LADSPA"), *i);
+               ARDOUR::PluginScanMessage(_("LADSPA"), *i, false);
                ladspa_discover (*i);
        }
 }
@@ -607,7 +632,7 @@ PluginManager::au_refresh ()
 #ifdef WINDOWS_VST_SUPPORT
 
 void
-PluginManager::windows_vst_refresh ()
+PluginManager::windows_vst_refresh (bool cache_only)
 {
        if (_windows_vst_plugin_info) {
                _windows_vst_plugin_info->clear ();
@@ -615,22 +640,7 @@ PluginManager::windows_vst_refresh ()
                _windows_vst_plugin_info = new ARDOUR::PluginInfoList();
        }
 
-       if (windows_vst_path.length() == 0) {
-               windows_vst_path = "/usr/local/lib/vst:/usr/lib/vst";
-       }
-
-       windows_vst_discover_from_path (windows_vst_path);
-}
-
-int
-PluginManager::add_windows_vst_directory (string path)
-{
-       if (windows_vst_discover_from_path (path) == 0) {
-               windows_vst_path += ':';
-               windows_vst_path += path;
-               return 0;
-       }
-       return -1;
+       windows_vst_discover_from_path (Config->get_plugin_path_vst(), cache_only);
 }
 
 static bool windows_vst_filter (const string& str, void * /*arg*/)
@@ -641,7 +651,7 @@ static bool windows_vst_filter (const string& str, void * /*arg*/)
 }
 
 int
-PluginManager::windows_vst_discover_from_path (string path)
+PluginManager::windows_vst_discover_from_path (string path, bool cache_only)
 {
        PathScanner scanner;
        vector<string *> *plugin_objects;
@@ -650,12 +660,12 @@ PluginManager::windows_vst_discover_from_path (string path)
 
        DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
 
-       plugin_objects = scanner (windows_vst_path, windows_vst_filter, 0, false, true);
+       plugin_objects = scanner (Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
 
        if (plugin_objects) {
                for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
-                       ARDOUR::PluginScanMessage(_("VST"), **x);
-                       windows_vst_discover (**x);
+                       ARDOUR::PluginScanMessage(_("VST"), **x, !cache_only && !cancelled());
+                       windows_vst_discover (**x, cache_only || cancelled());
                }
 
                vector_delete (plugin_objects);
@@ -665,11 +675,13 @@ PluginManager::windows_vst_discover_from_path (string path)
 }
 
 int
-PluginManager::windows_vst_discover (string path)
+PluginManager::windows_vst_discover (string path, bool cache_only)
 {
        DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
 
-       vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()));
+       _cancel_timeout = false;
+       vector<VSTInfo*> * finfos = vstfx_get_info_fst (const_cast<char *> (path.c_str()),
+                       cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
 
        if (finfos->empty()) {
                DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
@@ -707,7 +719,8 @@ PluginManager::windows_vst_discover (string path)
                info->index = 0;
                info->n_inputs.set_audio (finfo->numInputs);
                info->n_outputs.set_audio (finfo->numOutputs);
-               info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
+               info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
+               info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
                info->type = ARDOUR::Windows_VST;
 
                // TODO: check dup-IDs (lxvst AND windows vst)
@@ -739,7 +752,7 @@ PluginManager::windows_vst_discover (string path)
 #ifdef LXVST_SUPPORT
 
 void
-PluginManager::lxvst_refresh ()
+PluginManager::lxvst_refresh (bool cache_only)
 {
        if (_lxvst_plugin_info) {
                _lxvst_plugin_info->clear ();
@@ -747,24 +760,7 @@ PluginManager::lxvst_refresh ()
                _lxvst_plugin_info = new ARDOUR::PluginInfoList();
        }
 
-       if (lxvst_path.length() == 0) {
-               lxvst_path = "/usr/local/lib64/lxvst:/usr/local/lib/lxvst:/usr/lib64/lxvst:/usr/lib/lxvst:"
-                       "/usr/local/lib64/linux_vst:/usr/local/lib/linux_vst:/usr/lib64/linux_vst:/usr/lib/linux_vst:"
-                       "/usr/lib/vst:/usr/local/lib/vst";
-       }
-
-       lxvst_discover_from_path (lxvst_path);
-}
-
-int
-PluginManager::add_lxvst_directory (string path)
-{
-       if (lxvst_discover_from_path (path) == 0) {
-               lxvst_path += ':';
-               lxvst_path += path;
-               return 0;
-       }
-       return -1;
+       lxvst_discover_from_path (Config->get_plugin_path_lxvst(), cache_only);
 }
 
 static bool lxvst_filter (const string& str, void *)
@@ -775,7 +771,7 @@ static bool lxvst_filter (const string& str, void *)
 }
 
 int
-PluginManager::lxvst_discover_from_path (string path)
+PluginManager::lxvst_discover_from_path (string path, bool cache_only)
 {
        PathScanner scanner;
        vector<string *> *plugin_objects;
@@ -788,12 +784,12 @@ PluginManager::lxvst_discover_from_path (string path)
 
        DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
 
-       plugin_objects = scanner (lxvst_path, lxvst_filter, 0, false, true);
+       plugin_objects = scanner (Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
 
        if (plugin_objects) {
                for (x = plugin_objects->begin(); x != plugin_objects->end (); ++x) {
-                       ARDOUR::PluginScanMessage(_("LXVST"), **x);
-                       lxvst_discover (**x);
+                       ARDOUR::PluginScanMessage(_("LXVST"), **x, !cache_only && !cancelled());
+                       lxvst_discover (**x, cache_only || cancelled());
                }
 
                vector_delete (plugin_objects);
@@ -803,11 +799,13 @@ PluginManager::lxvst_discover_from_path (string path)
 }
 
 int
-PluginManager::lxvst_discover (string path)
+PluginManager::lxvst_discover (string path, bool cache_only)
 {
        DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent LXVST plugin at %1\n", path));
 
-       vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()));
+       _cancel_timeout = false;
+       vector<VSTInfo*> * finfos = vstfx_get_info_lx (const_cast<char *> (path.c_str()),
+                       cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP);
 
        if (finfos->empty()) {
                DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Linux VST information from '%1'\n", path));
@@ -843,7 +841,8 @@ PluginManager::lxvst_discover (string path)
                info->index = 0;
                info->n_inputs.set_audio (finfo->numInputs);
                info->n_outputs.set_audio (finfo->numOutputs);
-               info->n_inputs.set_midi (finfo->wantMidi ? 1 : 0);
+               info->n_inputs.set_midi ((finfo->wantMidi&1) ? 1 : 0);
+               info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0);
                info->type = ARDOUR::LXVST;
 
                                        /* Make sure we don't find the same plugin in more than one place along
@@ -1048,8 +1047,7 @@ ARDOUR::PluginInfoList&
 PluginManager::lxvst_plugin_info ()
 {
 #ifdef LXVST_SUPPORT
-       if (!_lxvst_plugin_info)
-               lxvst_refresh();
+       assert(_lxvst_plugin_info);
        return *_lxvst_plugin_info;
 #else
        return _empty_plugin_info;
@@ -1059,8 +1057,7 @@ PluginManager::lxvst_plugin_info ()
 ARDOUR::PluginInfoList&
 PluginManager::ladspa_plugin_info ()
 {
-       if (!_ladspa_plugin_info)
-               ladspa_refresh();
+       assert(_ladspa_plugin_info);
        return *_ladspa_plugin_info;
 }
 
@@ -1068,8 +1065,7 @@ ARDOUR::PluginInfoList&
 PluginManager::lv2_plugin_info ()
 {
 #ifdef LV2_SUPPORT
-       if (!_lv2_plugin_info)
-               lv2_refresh();
+       assert(_lv2_plugin_info);
        return *_lv2_plugin_info;
 #else
        return _empty_plugin_info;
@@ -1080,8 +1076,7 @@ ARDOUR::PluginInfoList&
 PluginManager::au_plugin_info ()
 {
 #ifdef AUDIOUNIT_SUPPORT
-       if (!_au_plugin_info)
-               au_refresh();
+       assert(_au_plugin_info);
        return *_au_plugin_info;
 #else
        return _empty_plugin_info;