191 lines
6.3 KiB
C
191 lines
6.3 KiB
C
#include "test_common.h"
|
||
|
||
static int test_looper_looping(void) {
|
||
printf("Test: loop recording and playback (expect ≥3 repetitions)\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_looping", JackNoStartServer, &status);
|
||
if (!client) {
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
fprintf(stderr, " SKIP: JACK not running?\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_looping:out");
|
||
snprintf(my_in, sizeof(my_in), "test_looping: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(500000);
|
||
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);
|
||
safe_usleep(800000);
|
||
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(4000000);
|
||
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 (at least 3 repetitions)\n");
|
||
return 0;
|
||
}
|
||
|
||
static int test_record_loop_stop(void) {
|
||
printf("Test: full record‑loop‑stop (≥5 repetitions)\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_full", 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_full:out");
|
||
snprintf(my_in, sizeof(my_in), "test_full: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(500000);
|
||
int sr = jack_get_sample_rate(client);
|
||
continuous_sine = 0;
|
||
beep_remaining = (int)(0.5f * 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", 1, 127) != 0) {
|
||
jack_client_close(client);
|
||
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||
return 1;
|
||
}
|
||
safe_usleep(2500000);
|
||
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;
|
||
}
|
||
safe_usleep(200000);
|
||
int total_bursts = bursts;
|
||
jack_deactivate(client);
|
||
jack_client_close(client);
|
||
cleanup_persistent_midi_client();
|
||
kill(pid, SIGTERM);
|
||
waitpid(pid, NULL, 0);
|
||
if (total_bursts < 5) {
|
||
fprintf(stderr, " FAIL: expected ≥5 bursts, got %d\n", total_bursts);
|
||
return 1;
|
||
}
|
||
printf(" PASS (≥5 repetitions, stopped cleanly)\n");
|
||
return 0;
|
||
}
|
||
|
||
int test_loop(void) {
|
||
int failures = 0;
|
||
failures += test_looper_looping();
|
||
failures += test_record_loop_stop();
|
||
return failures;
|
||
}
|