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.
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
inHandleMidiInProc
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.