feat: add command queue and FIFO pipe for unified input handling

Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
Loic Coenen
2026-05-09 21:31:54 +00:00
parent f7f18f9fa7
commit 392dabbc0f
8 changed files with 234 additions and 38 deletions

View File

@@ -1,6 +1,8 @@
// cppcheck-suppress missingIncludeSystem
#include "midi.h"
#include "channel.h"
#include "command.h"
#include "queue.h"
#include <jack/jack.h>
#include <jack/midiport.h>
#include <stdatomic.h>
@@ -9,6 +11,7 @@ extern atomic_int control_key_active;
extern atomic_int cmd_add;
extern atomic_int cmd_remove;
extern atomic_int bind_channel;
extern spsc_queue_t cmd_queue;
void midi_handle_events(void *port_buffer, jack_nframes_t nframes) {
(void)nframes;
@@ -34,7 +37,8 @@ void midi_handle_events(void *port_buffer, jack_nframes_t nframes) {
if (ck) {
atomic_store(&control_key_active, 0);
if (note < 16) {
atomic_store(&bind_channel, note);
command_t cmd = { .type = CMD_BIND_CHANNEL, .channel = -1, .data = note };
queue_push(&cmd_queue, cmd);
} else {
switch (note) {
case 60:
@@ -43,30 +47,19 @@ void midi_handle_events(void *port_buffer, jack_nframes_t nframes) {
case 61:
atomic_store(&cmd_remove, 1);
break;
case 62: /* trigger looper channel via bind_channel */
case 62:
{
int bch = atomic_load(&bind_channel);
if (bch >= 0 && bch < MAX_CHANNELS) {
int cur = atomic_load(&channels[bch].state);
switch (cur) {
case STATE_IDLE:
atomic_store(&channels[bch].state, STATE_RECORD);
break;
case STATE_RECORD:
atomic_store(&channels[bch].state, STATE_LOOPING);
break;
case STATE_LOOPING:
atomic_store(&channels[bch].state, STATE_PAUSED);
break;
case STATE_PAUSED:
atomic_store(&channels[bch].state, STATE_LOOPING);
break;
}
command_t cmd = { .type = CMD_CYCLE, .channel = bch, .data = 0 };
queue_push(&cmd_queue, cmd);
}
} break;
case 63: /* unbind reset bind to channel 0 */
atomic_store(&bind_channel, 0);
break;
case 63:
{
command_t cmd = { .type = CMD_UNBIND, .channel = -1, .data = 0 };
queue_push(&cmd_queue, cmd);
} break;
default:
break;
}
@@ -74,24 +67,11 @@ void midi_handle_events(void *port_buffer, jack_nframes_t nframes) {
} 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 1:
{
command_t cmd = { .type = CMD_CYCLE, .channel = 0, .data = 0 };
queue_push(&cmd_queue, cmd);
} break;
case 60:
atomic_store(&cmd_add, 1);
break;