111 lines
4.3 KiB
Bash
Executable File
111 lines
4.3 KiB
Bash
Executable File
#!/bin/sh
|
|
# Regression test for the Veskslop TTS wrapper contract. No Wine needed: the wine
|
|
# and engine-host binaries are stubbed, so this checks the arguments the wrapper
|
|
# builds, the registry import it generates, and the voice metadata it publishes.
|
|
#
|
|
# The bug this guards against: rate/pitch sent as ITTSAttributes (-s/-p) override
|
|
# the Flextalk speaker profile, so the VOX/HEV presets sounded too fast and not
|
|
# deep enough. Flextalk must use the sticky vendor tags (\!R / \!%), and neutral
|
|
# sliders must emit neither.
|
|
set -eu
|
|
|
|
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
|
WRAP="$HERE/veskslop-tts.sh"
|
|
WORK=$(mktemp -d)
|
|
trap 'rm -rf "$WORK"' EXIT
|
|
|
|
mkdir -p "$WORK/build" "$WORK/bin" "$WORK/out"
|
|
"${MICROSLOP_FFMPEG:-ffmpeg}" -hide_banner -loglevel error -f lavfi \
|
|
-i "sine=frequency=200:duration=0.3" -ar 11025 -ac 1 -c:a pcm_s16le -y "$WORK/sine.wav"
|
|
|
|
cat > "$WORK/build/sapi4host.exe" <<'STUB'
|
|
#!/bin/sh
|
|
{ printf 'ARGV:'; for a in "$@"; do printf ' [%s]' "$a"; done; printf '\n'; } >> "$STUB_LOG"
|
|
OUT=""
|
|
while [ "$#" -ge 2 ]; do
|
|
[ "$1" = "-o" ] && OUT=$2
|
|
shift
|
|
done
|
|
cp "$STUB_SINE" "$OUT"
|
|
STUB
|
|
|
|
cat > "$WORK/bin/wine" <<'STUB'
|
|
#!/bin/sh
|
|
[ "${1:-}" = "reg" ] && [ "${2:-}" = "import" ] && cp "$3" "$STUB_REG"
|
|
exit 0
|
|
STUB
|
|
chmod +x "$WORK/build/sapi4host.exe" "$WORK/bin/wine"
|
|
|
|
printf 'Attention all personnel.\n' > "$WORK/text.txt"
|
|
|
|
export MICROSLOP_BUILD="$WORK/build"
|
|
export MICROSLOP_WINE="$WORK/bin/wine"
|
|
export MICROSLOP_FFMPEG="${MICROSLOP_FFMPEG:-ffmpeg}"
|
|
export DISPLAY=:99
|
|
export STUB_LOG="$WORK/host.log"
|
|
export STUB_REG="$WORK/profile.reg"
|
|
export STUB_SINE="$WORK/sine.wav"
|
|
|
|
FAIL=0
|
|
check() {
|
|
if [ "$2" = "$3" ]; then
|
|
echo "ok - $1"
|
|
else
|
|
echo "FAIL - $1: expected [$2], got [$3]"
|
|
FAIL=1
|
|
fi
|
|
}
|
|
|
|
run_wrapper() {
|
|
: > "$STUB_LOG"
|
|
sh "$WRAP" "$WORK/out.wav" "$WORK/text.txt" >/dev/null
|
|
}
|
|
|
|
# The spoken text is the -t argument; the engine host writes to the wrapper's temp file.
|
|
text_for() {
|
|
sed -n '1s/.*\[-t\] \[\(.*\)\] \[-o\].*/\1/p' "$STUB_LOG"
|
|
}
|
|
|
|
attr_count() {
|
|
grep -oE '\[-s\]|\[-p\]' "$STUB_LOG" | wc -l | tr -d ' '
|
|
}
|
|
|
|
# Neutral Flextalk sliders emit neither attributes nor tags.
|
|
VESKSLOP_TTS_VOICE=keith-bell run_wrapper
|
|
check "neutral flextalk text" "Attention all personnel." "$(text_for)"
|
|
check "neutral flextalk has no attributes" "0" "$(attr_count)"
|
|
|
|
# Adjustments ride as tags; attributes stay out even at non-neutral values.
|
|
VESKSLOP_TTS_VOICE=keith-bell VESKSLOP_TTS_VOX=0 \
|
|
VESKSLOP_TTS_SPEED=1.3 VESKSLOP_TTS_PITCH=3 run_wrapper
|
|
check "flextalk rate tag" "\!R0.769 \!%1.189 Attention all personnel." "$(text_for)"
|
|
check "flextalk has no attributes" "0" "$(attr_count)"
|
|
|
|
# MSTTS has no vendor tags and keeps the attributes.
|
|
VESKSLOP_TTS_VOICE=sam VESKSLOP_TTS_SPEED=1.3 VESKSLOP_TTS_PITCH=3 run_wrapper
|
|
check "mstts text has no tags" "Attention all personnel." "$(text_for)"
|
|
check "mstts keeps attributes" "2" "$(attr_count)"
|
|
|
|
# The vox preset implies VOX prosody when VESKSLOP_TTS_VOX is unset.
|
|
VESKSLOP_TTS_VOICE=keith-bell VESKSLOP_TTS_PRESET=vox run_wrapper
|
|
check "vox preset implies VOX parser" "1" "$(grep -c 'wH1' "$STUB_LOG")"
|
|
|
|
# The preset writes the full audible profile to both hives.
|
|
VESKSLOP_TTS_VOICE=keith-bell VESKSLOP_TTS_PRESET=vox run_wrapper
|
|
check "preset writes both hives" "2" "$(grep -c 'Speakers\\{11260610' "$STUB_REG")"
|
|
check "preset pitch (both hives)" "2" "$(grep -c '"Pitch"=dword:00000003' "$STUB_REG")"
|
|
check "preset rate (both hives)" "2" "$(grep -c '"Speaking Rate"=dword:00000011' "$STUB_REG")"
|
|
check "preset gender and line mode" "4" "$(grep -cE '"Gender"=dword:00000002|"Line Mode"=dword:00000001' "$STUB_REG")"
|
|
check "preset default speaker" "2" "$(grep -c '"Default Speaker"' "$STUB_REG")"
|
|
|
|
# A plain Flextalk run keeps the defaults and writes no preset extras.
|
|
VESKSLOP_TTS_VOICE=keith-bell run_wrapper
|
|
check "plain run writes both hives" "2" "$(grep -c 'Speakers\\{11260610' "$STUB_REG")"
|
|
check "plain run has no preset extras" "0" "$(grep -cE 'Gender|Line Mode|Default Speaker' "$STUB_REG")"
|
|
|
|
# Voice metadata follows the active preset.
|
|
check "voices reflect hev" "1" \
|
|
"$(VESKSLOP_TTS_PRESET=hev sh "$WRAP" --voices | tr ',' '\n' | grep -c 'keith-bell|Keith Bell|male|en|expression=59+defaults=pitch:15:rate:24')"
|
|
|
|
[ "$FAIL" = "0" ] && echo "wrapper tests passed" || { echo "wrapper tests failed"; exit 1; }
|