private void InputCallback(HMIDIIN hMidiIn, MidiInMessage wMsg, UIntPtr dwInstance, UIntPtr dwParam1, UIntPtr dwParam2) { _isInsideInputHandler = true; try { switch (wMsg) { case MidiInMessage.MIM_DATA: { HandleInputMimData(dwParam1, dwParam2); break; } case MidiInMessage.MIM_LONGDATA: { HandleInputMimLongData(dwParam1, dwParam2); } break; case MidiInMessage.MIM_MOREDATA: SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x13 }, 13)); break; case MidiInMessage.MIM_OPEN: //SysEx(new SysExMessage(this, new byte[] { 0x01 }, 1)); break; case MidiInMessage.MIM_CLOSE: //SysEx(new SysExMessage(this, new byte[] { 0x02 }, 2)); break; case MidiInMessage.MIM_ERROR: SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x03 }, 3)); break; case MidiInMessage.MIM_LONGERROR: SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x04 }, 4)); break; default: SysEx?.Invoke(new SysExMessage(this, new byte[] { 0x05 }, 5)); break; } } finally { _isInsideInputHandler = false; } }
private void Decode(byte[] message) { byte status = message[0]; switch (status & 0b1111_1000) { case Midi.Status.NoteOffBitmask: if (NoteOffMessage.TryDecode(message, out var noteOffMessage)) { NoteOff?.Invoke(this, in noteOffMessage); } break; case Midi.Status.NoteOnBitmask: if (NoteOnMessage.TryDecode(message, out var noteOnMessage)) { NoteOn?.Invoke(this, in noteOnMessage); } break; case Midi.Status.PolyphonicKeyPressureBitmask: if (PolyphonicKeyPressureMessage.TryDecode(message, out var polyphonicKeyPressureMessage)) { PolyphonicKeyPressure?.Invoke(this, in polyphonicKeyPressureMessage); } break; case Midi.Status.ControlChangeBitmask: if (ControlChangeMessage.TryDecode(message, out var controlChangeMessage)) { _nrpnInterpreters[(int)controlChangeMessage.Channel].HandleControlChangeMessage(in controlChangeMessage); } break; case Midi.Status.ProgramChangeBitmask: if (ProgramChangeMessage.TryDecode(message, out var programChangeMessage)) { ProgramChange?.Invoke(this, in programChangeMessage); } break; case Midi.Status.ChannelPressureBitmask: if (ChannelPressureMessage.TryDecode(message, out var channelPressureMessage)) { ChannelPressure?.Invoke(this, in channelPressureMessage); } break; case Midi.Status.PitchBendChange: if (PitchBendMessage.TryDecode(message, out var pitchBendMessage)) { PitchBend?.Invoke(this, in pitchBendMessage); } break; case Midi.Status.System: switch (status) { case Midi.Status.SysExStart: if (SysExMessage.TryDecode(message, out var sysExMessage)) { SysEx?.Invoke(this, in sysExMessage); } break; default: Log.Error("Unknown system message type {Status}", $"{status:X2}"); break; } break; case Midi.Status.SystemRealTimeBitmask: if (SystemRealTimeMessage.TryDecode(message[0], out var systemRealTimeMessage)) { SystemRealTime?.Invoke(this, in systemRealTimeMessage); } break; default: Log.Error("Unknown message type {Bitmask}", $"{status & 0b1111_0000:X2}"); break; } }