Crash on OSX when using programmer sound

Hi all!

We’re using Unity 2019.2.11 and FMOD 2.00.01 and we’re seeing a crash on OSX when trying to play a programmer sound. Here is the stacktrace:

<i>OSXPlayer(ANZC02SC05QGQ17)</i> StackOverflowException: The requested operation caused a stack overflow.
  at (wrapper managed-to-native) FMOD.Studio.EventInstance.FMOD_Studio_EventInstance_GetUserData(intptr,intptr&)
  at FMOD.Studio.EventInstance.getUserData (System.IntPtr& userdata) [0x00001] in /Users/soap.build1/Desktop/NWH_macOS/Assets/Plugins/FMOD/src/Runtime/wrapper/fmod_studio.cs:1255 
  at AudioManager.ProgrammerSoundEventCallback (FMOD.Studio.EVENT_CALLBACK_TYPE eventCbType, FMOD.Studio.EventInstance ev, System.IntPtr parameterPtr) [0x00001] in /Users/soap.build1/Desktop/NWH_macOS/Assets/Classes/gameClasses/audio/AudioManager.cs:336 
  at (wrapper native-to-managed) AudioManager.ProgrammerSoundEventCallback(FMOD.Studio.EVENT_CALLBACK_TYPE,FMOD.Studio.EventInstance,intptr)
UnityEngine.DebugLogHandler:Internal_LogException(Exception, Object)
UnityEngine.DebugLogHandler:LogException(Exception, Object)
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
UnityEngine.UnhandledExceptionHandler:<RegisterUECatcher>m__0(Object, UnhandledExceptionEventArgs) (at /Users/builduser/buildslave/unity/build/Runtime/Export/Scripting/UnhandledExceptionHandler.bindings.cs:46)
FMOD.Studio.EventInstance:FMOD_Studio_EventInstance_GetUserData(IntPtr, IntPtr&)
FMOD.Studio.EventInstance:getUserData(IntPtr&) (at /Users/soap.build1/Desktop/NWH_macOS/Assets/Plugins/FMOD/src/Runtime/wrapper/fmod_studio.cs:1255)
AudioManager:ProgrammerSoundEventCallback(EVENT_CALLBACK_TYPE, EventInstance, IntPtr) (at /Users/soap.build1/Desktop/NWH_macOS/Assets/Classes/gameClasses/audio/AudioManager.cs:336)
 
(Filename: /Users/soap.build1/Desktop/NWH_macOS/Assets/Plugins/FMOD/src/Runtime/wrapper/fmod_studio.cs Line: 1255)

We’ve just taken the example from the FMOD’s website to play programmer sounds and removed what seemed unnecessary. It works fine on IOS or TVOS but will crash on MacOSX. Here is the code

public static EventInstance PlayProgrammerSound(string key, bool radioFilter)
{
    EventInstance ev = new EventInstance();
    try
    {
        string audioEventID = radioFilter ? AudioDB.VO_Dialogue_RADIO : AudioDB.VO_Dialogue;
        ev =  RuntimeManager.CreateInstance(audioEventID);
        ev.set3DAttributes(RuntimeUtils.To3DAttributes(Vector3.zero));
        
        if (!voiceOverEnabled)
        {
            return ev;
        }

        GCHandle stringHandle = GCHandle.Alloc(key, GCHandleType.Pinned);
        ev.setUserData(GCHandle.ToIntPtr(stringHandle));

        ev.setCallback(programmerSoundCallback);
        ev.start();
        ev.release();

    }
    catch (EventNotFoundException)
    {
        ev.setPaused(true);
        return ev;
    }

    return ev;
}
static GCHandle stringHandle;
// Cleaned up from FMOD website
[AOT.MonoPInvokeCallback(typeof(EVENT_CALLBACK))]
static RESULT ProgrammerSoundEventCallback(EVENT_CALLBACK_TYPE eventCbType, EventInstance ev, IntPtr parameterPtr)
{
    ev.getUserData(out IntPtr stringPtr);

    stringHandle = GCHandle.FromIntPtr(stringPtr);
    string key = stringHandle.Target as string;

    if (eventCbType == EVENT_CALLBACK_TYPE.CREATE_PROGRAMMER_SOUND)
    {
        MODE soundMode = MODE.LOOP_NORMAL | MODE.CREATECOMPRESSEDSAMPLE | MODE.NONBLOCKING;
        PROGRAMMER_SOUND_PROPERTIES parameter = (PROGRAMMER_SOUND_PROPERTIES) Marshal.PtrToStructure(parameterPtr, typeof(PROGRAMMER_SOUND_PROPERTIES));

        RESULT keyResult = RuntimeManager.StudioSystem.getSoundInfo(key, out SOUND_INFO dialogueSoundInfo);
        if (keyResult != RESULT.OK)
        {
            return keyResult;
        }

        RESULT soundResult = RuntimeManager.CoreSystem.createSound(dialogueSoundInfo.name_or_data, soundMode | dialogueSoundInfo.mode, ref dialogueSoundInfo.exinfo, out Sound dialogueSound);
        if (soundResult == RESULT.OK)
        {
            parameter.sound = dialogueSound.handle;
            parameter.subsoundIndex = dialogueSoundInfo.subsoundindex;
            Marshal.StructureToPtr(parameter, parameterPtr, false);
        }
    }
    else if (eventCbType == EVENT_CALLBACK_TYPE.DESTROY_PROGRAMMER_SOUND)
    {
        PROGRAMMER_SOUND_PROPERTIES parameter = (PROGRAMMER_SOUND_PROPERTIES)Marshal.PtrToStructure(parameterPtr, typeof(PROGRAMMER_SOUND_PROPERTIES));
        Sound sound = new Sound { handle = parameter.sound };
        sound.release();
    }
    else if (eventCbType == EVENT_CALLBACK_TYPE.DESTROYED)
    {
        stringHandle.Free();
    }

    return RESULT.OK;
}

The stacktrace indicates it’s crashing on ev.getUserData(out IntPtr stringPtr); in ProgrammerSoundEventCallback. the issue we’re having seems a bit similar to Supersonic C# Wrapper (DSP callback problem) but we’re not sure to understand what needs to be done. Any help will be much appreciated! Thanks!

Are you able to update the FMOD version at all? There was a fix put out in 2.00.03 that fixed an issue with callbacks on Mac.

Thanks for getting back to me.
We’re now hit with that issue: Linker error with FMOD Studio Unity iOS fmodstudio11009_v2_patch2

We then changed the wrapper to that. Is there any value you’d advise for exclusive and inclusive?

public RESULT getCPUUsage(out uint exclusive, out uint inclusive)
{
    //return FMOD_Studio_Bus_GetCPUUsage(this.handle, out exclusive, out inclusive);
    exclusive = 1;
    inclusive = 1;
    return RESULT.OK;
}

That is an old issue that was resolved before 2.0 was released, there is a similar one with a couple of new getCPUUsage functions: