[bug] CoreAudioInternal can miss device property changes

Hi there,

I am looking into a problem with a CoreAudio HAL driver that I maintain. During my debugging, I tried sending a kAudioDevicePropertyDeviceHasChanged property change on the device in order to force a test application using juce::AudioDeviceManager to restart its processing.

What I’ve seen is that CoreAudio batches multiple property changes together in one CoreAudioInternal::deviceListenerProc() callback. Unfortunately, deviceListenerProc() ignores the inNumberAddresses argument, and so only checks the first changed selector instead of all of the changed selectors.

This means that depending on the order of properties, the kAudioDevicePropertyDeviceHasChanged could be missed. I think this is a bug in JUCE, but I am not by any means a CoreAudio expert, so feel free to argue. :wink:

I am attaching a patch that changes the code to loop over all the changed properties. I realize that the calls to deviceDetailsChanged() and deviceRequestedRestart() should probably be pulled out of the loop to be called at most once. The patch is just meant as a starting point to illustrate my point.

Any feedback is welcome! :slight_smile:

0001-CoreAudio-Iterate-over-all-changed-properties.patch (3.6 KB)

This means that depending on the order of properties, the kAudioDevicePropertyDeviceHasChanged could be missed.

To elaborate a bit: in my testing, after sending the change from the driver, the JUCE application gets the callback with inNumberAddresses = 20 and the kAudioDevicePropertyDeviceHasChanged at index 2 in the AudioObjectPropertyAddress array.

A polite bump - can someone from the JUCE team take a look at this?

Thanks for reporting, this should now be fixed:

@reuk, I tested your changes and the AudioDeviceManager is now consistently restarted when the channel count changes from the driver. Thanks a lot!