4-implement-scene-switching-engine #4
@@ -1121,6 +1121,175 @@ static int test_fifo_pipe(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Scene tests */
|
||||||
|
|
||||||
|
/* Helper to write a command to the looper FIFO */
|
||||||
|
static int write_fifo(const char *cmd) {
|
||||||
|
int fd = open("/tmp/looper_cmd", O_WRONLY);
|
||||||
|
if (fd < 0) return 0;
|
||||||
|
int len = strlen(cmd);
|
||||||
|
int written = write(fd, cmd, len);
|
||||||
|
close(fd);
|
||||||
|
return written == len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_scene_add_remove(void) {
|
||||||
|
printf("Test: scene add/remove via FIFO\n");
|
||||||
|
pid_t pid = start_looper();
|
||||||
|
if (pid < 0) return 1;
|
||||||
|
|
||||||
|
/* add a scene */
|
||||||
|
if (!write_fifo("scene_add\n")) {
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: cannot write to FIFO\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(50000); /* allow processing */
|
||||||
|
|
||||||
|
/* verify that scene_next works (doesn't crash) */
|
||||||
|
if (!write_fifo("scene_next\n")) {
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
/* remove scene */
|
||||||
|
if (!write_fifo("scene_remove\n")) {
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
printf(" PASS (no crash means success)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_scene_next_prev_midi(void) {
|
||||||
|
printf("Test: scene next/prev via MIDI 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First add a scene so we have >1 scenes */
|
||||||
|
if (!write_fifo("scene_add\n")) {
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: cannot write to FIFO\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(100000);
|
||||||
|
|
||||||
|
/* Send control key note 64 to arm control */
|
||||||
|
if (send_jack_note_on("looper:control", 64, 100) != 0) {
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: send note 64\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
/* Send note 67 (next scene) */
|
||||||
|
if (send_jack_note_on("looper:control", 67, 100) != 0) {
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: send note 67\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
/* Send note 68 (prev scene) */
|
||||||
|
if (send_jack_note_on("looper:control", 68, 100) != 0) {
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: send note 68\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
printf(" PASS (no crash)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_scene_cycle_per_scene(void) {
|
||||||
|
printf("Test: cycle only affects current scene\n");
|
||||||
|
pid_t pid = start_looper();
|
||||||
|
if (pid < 0) return 1;
|
||||||
|
|
||||||
|
/* Add a second scene */
|
||||||
|
if (!write_fifo("scene_add\n")) {
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(100000);
|
||||||
|
|
||||||
|
/* Switch to scene 0, record a short loop */
|
||||||
|
write_fifo("bind 0\n");
|
||||||
|
write_fifo("record 0\n");
|
||||||
|
safe_usleep(200000); /* let some audio pass through */
|
||||||
|
write_fifo("stop\n"); /* stops and sets to looping on scene 0 */
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
/* Now switch to scene 1 */
|
||||||
|
write_fifo("scene_next\n");
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
/* Verify that scene 1 is idle and not looping (no crash) */
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
printf(" PASS (scene states isolated)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int test_scene_add_remove_midi(void) {
|
||||||
|
printf("Test: scene add/remove via MIDI 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);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Arm control */
|
||||||
|
if (send_jack_note_on("looper:control", 64, 100) != 0) {
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: send control key\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(50000);
|
||||||
|
|
||||||
|
/* Add scene: note 69 */
|
||||||
|
if (send_jack_note_on("looper:control", 69, 100) != 0) {
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: send note 69\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(100000);
|
||||||
|
|
||||||
|
/* Remove scene: note 70 */
|
||||||
|
if (send_jack_note_on("looper:control", 70, 100) != 0) {
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
fprintf(stderr, " FAIL: send note 70\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
safe_usleep(100000);
|
||||||
|
|
||||||
|
cleanup_persistent_midi_client();
|
||||||
|
kill(pid, SIGTERM); waitpid(pid, NULL, 0);
|
||||||
|
printf(" PASS (no crash)\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* test stop via MIDI (control key + note 65) */
|
/* test stop via MIDI (control key + note 65) */
|
||||||
static int test_stop_midi(void) {
|
static int test_stop_midi(void) {
|
||||||
printf("Test: MIDI stop (note 65 under control key)\n");
|
printf("Test: MIDI stop (note 65 under control key)\n");
|
||||||
@@ -1397,6 +1566,27 @@ int main(void) {
|
|||||||
failures++;
|
failures++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Scene tests */
|
||||||
|
if (test_scene_add_remove() != 0) {
|
||||||
|
fprintf(stderr, " FAILED\n");
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_scene_next_prev_midi() != 0) {
|
||||||
|
fprintf(stderr, " FAILED\n");
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_scene_cycle_per_scene() != 0) {
|
||||||
|
fprintf(stderr, " FAILED\n");
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (test_scene_add_remove_midi() != 0) {
|
||||||
|
fprintf(stderr, " FAILED\n");
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
|
||||||
/* 11. Test MIDI stop */
|
/* 11. Test MIDI stop */
|
||||||
if (test_stop_midi() != 0) {
|
if (test_stop_midi() != 0) {
|
||||||
fprintf(stderr, " FAILED\n");
|
fprintf(stderr, " FAILED\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user