75 lines
2.9 KiB
Bash
Executable file
75 lines
2.9 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
|
|
# See LICENSE.md for license information.
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
# verify-web-audio.sh - Web audio gate, graded on the sound the page plays.
|
|
#
|
|
# Runs AUDIO's page in headless Chromium (scripts/lib/webDriver.mjs, which
|
|
# lets it play without a click) and records what it plays: SDL3 hands the
|
|
# browser its sound through a ScriptProcessorNode, and the driver keeps a
|
|
# copy of every buffer the node fills, as a WAV. tools/gradeAudioPhases.py
|
|
# grades it through the same six phases as the SDL3 gate -- music, paused,
|
|
# SFX into the pause, resumed, the noise sweep alone, the MOD -- so the
|
|
# browser's audio path (the page's audio context, SDL's resampling to its
|
|
# rate) is checked as well as the mix, which is the SDL3 port's own.
|
|
#
|
|
# The recording, and the driver's key script, start with the first buffer
|
|
# the page plays, so the phases fall where the SDL3 gate's do.
|
|
#
|
|
# Usage: scripts/verify-web-audio.sh
|
|
# Env: WEB_AUDIO_KEEP set to keep the recording as build/web/headless-audio.wav
|
|
# Requires: Chromium, emsdk's node, python3; build/web/bin/AUDIO (make web).
|
|
set -uo pipefail
|
|
|
|
repo=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
source "$repo/scripts/lib/joeyEnv.sh"
|
|
source "$repo/scripts/lib/webGate.sh"
|
|
webNeed
|
|
grader=$repo/tools/gradeAudioPhases.py
|
|
label=verify-web-audio
|
|
|
|
dir=$repo/build/web/bin/AUDIO
|
|
[ -f "$dir/AUDIO.html" ] || { echo "$label: build AUDIO first (make web)" >&2; exit 2; }
|
|
|
|
work=$(mktemp -d -t joeylib-web-audio.XXXXXX)
|
|
cleanup() {
|
|
webStop
|
|
rm -rf "$work"
|
|
return 0
|
|
}
|
|
trap cleanup EXIT
|
|
|
|
webServe "$dir"
|
|
# A null sink's clock paces the page's sound (webSoundSink), so the phases
|
|
# fall in real time.
|
|
webSoundSink || { echo "$label: no PulseAudio/PipeWire null sink for Chromium to play to" >&2; exit 2; }
|
|
# The same timeline as verify-sdl3-audio.sh (seconds since the first buffer).
|
|
if ! webDrive "AUDIO.html" --seconds 120 --audio "$work/out.wav" \
|
|
--step wait:5 --step hold:p:400 \
|
|
--step wait:8 \
|
|
--step "hold: :400" --step wait:1.5 --step "hold: :400" --step wait:1.5 --step "hold: :400" --step wait:1.5 \
|
|
--step wait:4 --step hold:p:400 \
|
|
--step wait:5.6 --step hold:p:400 \
|
|
--step wait:0.6 --step hold:n:400 \
|
|
--step wait:4.6 --step hold:m:400 \
|
|
--step wait:7.6; then
|
|
echo "$label: FAIL - the page could not be driven" >&2
|
|
exit 1
|
|
fi
|
|
[ -s "$work/out.wav" ] || { echo "$label: FAIL - recorded no audio at all" >&2; exit 1; }
|
|
|
|
# Thresholds sit at about half the measured levels (music ~3090, paused 0,
|
|
# sfx ~1240, noise ~1500, mod ~7980, the grader averaging the two channels).
|
|
python3 "$grader" "$label" "$work/out.wav" \
|
|
"music:1:5:1500:" \
|
|
"paused:8:13::100" \
|
|
"sfx:15:22:600:" \
|
|
"resumed:25:29:1500:" \
|
|
"noise:31.5:34:700:" \
|
|
"mod:37:43:4000:"
|
|
status=$?
|
|
if [ -n "${WEB_AUDIO_KEEP:-}" ]; then
|
|
cp "$work/out.wav" "$repo/build/web/headless-audio.wav"
|
|
fi
|
|
exit $status
|