X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=libs%2Fardour%2Fplugin_manager.cc;h=596acadf6cd24af8c20c17fda788d6f7d6c7e641;hb=8b93fb02f38148c25c91ed41a4f12735be38dbf0;hp=cccc1635f1727a9f51a19263e088a984e0b8a9a2;hpb=d1d5f7f311c094339d7014408dc8bd550662b398;p=ardour.git diff --git a/libs/ardour/plugin_manager.cc b/libs/ardour/plugin_manager.cc index cccc1635f1..596acadf6c 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,18 @@ 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); + } +#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 +410,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 +457,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 +472,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 +487,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 +565,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 +649,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; } @@ -778,7 +846,7 @@ PluginManager::windows_vst_discover_from_path (string path, bool cache_only) 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()); @@ -801,52 +869,53 @@ static std::string dll_info (std::string path) { int fd = g_open(path.c_str(), O_RDONLY, 0444); if (fd < 0) { - return _("- cannot open dll"); // TODO strerror() + return _("cannot open dll"); // TODO strerror() } if (68 != read (fd, buf, 68)) { - rv = _("- invalid dll, file too small"); + rv = _("invalid dll, file too small"); goto errorout; } if (buf[0] != 'M' && buf[1] != 'Z') { - rv = _("- not a dll"); + rv = _("not a dll"); goto errorout; } pe_hdr_off = *((int32_t*) &buf[60]); if (pe_hdr_off !=lseek (fd, pe_hdr_off, SEEK_SET)) { - rv = _("- cannot determine dll type"); + rv = _("cannot determine dll type"); goto errorout; } if (6 != read (fd, buf, 6)) { - rv = _("- cannot read dll PE header"); + rv = _("cannot read dll PE header"); goto errorout; } if (buf[0] != 'P' && buf[1] != 'E') { - rv = _("- invalid dll PE header"); + rv = _("invalid dll PE header"); goto errorout; } type = *((uint16_t*) &buf[4]); switch (type) { case 0x014c: - rv = _("- i386 (32bit)"); + rv = _("i386 (32-bit)"); break; case 0x0200: - rv = _("- Itanium"); + rv = _("Itanium"); break; case 0x8664: - rv = _("- x64 (64bit)"); + rv = _("x64 (64-bit)"); break; case 0: - rv = _("- Native Architecture"); + rv = _("Native Architecture"); break; default: - rv = _("- Unknown Architecture"); + rv = _("Unknown Architecture"); break; } errorout: + assert (rv.length() > 0); close (fd); return rv; } @@ -860,7 +929,7 @@ PluginManager::windows_vst_discover (string path, bool cache_only) if (cache_only) { info << string_compose (_(" * %1 (cache only)"), path) << endmsg; } else { - info << string_compose (_(" * %1 %2"), path, dll_info (path)) << endmsg; + info << string_compose (_(" * %1 - %2"), path, dll_info (path)) << endmsg; } } @@ -943,6 +1012,112 @@ 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; + + find_paths_matching_filter (plugin_objects, path, mac_vst_filter, 0, true, true, false); + + 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 @@ -1101,6 +1276,12 @@ PluginManager::save_statuses () case LXVST: ofs << "LXVST"; break; + case MacVST: + ofs << "MacVST"; + break; + case Lua: + ofs << "Lua"; + break; } ofs << ' '; @@ -1122,6 +1303,7 @@ PluginManager::save_statuses () ofs << endl; } g_file_set_contents (path.c_str(), ofs.str().c_str(), -1, NULL); + PluginStatusesChanged (); /* EMIT SIGNAL */ } void @@ -1186,6 +1368,8 @@ PluginManager::load_statuses () type = Windows_VST; } else if (stype == "LXVST") { type = LXVST; + } else if (stype == "Lua") { + type = Lua; } else { error << string_compose (_("unknown plugin type \"%1\" - ignored"), stype) << endmsg; @@ -1224,6 +1408,17 @@ PluginManager::windows_vst_plugin_info () #endif } +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 +} + ARDOUR::PluginInfoList& PluginManager::lxvst_plugin_info () { @@ -1263,3 +1458,10 @@ PluginManager::au_plugin_info () #endif return _empty_plugin_info; } + +ARDOUR::PluginInfoList& +PluginManager::lua_plugin_info () +{ + assert(_lua_plugin_info); + return *_lua_plugin_info; +}