/// <summary> /// Process a message, adjusting the MIDI context /// </summary> /// <param name="message">The message to process</param> public void ProcessMessage(MidiMessage message) { var hasStatus = true; if (0 != message.Status) { RunningStatus = message.Status; } else { hasStatus = false; } int cn = (hasStatus ? message.Status & 0xF : (0XFF != ChannelPrefix ? ChannelPrefix : (RunningStatus & 0xF))); switch (RunningStatus & 0xF0) { case 0xC0: var mb = message as MidiMessageByte; Channels[cn].Patch = mb.Data1; break; case 0xD0: mb = message as MidiMessageByte; Channels[cn].ChannelPressure = mb.Data1; break; case 0x80: var mw = message as MidiMessageWord; Channels[cn].Notes[mw.Data1] = 0; break; case 0x90: mw = message as MidiMessageWord; Channels[cn].Notes[mw.Data1] = mw.Data2; break; case 0xA0: mw = message as MidiMessageWord; Channels[cn].KeyPressure[mw.Data1] = mw.Data2; break; case 0xB0: mw = message as MidiMessageWord; // respect send all notes off as necessary if (mw.Data1 >= 123 && mw.Data2 >= 127) { for (int i = 0; i < 128; ++i) { var b = Channels[cn].Notes[i]; if (0xFF != b) { Channels[cn].Notes[i] = 0; } } } Channels[cn].Controls[mw.Data1] = mw.Data2; break; case 0xE0: mw = message as MidiMessageWord; Channels[cn].PitchWheel = mw.Data; break; case 0xF0: switch (RunningStatus & 0xF) { case 0xF: var mbs = message as MidiMessageMeta; switch (mbs.Data1) { case 0x20: ChannelPrefix = mbs.Data[0]; break; case 0x51: if (BitConverter.IsLittleEndian) { MicroTempo = (mbs.Data[0] << 16) | (mbs.Data[1] << 8) | mbs.Data[2]; } else { MicroTempo = (mbs.Data[2] << 16) | (mbs.Data[1] << 8) | mbs.Data[0]; } break; case 0x58: TimeSignature = new MidiTimeSignature(mbs.Data[0], (byte)Math.Pow(mbs.Data[1], 2), mbs.Data[2], mbs.Data[3]); break; } break; } break; } }
/// <summary> /// Creates an event at the specified position with the specified MIDI message /// </summary> /// <param name="position">The position in MIDI ticks</param> /// <param name="message">The MIDI message for this event</param> public MidiEvent(int position, MidiMessage message) { Position = position; Message = message; }
internal static MidiSequence ReadFrom(Stream stream) { MidiSequence result = new MidiSequence(); var rs = (byte)0; var delta = _ReadVarlen(stream); if (BitConverter.IsLittleEndian) { delta = _Swap(delta); } var i = stream.ReadByte(); while (-1 != i) { var hasStatus = false; var b = (byte)i; if (0x7F < b) { hasStatus = true; rs = b; i = stream.ReadByte(); if (-1 != i) { b = (byte)i; } else { b = 0; } } var st = hasStatus ? rs : (byte)0; var m = (MidiMessage)null; switch (rs & 0xF0) { case 0x80: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageNoteOff(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F))); break; case 0x90: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageNoteOn(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F))); break; case 0xA0: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageKeyPressure(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F))); break; case 0xB0: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageCC(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F))); break; case 0xC0: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessagePatchChange(b, unchecked ((byte)(st & 0x0F))); break; case 0xD0: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageChannelPressure(b, unchecked ((byte)(st & 0x0F))); break; case 0xE0: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageChannelPitch(b, (byte)stream.ReadByte(), unchecked ((byte)(st & 0x0F))); break; case 0xF0: switch (rs & 0xF) { case 0xF: if (i == -1) { throw new EndOfStreamException(); } var l = _ReadVarlen(stream); //if (BitConverter.IsLittleEndian) // l = _Swap(l); var ba = new byte[l]; if (l != stream.Read(ba, 0, ba.Length)) { throw new EndOfStreamException(); } m = new MidiMessageMeta(st, b, ba); break; case 0x0: case 0x7: if (i == -1) { throw new EndOfStreamException(); } l = _ReadVarlen(b, stream); //if (BitConverter.IsLittleEndian) // l = _Swap(l); ba = new byte[l]; if (l != stream.Read(ba, 0, ba.Length)) { throw new EndOfStreamException(); } m = new MidiMessageSysex(st, ba); break; case 0x2: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageWord(st, b, (byte)stream.ReadByte()); break; case 0x3: if (i == -1) { throw new EndOfStreamException(); } m = new MidiMessageByte(st, b); break; case 0x6: case 0x8: case 0xA: case 0xB: case 0xC: // status *was* specified if we got here m = new MidiMessage(st); break; default: throw new NotSupportedException("The MIDI message is not recognized."); } break; } result.Events.Add(new MidiEvent(delta, m)); i = _ReadVarlen(stream); if (-1 == i) { break; } delta = i; i = stream.ReadByte(); } return(result); }