Audio Units manage their internal state through a generic property mechanism.
There are several properties that are generic for all types of Audio Units and
some that are specific to particular types. These general properties are listed
in AudioUnit/AudioUnitProperties.h
. Property values vary, with each
property needing to describe (in documentation) to the user what
type
will represent the value of a particular property. Property
values are always passed by reference when both getting and setting the value of
a property.
Contents | |
Getting and Setting Properties | |
Listening for Property Changes |
Functions | ||
AudioUnitGetPropertyInfo | Retrieve the size of property's value and whether it is read-only. | |
AudioUnitGetProperty | Retrieve the current value of a property. | |
AudioUnitSetProperty | Set a property value. | |
AudioUnitAddPropertyListener | Request notification when a property value changes. | |
AudioUnitRemovePropertyListener | Remove a property change notification callback. | |
Callbacks | ||
AudioUnitPropertyListenerProc | Called when a property value changes. |
There are three functions that are used when dealing with properties. Properties are defined using three parameters, the ID - this delineates which property is being queried, the Scope - this specifies which scope the property is applied to, and the elementID, which further specifies the scope (particularly on the input and output scopes).
ComponentResult AudioUnitGetPropertyInfo( AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, UInt32 * outDataSize, Boolean * outWritable );
ComponentResult AudioUnitGetProperty( AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void * outData, UInt32 * ioDataSize );This call is used to retrieve the value of the specified property. The caller is responsible for allocating enough space to hold the value of the property. If insufficient space is specified then the Audio Unit is free to retrieve either an error, or a partial result - where the value is filled in as much as is possible given the specified space. On return, the
ioDataSize
will be set to the number of bytes
that were actually used and written to the memory location as specified
by the outData
address. The property must be readable for
this call to succeed.
If outData
is NULL, then upon return
ioDataSize
will contain the size needed to retrieve the
property's value.
ComponentResult AudioUnitSetProperty( AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement, void * inData, UInt32 inDataSize );This call is used to set the value of the specified property. If
inDataSize
is less than the size needed to set the complete value
of the property the call will return an error. The property must be writable for
this call to succeed.
A property's value can be changed by any number of actions both internal and external to the Audio Unit, depending of course on the property itself.
For instance, an output unit that tracks the device that the user chooses as
the Default Output Unit in the Sound Preferences pane, can be changed at any
time through this action. If a program has an instance of the
DefaultOutputUnit
open, then a property listener for the
AudioDeviceID property can be established to allow the program to detect that
change. Alternatively, the program may not care about the particular device that
the DefaultOutputUnit is connected too, but may care about the format of that
device, e.g. the sample rate of the device. When that property changes, any
listener instantiated for that property will be notified that that property has
changed. The program can then take any appropriate actions that it needs to.
Other, and probably the more usual condition, will have an Audio Unit's properties completely under the control of the program itself, and so a property listener is not required. Nevertheless, there are many situations where it is more convenient, and provides a better locality of code, to have reactions to changes in a property's value handled through a notification that the property has been changed.
There are two functions that are provided, one to register a listener for a particular property, and another to remove a listener. Wild-card instantiation of listeners are not currently supported by Audio Units, so any property listener that is registered must identify the particular property. Any changes to the value of that property, regardless of its scope, will be notified to the registered listener.
ComponentResult AudioUnitAddPropertyListener( AudioUnit ci, AudioUnitPropertyID inID, AudioUnitPropertyListenerProc inProc, void * inProcRefCon );This function registers the specified listenerProc for the specified property ID. This listenerProc will be called if and when that property's value is changed, and when called, the listenerProc will be passed in both the Audio Unit upon which the property has been changed, and the inProcRefCon that is supplied in this function. Property listener procs can be registered multiple times for different property IDs. The Audio Unit allows for multiple listeners for the same ID, as long as these listeners have a different inProc address.
ComponentResult AudioUnitRemovePropertyListener( AudioUnit ci, AudioUnitPropertyID inID, AudioUnitPropertyListenerProc inProc );This function will remove all of the property listeners that match the specified property ID and the inProc address.
typedef void (*AudioUnitPropertyListenerProc)( void * inRefCon, AudioUnit ci, AudioUnitPropertyID inID, AudioUnitScope inScope, AudioUnitElement inElement );This is the callback function established by AudioUnitAddPropertyListener.