handle AU Factory presets along with user presets 2.8.3
authorPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Oct 2009 13:48:40 +0000 (13:48 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Fri, 9 Oct 2009 13:48:40 +0000 (13:48 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@5763 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/ardour/SConscript
libs/ardour/ardour/audio_unit.h
libs/ardour/audio_unit.cc

index 1d96fd0777d927b3f9cfe52cb28ddb539db1ee6c..06242d3618ebe12ec6a8236de2255070cbfb0c37 100644 (file)
@@ -327,6 +327,7 @@ sse_env = ardour.Clone()
 sse_env.Append (CXXFLAGS="-msse")
 
 if env['FPU_OPTIMIZATION']:
+       print "FPU OPTIMIZATION WITH TARGET "; print env['DIST_TARGET'];
        if env['DIST_TARGET'] == "i386":
                arch_specific_objects = env.SharedAsmObject('sse_functions.os', 'sse_functions.s')
                always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ]
@@ -336,6 +337,8 @@ if env['FPU_OPTIMIZATION']:
        if env['DIST_TARGET'] == "x86_64":
                arch_specific_objects = env.SharedAsmObject('sse_functions_64bit.os', 'sse_functions_64bit.s')
                always_sse_objects += [ sse_env.SharedObject (source = 'sse_functions_xmm.cc') ]
+else:
+       print "No FPU OPTIMIZATION here!!!\n"
                        
 libardour = ardour.SharedLibrary('ardour', ardour_files + always_sse_objects + timefx_sources + extra_sources + arch_specific_objects)
 
index 50c7c5fcbca5522a370826ee6621228554d70bb1..ec9c82a6630bf6759c32412b028706c87b4f1f83 100644 (file)
@@ -33,6 +33,7 @@
 #include <ardour/plugin.h>
 
 #include <AudioUnit/AudioUnit.h>
+#include <AudioUnit/AudioUnitProperties.h>
 #include <appleutility/AUParamInfo.h>
 
 #include <boost/shared_ptr.hpp>
@@ -124,10 +125,18 @@ class AUPlugin : public ARDOUR::Plugin
        std::vector<std::pair<int,int> > io_configs;
        AudioBufferList* buffers;
 
-       /* XXX this should really be shared across all AUPlugin instances */
+       /* despite all the cool work that apple did on their AU preset
+          system, they left factory presets and user presets as two
+          entirely different kinds of things, handled by two entirely
+          different parts of the API. Resolve this.
+       */
 
-       typedef std::map<std::string,std::string> PresetMap;
-       PresetMap preset_map;
+       /* XXX these two maps should really be shared across all instances of this AUPlugin */
+
+       typedef std::map<std::string,std::string> UserPresetMap;
+       UserPresetMap user_preset_map;
+       typedef std::map<std::string,int> FactoryPresetMap;
+       FactoryPresetMap factory_preset_map;
 
        UInt32 global_elements;
        UInt32 output_elements;
@@ -148,6 +157,8 @@ class AUPlugin : public ARDOUR::Plugin
        
        std::vector<AUParameterDescriptor> descriptors;
        void init ();
+
+       void discover_factory_presets ();
 };
        
 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
index 6692e90d247b12388547ca70eca64670de08d486..0cd21b90ee344c6857cc3d225238a2e4c189fab3 100644 (file)
@@ -111,7 +111,7 @@ save_property_list (CFPropertyListRef propertyList, Glib::ustring path)
 
        size_t cnt = CFDataGetLength (xmlData);
 
-       if (write (fd, CFDataGetBytePtr (xmlData), cnt) != cnt) {
+       if (write (fd, CFDataGetBytePtr (xmlData), cnt) != (ssize_t) cnt) {
                CFRelease (xmlData);
                close (fd);
                return -1;
@@ -328,6 +328,35 @@ AUPlugin::~AUPlugin ()
        }
 }
 
