Re: AU->View communication
Re: AU->View communication
- Subject: Re: AU->View communication
- From: William Stewart <email@hidden>
- Date: Tue, 19 Jul 2005 14:40:34 -0700
There's one other clarification I should make here. This concerns the
usage of the AUEventListenerNotify call.
This call takes a AUEvent struct, that as described below, has 4
event types. Typically though you would only use the Notify API with
3 of these events: the parameter events (value changed, begin and end
gesture). You would not use it for Property changes: why?
Property Changes already have a notification mechanism built into
them. AudioUnitSetProperty's implementation is required to notify
when a property's value has changed. AudioUnitAdd/
RemovePropertyListener has existed since the beginning so that
clients can register and receive notifications.
In the implementation of AUBase, you will see at the end of
DispatchSetProperty, a call to the method PropertyChanged. This
method then goes and iterates through the registered listeners and
calls them if there is a match.
So, the question arises, why add this as an explicit event with the
AUEvent API?
A property changed notification is sent on the same thread as the
property's value is changed on. That is, a call to
AudioUnitSetProperty will involve a callout to registered property
change listeners before that call returns. It is a synchronous
operation.
This is inconvenient in many situations because as a listener you
really wish to receive the notification on say the main thread, where
you can say change the view of some data, etc.. A good illustration
of this is the parameter list and info properties - as they change
you really want to ensure that you are responding to that change on
the main thread, as if this were an event, so you can redraw the new
parameters sliders, etc. As a client of this notification, you don't
want to have to be worried about what thread you are on, and if it is
safe to do all of that work or not.
Thus, all of the AU views we ship now use the AUEventListener to
register for Property Changes - you can see this in the Carbon View
code that we ship in the SDK.
Code that is implementing an AU cannot use the AUEventListenerNotify
call to issue a notification of a property change; this does NOT
trigger the notification mechanism because the notification mechanism
is not using this as the basis to begin a series of notifications.
Nor does it make sense for a client outside of the AU directly to use
this API (aside from the fact that it won't work! the knowledge of
property value changes correctly belongs in the AU itself). If an AU
needs to notify of changes to the value of a property(s), then it
should call the implementation method "AUBase::PropertyChanged" =
there are example of this in the AUSDK. Ultimately, there is no way
(by design) for a client of an AU to notify of a property change;
this is a privileged action of the AU.
We should make sure that we return an error if AUEventListenerNotify
is called with a property changed event specified.
Thanks; esp. to Antoine who had to suffer as we figured this out :-)
Bill
On 14/07/2005, at 11:42 AM, William Stewart wrote:
Russell
On 13/07/2005, at 8:27 PM, Russell Edwards wrote:
Thanks for your reply & my apologies for taking so long to respond:
An alternative I have seen little references to seems to be to use
properties. But apparently you shouldn't send property change
notifications from the audio thread as they might block for too
long.
No. You can use the AUEventListener notification mechanism with
properties just as you can with parameters; this is a non-
blocking notification. A view which *listens* to private property
changes should also use this mechanism so that it ensures that
its notification occurs on the main thread. Thus, this becomes a
"render process" safe mechanism.
Oh that's interesting! So is the second paragraph of the
following post wrong, out of date, or pertaining to some other
listening mechanism? :
http://lists.apple.com/archives/coreaudio-api/2003/Jun/msg00056.html
No, this is completely correct. You are confusing two distinct parts:
PropertyChanged is an implementation method of AUBase - it is used
by an AudioUnit implementation to indicate that the value of a
property has changed. This method will then call out (on the same
thread) to any property listeners that have been registered with
the AU for that property change (AudioUnitAddPropertyListener).
AUEventListener is a service that sits *outside* of the AU. If you
think of the Model-View-Controller model, the AU is the model, its
view is, well, the view, and the AUEventListener is the controller
aspect.
In its initial release the AUEventListener (AUParameterListener)
only listened to parameter value change events. But we need to
extend this to provide a general mechansim for the 4 events that it
now deals with:
parameter - begin gesture
parameter - value change
parameter - end gesture
property - value change
The AUEventListener uses the existing AU API. So for its property
event, it establishes a property listener on the AU using the
AudioUnitAddPropertyListener call. When the client creates an
AUEventListener object, it specifies a number of conditions around
notification granularity:
The thread to call it on (CFRunLoop)
The mode of the run loop if you want to task this your self
2 values that affect the granularity of events
So, when the event listener's property listener is called by the
AU, it does a cross-thread thunk to go to the thread you've
registered and essentially says: this event occurred. It then
returns to the AU. So, from the AU's perspective the call out was a
minimal time.
Then, next time that run loop is tickled in that run loop mode, the
AUEventListener will notice that there is an event that has been
queued, and you get your notification that the property value has
changed - meanwhile of course, the AU has gone on its merry way.
If it is extremely important to you that this property changed
notification be a synchronous transaction, then you can still
register directly with the AudioUnit using the AddPropertyListener
API - but then you have the limitations that imposes on you to take
into account.
The PulseDetector AU in the DiagnosticAUs in the SDK uses the
AUEventListener property changed notification to display the
detected pulses - the AU's code is aware of the fact that this is
primarily an asynchronous transaction with potential threading
issues; that's probably a good place to have a look at how this can
work for you.
We obviously need to improve our documentation in this area :-)
CAUGui, in its "internal parameters" stuff, therefore just polls
them
in the GUI's idle timer.
Yes, that is a very bad approach and one we would discourage -
the exception to this is a metered, read-only parameter which by
its nature needs to be drawn on a regular basis.
I have something like that, but I don't do it with a timer loop
like this because I don't want to be drawing the meter more often,
or less often, than the update interval of the meter value in the
actual audiounit thread. So, I have the audiounit "push" meter
values via private parameter change notifications ... is there
anything "wrong" with that? (I update them every 100 ms, done by
counting samples).
Nope, that's a very good solution I think as long as you aren't
pushing at a granularity that is too fine (which of course you
aren't with the 100ms update). The advantage of doing it this way
is that you already have the regular call to your render method, so
this is a great way to do this I think.
Bill
--
mailto:email@hidden
tel: +1 408 974 4056
______________________________________________________________________
____
"Much human ingenuity has gone into finding the ultimate Before.
The current state of knowledge can be summarized thus:
In the beginning, there was nothing, which exploded" - Terry Pratchett
______________________________________________________________________
____
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
--
mailto:email@hidden
tel: +1 408 974 4056
________________________________________________________________________
__
"Much human ingenuity has gone into finding the ultimate Before.
The current state of knowledge can be summarized thus:
In the beginning, there was nothing, which exploded" - Terry Pratchett
________________________________________________________________________
__
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden