FMOD ERROR:Resume must be called from the same thread as suspend

Hi, forums
I use coreSystem.mixerResume() to resume FMOD when when my game comeback from background.
However, sometimes there are some logError from Debug_Callback like this:

[FMOD] SystemI::mixerResume : Resume must be called from the same thread as suspend. 

 : ../../src/fmod_systemi.cpp : 3632, time : 3635.888  

FMODUnity.RuntimeManager:DEBUG_CALLBACK(DEBUG_FLAGS, StringWrapper, Int32, StringWrapper, StringWrapper)  

FMOD.System:FMOD5_System_MixerResume(IntPtr)  

FMODUnity.RuntimeManager:OnFocusChange(Boolean)  

I wonder why this error occurs and how to solve it. Is there anyone who can help me?
Thank you!

Is this happening in the Unity Editor or in a built game? You mention when coming back from the background so is this on iOS/Android?
This error indicated that mixerSupend is being called from one thread, and mixerResume is being called from a different thread. We call both of these functions in RuntimeManager.OnApplicationPause, or RuntimeManager.HandleInterrupt for iOS which should be on the same thread in each case- it sounds like the thread you are calling it on must be different to that. Are you calling it from a callback or a separate thread or something like that?

Thank you for your reply!
This happened in a built game on android and ios.
On ios, we listened on both Unity’s OnApplicationFocus and ios’s own SuspendCallback.
According to your description, is the correct way to do this the following:
1、On Ios, we should just listen to ios SuspendCallback because sometimes OnApplicationFocus is not triggered
2、On Android, we should just listen to OnApplicationPause but not OnApplicationFocus

If you are using the FMOD Unity integration then the RuntimeManager should be pausing and resuming the mixer for you and there should be no need to call it yourself. Are you finding that FMOD audio isn’t disappearing when the application enters the background or isn’t re-appearing when coming back into the foreground?
In some much older versions of the integration you needed to call it yourself- what version of FMOD are you using?

Thank you for your reply!
I made some modification and it is ok on IOS.
However, the audio isn’t re-appearing when coming back into the foreground on Andriod, and it LogError as ‘Suspend Mixer Error:ERR_INTERNAL’. It work like this on Andriod:

          void OnApplicationPause(bool pauseStatus)
            {
                OnFocusChange(pauseStatus);
            }
        private void OnFocusChange(bool focusOut)
        {
            UnityEngine.Debug.Log($"OnFocusChange, {focusOut}");

            if (!IsInitialized)
            {
                UnityEngine.Debug.LogError("OnFocusChange not Initialized");
                return;
            }

            if (!studioSystem.isValid())
            {
                UnityEngine.Debug.LogError("OnFocusChange studio system not valid");
                return;
            }

            if (!PauseAllEvents(focusOut))
            {
                UnityEngine.Debug.LogError("Pause Event Error");
                return;
            }

            var result = RESULT.OK;
            if (focusOut)
                result = coreSystem.mixerSuspend();
            else
                result = coreSystem.mixerResume();

            if (result != RESULT.OK)
            {
                UnityEngine.Debug.LogError("Suspend Mixer Error: " + result);
                return;
            }

            m_FoucusOut = focusOut;
        }

The issue is probably appearing because you are calling suspend on an already suspended mixer, the mixer we suspended ourselves during RuntimeManager.OnApplicationPause.
If you really need to handle the mixer suspend and resume yourself then perhaps try commenting it out from RuntimeManager.OnApplicationPause and RuntimeManager.HandleInterrupt.
Again, I am not sure why you are needing to do any of this yourself as the RuntimeManger should be handling all of this for you, so if you are finding that the RuntimeManager is failing to suspend/resume audio when exiting/entering the foreground then please let us know so we can try to fix it!

Thank you again!
I found there is no RuntimeManager.OnApplicationPause or RuntimeManager.HandleInterrupt( which is aimed to ios ) in my version(2.0.0).
That is why I handle the mixer suspend and resume by myself.
As show in the code before, it seems I did not call suspend on an already suspended mixer. So do you know the real reason why this happened? ps: It just happens on Andriod.

RuntimeManager.HandleInterrupt was added in 2.00.06, and FMOD 2.00.00 certainly has RuntimeManager.OnApplicationPause, can you please double check your FMOD version there?
I see you are calling OnApplicationPause inside OnApplicationFocus which seems like it could create double calls to suspend/resume. They should be on the same thread though.
Here is what the calls in RuntimeManager.cs look like in 2.00.00 which may help:

        #if UNITY_IOS
        /* iOS alarm interruptions do not trigger OnApplicationPause
         * Sending the app to the background does trigger OnApplicationFocus
         * We don't want to use this on Android as other things (like the keyboard)
         * can steal focus.
         * https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnApplicationFocus.html */

        void OnApplicationFocus(bool focus)
        {
            if (studioSystem.isValid())
            {
                // Strings bank is always loaded
                if (loadedBanks.Count > 1)
                    PauseAllEvents(!focus);

                if (focus)
                {
                    lowlevelSystem.mixerResume();
                }
                else
                {
                    lowlevelSystem.mixerSuspend();
                }
            }
        }
        #else
        void OnApplicationPause(bool pauseStatus)
        {
            if (studioSystem.isValid())
            {
                PauseAllEvents(pauseStatus);

                if (pauseStatus)
                {
                    coreSystem.mixerSuspend();
                }
                else
                {
                    coreSystem.mixerResume();
                }
            }
        }
        #endif