From 20176517a4224370db45439a22cfc0cc55a232c2 Mon Sep 17 00:00:00 2001 From: Loic Coenen Date: Sun, 31 May 2026 13:05:28 +0000 Subject: [PATCH] refactor: rename looper ports to ch0in/ch0out and move connection logic to client --- client/src/carla_host.c | 9 ----- client/src/client_cmd.c | 8 ++--- client/src/tui.c | 25 +++++++++----- e2e/test.ts | 4 +-- engine/src/channel.c | 12 +++---- engine/src/looper.c | 4 +-- engine/src/pipe.c | 76 ----------------------------------------- 7 files changed, 31 insertions(+), 107 deletions(-) diff --git a/client/src/carla_host.c b/client/src/carla_host.c index 8055f25..614a415 100644 --- a/client/src/carla_host.c +++ b/client/src/carla_host.c @@ -322,15 +322,6 @@ bool carla_get_connected_port(int channel, bool is_input, char *buf, size_t bufs return true; } } - // Also look for direct connections to looper:input / looper:output (channel 0) - const char *direct_needle = is_input ? "looper:input" : "looper:output"; - for (int i = 0; i < conn_count; i++) { - if (strcmp(connections[i].looper_port, direct_needle) == 0) { - strncpy(buf, connections[i].plugin_port, bufsize - 1); - buf[bufsize - 1] = '\0'; - return true; - } - } buf[0] = '\0'; return false; } diff --git a/client/src/client_cmd.c b/client/src/client_cmd.c index c803faf..22e9638 100644 --- a/client/src/client_cmd.c +++ b/client/src/client_cmd.c @@ -36,14 +36,14 @@ int handle_client_command(const char *input, int *out_id) { if (strcmp(token, "from") == 0) { const char *port = strtok(NULL, " "); if (!port) return -1; - int ret = carla_connect_direct(port, "looper:input"); + int ret = carla_connect_direct(port, "looper:ch0in"); if (ret == 0) { strncpy(from_port, port, sizeof(from_port)-1); from_port[sizeof(from_port)-1] = '\0'; g_connect_error[0] = '\0'; } else { snprintf(g_connect_error, sizeof(g_connect_error), - "Failed: %s -> looper:input (ret=%d)", port, ret); + "Failed: %s -> looper:ch0in (ret=%d)", port, ret); } return ret; } @@ -52,14 +52,14 @@ int handle_client_command(const char *input, int *out_id) { if (strcmp(token, "to") == 0) { const char *port = strtok(NULL, " "); if (!port) return -1; - int ret = carla_connect_direct("looper:output", port); + int ret = carla_connect_direct("looper:ch0out", port); if (ret == 0) { strncpy(to_port, port, sizeof(to_port)-1); to_port[sizeof(to_port)-1] = '\0'; g_connect_error[0] = '\0'; } else { snprintf(g_connect_error, sizeof(g_connect_error), - "Failed: looper:output -> %s (ret=%d)", port, ret); + "Failed: looper:ch0out -> %s (ret=%d)", port, ret); } return ret; } diff --git a/client/src/tui.c b/client/src/tui.c index 1280f84..79f706e 100644 --- a/client/src/tui.c +++ b/client/src/tui.c @@ -440,14 +440,23 @@ void tui_run(void) { int channel = selected_col; // selected column = channel number bool found = carla_resolve_channel_port(channel, is_to, looper_port, sizeof(looper_port)); if (!found) { - /* Fallback to generic name (may not exist) */ + /* Fallback to generic name with looper: prefix */ if (is_to) - snprintf(looper_port, sizeof(looper_port), "ch%dout", channel); + snprintf(looper_port, sizeof(looper_port), "looper:ch%dout", channel); else - snprintf(looper_port, sizeof(looper_port), "ch%din", channel); - /* The actual port name includes a PID suffix, but we try anyway */ + snprintf(looper_port, sizeof(looper_port), "looper:ch%din", channel); + } + int ret; + const char *src, *dst; + if (is_to) { + ret = carla_connect_direct(looper_port, port_name); + src = looper_port; + dst = port_name; + } else { + ret = carla_connect_direct(port_name, looper_port); + src = port_name; + dst = looper_port; } - int ret = carla_connect_direct(port_name, looper_port); if (ret == 0) { if (is_to) { strncpy(g_to_port, port_name, sizeof(g_to_port)-1); @@ -457,11 +466,11 @@ void tui_run(void) { g_from_port[sizeof(g_from_port)-1] = '\0'; } g_connect_error[0] = '\0'; - log_msg("Connected %s -> %s", port_name, looper_port); + log_msg("Connected %s -> %s", src, dst); } else { snprintf(g_connect_error, sizeof(g_connect_error), - "Failed: %s -> %s (ret=%d)", port_name, looper_port, ret); - log_msg("Failed to connect %s -> %s (ret=%d)", port_name, looper_port, ret); + "Failed: %s -> %s (ret=%d)", src, dst, ret); + log_msg("Failed to connect %s -> %s (ret=%d)", src, dst, ret); } } if (!potential_arg) g_selected_port[0] = '\0'; diff --git a/e2e/test.ts b/e2e/test.ts index c5d276e..e9168c8 100644 --- a/e2e/test.ts +++ b/e2e/test.ts @@ -1048,8 +1048,8 @@ async function testFromToAudioPass(): Promise { } // Now check the connection result – look for error lines produced by the fixed pipe.c - const fromFailed = stderrLog.includes("Failed to connect system:capture_1 -> looper:input"); - const toFailed = stderrLog.includes("Failed to connect looper:output -> system:playback_1"); + const fromFailed = stderrLog.includes("Failed to connect system:capture_1 -> looper:ch0in"); + const toFailed = stderrLog.includes("Failed to connect looper:ch0out -> system:playback_1"); const anyError = stderrLog.includes("Failed to connect") || stderrLog.includes("Retry also failed"); if (fromFailed) { diff --git a/engine/src/channel.c b/engine/src/channel.c index a9d595d..573944c 100644 --- a/engine/src/channel.c +++ b/engine/src/channel.c @@ -16,8 +16,8 @@ void init_scene(scene_t *sc) { void channel_add(jack_client_t *client, int idx) { char in_name[64], out_name[64]; pid_t pid = getpid(); - snprintf(in_name, sizeof(in_name), "ch%din_%d", next_channel_id, (int)pid); - snprintf(out_name, sizeof(out_name), "ch%dout_%d", next_channel_id, (int)pid); + snprintf(in_name, sizeof(in_name), "ch%din", next_channel_id); + snprintf(out_name, sizeof(out_name), "ch%dout", next_channel_id); /* Always register audio ports (needed for pass-through even for MIDI * channels?) */ @@ -36,10 +36,10 @@ void channel_add(jack_client_t *client, int idx) { /* If this is a MIDI channel, register MIDI ports */ if (channels[idx].type == CHANNEL_MIDI) { char midi_in_name[64], midi_out_name[64]; - snprintf(midi_in_name, sizeof(midi_in_name), "ch%dmidiin_%d", - next_channel_id, (int)pid); - snprintf(midi_out_name, sizeof(midi_out_name), "ch%dmidiout_%d", - next_channel_id, (int)pid); + snprintf(midi_in_name, sizeof(midi_in_name), "ch%dmidiin", + next_channel_id); + snprintf(midi_out_name, sizeof(midi_out_name), "ch%dmidiout", + next_channel_id); channels[idx].midi_in = jack_port_register( client, midi_in_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); channels[idx].midi_out = jack_port_register( diff --git a/engine/src/looper.c b/engine/src/looper.c index 76a4dbe..87c9937 100644 --- a/engine/src/looper.c +++ b/engine/src/looper.c @@ -590,9 +590,9 @@ int looper_init(jack_client_t *client) { atomic_store(&channels[0].save_complete, 0); channels[0].audio_in = jack_port_register( - client, "input", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + client, "ch0in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); channels[0].audio_out = jack_port_register( - client, "output", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + client, "ch0out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); if (!channels[0].audio_in || !channels[0].audio_out) { fprintf(stderr, "Could not create audio ports for channel 0\n"); return -1; diff --git a/engine/src/pipe.c b/engine/src/pipe.c index 3aef820..e0b709d 100644 --- a/engine/src/pipe.c +++ b/engine/src/pipe.c @@ -10,17 +10,10 @@ #include #include #include -#include #define FIFO_PATH "/tmp/looper_cmd" #define LINE_MAX 256 -/* Global JACK client (from looper.c) */ -extern jack_client_t *global_client; - -/* Stored ports for from/to */ -static char fifo_from[256] = ""; -static char fifo_to[256] = ""; /* Filename for the next load command (default "loop.wav") */ char load_filename[256] = "loop.wav"; @@ -105,75 +98,6 @@ static void *pipe_thread_func(void *arg) { command_t cmd = {.type = CMD_SAVE, .channel = -1, .data = 0}; queue_push(&cmd_queue_main_fifo, cmd); } - // --- from --- - else if (strncmp(line, "from ", 5) == 0) { - fprintf(stderr, "FIFO RECEIVED from: %s\n", line + 5); - strncpy(fifo_from, line + 5, sizeof(fifo_from)-1); - fifo_from[sizeof(fifo_from)-1] = '\0'; - // Immediately connect source to looper:input (independently of :to) - if (global_client) { - const char *target = "looper:input"; - int ret = jack_connect(global_client, fifo_from, target); - if (ret != 0) { - fprintf(stderr, "Failed to connect %s -> %s (ret=%d), retrying...\n", fifo_from, target, ret); - struct timespec ts = {.tv_sec = 0, .tv_nsec = 500000000}; - nanosleep(&ts, NULL); - ret = jack_connect(global_client, fifo_from, target); - if (ret != 0) - fprintf(stderr, "Retry also failed %s -> %s (ret=%d)\n", fifo_from, target, ret); - } - } - } - // --- to --- - else if (strncmp(line, "to ", 3) == 0) { - fprintf(stderr, "FIFO RECEIVED to: %s\n", line + 3); - strncpy(fifo_to, line + 3, sizeof(fifo_to)-1); - fifo_to[sizeof(fifo_to)-1] = '\0'; - // Immediately connect looper:output to target (independently of :from) - if (global_client) { - const char *source = "looper:output"; - int ret = jack_connect(global_client, source, fifo_to); - if (ret != 0) { - fprintf(stderr, "Failed to connect %s -> %s (ret=%d), retrying...\n", source, fifo_to, ret); - struct timespec ts = {.tv_sec = 0, .tv_nsec = 500000000}; - nanosleep(&ts, NULL); - ret = jack_connect(global_client, source, fifo_to); - if (ret != 0) - fprintf(stderr, "Retry also failed %s -> %s (ret=%d)\n", source, fifo_to, ret); - } - } - } - // --- connect [from] [to] --- - else if (strncmp(line, "connect", 7) == 0) { - char from[256] = ""; - char to[256] = ""; - // parse optional arguments: "connect from to" - char *p = line + 7; - while (*p == ' ') p++; - if (*p) { - char *space = strchr(p, ' '); - if (space) { - strncpy(from, p, space - p); from[space-p] = '\0'; - strncpy(to, space+1, sizeof(to)-1); - } else { - strncpy(from, p, sizeof(from)-1); - } - } - // fallback to stored ports - if (!from[0]) strncpy(from, fifo_from, sizeof(from)-1); - if (!to[0]) strncpy(to, fifo_to, sizeof(to)-1); - if (from[0] && to[0] && global_client) { - int ret = jack_connect(global_client, from, to); - if (ret != 0) { - fprintf(stderr, "Failed to connect %s -> %s (ret=%d), retrying...\n", from, to, ret); - struct timespec ts = {.tv_sec = 0, .tv_nsec = 500000000}; - nanosleep(&ts, NULL); - ret = jack_connect(global_client, from, to); - if (ret != 0) - fprintf(stderr, "Retry also failed %s -> %s (ret=%d)\n", from, to, ret); - } - } - } /* ignore unknown lines */ } /* EOF – all writers closed, reopen for next connection */