discover all AU parameters, map to ardour internal data, make automationt tracks...
authorPaul Davis <paul@linuxaudiosystems.com>
Wed, 13 Feb 2008 04:34:54 +0000 (04:34 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Wed, 13 Feb 2008 04:34:54 +0000 (04:34 +0000)
git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@3046 d708f5d6-7413-0410-9779-e7cbd77b26cf

libs/appleutility/AUParamInfo.cpp [new file with mode: 0644]
libs/appleutility/AUParamInfo.h [new file with mode: 0644]
libs/appleutility/CAAUParameter.cpp [new file with mode: 0644]
libs/appleutility/CAAUParameter.h [new file with mode: 0644]
libs/ardour/ardour/audio_unit.h
libs/ardour/audio_unit.cc
svn_revision.h

diff --git a/libs/appleutility/AUParamInfo.cpp b/libs/appleutility/AUParamInfo.cpp
new file mode 100644 (file)
index 0000000..9b00461
--- /dev/null
@@ -0,0 +1,134 @@
+/*     Copyright:      � Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+       Disclaimer:     IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
+                       ("Apple") in consideration of your agreement to the following terms, and your
+                       use, installation, modification or redistribution of this Apple software
+                       constitutes acceptance of these terms.  If you do not agree with these terms,
+                       please do not use, install, modify or redistribute this Apple software.
+
+                       In consideration of your agreement to abide by the following terms, and subject
+                       to these terms, Apple grants you a personal, non-exclusive license, under Apple�s
+                       copyrights in this original Apple software (the "Apple Software"), to use,
+                       reproduce, modify and redistribute the Apple Software, with or without
+                       modifications, in source and/or binary forms; provided that if you redistribute
+                       the Apple Software in its entirety and without modifications, you must retain
+                       this notice and the following text and disclaimers in all such redistributions of
+                       the Apple Software.  Neither the name, trademarks, service marks or logos of
+                       Apple Computer, Inc. may be used to endorse or promote products derived from the
+                       Apple Software without specific prior written permission from Apple.  Except as
+                       expressly stated in this notice, no other rights or licenses, express or implied,
+                       are granted by Apple herein, including but not limited to any patent rights that
+                       may be infringed by your derivative works or by other works in which the Apple
+                       Software may be incorporated.
+
+                       The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+                       WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+                       WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+                       PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+                       COMBINATION WITH YOUR PRODUCTS.
+
+                       IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+                       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+                       GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+                       ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+                       OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+                       (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+                       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+       AUParamInfo.cpp
+       
+=============================================================================*/
+#include "AUParamInfo.h"
+#include "CAXException.h"
+
+AUParamInfo::AUParamInfo (AudioUnit                            inAU, 
+                                                       bool                            inIncludeExpert, 
+                                                       bool                            inIncludeReadOnly,
+                                                       AudioUnitScope          inScope,
+                                                       AudioUnitElement        inElement)
+       : mAU (inAU),
+         mNumParams (0),
+         mParamListID(NULL),
+         mScope (inScope),
+         mElement (inElement)
+{
+       UInt32 size;
+       OSStatus result = AudioUnitGetPropertyInfo(mAU, kAudioUnitProperty_ParameterList, inScope, mElement, &size, NULL);
+               if (size == 0 || result) return;
+       
+       int nparams = size / sizeof(AudioUnitPropertyID);
+       mParamListID = new AudioUnitParameterID[nparams];
+
+       memset (mParamListID, 0xFF, size);
+
+       AudioUnitParameterID *paramList = new AudioUnitParameterID[nparams];
+       
+       result = AudioUnitGetProperty(mAU, kAudioUnitProperty_ParameterList, mScope, mElement, paramList, &size);
+       if (result) {
+               delete [] mParamListID;
+               delete [] paramList;
+               mParamListID = NULL;
+               return;
+       }
+       
+       ParameterMap params;
+       for (int i = 0; i < nparams; ++i) 
+       {
+               CAAUParameter auvp (mAU, paramList[i], mScope, mElement); // took out only using global scope in CAAUParameter creation
+               const AudioUnitParameterInfo &paramInfo = auvp.ParamInfo();
+                       
+               //      don't include if parameter can't be read or written
+               if (!(paramInfo.flags & kAudioUnitParameterFlag_IsWritable) 
+                       && !(paramInfo.flags & kAudioUnitParameterFlag_IsReadable))
+                       continue;
+
+               // only include if expert params wanted
+               if (!inIncludeExpert && auvp.IsExpert())
+                       continue;
+               
+               // only include if read only params are wanted
+               if (!(paramInfo.flags & kAudioUnitParameterFlag_IsWritable) 
+                       && (paramInfo.flags & kAudioUnitParameterFlag_IsReadable))
+               {       
+                       if (!inIncludeReadOnly)
+                               continue;
+               }
+               
+               mParamListID[mNumParams] = paramList[i];
+               mNumParams++;
+               
+               // ok - if we're here, then we have a parameter we are going to display.
+               UInt32 clump = 0;
+               auvp.GetClumpID (clump);
+               mParams[clump].push_back (auvp);
+       }
+
+       delete [] paramList;
+}
+
+AUParamInfo::~AUParamInfo()
+{
+       delete [] mParamListID;
+}
+
+UInt32                 AUParamInfo::NumParamsForClump (UInt32 inClump) const
+{ 
+       ParameterMap::const_iterator it = mParams.find(inClump);
+       if (it != mParams.end()) 
+               return (*it).second.size();
+       return 0;
+}
+
+const CAAUParameter*   AUParamInfo::GetParamInfo (AudioUnitParameterID inParamID) const
+{
+       for (ParameterMap::const_iterator it = mParams.begin(); it != mParams.end(); ++it) {
+               const ParameterList &list = (*it).second;
+               for (ParameterList::const_iterator iter = list.begin(); iter != list.end(); ++iter) {
+                       if (inParamID == (*iter).mParameterID) {
+                               return &(*iter);
+                       }
+               }
+       }
+       return NULL;
+}
diff --git a/libs/appleutility/AUParamInfo.h b/libs/appleutility/AUParamInfo.h
new file mode 100644 (file)
index 0000000..9d34208
--- /dev/null
@@ -0,0 +1,107 @@
+/*     Copyright:      � Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+       Disclaimer:     IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
+                       ("Apple") in consideration of your agreement to the following terms, and your
+                       use, installation, modification or redistribution of this Apple software
+                       constitutes acceptance of these terms.  If you do not agree with these terms,
+                       please do not use, install, modify or redistribute this Apple software.
+
+                       In consideration of your agreement to abide by the following terms, and subject
+                       to these terms, Apple grants you a personal, non-exclusive license, under Apple�s
+                       copyrights in this original Apple software (the "Apple Software"), to use,
+                       reproduce, modify and redistribute the Apple Software, with or without
+                       modifications, in source and/or binary forms; provided that if you redistribute
+                       the Apple Software in its entirety and without modifications, you must retain
+                       this notice and the following text and disclaimers in all such redistributions of
+                       the Apple Software.  Neither the name, trademarks, service marks or logos of
+                       Apple Computer, Inc. may be used to endorse or promote products derived from the
+                       Apple Software without specific prior written permission from Apple.  Except as
+                       expressly stated in this notice, no other rights or licenses, express or implied,
+                       are granted by Apple herein, including but not limited to any patent rights that
+                       may be infringed by your derivative works or by other works in which the Apple
+                       Software may be incorporated.
+
+                       The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+                       WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+                       WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+                       PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+                       COMBINATION WITH YOUR PRODUCTS.
+
+                       IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+                       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+                       GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+                       ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+                       OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+                       (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+                       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+       AUParamInfo.h
+       
+=============================================================================*/
+#include <map>
+#include <vector>
+#include <AudioUnit/AudioUnit.h>
+#include "CAAUParameter.h"
+
+/*
+       The ParameterMap returned by the Map() method is a map where 
+               - the key is the clumpID
+               - the value is a ParameterList (vector<CAAUParameter>)
+               
+       If you have parameters on multiple scopes (or elements within a scope), then you should create one of these 
+       for each scope-element pair
+*/
+
+class AUParamInfo {
+
+public:
+       typedef std::vector <CAAUParameter> ParameterList;
+       typedef std::map <UInt32, ParameterList, std::less<UInt32> > ParameterMap;
+
+
+
+                                                       AUParamInfo (AudioUnit          inAU, 
+                                                                       bool                            inIncludeExpert, 
+                                                                       bool                            inIncludeReadOnly, 
+                                                                       AudioUnitScope          inScope = kAudioUnitScope_Global,
+                                                                       AudioUnitElement        inElement = 0);
+                                                                       
+                                                       ~AUParamInfo();
+                                                       
+       const ParameterMap&             Map () const { return mParams; }
+       
+       // some convenience methods
+       UInt32                                  NumParams () const { return mNumParams; }
+       
+       AudioUnitParameterID    ParamID (UInt32 inIndex) const 
+                                                       { 
+                                                               if (inIndex < mNumParams) return mParamListID[inIndex]; 
+                                                               return 0xFFFFFFFF; 
+                                                       }
+                                                        
+       UInt32                                  NumClumps () const { return mParams.size(); }
+
+       UInt32                                  NumParamsForClump (UInt32 inClump) const;
+       
+                       // returns NULL if there's no info for the parameter
+       const CAAUParameter*    GetParamInfo (AudioUnitParameterID inParamID) const;
+       
+       AudioUnitScope                  GetScope () const { return mScope; }
+       AudioUnitElement                GetElement () const { return mElement; }
+       
+private:
+
+       AudioUnit                               mAU;
+       UInt32                                  mNumParams;
+       AudioUnitParameterID *  mParamListID;
+       
+       ParameterMap                    mParams;
+       AudioUnitScope                  mScope;
+       AudioUnitElement                mElement;
+               
+               // disallow
+       AUParamInfo () {}
+       AUParamInfo (const AUParamInfo &c) {}
+       AUParamInfo& operator= (const AUParamInfo& c) { return *this; }
+};
diff --git a/libs/appleutility/CAAUParameter.cpp b/libs/appleutility/CAAUParameter.cpp
new file mode 100644 (file)
index 0000000..b99b6ab
--- /dev/null
@@ -0,0 +1,316 @@
+/*     Copyright:      � Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+       Disclaimer:     IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
+                       ("Apple") in consideration of your agreement to the following terms, and your
+                       use, installation, modification or redistribution of this Apple software
+                       constitutes acceptance of these terms.  If you do not agree with these terms,
+                       please do not use, install, modify or redistribute this Apple software.
+
+                       In consideration of your agreement to abide by the following terms, and subject
+                       to these terms, Apple grants you a personal, non-exclusive license, under Apple�s
+                       copyrights in this original Apple software (the "Apple Software"), to use,
+                       reproduce, modify and redistribute the Apple Software, with or without
+                       modifications, in source and/or binary forms; provided that if you redistribute
+                       the Apple Software in its entirety and without modifications, you must retain
+                       this notice and the following text and disclaimers in all such redistributions of
+                       the Apple Software.  Neither the name, trademarks, service marks or logos of
+                       Apple Computer, Inc. may be used to endorse or promote products derived from the
+                       Apple Software without specific prior written permission from Apple.  Except as
+                       expressly stated in this notice, no other rights or licenses, express or implied,
+                       are granted by Apple herein, including but not limited to any patent rights that
+                       may be infringed by your derivative works or by other works in which the Apple
+                       Software may be incorporated.
+
+                       The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+                       WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+                       WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+                       PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+                       COMBINATION WITH YOUR PRODUCTS.
+
+                       IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+                       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+                       GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+                       ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+                       OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+                       (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+                       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+       CAAUParameter.cpp
+       
+=============================================================================*/
+
+#include "CAAUParameter.h"
+
+CAAUParameter::CAAUParameter() 
+{
+       memset(this, 0, sizeof(CAAUParameter));
+}
+
+CAAUParameter::CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
+{
+       memset(this, 0, sizeof(CAAUParameter));
+       Init (au, param, scope, element);
+}
+
+CAAUParameter::CAAUParameter (AudioUnitParameter &inParam)
+{
+       memset(this, 0, sizeof(CAAUParameter));
+       Init (inParam.mAudioUnit, inParam.mParameterID, inParam.mScope, inParam.mElement);
+}
+
+CAAUParameter::CAAUParameter(const CAAUParameter &a) 
+{
+       memset(this, 0, sizeof(CAAUParameter));
+       *this = a;
+}
+
+CAAUParameter &        CAAUParameter::operator = (const CAAUParameter &a)
+{
+       if (mParamName) CFRelease(mParamName);
+       if (mParamTag) CFRelease(mParamTag);
+       if (mNamedParams) CFRelease(mNamedParams);
+       
+       memcpy(this, &a, sizeof(CAAUParameter));
+
+       if (mParamName) CFRetain(mParamName);
+       if (mParamTag) CFRetain(mParamTag);
+       if (mNamedParams) CFRetain(mNamedParams);
+       
+       return *this;
+}
+
+CAAUParameter::~CAAUParameter()
+{
+       if (mParamName) CFRelease(mParamName);
+       if (mParamTag) CFRelease(mParamTag);
+       if (mNamedParams) CFRelease (mNamedParams);
+}
+
+void           CAAUParameter::Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element)
+{
+       mAudioUnit = au;
+       mParameterID = param;
+       mScope = scope;
+       mElement = element;
+       
+       UInt32 propertySize = sizeof(mParamInfo);
+       OSStatus err = AudioUnitGetProperty(au, kAudioUnitProperty_ParameterInfo,
+                       scope, param, &mParamInfo, &propertySize);
+       if (err)
+               memset(&mParamInfo, 0, sizeof(mParamInfo));
+       if (mParamInfo.flags & kAudioUnitParameterFlag_HasCFNameString) {
+               mParamName = mParamInfo.cfNameString;
+               if (!(mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease)) 
+                       CFRetain (mParamName);
+       } else
+               mParamName = CFStringCreateWithCString(NULL, mParamInfo.name, kCFStringEncodingUTF8);
+       
+       char* str = 0;
+       switch (mParamInfo.unit)
+       {
+               case kAudioUnitParameterUnit_Boolean:
+                       str = "T/F";
+                       break;
+               case kAudioUnitParameterUnit_Percent:
+               case kAudioUnitParameterUnit_EqualPowerCrossfade:
+                       str = "%";
+                       break;
+               case kAudioUnitParameterUnit_Seconds:
+                       str = "Secs";
+                       break;
+               case kAudioUnitParameterUnit_SampleFrames:
+                       str = "Samps";
+                       break;
+               case kAudioUnitParameterUnit_Phase:
+               case kAudioUnitParameterUnit_Degrees:
+                       str = "Degr.";
+                       break;
+               case kAudioUnitParameterUnit_Hertz:
+                       str = "Hz";
+                       break;
+               case kAudioUnitParameterUnit_Cents:
+               case kAudioUnitParameterUnit_AbsoluteCents:
+                       str = "Cents";
+                       break;
+               case kAudioUnitParameterUnit_RelativeSemiTones:
+                       str = "S-T";
+                       break;
+               case kAudioUnitParameterUnit_MIDINoteNumber:
+               case kAudioUnitParameterUnit_MIDIController:
+                       str = "MIDI";
+                               //these are inclusive, so add one value here
+                       mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
+                       break;
+               case kAudioUnitParameterUnit_Decibels:
+                       str = "dB";
+                       break;
+               case kAudioUnitParameterUnit_MixerFaderCurve1:
+               case kAudioUnitParameterUnit_LinearGain:
+                       str = "Gain";
+                       break;
+               case kAudioUnitParameterUnit_Pan:
+                       str = "L/R";
+                       break;
+               case kAudioUnitParameterUnit_Meters:
+                       str = "Mtrs";
+                       break;
+               case kAudioUnitParameterUnit_Octaves:
+                       str = "8ve";
+                       break;
+               case kAudioUnitParameterUnit_BPM:
+                       str = "BPM";
+                       break;
+               case kAudioUnitParameterUnit_Beats:
+                       str = "Beats";
+                       break;
+               case kAudioUnitParameterUnit_Milliseconds:
+                       str = "msecs";
+                       break;
+               case kAudioUnitParameterUnit_Ratio:
+                       str = "ratio";
+                       break;
+               case kAudioUnitParameterUnit_Indexed:
+                       {
+                               propertySize = sizeof(mNamedParams);
+                               err = AudioUnitGetProperty (au, 
+                                                                       kAudioUnitProperty_ParameterValueStrings,
+                                                                       scope, 
+                                                                       param, 
+                                                                       &mNamedParams, 
+                                                                       &propertySize);
+                               if (!err && mNamedParams) {
+                                       mNumIndexedParams = CFArrayGetCount(mNamedParams);
+                               } else {
+                                               //these are inclusive, so add one value here
+                                       mNumIndexedParams = short(mParamInfo.maxValue+1 - mParamInfo.minValue);
+                               }
+                               str = NULL;
+                       }
+                       break;
+               case kAudioUnitParameterUnit_CustomUnit:
+               {
+                       CFStringRef unitName = mParamInfo.unitName;
+                       static char paramStr[256];
+                       CFStringGetCString (unitName, paramStr, 256, kCFStringEncodingUTF8);
+                       if (mParamInfo.flags & kAudioUnitParameterFlag_CFNameRelease)
+                               CFRelease (unitName);
+                       str = paramStr;
+                       break;
+               }
+               case kAudioUnitParameterUnit_Generic:
+               case kAudioUnitParameterUnit_Rate:
+               default:
+                       str = NULL;
+                       break;
+       }
+       
+       if (str)
+               mParamTag = CFStringCreateWithCString(NULL, str, kCFStringEncodingUTF8);
+       else
+               mParamTag = NULL;
+}
+
+
+Float32                CAAUParameter::GetValue() const
+{
+       Float32 value = 0.;
+       //OSStatus err = 
+       AudioUnitGetParameter(mAudioUnit, mParameterID, mScope, mElement, &value);
+       return value;
+}
+
+CFStringRef CAAUParameter::GetStringFromValueCopy(const Float32 *value) const
+{
+       if (HasNamedParams())
+       {
+               Float32 val = (value == NULL ? GetValue() : *value);
+               int index = int(mParamInfo.minValue) + int(val);
+               CFStringRef str = GetParamName (index);
+               if (str) {
+                       CFRetain (str);
+                       return str;
+               }
+       }
+       else if (ValuesHaveStrings()) 
+       {
+               AudioUnitParameterStringFromValue stringValue;
+               stringValue.inParamID = mParameterID;
+               stringValue.inValue = value;
+               stringValue.outString = NULL;
+               UInt32 propertySize = sizeof(stringValue);
+               
+               OSStatus err = AudioUnitGetProperty (mAudioUnit, 
+                                                                                       kAudioUnitProperty_ParameterStringFromValue,
+                                                                                       mScope, 
+                                                                                       mParameterID, 
+                                                                                       &stringValue, 
+                                                                                       &propertySize);
+               
+               if (err == noErr && stringValue.outString != NULL)
+                       return stringValue.outString;
+       }
+       
+       Float32 val = (value == NULL ? GetValue() : *value);
+       char valstr[32];
+       AUParameterFormatValue (val, this, valstr, 4);
+       return CFStringCreateWithCString(NULL, valstr, kCFStringEncodingUTF8);
+}
+
+Float32 CAAUParameter::GetValueFromString(CFStringRef str) const
+{
+       if (ValuesHaveStrings()) 
+       {
+               AudioUnitParameterValueFromString valueString;
+               valueString.inParamID = mParameterID;
+               valueString.inString = str;
+               UInt32 propertySize = sizeof(valueString);
+               
+               OSStatus err = AudioUnitGetProperty (mAudioUnit, 
+                                                                               kAudioUnitProperty_ParameterValueFromString,
+                                                                               mScope, 
+                                                                               mParameterID, 
+                                                                               &valueString, 
+                                                                               &propertySize);
+                                                                               
+               if (err == noErr) {
+                       return valueString.outValue;
+               }
+       }
+       
+       Float32 paramValue = mParamInfo.defaultValue;
+       char valstr[32];
+       CFStringGetCString(str, valstr, sizeof(valstr), kCFStringEncodingUTF8);
+       sscanf(valstr, "%f", &paramValue);
+       return paramValue;
+}
+
+void           CAAUParameter::SetValue(        AUParameterListenerRef          inListener, 
+                                                                       void *                                                  inObject,
+                                                                       Float32                                                 inValue) const
+{
+    // clip inValue as: maxValue >= inValue >= minValue before setting
+    Float32 valueToSet = inValue;
+    if (valueToSet > mParamInfo.maxValue)
+        valueToSet = mParamInfo.maxValue;
+    if (valueToSet < mParamInfo.minValue)
+        valueToSet = mParamInfo.minValue;
+    
+       AUParameterSet(inListener, inObject, this, valueToSet, 0);
+}
+
+#if DEBUG
+void   CAAUParameter::Print() const
+{
+       UInt32 clump = 0;
+       GetClumpID (clump);
+       
+       UInt32 len = CFStringGetLength(mParamName);
+       char* chars = (char*)malloc (len * 2); // give us plenty of room for unichar chars
+       if (!CFStringGetCString (mParamName, chars, len * 2, kCFStringEncodingUTF8))
+               chars[0] = 0;
+       
+       printf ("ID: %ld, Clump: %ld, Name: %s\n", mParameterID, clump, chars);
+       free (chars);
+}
+#endif
diff --git a/libs/appleutility/CAAUParameter.h b/libs/appleutility/CAAUParameter.h
new file mode 100644 (file)
index 0000000..4f35b26
--- /dev/null
@@ -0,0 +1,187 @@
+/*     Copyright:      � Copyright 2005 Apple Computer, Inc. All rights reserved.
+
+       Disclaimer:     IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
+                       ("Apple") in consideration of your agreement to the following terms, and your
+                       use, installation, modification or redistribution of this Apple software
+                       constitutes acceptance of these terms.  If you do not agree with these terms,
+                       please do not use, install, modify or redistribute this Apple software.
+
+                       In consideration of your agreement to abide by the following terms, and subject
+                       to these terms, Apple grants you a personal, non-exclusive license, under Apple�s
+                       copyrights in this original Apple software (the "Apple Software"), to use,
+                       reproduce, modify and redistribute the Apple Software, with or without
+                       modifications, in source and/or binary forms; provided that if you redistribute
+                       the Apple Software in its entirety and without modifications, you must retain
+                       this notice and the following text and disclaimers in all such redistributions of
+                       the Apple Software.  Neither the name, trademarks, service marks or logos of
+                       Apple Computer, Inc. may be used to endorse or promote products derived from the
+                       Apple Software without specific prior written permission from Apple.  Except as
+                       expressly stated in this notice, no other rights or licenses, express or implied,
+                       are granted by Apple herein, including but not limited to any patent rights that
+                       may be infringed by your derivative works or by other works in which the Apple
+                       Software may be incorporated.
+
+                       The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
+                       WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
+                       WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+                       PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
+                       COMBINATION WITH YOUR PRODUCTS.
+
+                       IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
+                       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+                       GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+                       ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION
+                       OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT
+                       (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN
+                       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+/*=============================================================================
+       CAAUParameter.h
+       
+=============================================================================*/
+
+#ifndef __CAAUParameter_h__
+#define __CAAUParameter_h__
+
+#include <AudioToolbox/AudioUnitUtilities.h>
+
+// ____________________________________________________________________________
+//     CAAUParameter
+//     complete parameter specification
+       /*! @class CAAUParameter */
+class CAAUParameter : public AudioUnitParameter {
+public:
+                                                               /*! @ctor CAAUParameter.0 */
+                                                               CAAUParameter();
+                                                               /*! @ctor CAAUParameter.1 */
+                                                               CAAUParameter(AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
+                                                               /*! @ctor CAAUParameter.2 */
+                                                               CAAUParameter(AudioUnitParameter &inParam);
+                                                               /*! @ctor CAAUParameter.3 */
+                                                               CAAUParameter(const CAAUParameter &a);
+                                                               /*! @dtor ~CAAUParameter */
+                                                               ~CAAUParameter();
+               
+       /*! @method operator <@ */
+       bool                                            operator < (const CAAUParameter &a) const 
+                                                               { 
+                                                                       return memcmp(this, &a, sizeof(AudioUnitParameter)) < 0; 
+                                                               }
+
+       /*! @method operator ==@ */
+       bool                                            operator == (const CAAUParameter &a) const 
+                                                               { 
+                                                                       return !memcmp(this, &a, sizeof(AudioUnitParameter)); 
+                                                               }
+       
+       /*! @method operator =@ */
+       CAAUParameter &                         operator = (const CAAUParameter &a);
+       
+       /*! @method GetValue */
+       Float32                                         GetValue() const;
+       /*! @method SetValue */
+       void                                            SetValue(       AUParameterListenerRef                  inListener, 
+                                                                                       void *                                                  inObject,
+                                                                                       Float32                                                 inValue) const;
+       
+       /*! @method GetName */
+       CFStringRef                                     GetName() const { return mParamName; }  
+                                                                               // borrowed reference!
+
+       /*! @method GetStringFromValueCopy */
+       CFStringRef                                     GetStringFromValueCopy(const Float32 *value = NULL) const;      
+                                                                               // returns a copy of the name of the current parameter value
+                                                                               // or null if there is no name associated
+                                                                               // caller must release
+       /*! @method ValuesHaveStrings */
+       bool                                            ValuesHaveStrings () const 
+                                                               { 
+                                                                       return (mParamInfo.flags & kAudioUnitParameterFlag_ValuesHaveStrings) != 0; 
+                                                               }
+       
+       /*! @method GetValueFromString */
+       Float32                                         GetValueFromString (CFStringRef str) const;                                     
+                                                                       // caller must release
+
+       /*! @method ParamInfo */
+       const AudioUnitParameterInfo &          
+                                                               ParamInfo()     const { return mParamInfo; }
+
+       /*! @method GetParamTag */
+       CFStringRef                                     GetParamTag() const     { return mParamTag; }
+                                                                       // this may return null! - 
+                                                                       // in which case there is no descriptive tag for the parameter
+
+       /*! @method GetParamName */
+       CFStringRef                                     GetParamName (int inIndex) const
+                                                                       // this can return null if there is no name for the parameter
+                                                               { 
+                                                                       return (mNamedParams && inIndex < mNumIndexedParams) 
+                                                                                               ? (CFStringRef) CFArrayGetValueAtIndex(mNamedParams, inIndex)
+                                                                                               : 0; 
+                                                               }
+       
+       /*! @method GetNumIndexedParams */
+       int                                                     GetNumIndexedParams () const { return mNumIndexedParams; }
+       
+       /*! @method IsIndexedParam */
+       bool                                            IsIndexedParam () const { return mNumIndexedParams != 0; }
+       
+       /*! @method HasNamedParams */
+       bool                                            HasNamedParams () const { return IsIndexedParam() && mNamedParams; }
+       
+       /*! @method GetClumpID */
+       bool                                            GetClumpID (UInt32 &outClumpID) const 
+                                                               { 
+                                                                       if (mParamInfo.flags & kAudioUnitParameterFlag_HasClump) {
+                                                                               outClumpID = mParamInfo.clumpID;
+                                                                               return true;
+                                                                       }
+                                                                       return false;
+                                                               }
+                                                               
+       /*! @method HasDisplayTransformation */
+       bool                                            HasDisplayTransformation () const 
+                                                               { 
+                                                                       return GetAudioUnitParameterDisplayType (mParamInfo.flags); 
+                                                               }
+
+       /*! @method IsExpert */
+       bool                                            IsExpert () const 
+                                                               { 
+                                                                       return mParamInfo.flags & kAudioUnitParameterFlag_ExpertMode; 
+                                                               }
+#if DEBUG
+       void                                            Print () const;
+#endif
+       
+               // these methods are defined in CAPersistence.cpp
+               // they will persist and restore only the scope, element and param ID's of the AudioUnitParameter
+               // however, this is sufficient to be able to save/restore a CAAUParameter object
+       void                                            Save (CFPropertyListRef &outData) const;
+       
+       static void                                     Save (const AudioUnitParameter &inParam, CFPropertyListRef &outData);
+       
+       static OSStatus                         Restore (const CFPropertyListRef inData, AudioUnitParameter &outParam);
+
+protected:
+       // cached parameter info
+       /*! @var mParamInfo */
+       AudioUnitParameterInfo          mParamInfo;
+       /*! @var mParamName */
+       CFStringRef                                     mParamName;
+       /*! @var mParamTag */
+       CFStringRef                                     mParamTag;
+       /*! @var mNumIndexedParams */
+       short                                           mNumIndexedParams;
+       /*! @var mNamedParams */
+       CFArrayRef                                      mNamedParams;
+       
+private:
+       void                                            Init (AudioUnit au, AudioUnitParameterID param, AudioUnitScope scope, AudioUnitElement element);
+
+};
+
+
+
+#endif // __CAAUParameter_h__
index 306269b291423cb142c8ed9998d72e6e271a3164..0ddd4c1a50971f680728d218baea364dd9d7dc36 100644 (file)
@@ -32,6 +32,7 @@
 #include <ardour/plugin.h>
 
 #include <AudioUnit/AudioUnit.h>
+#include <appleutility/AUParamInfo.h>
 
 #include <boost/shared_ptr.hpp>
 
@@ -45,6 +46,14 @@ namespace ARDOUR {
 class AudioEngine;
 class Session;
 
+struct AUParameterDescriptor : public Plugin::ParameterDescriptor {
+       // additional fields to make operations more efficient
+       AudioUnitParameterID id;
+       AudioUnitScope scope;
+       AudioUnitElement element;
+       float default_value;
+};
+
 class AUPlugin : public ARDOUR::Plugin
 {
   public:
@@ -104,7 +113,8 @@ class AUPlugin : public ARDOUR::Plugin
   private:
         boost::shared_ptr<CAComponent> comp;
         boost::shared_ptr<CAAudioUnit> unit;
-       
+       AUParamInfo* param_info;
+
        AudioStreamBasicDescription streamFormat;
         bool initialized;
         int format_set;
@@ -125,6 +135,8 @@ class AUPlugin : public ARDOUR::Plugin
         nframes_t cb_offset;
         vector<Sample*>* current_buffers;
         nframes_t frames_processed;
+
+       std::vector<AUParameterDescriptor> descriptors;
 };
        
 typedef boost::shared_ptr<AUPlugin> AUPluginPtr;
index dae5eea99e33a0655f94298a90b4a2005266e6c0..30f97dea9684985f794dde06843d17042b21676a 100644 (file)
@@ -32,6 +32,7 @@
 #include <ardour/utils.h>
 
 #include <appleutility/CAAudioUnit.h>
+#include <appleutility/CAAUParameter.h>
 
 #include <CoreServices/CoreServices.h>
 #include <AudioUnit/AudioUnit.h>
@@ -58,6 +59,7 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
        Plugin (engine, session),
        comp (_comp),
        unit (new CAAudioUnit),
+       param_info (0),
        initialized (false),
        buffers (0),
        current_maxbuf (0),
@@ -83,6 +85,7 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
                throw failed_constructor();
        }
 
+       unit->GetElementCount (kAudioUnitScope_Global, global_elements);
        unit->GetElementCount (kAudioUnitScope_Input, input_elements);
        unit->GetElementCount (kAudioUnitScope_Output, output_elements);
 
@@ -106,6 +109,100 @@ AUPlugin::AUPlugin (AudioEngine& engine, Session& session, boost::shared_ptr<CAC
                error << _("AUPlugin: cannot set processing block size") << endmsg;
                throw failed_constructor();
        }
+
+       /* discover writable parameters */
+       
+       cerr << "get param info, there are " << global_elements << " global elements\n";
+
+       param_info = new AUParamInfo (unit->AU(), false, false, kAudioUnitScope_Global);
+
+       cerr << "discovered " << param_info->NumParams() << " parameters\n";
+
+       for (uint32_t i = 0; i < param_info->NumParams(); ++i) {
+
+               AUParameterDescriptor d;
+
+               d.id = param_info->ParamID (i);
+
+               const CAAUParameter* param = param_info->GetParamInfo (d.id);
+               const AudioUnitParameterInfo& info (param->ParamInfo());
+
+               d.scope = param_info->GetScope ();
+               d.element = param_info->GetElement ();
+
+               /* info.units to consider */
+               /*
+                 kAudioUnitParameterUnit_Generic             = 0
+                 kAudioUnitParameterUnit_Indexed             = 1
+                 kAudioUnitParameterUnit_Boolean             = 2
+                 kAudioUnitParameterUnit_Percent             = 3
+                 kAudioUnitParameterUnit_Seconds             = 4
+                 kAudioUnitParameterUnit_SampleFrames        = 5
+                 kAudioUnitParameterUnit_Phase               = 6
+                 kAudioUnitParameterUnit_Rate                = 7
+                 kAudioUnitParameterUnit_Hertz               = 8
+                 kAudioUnitParameterUnit_Cents               = 9
+                 kAudioUnitParameterUnit_RelativeSemiTones   = 10
+                 kAudioUnitParameterUnit_MIDINoteNumber      = 11
+                 kAudioUnitParameterUnit_MIDIController      = 12
+                 kAudioUnitParameterUnit_Decibels            = 13
+                 kAudioUnitParameterUnit_LinearGain          = 14
+                 kAudioUnitParameterUnit_Degrees             = 15
+                 kAudioUnitParameterUnit_EqualPowerCrossfade = 16
+                 kAudioUnitParameterUnit_MixerFaderCurve1    = 17
+                 kAudioUnitParameterUnit_Pan                 = 18
+                 kAudioUnitParameterUnit_Meters              = 19
+                 kAudioUnitParameterUnit_AbsoluteCents       = 20
+                 kAudioUnitParameterUnit_Octaves             = 21
+                 kAudioUnitParameterUnit_BPM                 = 22
+                 kAudioUnitParameterUnit_Beats               = 23
+                 kAudioUnitParameterUnit_Milliseconds        = 24
+                 kAudioUnitParameterUnit_Ratio               = 25
+               */
+
+               /* info.flags to consider */
+
+               /*
+
+                 kAudioUnitParameterFlag_CFNameRelease       = (1L << 4)
+                 kAudioUnitParameterFlag_HasClump            = (1L << 20)
+                 kAudioUnitParameterFlag_HasName             = (1L << 21)
+                 kAudioUnitParameterFlag_DisplayLogarithmic  = (1L << 22)
+                 kAudioUnitParameterFlag_IsHighResolution    = (1L << 23)
+                 kAudioUnitParameterFlag_NonRealTime         = (1L << 24)
+                 kAudioUnitParameterFlag_CanRamp             = (1L << 25)
+                 kAudioUnitParameterFlag_ExpertMode          = (1L << 26)
+                 kAudioUnitParameterFlag_HasCFNameString     = (1L << 27)
+                 kAudioUnitParameterFlag_IsGlobalMeta        = (1L << 28)
+                 kAudioUnitParameterFlag_IsElementMeta       = (1L << 29)
+                 kAudioUnitParameterFlag_IsReadable          = (1L << 30)
+                 kAudioUnitParameterFlag_IsWritable          = (1L << 31)
+               */
+
+               d.integer_step = false;
+               d.toggled = false;
+               d.logarithmic = false;
+               d.sr_dependent = false;
+
+               const int len = CFStringGetLength (param->GetName());;
+               char local_buffer[len*2];
+               Boolean good = CFStringGetCString(param->GetName(),local_buffer,len*2,kCFStringEncodingMacRoman);
+               if (!good) {
+                       d.label = "???";
+               } else {
+                       d.label = local_buffer;
+               }
+               d.lower = info.minValue;
+               d.upper = info.maxValue;
+               d.default_value = info.defaultValue;
+               d.step = 1.0;
+               d.smallstep = 0.1;
+               d.largestep = 10.0;
+               d.min_unbound = d.lower;
+               d.max_unbound = d.upper;
+
+               descriptors.push_back (d);
+       }
 }
 
 AUPlugin::~AUPlugin ()
