rework AU scanning/discovery
authorRobin Gareus <robin@gareus.org>
Thu, 16 Jul 2015 14:32:38 +0000 (16:32 +0200)
committerRobin Gareus <robin@gareus.org>
Thu, 16 Jul 2015 14:54:57 +0000 (16:54 +0200)
Scan-only: â€œIterate over all plugins. skip the ones where there's no
 io-cache entry

Discover: cache new plugins info, update cache if needed.

libs/ardour/ardour/audio_unit.h
libs/ardour/audio_unit.cc
libs/ardour/plugin_manager.cc

index 13b16827cba6150adcbbbeb1af9c93866dc1b72b..8fcdcf75a46b6bd77773c97bbc42b550d3e9184f 100644 (file)
@@ -241,7 +241,7 @@ class LIBARDOUR_API AUPluginInfo : public PluginInfo {
 
        bool reconfigurable_io() const { return true; }
 
-       static PluginInfoList* discover ();
+       static PluginInfoList* discover (bool scan_only);
        static bool au_get_crashlog (std::string &msg);
        static void get_names (CAComponentDescription&, std::string& name, std::string& maker);
        static std::string stringify_descriptor (const CAComponentDescription&);
@@ -252,6 +252,7 @@ class LIBARDOUR_API AUPluginInfo : public PluginInfo {
        boost::shared_ptr<CAComponentDescription> descriptor;
        UInt32 version;
        static FILE * _crashlog_fd;
+       static bool _scan_only;
 
        static void au_start_crashlog (void);
        static void au_remove_crashlog (void);
@@ -267,7 +268,7 @@ class LIBARDOUR_API AUPluginInfo : public PluginInfo {
        typedef std::map<std::string,AUPluginCachedInfo> CachedInfoMap;
        static CachedInfoMap cached_info;
 
-       static bool cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
+       static int cached_io_configuration (const std::string&, UInt32, CAComponent&, AUPluginCachedInfo&, const std::string& name);
        static void add_cached_info (const std::string&, AUPluginCachedInfo&);
        static void save_cached_info ();
 };
index 4b9a81eb9f3aa2869bb93e488708bb047c8de639..2ce4b763c3e03b08964597c3f4d9cc56a8b0bae9 100644 (file)
@@ -73,6 +73,7 @@ static string preset_search_path = "/Library/Audio/Presets:/Network/Library/Audi
 static string preset_suffix = ".aupreset";
 static bool preset_search_path_initialized = false;
 FILE * AUPluginInfo::_crashlog_fd = NULL;
+bool AUPluginInfo::_scan_only = true;
 
 
 static void au_blacklist (std::string id)
@@ -2277,10 +2278,19 @@ AUPluginInfo::au_cache_path ()
 }
 
 PluginInfoList*
-AUPluginInfo::discover ()
+AUPluginInfo::discover (bool scan_only)
 {
        XMLTree tree;
 
+       /* 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).
+        * 
+        * "Scan Only" means
+        * "Iterate over all plugins. skip the ones where there's no io-cache".
+        */
+       _scan_only = scan_only;
+
        if (!Glib::file_test (au_cache_path(), Glib::FILE_TEST_EXISTS)) {
                ARDOUR::BootMessage (_("Discovering AudioUnit plugins (could take some time ...)"));
        }
@@ -2498,8 +2508,9 @@ AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescrip
                        info->version = 0;
                }
 
-               if (cached_io_configuration (info->unique_id, info->version, cacomp, info->cache, info->name)) {
+               const int rv = cached_io_configuration (info->unique_id, info->version, cacomp, info->cache, info->name);
 
+               if (rv == 0) {
                        /* here we have to map apple's wildcard system to a simple pair
                           of values. in ::can_do() we use the whole system, but here
                           we need a single pair of values. XXX probably means we should
@@ -2533,7 +2544,8 @@ AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescrip
 
                        plugs.push_back (info);
 
-               } else {
+               }
+               else if (rv == -1) {
                        error << string_compose (_("Cannot get I/O configuration info for AU %1"), info->name) << endmsg;
                }
 
@@ -2545,7 +2557,7 @@ AUPluginInfo::discover_by_description (PluginInfoList& plugs, CAComponentDescrip
        au_crashlog(string_compose("End AU discovery for Type: %1", (int)desc.componentType));
 }
 
-bool
+int
 AUPluginInfo::cached_io_configuration (const std::string& unique_id,
                                       UInt32 version,
                                       CAComponent& comp,
@@ -2569,7 +2581,12 @@ AUPluginInfo::cached_io_configuration (const std::string& unique_id,
 
        if (cim != cached_info.end()) {
                cinfo = cim->second;
-               return true;
+               return 0;
+       }
+
+       if (_scan_only) {
+               PBD::info << string_compose (_("Skipping AU %1 (not indexed. Discover new plugins to add)"), unique_id) << endmsg;
+               return 1;
        }
 
        CAAudioUnit unit;
@@ -2582,19 +2599,19 @@ AUPluginInfo::cached_io_configuration (const std::string& unique_id,
        try {
 
                if (CAAudioUnit::Open (comp, unit) != noErr) {
-                       return false;
+                       return -1;
                }
 
        } catch (...) {
 
                warning << string_compose (_("Could not load AU plugin %1 - ignored"), name) << endmsg;
-               return false;
+               return -1;
 
        }
 
        DEBUG_TRACE (DEBUG::AudioUnits, "get AU channel info\n");
        if ((ret = unit.GetChannelInfo (&channel_info, cnt)) < 0) {
-               return false;
+               return -1;
        }
 
        if (ret > 0) {
@@ -2620,7 +2637,7 @@ AUPluginInfo::cached_io_configuration (const std::string& unique_id,
        add_cached_info (id, cinfo);
        save_cached_info ();
 
-       return true;
+       return 0;
 }
 
 void
index 458f7e15470e171c7f145811e096e71f79facc09..2b84c22fe7396c09a77fa003221d624d3ec33ed4 100644 (file)
@@ -639,31 +639,17 @@ void
 PluginManager::au_refresh (bool cache_only)
 {
        DEBUG_TRACE (DEBUG::PluginManager, "AU: refresh\n");
-       if (cache_only && !Config->get_discover_audio_units ()) {
-               return;
-       }
-       delete _au_plugin_info;
-       _au_plugin_info = AUPluginInfo::discover();
 
-       // disable automatic scan in case we crash
+       // disable automatic discovery in case we crash
+       bool discover_at_start = Config->get_discover_audio_units ();
        Config->set_discover_audio_units (false);
        Config->save_state();
 
-       /* 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.
-        */
+       delete _au_plugin_info;
+       _au_plugin_info = AUPluginInfo::discover(cache_only && !discover_at_start);
 
-       // successful scan re-enabled automatic discovery
-       Config->set_discover_audio_units (true);
+       // successful scan re-enabled automatic discovery if it was set
+       Config->set_discover_audio_units (discover_at_start);
        Config->save_state();
 }