private int ParseBuffer(byte[] data, int offset, int length, out MidiMessage message) { message = null; int messageLength = 0; if (length == 0) { // Should not happen return(0); } uint rawCommand = data[offset]; uint channel = (rawCommand & 0x0f) + 1; EMidiCommand command = (EMidiCommand)(rawCommand & 0xF0); if (command == EMidiCommand.SystemMessageMask) { // System message channel = 0; command = (EMidiCommand)rawCommand; messageLength = 1; switch (command) { case EMidiCommand.TimingClock: message = new TimingClockMessage(); break; case EMidiCommand.StartSequence: message = new StartSequenceMessage(); break; case EMidiCommand.ContinueSequence: message = new ContinueSequenceMessage(); break; case EMidiCommand.StopSequence: message = new StopSequenceMessage(); break; case EMidiCommand.ActiveSensing: message = new ActiveSensingMessage(); break; case EMidiCommand.SystemExclusive: messageLength = ParseSysex(data, offset, length, ref message); break; } } else { uint p1 = (length >= 2) ? data[offset + 1] : 0u; uint p2 = (length >= 3) ? data[offset + 2] : 0u; // Common message switch (command) { case EMidiCommand.NoteOff: case EMidiCommand.NoteOn: case EMidiCommand.KeyAfterTouch: message = new MidiNoteMessage(channel, command, p1, p2); messageLength = 3; break; case EMidiCommand.ControlChange: message = new MidiControlChangeMessage(channel, p1, p2); messageLength = 3; break; case EMidiCommand.PatchChange: message = new MidiPatchChangeMessage(channel, p1); messageLength = 2; break; case EMidiCommand.ChannelAfterTouch: message = new MidiChannelAfterTouchMessage(channel, p1); messageLength = 2; break; case EMidiCommand.PitchWheelChange: message = new MidiPitchChangeMessage(channel, p1 + (p2 << 7)); messageLength = 3; break; } // Indicate truncated message in reply if (length < messageLength) { messageLength = -1; } } return(messageLength); }
// Parse a midi message from a midi input MIM_DATA message private static MidiMessage ParseShortMessage(uint message) { MidiMessage result = null; uint rawCommand = message & 0xff; uint channel = (rawCommand & 0x0f) + 1; EMidiCommand command = (EMidiCommand)(rawCommand & 0xF0); if (command == EMidiCommand.SystemMessageMask) { // System message channel = 0; command = (EMidiCommand)rawCommand; switch (command) { case EMidiCommand.TimingClock: result = new TimingClockMessage(); break; case EMidiCommand.StartSequence: result = new StartSequenceMessage(); break; case EMidiCommand.ContinueSequence: result = new ContinueSequenceMessage(); break; case EMidiCommand.StopSequence: result = new StopSequenceMessage(); break; case EMidiCommand.ActiveSensing: result = new ActiveSensingMessage(); break; } } else { uint p1 = (message >> 8) & 0xff; uint p2 = (message >> 16) & 0xff; // Common message switch (command) { case EMidiCommand.NoteOff: case EMidiCommand.NoteOn: case EMidiCommand.KeyAfterTouch: result = new MidiNoteMessage(channel, command, p1, p2); break; case EMidiCommand.ControlChange: result = new MidiControlChangeMessage(channel, p1, p2); break; case EMidiCommand.PatchChange: result = new MidiPatchChangeMessage(channel, p1); break; case EMidiCommand.ChannelAfterTouch: result = new MidiChannelAfterTouchMessage(channel, p1); break; case EMidiCommand.PitchWheelChange: result = new MidiPitchChangeMessage(channel, p1 + (p2 << 7)); break; } } return(result); }