@@ -114,6 +211,10 @@ AUPlugin::~AUPlugin ()
                unit->Uninitialize ();
        }
 
+       if (param_info) {
+               delete param_info;
+       }
+
        if (buffers) {
                free (buffers);
        }
@@ -134,13 +235,16 @@ AUPlugin::label () const
 uint32_t
 AUPlugin::parameter_count () const
 {
-       return 0;
+       return param_info->NumParams ();
 }
 
 float
 AUPlugin::default_value (uint32_t port)
 {
-       // AudioUnits don't have default values.  Maybe presets though?
+       if (port < descriptors.size()) {
+               return descriptors[port].default_value;
+       }
+
        return 0;
 }
 
@@ -153,7 +257,7 @@ AUPlugin::latency () const
 void
 AUPlugin::set_parameter (uint32_t which, float val)
 {
-       // unit->SetParameter (parameter_map[which].first, parameter_map[which].second, 0, val);
+       // unit->SetParameter (id, 0, val);
 }
 
 float
@@ -167,14 +271,23 @@ AUPlugin::get_parameter (uint32_t which) const
 }
 
 int
-AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor&) const
+AUPlugin::get_parameter_descriptor (uint32_t which, ParameterDescriptor& pd) const
 {
-       return 0;
+       if (which < descriptors.size()) {
+               pd = descriptors[which];
+               return 0;
+       } 
+       return -1;
 }
 
 uint32_t
 AUPlugin::nth_parameter (uint32_t which, bool& ok) const
 {
+       if (which < descriptors.size()) {
+               ok = true;
+               return which;
+       }
+       ok = false;
        return 0;
 }
 
