summaryrefslogtreecommitdiffstats
path: root/src/midi.c
diff options
context:
space:
mode:
authorgramanas <anastasis.gramm2@gmail.com>2023-04-20 18:24:49 +0300
committergramanas <anastasis.gramm2@gmail.com>2023-04-20 18:24:49 +0300
commitc161e1016a04566a56b4858ea43502fed88dcc7f (patch)
treeb4b3086f000df6b63229dae6057f1aa253811b30 /src/midi.c
parent1e374b426b4182c7b73b35219aadaca267b9623c (diff)
downloadsynth-project-c161e1016a04566a56b4858ea43502fed88dcc7f.tar.gz
synth-project-c161e1016a04566a56b4858ea43502fed88dcc7f.tar.bz2
synth-project-c161e1016a04566a56b4858ea43502fed88dcc7f.zip
Add midi
Diffstat (limited to 'src/midi.c')
-rw-r--r--src/midi.c91
1 files changed, 91 insertions, 0 deletions
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 <string.h>
+
+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();
+}