test: add audio pass-through test with RMS validation
Co-authored-by: aider (deepseek/deepseek-reasoner) <aider@aider.chat>
This commit is contained in:
@@ -180,6 +180,70 @@ static void test_clock_continue(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int test_audio_pass_through(void) {
|
||||||
|
printf("Test: audio pass‑through (latency & RMS)\n");
|
||||||
|
|
||||||
|
/* check required tools */
|
||||||
|
if (system("which jack_sine >/dev/null 2>&1") != 0) {
|
||||||
|
fprintf(stderr, " SKIP: jack_sine not installed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (system("which jack_capture >/dev/null 2>&1") != 0) {
|
||||||
|
fprintf(stderr, " SKIP: jack_capture not installed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (system("which sox >/dev/null 2>&1") != 0) {
|
||||||
|
fprintf(stderr, " SKIP: sox not installed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (system("which python3 >/dev/null 2>&1") != 0) {
|
||||||
|
fprintf(stderr, " SKIP: python3 not installed\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pid_t pid = start_looper();
|
||||||
|
if (pid < 0) {
|
||||||
|
fprintf(stderr, "FAIL: could not start looper\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* connect sine generator to looper input */
|
||||||
|
if (system("jack_connect sine:output looper:input 2>/dev/null") != 0) {
|
||||||
|
fprintf(stderr, "FAIL: could not connect sine -> looper:input\n");
|
||||||
|
kill(pid, SIGTERM);
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* capture 2 seconds of looper output */
|
||||||
|
system("jack_capture -d 2 -f /tmp/looper_test.wav 2>/dev/null");
|
||||||
|
|
||||||
|
/* compute RMS of captured WAV using Python */
|
||||||
|
int rms_ok = system(
|
||||||
|
"python3 -c '"
|
||||||
|
"import wave, math;"
|
||||||
|
"w=wave.open(\"/tmp/looper_test.wav\");"
|
||||||
|
"f=w.readframes(w.getnframes());"
|
||||||
|
"s=[int.from_bytes(f[i:i+2],\"little\",signed=True) for i in range(0,len(f),2)];"
|
||||||
|
"r=math.sqrt(sum(x*x for x in s)/len(s));"
|
||||||
|
"print(\"RMS=%%d\"%%r);"
|
||||||
|
"exit(0 if r>1000 else 1)'"
|
||||||
|
" 2>/dev/null"
|
||||||
|
);
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
kill(pid, SIGTERM);
|
||||||
|
waitpid(pid, NULL, 0);
|
||||||
|
|
||||||
|
if (rms_ok == 0) {
|
||||||
|
printf(" PASS (RMS > 1000)\n");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
fprintf(stderr, " FAIL: RMS too low or Python error\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
/* 1. binary must exist */
|
/* 1. binary must exist */
|
||||||
if (system("test -x ./looper") != 0) {
|
if (system("test -x ./looper") != 0) {
|
||||||
@@ -204,6 +268,9 @@ int main(void) {
|
|||||||
test_clock_stop();
|
test_clock_stop();
|
||||||
test_clock_continue();
|
test_clock_continue();
|
||||||
|
|
||||||
|
/* 5. Audio pass‑through test (optional tools) */
|
||||||
|
test_audio_pass_through();
|
||||||
|
|
||||||
printf("All tests passed!\n");
|
printf("All tests passed!\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user