@@ -393,20 +506,24 @@ set<uint32_t>
 AUPlugin::automatable() const
 {
        set<uint32_t> automates;
-       
+
+       for (uint32_t i = 0; i < descriptors.size(); ++i) {
+               automates.insert (i);
+       }
+
        return automates;
 }
 
 string
-AUPlugin::describe_parameter (uint32_t)
+AUPlugin::describe_parameter (uint32_t param)
 {
-       return "";
+       return descriptors[param].label;
 }
 
 void
-AUPlugin::print_parameter (uint32_t, char*, uint32_t len) const
+AUPlugin::print_parameter (uint32_t param, char* buf, uint32_t len) const
 {
-       
+       // NameValue stuff here
 }
 
 bool
@@ -418,7 +535,7 @@ AUPlugin::parameter_is_audio (uint32_t) const
 bool
 AUPlugin::parameter_is_control (uint32_t) const
 {
-       return false;
+       return true;
 }
 
 bool
index d65f7e7dabad3c72e292f820961696444b0da29e..7c3bd4879c55561cda42b92d0ae6db932eab3d5a 100644 (file)
@@ -1,4 +1,4 @@
 #ifndef __ardour_svn_revision_h__
 #define __ardour_svn_revision_h__
-static const char* ardour_svn_revision = "3029";
+static const char* ardour_svn_revision = "3045";
 #endif