diff --git a/src/channel.o b/src/channel.o new file mode 100644 index 0000000..72477e1 Binary files /dev/null and b/src/channel.o differ diff --git a/src/looper.c b/src/looper.c index 4aabbe5..6f6e2d5 100644 --- a/src/looper.c +++ b/src/looper.c @@ -1,7 +1,9 @@ // cppcheck-suppress missingIncludeSystem #include "looper.h" #include "channel.h" +#include "command.h" #include "midi.h" +#include "queue.h" #include #include #include @@ -9,8 +11,6 @@ #include #include #include -#include "command.h" -#include "queue.h" /* Global state (shared across files) */ struct channel_t channels[MAX_CHANNELS]; @@ -30,38 +30,48 @@ static int pending_unregister_idx = -1; static int pending_unregister_cycle = 0; static void apply_command(command_t cmd) { - switch (cmd.type) { - case CMD_CYCLE: - if (cmd.channel >= 0 && cmd.channel < MAX_CHANNELS) { - int cur = atomic_load(&channels[cmd.channel].state); - int next; - switch (cur) { - case STATE_IDLE: next = STATE_RECORD; break; - case STATE_RECORD: next = STATE_LOOPING; break; - case STATE_LOOPING: next = STATE_PAUSED; break; - case STATE_PAUSED: next = STATE_LOOPING; break; - default: next = STATE_IDLE; break; - } - atomic_store(&channels[cmd.channel].state, next); - } + switch (cmd.type) { + case CMD_CYCLE: + if (cmd.channel >= 0 && cmd.channel < MAX_CHANNELS) { + int cur = atomic_load(&channels[cmd.channel].state); + int next; + switch (cur) { + case STATE_IDLE: + next = STATE_RECORD; break; - case CMD_STOP: - if (cmd.channel >= 0 && cmd.channel < MAX_CHANNELS) - atomic_store(&channels[cmd.channel].state, STATE_IDLE); - else { - for (int i = 0; i < MAX_CHANNELS; i++) - atomic_store(&channels[i].state, STATE_IDLE); - } + case STATE_RECORD: + next = STATE_LOOPING; break; - case CMD_BIND_CHANNEL: - atomic_store(&bind_channel, cmd.data); + case STATE_LOOPING: + next = STATE_PAUSED; break; - case CMD_UNBIND: - atomic_store(&bind_channel, 0); + case STATE_PAUSED: + next = STATE_LOOPING; break; - default: + default: + next = STATE_IDLE; break; + } + atomic_store(&channels[cmd.channel].state, next); } + break; + case CMD_STOP: + if (cmd.channel >= 0 && cmd.channel < MAX_CHANNELS) + atomic_store(&channels[cmd.channel].state, STATE_IDLE); + else { + for (int i = 0; i < MAX_CHANNELS; i++) + atomic_store(&channels[i].state, STATE_IDLE); + } + break; + case CMD_BIND_CHANNEL: + atomic_store(&bind_channel, cmd.data); + break; + case CMD_UNBIND: + atomic_store(&bind_channel, 0); + break; + default: + break; + } } /* ---------------------------------------------------------------- diff --git a/src/looper.o b/src/looper.o new file mode 100644 index 0000000..026da08 Binary files /dev/null and b/src/looper.o differ diff --git a/src/main.o b/src/main.o new file mode 100644 index 0000000..fd3175c Binary files /dev/null and b/src/main.o differ diff --git a/src/midi.c b/src/midi.c index 4395550..6cfddaf 100644 --- a/src/midi.c +++ b/src/midi.c @@ -36,36 +36,34 @@ void midi_handle_events(void *port_buffer, jack_nframes_t nframes) { if (ck) { atomic_store(&control_key_active, 0); if (note < 16) { - command_t cmd = { .type = CMD_BIND_CHANNEL, .channel = -1, .data = note }; + command_t cmd = { + .type = CMD_BIND_CHANNEL, .channel = -1, .data = note}; queue_push(&cmd_queue, cmd); } else { switch (note) { - case 60: - { - command_t cmd = { .type = CMD_ADD_CHANNEL, .channel = -1, .data = 0 }; + case 60: { + command_t cmd = { + .type = CMD_ADD_CHANNEL, .channel = -1, .data = 0}; queue_push(&cmd_queue_main_midi, cmd); } break; - case 61: - { - command_t cmd = { .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0 }; + case 61: { + command_t cmd = { + .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0}; queue_push(&cmd_queue_main_midi, cmd); } break; - case 62: - { + case 62: { int bch = atomic_load(&bind_channel); if (bch >= 0 && bch < MAX_CHANNELS) { - command_t cmd = { .type = CMD_CYCLE, .channel = bch, .data = 0 }; + command_t cmd = {.type = CMD_CYCLE, .channel = bch, .data = 0}; queue_push(&cmd_queue, cmd); } } break; - case 63: - { - command_t cmd = { .type = CMD_UNBIND, .channel = -1, .data = 0 }; + case 63: { + command_t cmd = {.type = CMD_UNBIND, .channel = -1, .data = 0}; queue_push(&cmd_queue, cmd); } break; - case 65: - { - command_t cmd = { .type = CMD_STOP, .channel = -1, .data = 0 }; + case 65: { + command_t cmd = {.type = CMD_STOP, .channel = -1, .data = 0}; queue_push(&cmd_queue, cmd); } break; default: @@ -75,19 +73,17 @@ void midi_handle_events(void *port_buffer, jack_nframes_t nframes) { } else { /* direct mapping */ switch (note) { - case 1: - { - command_t cmd = { .type = CMD_CYCLE, .channel = 0, .data = 0 }; - queue_push(&cmd_queue, cmd); - } break; - case 60: - { - command_t cmd = { .type = CMD_ADD_CHANNEL, .channel = -1, .data = 0 }; + case 1: { + command_t cmd = {.type = CMD_CYCLE, .channel = 0, .data = 0}; + queue_push(&cmd_queue, cmd); + } break; + case 60: { + command_t cmd = {.type = CMD_ADD_CHANNEL, .channel = -1, .data = 0}; queue_push(&cmd_queue_main_midi, cmd); } break; - case 61: - { - command_t cmd = { .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0 }; + case 61: { + command_t cmd = { + .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0}; queue_push(&cmd_queue_main_midi, cmd); } break; default: diff --git a/src/midi.o b/src/midi.o new file mode 100644 index 0000000..c89e0e5 Binary files /dev/null and b/src/midi.o differ diff --git a/src/pipe.c b/src/pipe.c index c9a4e8b..da043f8 100644 --- a/src/pipe.c +++ b/src/pipe.c @@ -1,14 +1,14 @@ #include "pipe.h" -#include "queue.h" #include "command.h" +#include "queue.h" +#include +#include +#include #include #include #include -#include -#include #include -#include -#include +#include #define FIFO_PATH "/tmp/looper_cmd" #define LINE_MAX 256 @@ -18,57 +18,57 @@ extern spsc_queue_t cmd_queue; extern spsc_queue_t cmd_queue_main_fifo; static void *pipe_thread_func(void *arg) { - (void)arg; - FILE *fifo = fopen(FIFO_PATH, "r"); - if (!fifo) { - perror("fopen fifo"); - return NULL; - } - char line[LINE_MAX]; - while (fgets(line, sizeof(line), fifo)) { - /* strip newline */ - size_t len = strlen(line); - if (len > 0 && line[len-1] == '\n') - line[len-1] = '\0'; - - if (strcmp(line, "add") == 0) { - command_t cmd = { .type = CMD_ADD_CHANNEL, .channel = -1, .data = 0 }; - queue_push(&cmd_queue_main_fifo, cmd); - } else if (strcmp(line, "remove") == 0) { - command_t cmd = { .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0 }; - queue_push(&cmd_queue_main_fifo, cmd); - } else if (strncmp(line, "record ", 7) == 0) { - int ch = atoi(line + 7); - command_t cmd = { .type = CMD_CYCLE, .channel = ch, .data = 0 }; - queue_push(&cmd_queue, cmd); - } else if (strcmp(line, "stop") == 0) { - command_t cmd = { .type = CMD_STOP, .channel = -1, .data = 0 }; - queue_push(&cmd_queue, cmd); - } else if (strncmp(line, "bind ", 5) == 0) { - int ch = atoi(line + 5); - command_t cmd = { .type = CMD_BIND_CHANNEL, .channel = -1, .data = ch }; - queue_push(&cmd_queue, cmd); - } else if (strcmp(line, "unbind") == 0) { - command_t cmd = { .type = CMD_UNBIND, .channel = -1, .data = 0 }; - queue_push(&cmd_queue, cmd); - } - /* ignore unknown lines */ - } - fclose(fifo); + (void)arg; + FILE *fifo = fopen(FIFO_PATH, "r"); + if (!fifo) { + perror("fopen fifo"); return NULL; + } + char line[LINE_MAX]; + while (fgets(line, sizeof(line), fifo)) { + /* strip newline */ + size_t len = strlen(line); + if (len > 0 && line[len - 1] == '\n') + line[len - 1] = '\0'; + + if (strcmp(line, "add") == 0) { + command_t cmd = {.type = CMD_ADD_CHANNEL, .channel = -1, .data = 0}; + queue_push(&cmd_queue_main_fifo, cmd); + } else if (strcmp(line, "remove") == 0) { + command_t cmd = {.type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0}; + queue_push(&cmd_queue_main_fifo, cmd); + } else if (strncmp(line, "record ", 7) == 0) { + int ch = atoi(line + 7); + command_t cmd = {.type = CMD_CYCLE, .channel = ch, .data = 0}; + queue_push(&cmd_queue, cmd); + } else if (strcmp(line, "stop") == 0) { + command_t cmd = {.type = CMD_STOP, .channel = -1, .data = 0}; + queue_push(&cmd_queue, cmd); + } else if (strncmp(line, "bind ", 5) == 0) { + int ch = atoi(line + 5); + command_t cmd = {.type = CMD_BIND_CHANNEL, .channel = -1, .data = ch}; + queue_push(&cmd_queue, cmd); + } else if (strcmp(line, "unbind") == 0) { + command_t cmd = {.type = CMD_UNBIND, .channel = -1, .data = 0}; + queue_push(&cmd_queue, cmd); + } + /* ignore unknown lines */ + } + fclose(fifo); + return NULL; } int pipe_start_reader(void) { - /* create FIFO if it doesn't exist */ - if (mkfifo(FIFO_PATH, 0666) != 0 && errno != EEXIST) { - perror("mkfifo"); - return -1; - } - pthread_t tid; - if (pthread_create(&tid, NULL, pipe_thread_func, NULL) != 0) { - perror("pthread_create"); - return -1; - } - pthread_detach(tid); /* we don't need to join */ - return 0; + /* create FIFO if it doesn't exist */ + if (mkfifo(FIFO_PATH, 0666) != 0 && errno != EEXIST) { + perror("mkfifo"); + return -1; + } + pthread_t tid; + if (pthread_create(&tid, NULL, pipe_thread_func, NULL) != 0) { + perror("pthread_create"); + return -1; + } + pthread_detach(tid); /* we don't need to join */ + return 0; } diff --git a/src/pipe.o b/src/pipe.o new file mode 100644 index 0000000..7c189fb Binary files /dev/null and b/src/pipe.o differ diff --git a/src/queue.c b/src/queue.c index bca85c6..6e7f6e3 100644 --- a/src/queue.c +++ b/src/queue.c @@ -3,28 +3,29 @@ #include void queue_init(spsc_queue_t *q) { - /* nothing to allocate, just ensure head/tail start at 0 */ - q->head = 0; - q->tail = 0; + /* nothing to allocate, just ensure head/tail start at 0 */ + q->head = 0; + q->tail = 0; } bool queue_push(spsc_queue_t *q, command_t cmd) { - int h = atomic_load_explicit(&q->head, memory_order_relaxed); - int t = atomic_load_explicit(&q->tail, memory_order_acquire); - int next = (h + 1) % QUEUE_CAPACITY; - if (next == t) - return false; /* queue full */ - q->buffer[h] = cmd; - atomic_store_explicit(&q->head, next, memory_order_release); - return true; + int h = atomic_load_explicit(&q->head, memory_order_relaxed); + int t = atomic_load_explicit(&q->tail, memory_order_acquire); + int next = (h + 1) % QUEUE_CAPACITY; + if (next == t) + return false; /* queue full */ + q->buffer[h] = cmd; + atomic_store_explicit(&q->head, next, memory_order_release); + return true; } bool queue_pop(spsc_queue_t *q, command_t *cmd) { - int t = atomic_load_explicit(&q->tail, memory_order_relaxed); - int h = atomic_load_explicit(&q->head, memory_order_acquire); - if (t == h) - return false; /* queue empty */ - *cmd = q->buffer[t]; - atomic_store_explicit(&q->tail, (t + 1) % QUEUE_CAPACITY, memory_order_release); - return true; + int t = atomic_load_explicit(&q->tail, memory_order_relaxed); + int h = atomic_load_explicit(&q->head, memory_order_acquire); + if (t == h) + return false; /* queue empty */ + *cmd = q->buffer[t]; + atomic_store_explicit(&q->tail, (t + 1) % QUEUE_CAPACITY, + memory_order_release); + return true; } diff --git a/src/queue.o b/src/queue.o new file mode 100644 index 0000000..216d259 Binary files /dev/null and b/src/queue.o differ