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

MidiInput.MessageReceived is dropping messages on Linux / not receiving all of them

oxysoft opened this issue · comments

Hello, I am writing an application using this library. The application receives MIDI input and tracks held notes using the incoming messages. Unfortunately if I press a large number of notes all at once, or release many at once, then the tracking is invalid

recording-2022-04-2520.46.36.mp4

Here, I am pressing all the white notes (non-ghosted) and releasing them all at once. As you can see, only some of them light up, and some of them stay stuck when I release them all.

This is the relevant code:

		public PianoDrawable()
		{
			IMidiAccess midiaccess = MidiAccessManager.Default;
			foreach (IMidiPortDetails details in midiaccess.Inputs)
			{
				IMidiInput input = midiaccess.OpenInputAsync(details.Id).Result;
				_midiInputs.Add(input);
				input.MessageReceived += OnMidiInputMessage;
			}
		}

		private void OnMidiInputMessage(object? sender, MidiReceivedEventArgs e)
		{
			var events = MidiEvent.Convert(e.Data, e.Start, e.Length);
			Console.WriteLine($"{e.Start} - {e.Length}@{events.Count()}");
			foreach (MidiEvent ev in events)
			{
				if (ev.EventType == MidiEvent.NoteOn)
				{
					byte a440 = ev.Msb;
					byte vel  = ev.Lsb;

					_notes[a440] = vel > 0;
				}
				else if (ev.EventType == MidiEvent.NoteOff)
				{
					byte a440 = ev.Msb;
					_notes[a440] = false;
				}
			}
		}

Anything off with this piece of code? Or is there a peculiarity about MIDI that I don't know? Note I've never had this kind of issue in FL Studio to my knowledge, using JACK and wineasio, so I don't think it's a problem or limitation with my MIDI/USB adapter.

Cheers

Hi. I'm rather curious about the outputs from Console.WriteLine(); if it drops some notes at that level then there may be problem with MidiEvent.Convert(). If the correct MIDI events are not passed at e.Data then there may be either MIDI packet dropouts at AlsaMidiAccess (or whatever I created, I haven't written C# code for years anymore) or it was already corrupt before our library. Try dumping e.Data content on the console as well?

(A) Pressing one by one:

0 - 3@1 [144, 48, 41]
0 - 3@1 [144, 48, 0]
0 - 3@1 [144, 50, 34]
0 - 3@1 [144, 50, 0]
0 - 3@1 [144, 52, 41]
0 - 3@1 [144, 52, 0]
0 - 3@1 [144, 53, 40]
0 - 3@1 [144, 53, 0]
0 - 3@1 [144, 55, 40]
0 - 3@1 [144, 55, 0]
0 - 3@1 [144, 48, 62]

(B) Pressing all five at once:

0 - 3@1 [144, 55, 49]
0 - 2@1 [52, 50]
0 - 2@1 [50, 54]
0 - 2@1 [48, 55]
0 - 2@1 [53, 50]

(C) Releasing all five at once:

0 - 3@1 [144, 48, 0]
0 - 2@1 [52, 0]
0 - 3@1 [144, 50, 0]
0 - 4@2 [254, 144, 53, 0]
0 - 3@1 [144, 55, 0]

Looks like the data is getting jumbled up somewhere. In (B) these look like the right messages, but missing 144 in front. In (C), we see an extra 254 slips in front.

The input byte sequences most likely contain input messages with running statuses.