In the case of anything else built on AUBase, including AUMultiChannelMixer, 
it's not a matter of the property being changed asynchronously and waiting for 
a notification (I'm reinstalling Xcode at the moment, hard to look at code, but 
from memory, setting the render callback might not send a notification anyhow).

The usual problem is that one can be in the middle of rendering upstream of the 
AU while trying to disconnect, and it's not the AU's responsibility to protect 
against that.

One solution is to use a mutex. Lock the mutex around the call to 
SetRenderCallback. When rendering upstream from the mixer, try to lock the 
mutex; if it fails, you know disconnection is in progress and can bail out. The 
realtime thread won't block because you're only trying to lock the mutex.


> On Nov 27, 2016, at 15:18 , Brian Willoughby <[email protected]> wrote:
> 
> CoreAudio is multi-threaded, and the calls you're dealing with are 
> asynchronous. That means other threads can still be in the process of 
> accessing resources even after your calls to disconnect the resources have 
> returned.
> 
> What you need to do is register for one or more property change 
> notifications. CoreAudio will then call your notification callbacks when the 
> audio threads have finished with your requested changes.
> 
> As one example, I assume that you must have called Start on the Output AU in 
> order to get your callback working. You should probably then call Stop on the 
> same Output AU in order to cease the callback. There are various property 
> change notifications associated with Running or stopped audio units. You 
> could use the callbacks to trigger freeing of the shared resources.
> 
> As another example, since you're using the SetRenderCallback property to 
> disconnect your callback, then I assume there is a property change 
> notification for SetRenderCallback that you could use to synchronize your 
> resource deallocation.
> 
> In either case, your application needs to wait for all the requested changes 
> to take effect, by listening for the notifications, before freeing the audio 
> converter.
> 
> Brian Willoughby
> Sound Consulting
> 
> 
> On Nov 27, 2016, at 8:51 AM, Andreas Falkenhahn <[email protected]> 
> wrote:
>> I am using a render callback to send PCM data to the audio hardware, it is 
>> installed
>> like this:
>> 
>>      callback.inputProc = MixerInputCallback;
>>      callback.inputProcRefCon = ci;
>>      
>>      AudioUnitSetProperty(mixerAudioUnit, 
>> kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, 
>> sizeof(AURenderCallbackStruct));
>> 
>> My MixerInputCallback() then looks like this:
>> 
>>      static OSStatus MixerInputCallback(void *inRefCon, 
>> AudioUnitRenderActionFlags *inActionFlags, const AudioTimeStamp 
>> *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList 
>> *ioData)
>>      {
>>              struct channelinfo *ci = (struct channelinfo *) inRefCon;
>> 
>>              AudioConverterFillComplexBuffer(ci->converter, 
>> ACComplexInputProc, inRefCon, &inNumFrames, ioData, NULL);
>>      
>>              return noErr;
>>      }
>> 
>> Now how can I safely dispose of the audio converter object accessed in 
>> MixerInputCallback()?
>> i.e. I need to make sure that the converter isn't accessed while I'm trying 
>> to kill it.
>> 
>> AFAIU I'm not allowed to use any form of mutex protection inside 
>> MixerInputCallback()
>> because it's running on the audio I/O proc and mustn't block.
>> 
>> So how can I make sure that it is safe to kill the audio converter? I've 
>> tried to kill the render
>> callback first, like so:
>> 
>>      callback.inputProc = NULL;
>>      callback.inputProcRefCon = NULL;                                
>>                                              
>>      AudioUnitSetProperty(mixerAudioUnit, 
>> kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, 
>> sizeof(AURenderCallbackStruct));
>> 
>> And then kill the audio convert using
>> 
>>      AudioConverterDispose(ci->converter);
>> 
>> But it doesn't work. Running a stress test with such code often leads to 
>> memory access faults
>> when disposing of the converter. 
>> 
>> So how can I make sure that the audio converter is no longer in use when 
>> calling AudioConverterDispose()?
>> I'd somehow need to find a way to wait for the completion of 
>> MixerInputCallback() while at the same
>> time forbidding Core Audio to run MixerInputCallback() again. I don't think 
>> this is as easy as setting
>> a flag because multithreading is involved and MixerInputCallback() runs on 
>> the audio I/O proc.
>> 
>> So how can I do this? How can I safely stop my MixerInputCallback() so that 
>> I can safely dispose of
>> the audio converter accessed by MixerInputCallback()?
>> 
>> -- 
>> Best regards,
>> Andreas Falkenhahn                          mailto:[email protected]
> 
> 
> _______________________________________________
> Do not post admin requests to the list. They will be ignored.
> Coreaudio-api mailing list      ([email protected])
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/coreaudio-api/dwyatt%40apple.com
> 
> This email sent to [email protected]


 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/coreaudio-api/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to