From 674b4ec0dbcadc6b0cb71cbded666dc72469170e Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Thu, 7 Jan 2016 20:35:28 +0100 Subject: [PATCH] discover AU presets without instantiating plugin --- libs/ardour/ardour/audio_unit.h | 2 + libs/ardour/audio_unit.cc | 90 ++++++++++++++++++++++++++++++--- 2 files changed, 86 insertions(+), 6 deletions(-) diff --git a/libs/ardour/ardour/audio_unit.h b/libs/ardour/ardour/audio_unit.h index 85be9b7cfa..c495f010b3 100644 --- a/libs/ardour/ardour/audio_unit.h +++ b/libs/ardour/ardour/audio_unit.h @@ -232,6 +232,8 @@ class LIBARDOUR_API AUPluginInfo : public PluginInfo { PluginPtr load (Session& session); + virtual std::vector get_presets(Session& session); + bool needs_midi_input (); bool is_effect () const; bool is_effect_without_midi_input () const; diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index d3597989ed..65590582cb 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -2124,16 +2124,16 @@ static bool au_preset_filter (const string& str, void* arg) include "/" in their path. */ - Plugin* p = (Plugin *) arg; - string match = p->maker(); + AUPluginInfo* p = (AUPluginInfo *) arg; + string match = p->creator; match += '/'; - match += p->name(); + match += p->name; ret = str.find (match) != string::npos; if (ret == false) { - string m = p->maker (); - string n = p->name (); + string m = p->creator; + string n = p->name; strip_whitespace_edges (m); strip_whitespace_edges (n); match = m; @@ -2285,7 +2285,10 @@ AUPlugin::find_presets () user_preset_map.clear (); - find_files_matching_filter (preset_files, preset_search_path, au_preset_filter, this, true, true, true); + PluginInfoPtr nfo = get_info(); + find_files_matching_filter (preset_files, preset_search_path, au_preset_filter, + boost::dynamic_pointer_cast (nfo).get(), + true, true, true); if (preset_files.empty()) { DEBUG_TRACE (DEBUG::AudioUnits, "AU No Preset Files found for given plugin.\n"); @@ -2380,6 +2383,81 @@ AUPluginInfo::load (Session& session) } } +std::vector +AUPluginInfo::get_presets(Session& session) +{ + std::vector p; + boost::shared_ptr comp; +#ifndef NO_PLUGIN_STATE + try { + comp = boost::shared_ptr(new CAComponent(*descriptor)); + if (!comp->IsValid()) { + throw failed_constructor(); + } + } catch (failed_constructor& err) { + return p; + } + + // user presets + + if (!preset_search_path_initialized) { + Glib::ustring p = Glib::get_home_dir(); + p += "/Library/Audio/Presets:"; + p += preset_search_path; + preset_search_path = p; + preset_search_path_initialized = true; + DEBUG_TRACE (DEBUG::AudioUnits, string_compose("AU Preset Path: %1\n", preset_search_path)); + } + + vector preset_files; + find_files_matching_filter (preset_files, preset_search_path, au_preset_filter, this, true, true, true); + + for (vector::iterator x = preset_files.begin(); x != preset_files.end(); ++x) { + string path = *x; + string preset_name; + preset_name = Glib::path_get_basename (path); + preset_name = preset_name.substr (0, preset_name.find_last_of ('.')); + if (check_and_get_preset_name (comp.get()->Comp(), path, preset_name)) { + p.push_back (Plugin::PresetRecord (path, preset_name)); + } + } + + // factory presets + + CFArrayRef presets; + UInt32 dataSize; + Boolean isWritable; + + boost::shared_ptr unit (new CAAudioUnit); + if (noErr != CAAudioUnit::Open (*(comp.get()), *unit)) { + return p; + } + if (noErr != unit->GetPropertyInfo (kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, &dataSize, &isWritable)) { + unit->Uninitialize (); + return p; + } + if (noErr != unit->GetProperty (kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, (void*) &presets, &dataSize)) { + unit->Uninitialize (); + return p; + } + if (!presets) { + unit->Uninitialize (); + return p; + } + + CFIndex cnt = CFArrayGetCount (presets); + for (CFIndex i = 0; i < cnt; ++i) { + AUPreset* preset = (AUPreset*) CFArrayGetValueAtIndex (presets, i); + string const uri = string_compose ("%1", i); + string name = CFStringRefToStdString (preset->presetName); + p.push_back (Plugin::PresetRecord (uri, name, false)); + } + CFRelease (presets); + unit->Uninitialize (); +#endif // NO_PLUGIN_STATE + return p; +} + Glib::ustring AUPluginInfo::au_cache_path () {