From 584b3fea95e06809ab677d73ba36a3194eb17c6b Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 30 Mar 2011 13:53:56 +0000 Subject: add an API for listening to AU properties git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@9246 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/appleutility/CAAudioUnit.cpp | 82 ++++++++++++++++++++++++++++++++++++++- libs/appleutility/CAAudioUnit.h | 24 +++++++++++- 2 files changed, 102 insertions(+), 4 deletions(-) diff --git a/libs/appleutility/CAAudioUnit.cpp b/libs/appleutility/CAAudioUnit.cpp index aaf57f233d..0e2cdbfe49 100644 --- a/libs/appleutility/CAAudioUnit.cpp +++ b/libs/appleutility/CAAudioUnit.cpp @@ -223,24 +223,102 @@ CAAudioUnit::CAAudioUnit (const AudioUnit& inUnit) } CAAudioUnit::CAAudioUnit (const CAComponent& inComp) - : mComp (inComp), mDataPtr (0) + : mComp (inComp), mDataPtr (0), mPropertyCallback (0) { mDataPtr = new AUState (mComp.Comp()); } CAAudioUnit::CAAudioUnit (const AUNode &inNode, const AudioUnit& inUnit) - : mComp (inUnit), mDataPtr(new AUState (inNode, inUnit)) + : mComp (inUnit), mDataPtr(new AUState (inNode, inUnit)), mPropertyCallback (0) { } CAAudioUnit::~CAAudioUnit () { + dropPropertyListens (); + if (mDataPtr) { mDataPtr->release(); mDataPtr = NULL; } } +void +CAAudioUnit::addPropertyListen (AudioUnitPropertyID id) +{ + if (mPropertyCallback == 0) { + return; + } + + if (mWatching.find (id) != mWatching.end()) { + return; + } + + if (AudioUnitAddPropertyListener (AU(), id, PropertyCallback, this) == noErr) { + mWatching.insert (id); + } +} + +void +CAAudioUnit::removePropertyListen (AudioUnitPropertyID id) +{ + if (!mPropertyCallback) { + return; + } + std::set::iterator i = mWatching.find (id); + if (i != mWatching.end()) { + mWatching.erase (i); + } + /* this is for 10.6 and above ... + AudioUnitRemovePropertyListenerWithUserData (AU(), id, PropertyCallback, this); + */ + AudioUnitRemovePropertyListener (AU(), id, PropertyCallback); +} + +void +CAAudioUnit::dropPropertyListens () +{ + for (std::set::iterator i = mWatching.begin(); i != mWatching.end(); ++i) { + /* this is for 10.6 and above ... + AudioUnitRemovePropertyListenerWithUserData (AU(), *i, PropertyCallback, this); + */ + AudioUnitRemovePropertyListener (AU(), *i, PropertyCallback); + } + mWatching.clear (); +} + +void +CAAudioUnit::SetPropertyCallback (void (*prop_callback)(void*, int32_t, float, void*), void* arg) +{ + dropPropertyListens (); + mPropertyCallback = prop_callback; + mPropertyCallbackArg = arg; +} + +void +CAAudioUnit::PropertyCallback (void *inRefCon, + AudioUnit inUnit, + AudioUnitPropertyID inID, + AudioUnitScope inScope, + AudioUnitElement inElement) +{ + static_cast(inRefCon)-> + DoPropertyCallback (inUnit, inID, inScope, inElement); +} + +void +CAAudioUnit::DoPropertyCallback (AudioUnit inUnit, + AudioUnitPropertyID inID, + AudioUnitScope inScope, + AudioUnitElement inElement) +{ + if (mPropertyCallback) { + float value; + AudioUnitGetParameter (inUnit, inID, inScope, inElement, &value); + mPropertyCallback (this, inID, value, mPropertyCallbackArg); + } +} + CAAudioUnit& CAAudioUnit::operator= (const CAAudioUnit &a) { if (mDataPtr != a.mDataPtr) { diff --git a/libs/appleutility/CAAudioUnit.h b/libs/appleutility/CAAudioUnit.h index 810b81be2f..9f6f5905e1 100644 --- a/libs/appleutility/CAAudioUnit.h +++ b/libs/appleutility/CAAudioUnit.h @@ -57,6 +57,7 @@ #endif #include +#include #include "CAStreamBasicDescription.h" #include "CAComponent.h" #include "CAAudioChannelLayout.h" @@ -328,14 +329,33 @@ public: #pragma mark __Print void Print () const { Print (stdout); } void Print (FILE* file) const; + + void SetPropertyCallback (void (*param_callback)(void*, int32_t, float, void*), void* arg); + void addPropertyListen (AudioUnitPropertyID); + void removePropertyListen (AudioUnitPropertyID); private: CAComponent mComp; class AUState; AUState* mDataPtr; - - // this can throw - so wrap this up in a static that returns a result code... + + void (*mPropertyCallback)(void* Unit, int32_t which, float val, void*); + void* mPropertyCallbackArg; + std::set mWatching; + void dropPropertyListens (); + static void PropertyCallback ( + void *inRefCon, + AudioUnit inUnit, + AudioUnitPropertyID inID, + AudioUnitScope inScope, + AudioUnitElement inElement); + void DoPropertyCallback (AudioUnit inUnit, + AudioUnitPropertyID inID, + AudioUnitScope inScope, + AudioUnitElement inElement); + + // this can throw - so wrap this up in a static that returns a result code... CAAudioUnit (const CAComponent& inComp); bool HasDynamicScope (AudioUnitScope inScope, SInt32 &outTotalNumChannels) const; -- cgit v1.2.3