+void
+AUPlugin::discover_factory_presets ()
+{
+       CFArrayRef presets;
+       UInt32 dataSize = 0;
+       OSStatus err = unit->GetPropertyInfo (kAudioUnitProperty_FactoryPresets,
+                                             kAudioUnitScope_Global, 0,
+                                             &dataSize, NULL);
+       if (err || !dataSize) {
+               /* no presets? */
+               return;
+       }
+
+       dataSize = sizeof (presets);
+
+       if ((err = unit->GetProperty (kAudioUnitProperty_FactoryPresets, kAudioUnitScope_Global, 0, (void*) &presets, &dataSize)) != 0) {
+               cerr << "cannot get factory preset info: " << err << endl;
+               return;
+       }
+
+       CFIndex cnt = CFArrayGetCount (presets);
+
+       for (CFIndex i = 0; i < cnt; ++i) {
+               AUPreset* preset = (AUPreset*) CFArrayGetValueAtIndex (presets, i);
+
+               string name = CFStringRefToStdString (preset->presetName);
+               factory_preset_map[name] = preset->presetNumber;
+       }
+}
 
 void
 AUPlugin::init ()
@@ -374,6 +403,7 @@ AUPlugin::init ()
        }
 
        discover_parameters ();
+       discover_factory_presets ();
 
        Plugin::setup_controls ();
 }
@@ -1097,18 +1127,34 @@ AUPlugin::load_preset (const string preset_label)
        bool ret = false;
        CFPropertyListRef propertyList;
        Glib::ustring path;
-       PresetMap::iterator x = preset_map.find (preset_label);
+       UserPresetMap::iterator ux;
+       FactoryPresetMap::iterator fx;
 
-       if (x == preset_map.end()) {
-               return false;
-       }
+       /* look first in "user" presets */
+
+       if ((ux = user_preset_map.find (preset_label)) != user_preset_map.end()) {
        
-       if ((propertyList = load_property_list (x->second)) != 0) {
-               if (unit->SetAUPreset (propertyList) == noErr) {
+               if ((propertyList = load_property_list (ux->second)) != 0) {
+                       if (unit->SetAUPreset (propertyList) == noErr) {
+                               ret = true;
+                       }
+                       CFRelease(propertyList);
+               }
+
+       } else if ((fx = factory_preset_map.find (preset_label)) != factory_preset_map.end()) {
+               
+               AUPreset preset;
+               
+               preset.presetNumber = fx->second;
+               preset.presetName = CFStringCreateWithCString (kCFAllocatorDefault, fx->first.c_str(), kCFStringEncodingUTF8);
+               
+               cerr << "Setting factory preset " << fx->second << endl;
+
+               if (unit->SetPresentPreset (preset) == 0) {
                        ret = true;
                }
-               CFRelease(propertyList);
        }
+
        
        return ret;
 #else
@@ -1360,10 +1406,14 @@ AUPlugin::current_preset() const
 vector<string>
 AUPlugin::get_presets ()
 {
-       vector<string*>* preset_files;
        vector<string> presets;
+
+#ifdef AU_STATE_SUPPORT
+       vector<string*>* preset_files;
        PathScanner scanner;
 
+       user_preset_map.clear ();
+
        preset_files = scanner (preset_search_path, au_preset_filter, this, true, true, -1, true);
        
        if (!preset_files) {
@@ -1386,14 +1436,27 @@ AUPlugin::get_presets ()
                */
 
                if (check_and_get_preset_name (get_comp()->Comp(), path, preset_name)) {
-                       presets.push_back (preset_name);
-                       preset_map[preset_name] = path;
+                       user_preset_map[preset_name] = path;
                } 
 
                delete *x;
        }
 
        delete preset_files;
+
+        /* now fill the vector<string> with the names we have */
+
+       for (UserPresetMap::iterator i = user_preset_map.begin(); i != user_preset_map.end(); ++i) {
+               presets.push_back (i->first);
+       }
+
+        /* add factory presets */
+
+       for (FactoryPresetMap::iterator i = factory_preset_map.begin(); i != factory_preset_map.end(); ++i) {
+               presets.push_back (i->first);
+       }
+
+#endif
        
        return presets;
 }