612 lines
20 KiB
C
612 lines
20 KiB
C
#include "test_common.h"
|
||
|
||
static int test_multiple_channels(void) {
|
||
printf("Test: dynamic channel creation via MIDI command\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_multi", JackNoStartServer, &status);
|
||
if (!client) {
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
fprintf(stderr, " SKIP: no JACK\n");
|
||
return 1;
|
||
}
|
||
if (send_jack_note_on("looper:control", 60, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
int found = 0;
|
||
for (int retries = 0; retries < 30; retries++) {
|
||
safe_usleep(100000);
|
||
const char **ports = jack_get_ports(client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0);
|
||
if (ports) {
|
||
for (int i = 0; ports[i]; i++) {
|
||
if (strstr(ports[i], "looper:channel1_input")) {
|
||
found = 1;
|
||
jack_free(ports);
|
||
goto port_found;
|
||
}
|
||
}
|
||
jack_free(ports);
|
||
}
|
||
}
|
||
port_found:
|
||
;
|
||
jack_client_close(client);
|
||
cleanup_persistent_midi_client();
|
||
kill(pid, SIGTERM);
|
||
waitpid(pid, NULL, 0);
|
||
if (!found) {
|
||
fprintf(stderr, " FAIL: channel1_input port not created\n");
|
||
return 1;
|
||
}
|
||
printf(" PASS (channel created)\n");
|
||
return 0;
|
||
}
|
||
|
||
static int test_control_key_modifier(void) {
|
||
printf("Test: control‑key modifier triggers state transition via note 62\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_ctrl_key", 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_ctrl_key:out");
|
||
snprintf(my_in, sizeof(my_in), "test_ctrl_key: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", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 62, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
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(200000);
|
||
if (send_jack_note_on("looper:control", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 62, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(2000000);
|
||
jack_deactivate(client);
|
||
jack_client_close(client);
|
||
cleanup_persistent_midi_client();
|
||
kill(pid, SIGTERM);
|
||
waitpid(pid, NULL, 0);
|
||
int got_bursts = bursts;
|
||
printf(" detected bursts: %d\n", got_bursts);
|
||
if (got_bursts < 3) {
|
||
fprintf(stderr, " FAIL: expected ≥3 bursts, got %d\n", got_bursts);
|
||
return 1;
|
||
}
|
||
printf(" PASS (control‑key modifier works)\n");
|
||
return 0;
|
||
}
|
||
|
||
static int test_bind_channel(void) {
|
||
printf("Test: control‑key bind channel (note 0) and toggle\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_bind", 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_bind:out");
|
||
snprintf(my_in, sizeof(my_in), "test_bind: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", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 0, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 62, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
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(200000);
|
||
if (send_jack_note_on("looper:control", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 62, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(2000000);
|
||
jack_deactivate(client);
|
||
jack_client_close(client);
|
||
cleanup_persistent_midi_client();
|
||
kill(pid, SIGTERM);
|
||
waitpid(pid, NULL, 0);
|
||
int got_bursts = bursts;
|
||
printf(" detected bursts: %d\n", got_bursts);
|
||
if (got_bursts < 3) {
|
||
fprintf(stderr, " FAIL: expected >=3 bursts, got %d\n", got_bursts);
|
||
return 1;
|
||
}
|
||
printf(" PASS (bind and toggle)\n");
|
||
return 0;
|
||
}
|
||
|
||
static int test_bind_unbind(void) {
|
||
printf("Test: bind to channel 5, unbind, then toggle default (channel 0)\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_unbind", 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_unbind:out");
|
||
snprintf(my_in, sizeof(my_in), "test_unbind: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", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 5, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 63, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 62, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
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(200000);
|
||
if (send_jack_note_on("looper:control", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 62, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(2000000);
|
||
jack_deactivate(client);
|
||
jack_client_close(client);
|
||
cleanup_persistent_midi_client();
|
||
kill(pid, SIGTERM);
|
||
waitpid(pid, NULL, 0);
|
||
int got_bursts = bursts;
|
||
printf(" detected bursts: %d\n", got_bursts);
|
||
if (got_bursts < 3) {
|
||
fprintf(stderr, " FAIL: expected >=3 bursts, got %d\n", got_bursts);
|
||
return 1;
|
||
}
|
||
printf(" PASS (unbind works, toggle channel 0)\n");
|
||
return 0;
|
||
}
|
||
|
||
static int test_remove_channel(void) {
|
||
printf("Test: dynamic channel removal via MIDI command\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_remove", JackNoStartServer, &status);
|
||
if (!client) {
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
fprintf(stderr, " SKIP: no JACK\n");
|
||
return 1;
|
||
}
|
||
if (send_jack_note_on("looper:control", 60, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
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);
|
||
}
|
||
if (!found) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
fprintf(stderr, " FAIL: channel1_input not created\n");
|
||
return 1;
|
||
}
|
||
printf(" channel1_input created\n");
|
||
if (send_jack_note_on("looper:control", 61, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
int still_found = 1;
|
||
for (int retries = 0; retries < 30; retries++) {
|
||
safe_usleep(100000);
|
||
ports = jack_get_ports(client, NULL, JACK_DEFAULT_AUDIO_TYPE, 0);
|
||
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);
|
||
}
|
||
if (!still_found) break;
|
||
}
|
||
jack_client_close(client);
|
||
cleanup_persistent_midi_client();
|
||
kill(pid, SIGTERM);
|
||
waitpid(pid, NULL, 0);
|
||
if (still_found) {
|
||
fprintf(stderr, " FAIL: channel1_input not removed after remove command\n");
|
||
return 1;
|
||
}
|
||
printf(" PASS (channel removed)\n");
|
||
return 0;
|
||
}
|
||
|
||
static int test_stop_midi(void) {
|
||
printf("Test: MIDI stop (note 65 under control key)\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_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_stop:out");
|
||
snprintf(my_in, sizeof(my_in), "test_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.2f * 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);
|
||
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(500000);
|
||
if (send_jack_note_on("looper:control", 64, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(200000);
|
||
if (send_jack_note_on("looper:control", 65, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
int prev = bursts;
|
||
for (int retries = 0; retries < 20; retries++) {
|
||
safe_usleep(100000);
|
||
int cur = bursts;
|
||
if (cur == prev) break;
|
||
prev = cur;
|
||
}
|
||
int bursts_before = bursts;
|
||
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 > bursts_before + 5) {
|
||
fprintf(stderr, " FAIL: bursts continued after stop (%d -> %d)\n",
|
||
bursts_before, bursts_after);
|
||
return 1;
|
||
}
|
||
printf(" PASS (stop stopped playback)\n");
|
||
return 0;
|
||
}
|
||
|
||
static int test_midi_channel_add(void) {
|
||
printf("Test: MIDI channel creation via FIFO (add_midi)\n");
|
||
pid_t pid = start_looper();
|
||
if (pid < 0) return 1;
|
||
jack_client_t *client;
|
||
jack_status_t status;
|
||
client = jack_client_open("test_midi_add", 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_midi\n", 9);
|
||
close(fd);
|
||
safe_usleep(1500000);
|
||
const char **ports = jack_get_ports(client, NULL, JACK_DEFAULT_MIDI_TYPE, 0);
|
||
int found = 0;
|
||
if (ports) {
|
||
for (int i = 0; ports[i]; i++) {
|
||
if (strstr(ports[i], "looper:channel1_midi_in")) {
|
||
found = 1;
|
||
break;
|
||
}
|
||
}
|
||
jack_free(ports);
|
||
}
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM);
|
||
waitpid(pid, NULL, 0);
|
||
if (!found) {
|
||
fprintf(stderr, " FAIL: channel1_midi_in port not created\n");
|
||
return 1;
|
||
}
|
||
printf(" PASS (MIDI channel created)\n");
|
||
return 0;
|
||
}
|
||
|
||
int test_channel(void) {
|
||
int failures = 0;
|
||
failures += test_multiple_channels();
|
||
failures += test_control_key_modifier();
|
||
failures += test_bind_channel();
|
||
failures += test_bind_unbind();
|
||
failures += test_remove_channel();
|
||
failures += test_stop_midi();
|
||
failures += test_midi_channel_add();
|
||
return failures;
|
||
}
|