From c161e1016a04566a56b4858ea43502fed88dcc7f Mon Sep 17 00:00:00 2001 From: gramanas Date: Thu, 20 Apr 2023 18:24:49 +0300 Subject: Add midi --- src/midi.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/midi.c (limited to 'src/midi.c') diff --git a/src/midi.c b/src/midi.c new file mode 100644 index 0000000..46608cb --- /dev/null +++ b/src/midi.c @@ -0,0 +1,91 @@ +#include "midi.h" + +#include + +void midi_decode(uint32_t msg) { + // printf("MIDI message: 0x%X\n", msg); + uint8_t status = msg; + uint8_t data1 = (msg >> 8) & 0xFF; + uint8_t data2 = (msg >> 16) & 0xFF; + uint8_t channel = (status & 0x0F) + 1; // convert to human + uint8_t message = status >> 4; + + switch (message) { + case 0x08: + printf("Note Off: channel=%d, note=%d, velocity=%d\n", channel, data1, data2); + break; + case 0x09: + printf("Note On: channel=%d, note=%d, velocity=%d\n", channel, data1, data2); + break; + case 0x0A: + printf("Aftertouch: channel=%d, note=%d, pressure=%d\n", channel, data1, data2); + break; + case 0x0B: + printf("Control Change: channel=%d, controller=%d, value=%d\n", channel, data1, data2); + break; + case 0x0C: + printf("Program Change: channel=%d, program=%d\n", channel, data1); + break; + case 0x0D: + printf("Channel Pressure: channel=%d, pressure=%d\n", channel, data1); + break; + case 0x0E: + printf("Pitch Bend: channel=%d, value=%d\n", channel, ((data2 << 7) | data1) - 8192); + break; + default: + printf("Unknown MIDI message\n"); + break; + } +} + + +void +midiCallback(PtTimestamp timestamp, void *userData) { + midi_t * m = (midi_t *)userData; + + if (!m->stream) return; + + if (!Pm_Poll(m->stream)) return; + + PmEvent buf; + Pm_Read(m->stream, &buf, 1); + + //printf("%d\n", buf.message); + midi_decode(buf.message); + +} + +void +init_midi(midi_t *m, synth_t *synth) +{ + m->stream = NULL; + + Pm_Initialize(); + + printf("midi devs: %d\n", Pm_CountDevices()); + const PmDeviceInfo *info; + int i; + for (i = 0; i < Pm_CountDevices(); i++) { + info = Pm_GetDeviceInfo(i); + printf("%d: %s [input: %d output: %d opened: %d is_virt:%d] (interf: %s) -- %d\n", i, info->name, info->input, info->output, info->opened, info->is_virtual, info->interf, Pm_GetDefaultInputDeviceID()); + //if (!strcmp("MPK225 MIDI", info->name) && !info->input) break; + if (!strcmp("MPK225 Port A", info->name) && info->input == 1) break; + } + + Pt_Start(1, midiCallback, m); + + Pm_OpenInput(&(m->stream), + i, //Pm_GetDefaultInputDeviceID(), + NULL, + 128, + NULL, + NULL); +} + +void +terminate_midi(midi_t *m) +{ + Pm_Close(m->stream); + Pt_Stop(); + Pm_Terminate(); +} -- cgit v1.2.3