atsushieno / managed-midi

[Past project] Cross-platform MIDI processing library for mono and .NET (ALSA, CoreMIDI, Android, WinMM and UWP).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Exception on device disconnect on Windows

holly-hacker opened this issue · comments

I run MidiAccessManager.Default.Inputs.ToList() every 500ms, and it crashes with the following stacktrace when a MIDI device gets removed:

System.ComponentModel.Win32Exception: There is no driver installed on your system. (6)
  at Commons.Music.Midi.WinMM.WinMMMidiInput.DieOnError(Int32 code) in D:\a\1\s\Commons.Music.Midi.DesktopShared\winmm\WinmmMidiAccess.cs:235
  at Commons.Music.Midi.WinMM.WinMMMidiInput.LongMessageBuffer.AddBuffer() in D:\a\1\s\Commons.Music.Midi.DesktopShared\winmm\WinmmMidiAccess.cs:286
  at Commons.Music.Midi.WinMM.WinMMMidiInput.LongMessageBuffer.Recycle() in D:\a\1\s\Commons.Music.Midi.DesktopShared\winmm\WinmmMidiAccess.cs:297
  at Commons.Music.Midi.WinMM.WinMMMidiInput.HandleLongData(IntPtr param1, IntPtr param2) in D:\a\1\s\Commons.Music.Midi.DesktopShared\winmm\WinmmMidiAccess.cs:147
  at Commons.Music.Midi.WinMM.WinMMMidiInput.HandleMidiInProc(IntPtr midiIn, MidiInMessage msg, IntPtr instance, IntPtr param1, IntPtr param2) in D:\a\1\s\Commons.Music.Midi.DesktopShared\winmm\WinmmMidiAccess.cs:171
  at at Commons.Music.Midi.WinMM.WinMMNatives.midiInGetNumDevs()
  at Commons.Music.Midi.WinMM.WinMMMidiAccess.get_Inputs()+MoveNext() in D:\a\1\s\Commons.Music.Midi.DesktopShared\winmm\WinmmMidiAccess.cs:18
  at at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
  at at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
  at at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
  at osu.Framework.Input.Handlers.MidiInputHandler.refreshDevices() in D:\Projects\Git\osu-framework\osu.Framework\Input\Handlers\MidiInputHandler.cs:58

Input from my device works fine, and on Linux I don't have this issue. You can see my usage here.

Thanks for the report!

@noname22 do you have any idea on how this WinMMMidiInput.HandleLongData() could fail like this? I will try by myself once I got a working Windows development setup too.

What I have figured out so far:

  • device disconnection would/should indeed trigger HandleMidiInProc.
  • The MidiIn msg is poorly documented and I have no idea what should be sent in such case.

c.f. https://social.msdn.microsoft.com/forums/vstudio/en-US/ede0ba0b-432c-48b7-9d6e-7bba3b4f062e/midiinproc-not-well-documented

I want to mention that I didn't have this when I was using NAudio, so comparing to it may be useful.

I wouldn't be surprised if we get a MidiInMessage.Close before that message (which we currently ignore).

See here.

If that's the case we should ignore any messages after close.

Thanks, but it does not seem to be sent. I tried adding case MidiInMessage.Close in HandleMidiInProc but it does not happen (at least before the crashy message above). Looks like the message size (buffer.Header.BytesRecorded) is 0.

Thanks, but it does not seem to be sent. I tried adding case MidiInMessage.Close in HandleMidiInProc but it does not happen (at least before the crashy message above). Looks like the message size (buffer.Header.BytesRecorded) is 0.

Ah, crap :(

Is it possible to just skip any zero byte messages?

After all there was no any decent solution, so I just added a workaround (skip it) code at 6b197af. I will be pushed to nuget soon.