• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: AU->View communication
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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


References: 
 >AU->View communication (From: "Russell ." <email@hidden>)
 >Re: AU->View communication (From: William Stewart <email@hidden>)
 >Re: AU->View communication (From: Russell Edwards <email@hidden>)
 >Re: AU->View communication (From: William Stewart <email@hidden>)

  • Prev by Date: Re: BeginParameterChangeGesture AU event listener weirdness
  • Next by Date: Listening in to MIDI messages sent to a device
  • Previous by thread: Re: AU->View communication
  • Next by thread: Audio Unit with variable Latency (user-modifyable)
  • Index(es):
    • Date
    • Thread