X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fplugin_manager.cc;h=5254b41a78ea4a81c577011c36527d7efc10a913;hb=4e5423b3487771220cdca4c2b1a79c4d74b6afa5;hp=89ddc5ff19f303fb204bd979f96be89e362a3426;hpb=51385ced3c5564bb9155c9072321740b8eaac928;p=ardour.git diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index 89ddc5ff19..5254b41a78 100644 --- a/libs/ardour/plugin_manager.cc +++ b/libs/ardour/plugin_manager.cc @@ -55,6 +55,14 @@ #include #endif //LXVST_SUPPORT +#ifdef MACVST_SUPPORT +#include "ardour/vst_info_file.h" +#include "ardour/mac_vst_support.h" +#include "ardour/mac_vst_plugin.h" +#include "pbd/basename.h" +#include +#endif //MACVST_SUPPORT + #include #include #include @@ -67,6 +75,8 @@ #include "ardour/filesystem_paths.h" #include "ardour/ladspa.h" #include "ardour/ladspa_plugin.h" +#include "ardour/luascripting.h" +#include "ardour/luaproc.h" #include "ardour/plugin.h" #include "ardour/plugin_manager.h" #include "ardour/rc_configuration.h" @@ -93,7 +103,7 @@ #include "pbd/error.h" #include "pbd/stl_delete.h" -#include "i18n.h" +#include "pbd/i18n.h" #include "ardour/debug.h" @@ -116,16 +126,18 @@ PluginManager::instance() PluginManager::PluginManager () : _windows_vst_plugin_info(0) , _lxvst_plugin_info(0) + , _mac_vst_plugin_info(0) , _ladspa_plugin_info(0) , _lv2_plugin_info(0) , _au_plugin_info(0) + , _lua_plugin_info(0) , _cancel_scan(false) , _cancel_timeout(false) { char* s; string lrdf_path; -#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT +#if defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT // source-tree (ardev, etc) PBD::Searchpath vstsp(Glib::build_filename(ARDOUR::ardour_dll_directory(), "fst")); @@ -180,6 +192,12 @@ PluginManager::PluginManager () } #endif /* Native LinuxVST support*/ +#ifdef MACVST_SUPPORT + if (Config->get_use_macvst ()) { + add_mac_vst_presets (); + } +#endif + if ((s = getenv ("VST_PATH"))) { windows_vst_path = s; } else if ((s = getenv ("VST_PLUGINS"))) { @@ -215,6 +233,8 @@ PluginManager::PluginManager () } BootMessage (_("Discovering Plugins")); + + LuaScripting::instance().scripts_changed.connect_same_thread (lua_refresh_connection, boost::bind (&PluginManager::lua_refresh_cb, this)); } @@ -224,9 +244,11 @@ PluginManager::~PluginManager() // don't bother, just exit quickly. delete _windows_vst_plugin_info; delete _lxvst_plugin_info; + delete _mac_vst_plugin_info; delete _ladspa_plugin_info; delete _lv2_plugin_info; delete _au_plugin_info; + delete _lua_plugin_info; } } @@ -244,6 +266,8 @@ PluginManager::refresh (bool cache_only) BootMessage (_("Scanning LADSPA Plugins")); ladspa_refresh (); + BootMessage (_("Scanning Lua DSP Processors")); + lua_refresh (); #ifdef LV2_SUPPORT BootMessage (_("Scanning LV2 Plugins")); lv2_refresh (); @@ -270,7 +294,22 @@ PluginManager::refresh (bool cache_only) } #endif //Native linuxVST SUPPORT -#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT) +#ifdef MACVST_SUPPORT + if(Config->get_use_macvst ()) { + if (cache_only) { + BootMessage (_("Scanning Mac VST Plugins")); + } else { + BootMessage (_("Discovering Mac VST Plugins")); + } + mac_vst_refresh (cache_only); + } else if (_mac_vst_plugin_info) { + _mac_vst_plugin_info->clear (); + } else { + _mac_vst_plugin_info = new ARDOUR::PluginInfoList(); + } +#endif //Native Mac VST SUPPORT + +#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT) if (!cache_only) { string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST); if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) { @@ -375,7 +414,7 @@ PluginManager::clear_vst_cache () #endif #endif // old cache cleanup -#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT) +#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT) { string dn = Glib::build_filename (ARDOUR::user_cache_directory(), "vst"); vector fsi_files; @@ -422,7 +461,7 @@ PluginManager::clear_vst_blacklist () #endif // old blacklist cleanup -#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT) +#if (defined WINDOWS_VST_SUPPORT || defined LXVST_SUPPORT || defined MACVST_SUPPORT) { string fn = Glib::build_filename (ARDOUR::user_cache_directory(), VST_BLACKLIST); if (Glib::file_test (fn, Glib::FILE_TEST_EXISTS)) { @@ -437,11 +476,7 @@ 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()); - } + AUPluginInfo::clear_cache (); #endif } @@ -456,6 +491,32 @@ PluginManager::clear_au_blacklist () #endif } +void +PluginManager::lua_refresh () +{ + if (_lua_plugin_info) { + _lua_plugin_info->clear (); + } else { + _lua_plugin_info = new ARDOUR::PluginInfoList (); + } + ARDOUR::LuaScriptList & _scripts (LuaScripting::instance ().scripts (LuaScriptInfo::DSP)); + for (LuaScriptList::const_iterator s = _scripts.begin(); s != _scripts.end(); ++s) { + LuaPluginInfoPtr lpi (new LuaPluginInfo(*s)); + _lua_plugin_info->push_back (lpi); + } +} + +void +PluginManager::lua_refresh_cb () +{ + Glib::Threads::Mutex::Lock lm (_lock, Glib::Threads::TRY_LOCK); + if (!lm.locked()) { + return; + } + lua_refresh (); + PluginListChanged (); /* EMIT SIGNAL */ +} + void PluginManager::ladspa_refresh () { @@ -508,6 +569,12 @@ PluginManager::add_windows_vst_presets() add_presets ("windows-vst"); } +void +PluginManager::add_mac_vst_presets() +{ + add_presets ("mac-vst"); +} + void PluginManager::add_lxvst_presets() { @@ -586,6 +653,11 @@ PluginManager::ladspa_discover (string path) DEBUG_TRACE (DEBUG::PluginManager, string_compose ("LADSPA plugin found at %1\n", path)); for (uint32_t i = 0; ; ++i) { + /* if a ladspa plugin allocates memory here + * it is never free()ed (or plugin-dependent only when unloading). + * For some plugins memory allocated is incremental, we should + * avoid re-scanning plugins and file bug reports. + */ if ((descriptor = dfunc (i)) == 0) { break; } @@ -774,11 +846,16 @@ PluginManager::windows_vst_discover_from_path (string path, bool cache_only) DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Discovering Windows VST plugins along %1\n", path)); + if (Session::get_disable_all_loaded_plugins ()) { + info << _("Disabled WindowsVST scan (safe mode)") << endmsg; + return -1; + } + 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); + find_files_matching_filter (plugin_objects, path, windows_vst_filter, 0, false, true, true); for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) { ARDOUR::PluginScanMessage(_("VST"), *x, !cache_only && !cancelled()); @@ -944,6 +1021,117 @@ PluginManager::windows_vst_discover (string path, bool cache_only) #endif // WINDOWS_VST_SUPPORT +#ifdef MACVST_SUPPORT +void +PluginManager::mac_vst_refresh (bool cache_only) +{ + if (_mac_vst_plugin_info) { + _mac_vst_plugin_info->clear (); + } else { + _mac_vst_plugin_info = new ARDOUR::PluginInfoList(); + } + + mac_vst_discover_from_path ("~/Library/Audio/Plug-Ins/VST:/Library/Audio/Plug-Ins/VST", cache_only); +} + +static bool mac_vst_filter (const string& str, void *) +{ + if (!Glib::file_test (str, Glib::FILE_TEST_IS_DIR)) { + return false; + } + string plist = Glib::build_filename (str, "Contents", "Info.plist"); + if (!Glib::file_test (plist, Glib::FILE_TEST_IS_REGULAR)) { + return false; + } + return str[0] != '.' && str.length() > 4 && strings_equal_ignore_case (".vst", str.substr(str.length() - 4)); +} + +int +PluginManager::mac_vst_discover_from_path (string path, bool cache_only) +{ + vector plugin_objects; + vector::iterator x; + + if (Session::get_disable_all_loaded_plugins ()) { + info << _("Disabled MacVST scan (safe mode)") << endmsg; + return -1; + } + + find_paths_matching_filter (plugin_objects, path, mac_vst_filter, 0, true, true, true); + + for (x = plugin_objects.begin(); x != plugin_objects.end (); ++x) { + ARDOUR::PluginScanMessage(_("MacVST"), *x, !cache_only && !cancelled()); + mac_vst_discover (*x, cache_only || cancelled()); + } + return 0; +} + +int +PluginManager::mac_vst_discover (string path, bool cache_only) +{ + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("checking apparent MacVST plugin at %1\n", path)); + + _cancel_timeout = false; + + vector* finfos = vstfx_get_info_mac (const_cast (path.c_str()), + cache_only ? VST_SCAN_CACHE_ONLY : VST_SCAN_USE_APP); + + if (finfos->empty()) { + DEBUG_TRACE (DEBUG::PluginManager, string_compose ("Cannot get Mac VST information from '%1'\n", path)); + return -1; + } + + uint32_t discovered = 0; + for (vector::iterator x = finfos->begin(); x != finfos->end(); ++x) { + VSTInfo* finfo = *x; + char buf[32]; + + if (!finfo->canProcessReplacing) { + warning << string_compose (_("Mac VST plugin %1 does not support processReplacing, and so cannot be used in %2 at this time"), + finfo->name, PROGRAM_NAME) + << endl; + continue; + } + + PluginInfoPtr info (new MacVSTPluginInfo); + + info->name = finfo->name; + + snprintf (buf, sizeof (buf), "%d", finfo->UniqueID); + info->unique_id = buf; + info->category = "MacVST"; + info->path = path; + info->creator = finfo->creator; + 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) ? 1 : 0); + info->n_outputs.set_midi ((finfo->wantMidi&2) ? 1 : 0); + info->type = ARDOUR::MacVST; + + bool duplicate = false; + if (!_mac_vst_plugin_info->empty()) { + for (PluginInfoList::iterator i =_mac_vst_plugin_info->begin(); i != _mac_vst_plugin_info->end(); ++i) { + if ((info->type == (*i)->type)&&(info->unique_id == (*i)->unique_id)) { + warning << "Ignoring duplicate Mac VST plugin " << info->name << "\n"; + duplicate = true; + break; + } + } + } + + if (!duplicate) { + _mac_vst_plugin_info->push_back (info); + discovered++; + } + } + + vstfx_free_info_list (finfos); + return discovered > 0 ? 0 : -1; +} + +#endif // MAC_VST_SUPPORT + #ifdef LXVST_SUPPORT void @@ -972,6 +1160,11 @@ PluginManager::lxvst_discover_from_path (string path, bool cache_only) vector::iterator x; int ret = 0; + if (Session::get_disable_all_loaded_plugins ()) { + info << _("Disabled LinuxVST scan (safe mode)") << endmsg; + return -1; + } + #ifndef NDEBUG (void) path; #endif @@ -1068,7 +1261,7 @@ PluginManager::lxvst_discover (string path, bool cache_only) PluginManager::PluginStatusType -PluginManager::get_status (const PluginInfoPtr& pi) +PluginManager::get_status (const PluginInfoPtr& pi) const { PluginStatus ps (pi->type, pi->unique_id); PluginStatusList::const_iterator i = find (statuses.begin(), statuses.end(), ps); @@ -1102,9 +1295,11 @@ PluginManager::save_statuses () case LXVST: ofs << "LXVST"; break; + case MacVST: + ofs << "MacVST"; + break; case Lua: - assert (0); - continue; + ofs << "Lua"; break; } @@ -1192,6 +1387,10 @@ PluginManager::load_statuses () type = Windows_VST; } else if (stype == "LXVST") { type = LXVST; + } else if (stype == "MacVST") { + type = MacVST; + } else if (stype == "Lua") { + type = Lua; } else { error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype) << endmsg; @@ -1217,7 +1416,7 @@ PluginManager::set_status (PluginType t, string id, PluginStatusType status) statuses.insert (ps); } -ARDOUR::PluginInfoList& +const ARDOUR::PluginInfoList& PluginManager::windows_vst_plugin_info () { #ifdef WINDOWS_VST_SUPPORT @@ -1230,7 +1429,18 @@ PluginManager::windows_vst_plugin_info () #endif } -ARDOUR::PluginInfoList& +const ARDOUR::PluginInfoList& +PluginManager::mac_vst_plugin_info () +{ +#ifdef MACVST_SUPPORT + assert(_mac_vst_plugin_info); + return *_mac_vst_plugin_info; +#else + return _empty_plugin_info; +#endif +} + +const ARDOUR::PluginInfoList& PluginManager::lxvst_plugin_info () { #ifdef LXVST_SUPPORT @@ -1241,14 +1451,14 @@ PluginManager::lxvst_plugin_info () #endif } -ARDOUR::PluginInfoList& +const ARDOUR::PluginInfoList& PluginManager::ladspa_plugin_info () { assert(_ladspa_plugin_info); return *_ladspa_plugin_info; } -ARDOUR::PluginInfoList& +const ARDOUR::PluginInfoList& PluginManager::lv2_plugin_info () { #ifdef LV2_SUPPORT @@ -1259,7 +1469,7 @@ PluginManager::lv2_plugin_info () #endif } -ARDOUR::PluginInfoList& +const ARDOUR::PluginInfoList& PluginManager::au_plugin_info () { #ifdef AUDIOUNIT_SUPPORT @@ -1269,3 +1479,10 @@ PluginManager::au_plugin_info () #endif return _empty_plugin_info; } + +const ARDOUR::PluginInfoList& +PluginManager::lua_plugin_info () +{ + assert(_lua_plugin_info); + return *_lua_plugin_info; +}