AudioIODevice start/stop broken with 6.1.4?

Moved from 6.1.2 to 6.1.4 yesterday and noticed that our AudioDevice only worked on the first play after calling open().
Had a look at the code and found that the breaking changes were introduced in commit f1b6bbc (CoreAudio: Fix thread sanitizer warnings @reuk).

The problem is that the “started” variable is only reset in juce_mac_CoreAudio.cpp line 742 within the stop function. But the code only gets executed when closing the audio device (where “leaveInterruptRunning” is set to false). We only close the device when the user switches audio devices and not at the end of play passes (which makes sense I think).

Did anyone run into the same behaviour and is there a workaround?
I can of course set the bool argument in stopAndGetLastCallback to false but that doesn’t feel right.

Any advice is appreciated. Thanks!

Could you elaborate a bit more on the series of operations that has stopped working in the way you expect? It sounds like you might be calling start and stop multiple times directly on an AudioIODevice, rather than using an AudioDeviceManager. Is that accurate?

1 Like

Thanks for your answer!

So basically without changing anything in the calling code and just updating the JUCE modules the playback only works for the first time.
We’re only using an AudioDeviceManager to get the devices and then wrap the juce::AudioIODevice in our own class. We built our own audio device selector UI with routing matrix etc.

When playback is started we call AudioIODevice::start on and AudioIODevice::stop when playback is to be stopped. This has worked for many years and I never saw a reason to change anything to be honest. With that change in JUCE 6.1.4 the device isn’t stopped properly, hence things are not working as expected anymore.

I checked the examples to see if maybe I’m doing something wrong and I saw that you’re using the AudioDeviceManager::addAudioCallback and AudioDeviceManager::removeAudioCallback to start/stop playback instead. Are there any benefits of using that over using the AudioIODevice directly?

Thanks for getting back to me. I wanted to check exactly what you were doing, to ensure that I was tracking down the same issue. I can reproduce the problem with a test case such as:

device->start (&callback);
expect (device->isPlaying());

device->start (&callback);
expect (device->isPlaying()); // This fails!

The fix looks straightforward, and I’ll attempt to get it onto develop later this week.

No, I think these are both valid approaches.

Exactly! The isPlaying() returns false as the start method doesn’t do anything the second time round since the stop() method call didn’t really stop the device from playing.

Please let me know when you had a chance to look at this. Happy to test of course.

Thanks! This is really much appreciated.

Hi again @reuk,

did you have a chance to look into this yet?

Yes, I have a pending fix. It should be out shortly.

It’s on develop now. I’ll try asap. Thanks for the quick help!

For the record, the patch that fixes the issue is here:

1 Like