iOS mixerResume freeze

Hello, we have encountered an interesting issue on iOS with the 2.02.31 C++ API.

When we rapidly collapse the app, then resume it, and repeat this several times (sometimes many), FMOD::System::mixerResume occasionally takes about a second instead of the usual 10–100 ms. We can reproduce this consistently. It freezes our main thread so users can see it.

The stack trace during the freeze looks like this:

libsystem_kernel +0x0000cd4 mach_msg2_trap
+0x6234c1c FMOD::OutputCoreAudio::startCallback
+0x62326c4 FMOD::Output::start
+0x61a1f1c FMOD::SystemI::startDriver
+0x625389c FMOD::SystemI::mixerResume
+0x62499d4 FMOD::System::mixerResume

I’ve uploaded detailed logs (log.txt, log2.txt) and a Tracy recording file (mixerResume.tracy, mixerResume2.tracy, please look for ResumeAudioContext zone) to my profile, where you can find additional information. The issue occurred between 12:20:21.644 and 12:20:22.957. The second one is between 13:09:53.837 and 13:09:54.814.

Thanks in advance!

Thanks for the logs and traces. Based on the order of events in the log, this appears to be a result of the AudioOutputUnitStart call we make during mixerResume.
We don’t have any control over how long OS calls take, and unfortunately in this instance it is a call we can’t make ahead of time without defeating the purpose of mixerSuspend/mixerResume, which is to free up resources we aren’t using during backgrounding.

We might be able to push the call out to a different thread, but from your Tracy recordings it looks like the call has max priority and freezes up all other threads (even the render thread, if I’m reading this correctly).

Perhaps you could implement some sort of debounce on your end, to delay the mixerSuspend/mixerResume calls and avoid flogging the OS?

We can’t implement such a solution because the current reproduction steps are only for testing. We’re seeing these hangs in production from real users, and we believe they also occur during normal app usage.

By the way, we have another hang with a different call stack that we can’t reproduce locally:

libsystem_kernel    0x241152808  __semwait_signal
libsystem_c         0x19ddc6828  nanosleep
libsystem_c         0x19ddc6740  usleep
0x105043204  FMOD_OS_Time_Sleep
0x1050e56c0  FMOD::AsyncManager::gameFlushCommands
0x105153dfc  FMOD::Studio::System::flushCommands
0x105153d4c  FMOD::Studio::System::flushCommands
0x102ecfac4  AudioManagerFMod::StopBankEvents 
0x102ecccbc  AudioManagerFMod::UnloadBank

I’ve included our function calls so you can better understand what we’re doing. Unfortunately, we don’t have FMOD verbose logs for this case.