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!