For the StandaloneApp audio settings, sometimes the app freezes when the buffer size is changed. I suspect it might be related to stopping and immediately restarting audio.
I tracked it to an infinite contention on callbackLock
inside juce_mac_CoreAudio.cpp
:
if (OK (AudioDeviceStart (deviceID, audioProcID)))
This sometimes can lock forever because it’s done inside a scoped lock for callbackLoop
, and CoreAudio HAL can already invoke and wait for audioCallback
to complete inside AudioDeviceStart
. The callback freezes on attempting to lock the same critical section from a different thread, and AudioDeviceStart
never returns, as it waits (through a set of its own pthread primitives) for the callback to complete.
I solved it in my source base by adding a scoped unlock before the AudioDeviceStart call:
+ const ScopedUnlock sul (callbackLock); // prevent lockup, as AudioDeviceStart may invoke callback
if (OK (AudioDeviceStart (deviceID, audioProcID)))
I don’t know if it has any implications or side effects to this. Maybe refactoring this way would do?
started = true;
const ScopedUnlock sul (callbackLock); // prevent lockup, as AudioDeviceStart may invoke callback
if (!OK (AudioDeviceStart (deviceID, audioProcID)))
{
started = false;
OK (AudioDeviceDestroyIOProcID (deviceID, audioProcID));
audioProcID = {};
}