melanchall / drywetmidi

.NET library to read, write, process MIDI files and to work with MIDI devices
https://melanchall.github.io/drywetmidi
MIT License
523 stars 73 forks source link

Crash when running in Unity on M2 MacBook #267

Closed akshayabd closed 11 months ago

akshayabd commented 11 months ago

Hi,

I'm using DryWetMIDI to process inputs from MIDI devices like an electric keyboard in a Unity project. I'm using the Unity asset available to do this.

Things work on a Windows machine, however when I try running on a MacBook it crashes fairly quickly with the following stacktrace:

NullReferenceException: Object reference not set to an instance of an object
Melanchall.DryWetMidi.Multimedia.InputDevice.OnMessage_Mac (System.IntPtr pktlist, System.IntPtr readProcRefCon, System.IntPtr srcConnRefCon) (at <aa425ed4de0e44068f897ec3718f60da>:0)
(wrapper native-to-managed) Melanchall.DryWetMidi.Multimedia.InputDevice.OnMessage_Mac(intptr,intptr,intptr)
UnityEngine.<>c:<RegisterUECatcher>b__0_0(Object, UnhandledExceptionEventArgs) (at /Users/bokken/build/output/unity/unity/Runtime/Export/Scripting/UnhandledExceptionHandler.bindings.cs:46)

I was wondering if you have encountered this before and if there is a solution for this?

I'm getting the connected device using the following code:

List<InputDevice> inputDevices = InputDevice.GetAll().ToList();
if (inputDevices.Count > 0)
{
      InputDevice _inputDevice = inputDevices.First();
      _inputDevice.EventReceived += OnEventReceived;
      _inputDevice.StartEventsListening();
}

Then I'm handling the events in a method with the signature:

private void OnEventReceived(object sender, MidiEventReceivedEventArgs e)
{
}

If you need more information please let me know, I can perhaps create a minimal project and share it on GitHub.

melanchall commented 11 months ago

Hi,

Unfortunately I have no Apple devices, so I won't be able to do tests on my side. So I really need your help with the issue.

Well, first of all, download please the ReceiveMidiData utility for macOS from here. Run it (in Terminal for example), select the same device and tell me please if the same error occurs.

Also what if you try to receive data from another MIDI device? Do you see the same error?

And one more question: do you have Visual Studio for Mac installed? I suppose we'll need to debug the library on your side.

Thanks, Max

melanchall commented 11 months ago

Oh wait, I've just noticed a problem in your code:

if (inputDevices.Count > 0)
{
      InputDevice _inputDevice = inputDevices.First();

You create local variable here which will be collected by GC when the method exits. So in OnEventReceived the _inputDevice is probably deleted. You need to declare _inputDevice as a class field, not as a local variable. And I suppose the problem will gone. See an example here: https://melanchall.github.io/drywetmidi/articles/devices/Input-device.html.

akshayabd commented 11 months ago

Ah such a silly mistake - thanks for pointing that out!

Confirmed when I use a class field the issue doesn't occur. Odd it worked on Windows, maybe the GC behavior is different there.