#include <glib/gstdio.h>
#include <glibmm/miscutils.h>
#include <glibmm/pattern.h>
+#include <glibmm/fileutils.h>
+#include <glibmm/miscutils.h>
#include "pbd/whitespace.h"
#include "pbd/file_utils.h"
#ifdef WINDOWS_VST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsi$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#ifdef LXVST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsi$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
{
string personal = get_personal_vst_info_cache_dir();
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, personal, "\\.fsi$");
+ find_files_matching_regex (fsi_files, personal, "\\.fsi$", /* user cache is flat, no recursion */ false);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#ifdef WINDOWS_VST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\.fsb$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_vst(), "\\" VST_EXT_BLACKLIST "$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#ifdef LXVST_SUPPORT
{
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\.fsb$");
+ find_files_matching_regex (fsi_files, Config->get_plugin_path_lxvst(), "\\" VST_EXT_BLACKLIST "$", true);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
string personal = get_personal_vst_blacklist_dir();
vector<string> fsi_files;
- find_files_matching_regex (fsi_files, personal, "\\.fsb$");
+ find_files_matching_regex (fsi_files, personal, "\\" VST_EXT_BLACKLIST "$", /* flat user cache */ false);
for (vector<string>::iterator i = fsi_files.begin(); i != fsi_files.end (); ++i) {
::g_unlink(i->c_str());
}
#endif
}
+void
+PluginManager::clear_au_cache ()
+{
+#ifdef AUDIOUNIT_SUPPORT
+ // AUPluginInfo::au_cache_path ()
+ string fn = Glib::build_filename (ARDOUR::user_config_directory(), "au_cache");
+ if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
+ ::g_unlink(fn.c_str());
+ }
+#endif
+}
+
+void
+PluginManager::clear_au_blacklist ()
+{
+#ifdef AUDIOUNIT_SUPPORT
+ string fn = Glib::build_filename (ARDOUR::user_cache_directory(), "au_blacklist.txt");
+ if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) {
+ ::g_unlink(fn.c_str());
+ }
+#endif
+}
+
void
PluginManager::ladspa_refresh ()
{
return;
}
delete _au_plugin_info;
+ _au_plugin_info = AUPluginInfo::discover();
// disable automatic scan in case we crash
Config->set_discover_audio_units (false);
Config->save_state();
- _au_plugin_info = AUPluginInfo::discover();
+ /* note: AU require a CAComponentDescription pointer provided by the OS.
+ * Ardour only caches port and i/o config. It can't just 'scan' without
+ * 'discovering' (like we do for VST).
+ *
+ * So in case discovery fails, we assume the worst: the Description
+ * is broken (malicious plugins) and even a simple 'scan' would always
+ * crash ardour on startup. Hence we disable Auto-Scan on start.
+ *
+ * If the crash happens at any later time (description is available),
+ * Ardour will blacklist the plugin in question -- unless
+ * the crash happens during realtime-run.
+ */
// successful scan re-enabled automatic discovery
Config->set_discover_audio_units (true);
static bool windows_vst_filter (const string& str, void * /*arg*/)
{
/* Not a dotfile, has a prefix before a period, suffix is "dll" */
-
- return str[0] != '.' && (str.length() > 4 && str.find (".dll") == (str.length() - 4));
+ return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".dll", str.substr(str.length() - 4));
}
int
vector<string>::iterator x;
int ret = 0;
- DEBUG_TRACE (DEBUG::PluginManager, string_compose ("detecting Windows VST plugins along %1\n", path));
+ DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path));
- find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true);
+ if (Config->get_verbose_plugin_scan()) {
+ info << string_compose (_("--- Windows VST plugins Scan: %1"), path) << endmsg;
+ }
+
+ find_files_matching_filter (plugin_objects, Config->get_plugin_path_vst(), windows_vst_filter, 0, false, true, true);
for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled());
windows_vst_discover (*x, cache_only || cancelled());
}
+ if (Config->get_verbose_plugin_scan()) {
+ info << _("--- Windows VST plugins Scan Done") << endmsg;
+ }
+
return ret;
}
{
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("windows_vst_discover '%1'\n", path));
+ if (Config->get_verbose_plugin_scan()) {
+ info << string_compose (_(" * %1 %2"), path, (cache_only ? _(" (cache only)") : "")) << endmsg;
+ }
+
_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);
+ // TODO get extended error messae from vstfx_get_info_fst() e.g blacklisted, 32/64bit compat,
+ // .err file scanner output etc.
+
if (finfos->empty()) {
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Windows VST information from '%1'\n", path));
+ if (Config->get_verbose_plugin_scan()) {
+ info << _(" -> Cannot get Windows VST information, plugin ignored.") << endmsg;
+ }
return -1;
}
char buf[32];
if (!finfo->canProcessReplacing) {
- warning << string_compose (_("VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"),
+ warning << string_compose (_("VST plugin %1 does not support processReplacing, and cannot be used in %2 at this time"),
finfo->name, PROGRAM_NAME)
<< endl;
continue;
if (!_windows_vst_plugin_info->empty()) {
for (PluginInfoList::iterator i =_windows_vst_plugin_info->begin(); i != _windows_vst_plugin_info->end(); ++i) {
- if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) {
- warning << "Ignoring duplicate Windows VST plugin " << info->name << "\n";
+ if ((info->type == (*i)->type) && (info->unique_id == (*i)->unique_id)) {
+ warning << string_compose (_("Ignoring duplicate Windows VST plugin \"%1\""), info->name) << endmsg;
duplicate = true;
break;
}
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Windows VST plugin ID '%1'\n", info->unique_id));
_windows_vst_plugin_info->push_back (info);
discovered++;
+ if (Config->get_verbose_plugin_scan()) {
+ PBD::info << string_compose (_(" -> OK. (VST Plugin \"%1\" added)."), info->name) << endmsg;
+ }
}
}
DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering linuxVST plugins along %1\n", path));
- find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true);
+ find_files_matching_filter (plugin_objects, Config->get_plugin_path_lxvst(), lxvst_filter, 0, false, true, true);
for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) {
ARDOUR::PluginScanMessage(_("LXVST"), *x, !cache_only && !cancelled());