public MidiNoteMessage(uint channel, EMidiCommand command, uint note, uint velocity) : base(command, channel) { switch (command) { case EMidiCommand.NoteOn: action = (velocity == 0) ? EMidiNoteAction.Off : EMidiNoteAction.On; break; case EMidiCommand.NoteOff: action = EMidiNoteAction.Off; break; case EMidiCommand.KeyAfterTouch: action = EMidiNoteAction.VelChange; break; } this.note = note; this.velocity = velocity; }
private MidiMessage[] GetMessages() { if (messages == null) { var msgList = new List <MidiMessage>(); for (int b = 0; b < data.Length; b++) { MidiMessage result = null; uint rawCommand = data[b]; uint channel = (rawCommand & 0x0f) + 1; EMidiCommand command = (EMidiCommand)(rawCommand & 0xF0); if (command != EMidiCommand.SystemMessageMask) { // Common message switch (command) { case EMidiCommand.NoteOff: case EMidiCommand.NoteOn: case EMidiCommand.KeyAfterTouch: result = new MidiNoteMessage(channel, command, data[++b], data[++b]); break; case EMidiCommand.ControlChange: result = new MidiControlChangeMessage(channel, data[++b], data[++b]); break; case EMidiCommand.PatchChange: result = new MidiPatchChangeMessage(channel, data[++b]); break; case EMidiCommand.ChannelAfterTouch: result = new MidiChannelAfterTouchMessage(channel, data[++b]); break; case EMidiCommand.PitchWheelChange: result = new MidiPitchChangeMessage(channel, data[++b] + ((uint)data[++b] << 7)); break; default: throw new InvalidOperationException("Unsupported message in sequence: " + command); } } else if (rawCommand == (uint)EMidiCommand.SystemExclusive) { var sysexBody = new List <byte>(); sysexBody.Add((byte)EMidiCommand.SystemExclusive); byte bodyByte = 0; while ((bodyByte = data[++b]) != (uint)EMidiCommand.EndOfSystemExclusive) { sysexBody.Add(bodyByte); } sysexBody.Add((byte)EMidiCommand.EndOfSystemExclusive); result = new MidiSysexMessage(sysexBody.ToArray()); } else { // System message throw new InvalidOperationException("Only sysex and common messages supported in sequence"); } msgList.Add(result); } messages = msgList.ToArray(); } return(messages); }
public MidiCommonMessage(EMidiCommand command, uint channel) : base(command, channel) { }
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); }
// Parse a midi message from a midi file private static MidiMessage ParseMidiMessage(MidiFileFormatReader mffr, uint runningStatus) { MidiMessage result = null; uint rawCommand; uint p1 = 0; bool alreadyReadP1 = false; // Read the command rawCommand = mffr.ReadUInt8(); if ((rawCommand & 0x80) == 0x80) { // New running status runningStatus = rawCommand; } else { // What we just read is actually p1 of a common message alreadyReadP1 = true; p1 = rawCommand; rawCommand = runningStatus; } // Get channel uint channel = (rawCommand & 0x0f) + 1; EMidiCommand command = (EMidiCommand)(rawCommand & 0xF0); if (command == EMidiCommand.SystemMessageMask) { // System message channel = 0; command = (EMidiCommand)rawCommand; switch (command) { // System messages - Exclusive case EMidiCommand.SystemExclusive: { // Determine length of body + end-of-exclusive uint length = mffr.ReadVarLengthQuantity(); byte[] sysexBody = new byte[length + 1]; // Read body sysexBody[0] = (byte)EMidiCommand.SystemExclusive; for (uint b = 0; b < length; b++) { sysexBody[b + 1] = mffr.ReadUInt8(); } // Verify end-of-exclusive if (sysexBody[length] != (byte)EMidiCommand.EndOfSystemExclusive) { throw new FormatException("Sysex of length " + length + " ending with " + sysexBody[length] + " instead of F7"); } result = new MidiSysexMessage(sysexBody); break; } // System messages - Common case EMidiCommand.SongPosition: case EMidiCommand.SongSelect: case EMidiCommand.TuneRequest: // System messages - Real time case EMidiCommand.TimingClock: case EMidiCommand.StartSequence: case EMidiCommand.ContinueSequence: case EMidiCommand.StopSequence: case EMidiCommand.ActiveSensing: throw new FormatException(string.Format("Found event type {0} - not supported!", command)); // Meta event case EMidiCommand.MetaEvent: result = ParseMidiMetaMessage(mffr); break; } } else { if (!alreadyReadP1) { p1 = mffr.ReadUInt8(); } // Channel message switch (command) { case EMidiCommand.NoteOff: case EMidiCommand.NoteOn: case EMidiCommand.KeyAfterTouch: result = new MidiNoteMessage(channel, command, p1, mffr.ReadUInt8()); break; case EMidiCommand.ControlChange: result = new MidiControlChangeMessage(channel, p1, mffr.ReadUInt8()); 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 + ((uint)mffr.ReadUInt8() << 7)); break; } } result.RunningStatus = runningStatus; return(result); }
// Build a serializable midi message from an actual midi message protected SerMidiMessage(MidiMessage midiMessage) { this.command = midiMessage.Command; this.channel = midiMessage.Channel; }