#include "test_common.h" static int test_fifo_pipe(void) { printf("Test: FIFO pipe add/remove\n"); pid_t pid = start_looper(); if (pid < 0) return 1; jack_client_t *client; jack_status_t status; client = jack_client_open("test_fifo", JackNoStartServer, &status); if (!client) { kill(pid, SIGTERM); waitpid(pid, NULL, 0); fprintf(stderr, " SKIP: no JACK\n"); return 1; } int fd = open("/tmp/looper_cmd", O_WRONLY); if (fd < 0) { perror("open fifo"); jack_client_close(client); kill(pid, SIGTERM); waitpid(pid, NULL, 0); return 1; } write(fd, "add\n", 4); safe_usleep(1500000); const char **ports = jack_get_ports(client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0); int found = 0; if (ports) { for (int i = 0; ports[i]; i++) { if (strstr(ports[i], "looper:channel1_input")) { found = 1; break; } } jack_free(ports); } write(fd, "remove\n", 7); close(fd); safe_usleep(1500000); ports = jack_get_ports(client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0); int still_found = 0; if (ports) { for (int i = 0; ports[i]; i++) { if (strstr(ports[i], "looper:channel1_input")) { still_found = 1; break; } } jack_free(ports); } jack_client_close(client); kill(pid, SIGTERM); waitpid(pid, NULL, 0); if (!found) { fprintf(stderr, " FAIL: channel not added via FIFO\n"); return 1; } if (still_found) { fprintf(stderr, " FAIL: channel not removed via FIFO\n"); return 1; } printf(" PASS (FIFO add/remove works)\n"); return 0; } static int test_fifo_stop_bind_unbind(void) { printf("Test: FIFO stop, bind, unbind\n"); pid_t pid = start_looper(); if (pid < 0) return 1; if (init_persistent_midi_client() != 0) { kill(pid, SIGTERM); waitpid(pid, NULL, 0); fprintf(stderr, " FAIL: cannot initialise persistent MIDI client\n"); return 1; } jack_client_t *client; jack_status_t status; client = jack_client_open("test_fifo_stop", JackNoStartServer, &status); if (!client) { kill(pid, SIGTERM); waitpid(pid, NULL, 0); fprintf(stderr, " SKIP: no JACK\n"); return 1; } jack_port_t *audio_out = jack_port_register(client, "out", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); jack_port_t *audio_in = jack_port_register(client, "in", JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); if (!audio_out || !audio_in) { jack_client_close(client); kill(pid, SIGTERM); waitpid(pid, NULL, 0); return 1; } safe_usleep(200000); char my_out[64], my_in[64]; snprintf(my_out, sizeof(my_out), "test_fifo_stop:out"); snprintf(my_in, sizeof(my_in), "test_fifo_stop:in"); if (jack_connect(client, my_out, "looper:input") || jack_connect(client, "looper:output", my_in)) { jack_client_close(client); kill(pid, SIGTERM); waitpid(pid, NULL, 0); return 1; } if (send_jack_note_on("looper:control", 1, 127) != 0) { jack_client_close(client); kill(pid, SIGTERM); waitpid(pid, NULL, 0); return 1; } safe_usleep(200000); int sr = jack_get_sample_rate(client); continuous_sine = 0; beep_remaining = (int)(0.1f * sr); bursts = 0; prev_above = 0; passthrough_output_port = audio_out; passthrough_input_port = audio_in; passthrough_phase = 0.0f; passthrough_freq = 440.0f; passthrough_sample_rate = sr; passthrough_total_samples = 0; passthrough_sum_sq = 0.0; passthrough_done = 0; jack_set_process_callback(client, passthrough_process, NULL); if (jack_activate(client)) { jack_client_close(client); kill(pid, SIGTERM); waitpid(pid, NULL, 0); return 1; } safe_usleep(150000); int fd = open("/tmp/looper_cmd", O_WRONLY); if (fd < 0) { perror("open fifo"); jack_deactivate(client); jack_client_close(client); kill(pid, SIGTERM); waitpid(pid, NULL, 0); return 1; } write(fd, "stop\n", 5); write(fd, "bind 0\n", 7); write(fd, "unbind\n", 7); close(fd); safe_usleep(500000); int bursts_after = bursts; jack_deactivate(client); jack_client_close(client); cleanup_persistent_midi_client(); kill(pid, SIGTERM); waitpid(pid, NULL, 0); if (bursts_after < 1) { fprintf(stderr, " FAIL: no burst detected (probably no recording)\n"); return 1; } printf(" PASS (FIFO stop, bind, unbind executed)\n"); return 0; } int test_fifo(void) { int failures = 0; failures += test_fifo_pipe(); failures += test_fifo_stop_bind_unbind(); return failures; }