12-command-art #2
BIN
src/channel.o
Normal file
BIN
src/channel.o
Normal file
Binary file not shown.
24
src/looper.c
24
src/looper.c
@@ -1,7 +1,9 @@
|
|||||||
// cppcheck-suppress missingIncludeSystem
|
// cppcheck-suppress missingIncludeSystem
|
||||||
#include "looper.h"
|
#include "looper.h"
|
||||||
#include "channel.h"
|
#include "channel.h"
|
||||||
|
#include "command.h"
|
||||||
#include "midi.h"
|
#include "midi.h"
|
||||||
|
#include "queue.h"
|
||||||
#include <jack/jack.h>
|
#include <jack/jack.h>
|
||||||
#include <jack/midiport.h>
|
#include <jack/midiport.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -9,8 +11,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "command.h"
|
|
||||||
#include "queue.h"
|
|
||||||
|
|
||||||
/* Global state (shared across files) */
|
/* Global state (shared across files) */
|
||||||
struct channel_t channels[MAX_CHANNELS];
|
struct channel_t channels[MAX_CHANNELS];
|
||||||
@@ -36,11 +36,21 @@ static void apply_command(command_t cmd) {
|
|||||||
int cur = atomic_load(&channels[cmd.channel].state);
|
int cur = atomic_load(&channels[cmd.channel].state);
|
||||||
int next;
|
int next;
|
||||||
switch (cur) {
|
switch (cur) {
|
||||||
case STATE_IDLE: next = STATE_RECORD; break;
|
case STATE_IDLE:
|
||||||
case STATE_RECORD: next = STATE_LOOPING; break;
|
next = STATE_RECORD;
|
||||||
case STATE_LOOPING: next = STATE_PAUSED; break;
|
break;
|
||||||
case STATE_PAUSED: next = STATE_LOOPING; break;
|
case STATE_RECORD:
|
||||||
default: next = STATE_IDLE; break;
|
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);
|
atomic_store(&channels[cmd.channel].state, next);
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/looper.o
Normal file
BIN
src/looper.o
Normal file
Binary file not shown.
BIN
src/main.o
Normal file
BIN
src/main.o
Normal file
Binary file not shown.
46
src/midi.c
46
src/midi.c
@@ -36,36 +36,34 @@ void midi_handle_events(void *port_buffer, jack_nframes_t nframes) {
|
|||||||
if (ck) {
|
if (ck) {
|
||||||
atomic_store(&control_key_active, 0);
|
atomic_store(&control_key_active, 0);
|
||||||
if (note < 16) {
|
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);
|
queue_push(&cmd_queue, cmd);
|
||||||
} else {
|
} else {
|
||||||
switch (note) {
|
switch (note) {
|
||||||
case 60:
|
case 60: {
|
||||||
{
|
command_t cmd = {
|
||||||
command_t cmd = { .type = CMD_ADD_CHANNEL, .channel = -1, .data = 0 };
|
.type = CMD_ADD_CHANNEL, .channel = -1, .data = 0};
|
||||||
queue_push(&cmd_queue_main_midi, cmd);
|
queue_push(&cmd_queue_main_midi, cmd);
|
||||||
} break;
|
} break;
|
||||||
case 61:
|
case 61: {
|
||||||
{
|
command_t cmd = {
|
||||||
command_t cmd = { .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0 };
|
.type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0};
|
||||||
queue_push(&cmd_queue_main_midi, cmd);
|
queue_push(&cmd_queue_main_midi, cmd);
|
||||||
} break;
|
} break;
|
||||||
case 62:
|
case 62: {
|
||||||
{
|
|
||||||
int bch = atomic_load(&bind_channel);
|
int bch = atomic_load(&bind_channel);
|
||||||
if (bch >= 0 && bch < MAX_CHANNELS) {
|
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);
|
queue_push(&cmd_queue, cmd);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case 63:
|
case 63: {
|
||||||
{
|
command_t cmd = {.type = CMD_UNBIND, .channel = -1, .data = 0};
|
||||||
command_t cmd = { .type = CMD_UNBIND, .channel = -1, .data = 0 };
|
|
||||||
queue_push(&cmd_queue, cmd);
|
queue_push(&cmd_queue, cmd);
|
||||||
} break;
|
} break;
|
||||||
case 65:
|
case 65: {
|
||||||
{
|
command_t cmd = {.type = CMD_STOP, .channel = -1, .data = 0};
|
||||||
command_t cmd = { .type = CMD_STOP, .channel = -1, .data = 0 };
|
|
||||||
queue_push(&cmd_queue, cmd);
|
queue_push(&cmd_queue, cmd);
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
@@ -75,19 +73,17 @@ void midi_handle_events(void *port_buffer, jack_nframes_t nframes) {
|
|||||||
} else {
|
} else {
|
||||||
/* direct mapping */
|
/* direct mapping */
|
||||||
switch (note) {
|
switch (note) {
|
||||||
case 1:
|
case 1: {
|
||||||
{
|
command_t cmd = {.type = CMD_CYCLE, .channel = 0, .data = 0};
|
||||||
command_t cmd = { .type = CMD_CYCLE, .channel = 0, .data = 0 };
|
|
||||||
queue_push(&cmd_queue, cmd);
|
queue_push(&cmd_queue, cmd);
|
||||||
} break;
|
} break;
|
||||||
case 60:
|
case 60: {
|
||||||
{
|
command_t cmd = {.type = CMD_ADD_CHANNEL, .channel = -1, .data = 0};
|
||||||
command_t cmd = { .type = CMD_ADD_CHANNEL, .channel = -1, .data = 0 };
|
|
||||||
queue_push(&cmd_queue_main_midi, cmd);
|
queue_push(&cmd_queue_main_midi, cmd);
|
||||||
} break;
|
} break;
|
||||||
case 61:
|
case 61: {
|
||||||
{
|
command_t cmd = {
|
||||||
command_t cmd = { .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0 };
|
.type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0};
|
||||||
queue_push(&cmd_queue_main_midi, cmd);
|
queue_push(&cmd_queue_main_midi, cmd);
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
BIN
src/midi.o
Normal file
BIN
src/midi.o
Normal file
Binary file not shown.
26
src/pipe.c
26
src/pipe.c
@@ -1,14 +1,14 @@
|
|||||||
#include "pipe.h"
|
#include "pipe.h"
|
||||||
#include "queue.h"
|
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
#include "queue.h"
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#define FIFO_PATH "/tmp/looper_cmd"
|
#define FIFO_PATH "/tmp/looper_cmd"
|
||||||
#define LINE_MAX 256
|
#define LINE_MAX 256
|
||||||
@@ -28,28 +28,28 @@ static void *pipe_thread_func(void *arg) {
|
|||||||
while (fgets(line, sizeof(line), fifo)) {
|
while (fgets(line, sizeof(line), fifo)) {
|
||||||
/* strip newline */
|
/* strip newline */
|
||||||
size_t len = strlen(line);
|
size_t len = strlen(line);
|
||||||
if (len > 0 && line[len-1] == '\n')
|
if (len > 0 && line[len - 1] == '\n')
|
||||||
line[len-1] = '\0';
|
line[len - 1] = '\0';
|
||||||
|
|
||||||
if (strcmp(line, "add") == 0) {
|
if (strcmp(line, "add") == 0) {
|
||||||
command_t cmd = { .type = CMD_ADD_CHANNEL, .channel = -1, .data = 0 };
|
command_t cmd = {.type = CMD_ADD_CHANNEL, .channel = -1, .data = 0};
|
||||||
queue_push(&cmd_queue_main_fifo, cmd);
|
queue_push(&cmd_queue_main_fifo, cmd);
|
||||||
} else if (strcmp(line, "remove") == 0) {
|
} else if (strcmp(line, "remove") == 0) {
|
||||||
command_t cmd = { .type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0 };
|
command_t cmd = {.type = CMD_REMOVE_CHANNEL, .channel = -1, .data = 0};
|
||||||
queue_push(&cmd_queue_main_fifo, cmd);
|
queue_push(&cmd_queue_main_fifo, cmd);
|
||||||
} else if (strncmp(line, "record ", 7) == 0) {
|
} else if (strncmp(line, "record ", 7) == 0) {
|
||||||
int ch = atoi(line + 7);
|
int ch = atoi(line + 7);
|
||||||
command_t cmd = { .type = CMD_CYCLE, .channel = ch, .data = 0 };
|
command_t cmd = {.type = CMD_CYCLE, .channel = ch, .data = 0};
|
||||||
queue_push(&cmd_queue, cmd);
|
queue_push(&cmd_queue, cmd);
|
||||||
} else if (strcmp(line, "stop") == 0) {
|
} else if (strcmp(line, "stop") == 0) {
|
||||||
command_t cmd = { .type = CMD_STOP, .channel = -1, .data = 0 };
|
command_t cmd = {.type = CMD_STOP, .channel = -1, .data = 0};
|
||||||
queue_push(&cmd_queue, cmd);
|
queue_push(&cmd_queue, cmd);
|
||||||
} else if (strncmp(line, "bind ", 5) == 0) {
|
} else if (strncmp(line, "bind ", 5) == 0) {
|
||||||
int ch = atoi(line + 5);
|
int ch = atoi(line + 5);
|
||||||
command_t cmd = { .type = CMD_BIND_CHANNEL, .channel = -1, .data = ch };
|
command_t cmd = {.type = CMD_BIND_CHANNEL, .channel = -1, .data = ch};
|
||||||
queue_push(&cmd_queue, cmd);
|
queue_push(&cmd_queue, cmd);
|
||||||
} else if (strcmp(line, "unbind") == 0) {
|
} else if (strcmp(line, "unbind") == 0) {
|
||||||
command_t cmd = { .type = CMD_UNBIND, .channel = -1, .data = 0 };
|
command_t cmd = {.type = CMD_UNBIND, .channel = -1, .data = 0};
|
||||||
queue_push(&cmd_queue, cmd);
|
queue_push(&cmd_queue, cmd);
|
||||||
}
|
}
|
||||||
/* ignore unknown lines */
|
/* ignore unknown lines */
|
||||||
|
|||||||
BIN
src/pipe.o
Normal file
BIN
src/pipe.o
Normal file
Binary file not shown.
@@ -25,6 +25,7 @@ bool queue_pop(spsc_queue_t *q, command_t *cmd) {
|
|||||||
if (t == h)
|
if (t == h)
|
||||||
return false; /* queue empty */
|
return false; /* queue empty */
|
||||||
*cmd = q->buffer[t];
|
*cmd = q->buffer[t];
|
||||||
atomic_store_explicit(&q->tail, (t + 1) % QUEUE_CAPACITY, memory_order_release);
|
atomic_store_explicit(&q->tail, (t + 1) % QUEUE_CAPACITY,
|
||||||
|
memory_order_release);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/queue.o
Normal file
BIN
src/queue.o
Normal file
Binary file not shown.
Reference in New Issue
Block a user