test(audio): use raw alsa for uac sanity

This commit is contained in:
Brad Stein 2026-04-24 22:14:43 -03:00
parent 49c25bbf21
commit 70426ad8a8
5 changed files with 31 additions and 24 deletions

6
Cargo.lock generated
View File

@ -1642,7 +1642,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "lesavka_client"
version = "0.13.9"
version = "0.13.10"
dependencies = [
"anyhow",
"async-stream",
@ -1676,7 +1676,7 @@ dependencies = [
[[package]]
name = "lesavka_common"
version = "0.13.9"
version = "0.13.10"
dependencies = [
"anyhow",
"base64",
@ -1688,7 +1688,7 @@ dependencies = [
[[package]]
name = "lesavka_server"
version = "0.13.9"
version = "0.13.10"
dependencies = [
"anyhow",
"base64",

View File

@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
name = "lesavka_client"
version = "0.13.9"
version = "0.13.10"
edition = "2024"
[dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "lesavka_common"
version = "0.13.9"
version = "0.13.10"
edition = "2024"
build = "build.rs"

View File

@ -18,8 +18,6 @@ fi
DURATION_SECONDS=${LESAVKA_UAC_SANITY_SECONDS:-4}
TONE_FREQ=${LESAVKA_UAC_SANITY_FREQ:-880}
TONE_VOLUME=${LESAVKA_UAC_SANITY_VOLUME:-0.45}
BUFFER_TIME_US=${LESAVKA_UAC_BUFFER_TIME_US:-20000}
LATENCY_TIME_US=${LESAVKA_UAC_LATENCY_TIME_US:-5000}
REQUESTED_DEV=${LESAVKA_UAC_SANITY_DEV:-${LESAVKA_UAC_DEV:-hw:UAC2Gadget,0}}
declare -A SEEN_CANDIDATES=()
@ -93,40 +91,49 @@ build_candidates() {
run_tone() {
local candidate="$1"
local log
local wav
log=$(mktemp)
wav=$(mktemp --suffix=.wav)
echo "🎧 trying UAC playback device: $candidate" >&2
python3 - "$wav" "$DURATION_SECONDS" "$TONE_FREQ" "$TONE_VOLUME" <<'PY'
import math, struct, sys, wave
path, duration_s, freq_hz, volume = sys.argv[1], float(sys.argv[2]), float(sys.argv[3]), float(sys.argv[4])
rate = 48_000
frames = max(1, int(rate * duration_s))
amp = max(0.0, min(volume, 1.0)) * 32767.0
with wave.open(path, "wb") as wf:
wf.setnchannels(2)
wf.setsampwidth(2)
wf.setframerate(rate)
for index in range(frames):
sample = int(math.sin((2.0 * math.pi * freq_hz * index) / rate) * amp)
frame = struct.pack("<hh", sample, sample)
wf.writeframesraw(frame)
PY
set +e
timeout --signal=INT "${DURATION_SECONDS}s" \
gst-launch-1.0 -q \
audiotestsrc wave=sine freq="$TONE_FREQ" volume="$TONE_VOLUME" is-live=true \
! audio/x-raw,format=S16LE,channels=2,rate=48000 \
! audioconvert \
! audioresample \
! alsasink \
device="$candidate" \
sync=false \
async=false \
provide-clock=false \
enable-last-sample=false \
buffer-time="$BUFFER_TIME_US" \
latency-time="$LATENCY_TIME_US" \
2>"$log"
timeout --signal=INT "$((DURATION_SECONDS + 2))s" \
aplay -q -D "$candidate" "$wav" \
>"$log" 2>&1
local rc=$?
set -e
if grep -Eiq 'unknown pcm|playback open error|invalid argument|no such (device|file)|^error:|could not open|failed to change state|not-negotiated' "$log"; then
if grep -Eiq 'unknown pcm|invalid argument|no such (device|file)|audio open error|device or resource busy|unable to open slave|unable to install hw params|unable to set hw params|audio open error|no such file or directory' "$log"; then
echo "⚠️ tone failed on $candidate (sink open error)" >&2
sed 's/^/ /' "$log" >&2 || true
rm -f "$log"
rm -f "$wav"
return 1
fi
if [[ $rc -eq 0 || $rc -eq 124 ]]; then
echo "✅ UAC tone completed on $candidate" >&2
rm -f "$log"
rm -f "$wav"
return 0
fi
echo "⚠️ tone failed on $candidate (rc=$rc)" >&2
sed 's/^/ /' "$log" >&2 || true
rm -f "$log"
rm -f "$wav"
return "$rc"
}

View File

@ -10,7 +10,7 @@ bench = false
[package]
name = "lesavka_server"
version = "0.13.9"
version = "0.13.10"
edition = "2024"
autobins = false