refactor: split monolithic main.c into modular source files

Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-08 21:03:10 +00:00
parent f1a92f1e95
commit 96295fdb4c
8 changed files with 423 additions and 336 deletions

91
src/midi.c Normal file
View File

@@ -0,0 +1,91 @@
#include <jack/jack.h>
#include <jack/midiport.h>
#include <stdatomic.h>
#include "midi.h"
#include "channel.h"
extern atomic_int control_key_active;
extern atomic_int cmd_add;
extern atomic_int cmd_remove;
void midi_handle_events(void *port_buffer, jack_nframes_t nframes)
{
(void)nframes;
jack_nframes_t nevents = jack_midi_get_event_count(port_buffer);
jack_midi_event_t ev;
for (jack_nframes_t i = 0; i < nevents; i++) {
if (jack_midi_event_get(&ev, port_buffer, i) != 0) continue;
if (ev.size < 3) continue;
unsigned char status = ev.buffer[0];
unsigned char note = ev.buffer[1];
unsigned char vel = ev.buffer[2];
/* noteon */
if ((status & 0xf0) == 0x90 && vel > 0) {
if (note == 64) {
atomic_store(&control_key_active, 1);
} else {
int ck = atomic_load(&control_key_active);
if (ck) {
atomic_store(&control_key_active, 0);
switch (note) {
case 60: atomic_store(&cmd_add, 1); break;
case 61: atomic_store(&cmd_remove, 1); break;
case 62: /* trigger looper channel 0 */
{
int cur0 = atomic_load(&channels[0].state);
switch (cur0) {
case STATE_IDLE:
atomic_store(&channels[0].state, STATE_RECORD);
break;
case STATE_RECORD:
atomic_store(&channels[0].state, STATE_LOOPING);
break;
case STATE_LOOPING:
atomic_store(&channels[0].state, STATE_PAUSED);
break;
case STATE_PAUSED:
atomic_store(&channels[0].state, STATE_LOOPING);
break;
}
}
break;
default:
break;
}
} else {
/* direct mapping */
switch (note) {
case 1: /* toggle channel 0 */
{
int cur0 = atomic_load(&channels[0].state);
switch (cur0) {
case STATE_IDLE:
atomic_store(&channels[0].state, STATE_RECORD);
break;
case STATE_RECORD:
atomic_store(&channels[0].state, STATE_LOOPING);
break;
case STATE_LOOPING:
atomic_store(&channels[0].state, STATE_PAUSED);
break;
case STATE_PAUSED:
atomic_store(&channels[0].state, STATE_LOOPING);
break;
}
}
break;
case 60: atomic_store(&cmd_add, 1); break;
case 61: atomic_store(&cmd_remove, 1); break;
default:
break;
}
}
}
} else if ((status & 0xf0) == 0x80 || ((status & 0xf0) == 0x90 && vel == 0)) {
atomic_store(&control_key_active, 0);
}
}
}