using System; using System.Collections.Generic; using System.Diagnostics.Metrics; using System.Linq; using System.Text; using System.Threading.Channels; using System.Threading.Tasks; namespace RushMidiLibrary { public struct MidiShortMessage { public UIntPtr dwParam1; public UIntPtr dwParam2; public MidiShortMessage(UIntPtr dwParam1, UIntPtr dwParam2) { this.dwParam1 = dwParam1; this.dwParam2 = dwParam2; } public bool IsNoteOn { get { return ((int)dwParam1 & 0xf0) == 0x90; } } public void GetNoteOn(out MidiChannel channel, out int noteId, out int velocity, out uint timestamp) { channel = (MidiChannel)((int)dwParam1 & 0x0f); noteId = ((int)dwParam1 & 0xff00) >> 8; velocity = ((int)dwParam1 & 0xff0000) >> 16; timestamp = (uint)dwParam2; } public bool IsNoteOff { get { return ((int)dwParam1 & 0xf0) == 0x80; } } public void GetNoteOff(out MidiChannel channel, out int noteId, out int velocity, out uint timestamp) { channel = (MidiChannel)((int)dwParam1 & 0x0f); noteId = ((int)dwParam1 & 0xff00) >> 8; velocity = ((int)dwParam1 & 0xff0000) >> 16; timestamp = (uint)dwParam2; } public bool IsControlChange { get { return ((int)dwParam1 & 0xf0) == 0xB0; } } public void GetControlChange(out MidiChannel channel, out MidiControl control, out int value, out uint timestamp) { channel = (MidiChannel)((int)dwParam1 & 0x0f); control = (MidiControl)(((int)dwParam1 & 0xff00) >> 8); value = ((int)dwParam1 & 0xff0000) >> 16; timestamp = (uint)dwParam2; } public bool IsProgramChange { get { return ((int)dwParam1 & 0xf0) == 0xC0; } } public void DecodeProgramChange(out MidiChannel channel, out MidiInstrument instrument, out uint timestamp) { channel = (MidiChannel)((int)dwParam1 & 0x0f); instrument = (MidiInstrument)(((int)dwParam1 & 0xff00) >> 8); timestamp = (uint)dwParam2; } public bool IsPitchBend { get { return ((int)dwParam1 & 0xf0) == 0xE0; } } public void GetPitchBend(out MidiChannel channel, out int value, out uint timestamp) { channel = (MidiChannel)((int)dwParam1 & 0x0f); value = ((((int)dwParam1 >> 9) & 0x3f80) | (((int)dwParam1 >> 8) & 0x7f)); timestamp = (uint)dwParam2; } public bool IsRealTime { get { return ((int)dwParam1 & 0xf8) == 0xF8; } } public void GetRealTime(out MidiRealTimeMessageType msgType, out uint timestamp) { int messageType = (int)dwParam1 & 0x07; switch (messageType) { case 0: msgType = MidiRealTimeMessageType.TimingClock; break; case 2: msgType = MidiRealTimeMessageType.Start; break; case 3: msgType = MidiRealTimeMessageType.Continue; break; case 4: msgType = MidiRealTimeMessageType.Stop; break; case 6: msgType = MidiRealTimeMessageType.ActiveSensing; break; case 7: msgType = MidiRealTimeMessageType.SystemReset; break; case 1: case 5: msgType = MidiRealTimeMessageType.Undefined; break; default: throw new ArgumentException("Unknown realtime message"); } timestamp = (uint)dwParam2; } } }