On Aug 20, 2010, at 7:24 PM, Ian Kerr wrote:
> I'm getting an occasional crash as my Audio Unit is being uninitialized. The stack trace shows that my UI thread invokes AudioUnitGetProperty() while com.apple.main-thread invokes AUEffectBase::Cleanup(). Inside my AudioUnitGetProperty() implementation, I query values from AUEffectBase's AUKernelBase instances. Meanwhile, AUEffectBase::Cleanup() is freeing these kernels. So, it seems that my approach is fundamentally flawed.
ok - the AU provides no explicit synchronisation mechanisms for multi-thread access, so yes this is something you have to take care of yourself.
> Now, I see that in the FilterDemo, AudioUnitGetProperty() is called in the UI's updateCurve function. The difference seems to be that updateCurve is called from within the Audio Unit event callback function. Is it this fact that makes AudioUnitGetProperty() thread-safe in this case (the "Audio Unit Programming Guide" says that the Audio Unit Event API is thread-safe)?
The affect of this is to dispatch this response to the property changing to the thread that in your case is also uninitialising the the audio unit.
> If the answer to that question is yes, then it seems I simply need to use Audio Unit events to get a thread-safe context from which to call AudioUnitGetProperty(). However, the property in question holds a meter level and needs to be updated many times per second. Is this an appropriate use of Audio Unit events or would a polling approach be better?
The way we do metering in our generic views is as follows:
We mark the parameter is being a read-only meter parameter
the generic view decides to draw a meter
In the main thread's UI scheduling, we redraw the meter. As this is the thread on which most of the UI interactions from the app are performed on, it has the affect of providing a single threaded message dispatch model (the response to the command to uninitialise the AU is happening on the same thread as the UI timer's command to redraw the meter).
> Speaking of polling, kAudioUnitParameterFlag_MeterReadOnly looks appealing. Should I simply set up a parameter with this flag and poll it from my UI thread with AudioUnitGetParameter()? Will I run into the same crash that I'm running into with AudioUnitGetProperty()?
I think the problem is that you are running your own UI thread. That is introducing these problems because you have your own thread to refresh your UI and the main thread, which is processing user events that can affect the AU, is also running. So, do you really need your own UI thread?
If so, if you can have all of the AU interactions you need to do moved over to that thread (see the CFRunLoop in the AudioUnitEvent create calls), that will help you to some extent; at least all of your AU Processing events will be on that thread as well. But as UI events are being processed on other threads (the AU can be getting removed from the host's graph in this case), you have that problem to deal with. As the kernels can be destroyed, etc on init calls, it would be better I think to keep the state you need to access in the AUEffectBase subclass (for instance, all of the parameter values the AU creates by default are kept in the elements that persist across the init state changes).
> Any clarifications would be appreciated. I apologize if this has been covered elsewhere. I have found some information through Google but am still struggling with these seemingly basic questions. I'm unable to get any response from the coreaudio-api list search...
> 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
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