setup: one-shot install.sh; docs: install, fixed-gain normalization, latency
This commit is contained in:
@@ -25,25 +25,18 @@ pure-native build, and keep a path to a fully portable engine.
|
|||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
Dependencies (once, as root):
|
Everything in one command (idempotent; sudo only for system packages):
|
||||||
|
|
||||||
sudo setup/install-deps.sh
|
setup/install.sh
|
||||||
|
|
||||||
Runtime + MSTTS voices (once):
|
Manual steps, if needed:
|
||||||
|
|
||||||
setup/setup-prefix.sh
|
sudo setup/install-deps.sh # Wine/Winelib/helpers
|
||||||
|
setup/setup-prefix.sh # prefix + SAPI4 runtime + MSTTS voices
|
||||||
Flextalk voices (once; needs the extracted installer, see `docs/NOTES.md`):
|
setup/setup-flextalk.sh # Flextalk extraction + registry
|
||||||
|
# host build:
|
||||||
setup/setup-flextalk.sh
|
|
||||||
|
|
||||||
Host:
|
|
||||||
|
|
||||||
# Winelib (native ELF + launcher): build/sapi4host-winlib.exe + .exe.so
|
|
||||||
winegcc -m32 -O2 -o build/sapi4host-winlib host/sapi4host.c -I../reference \
|
winegcc -m32 -O2 -o build/sapi4host-winlib host/sapi4host.c -I../reference \
|
||||||
-lole32 -luser32 -ladvapi32
|
-lole32 -luser32 -ladvapi32
|
||||||
|
|
||||||
# PE fallback (runs under wine):
|
|
||||||
i686-w64-mingw32-gcc -O2 -static -o build/sapi4host.exe host/sapi4host.c \
|
i686-w64-mingw32-gcc -O2 -static -o build/sapi4host.exe host/sapi4host.c \
|
||||||
-I../reference -lole32 -luser32 -ladvapi32 -luuid
|
-I../reference -lole32 -luser32 -ladvapi32 -luuid
|
||||||
|
|
||||||
@@ -70,6 +63,7 @@ which the setup script writes). Mapping details are in `docs/TTS-DESIGN.md`.
|
|||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
- `host/sapi4host.c` — host: voice select, pitch/speed, text -> WAV
|
- `host/sapi4host.c` — host: voice select, pitch/speed, text -> WAV
|
||||||
|
- `setup/install.sh` — one-shot installer (runs all steps below)
|
||||||
- `setup/install-deps.sh` — Wine/Winelib/helpers (root)
|
- `setup/install-deps.sh` — Wine/Winelib/helpers (root)
|
||||||
- `setup/setup-prefix.sh` — prefix + SAPI4 runtime + MSTTS engine/voices
|
- `setup/setup-prefix.sh` — prefix + SAPI4 runtime + MSTTS engine/voices
|
||||||
- `setup/setup-flextalk.sh` — Flextalk files + registry
|
- `setup/setup-flextalk.sh` — Flextalk files + registry
|
||||||
|
|||||||
+23
-8
@@ -214,9 +214,17 @@ record what the engine needs to interpret, add, or hide._
|
|||||||
so one shared level target is required. The engine post-processes every line:
|
so one shared level target is required. The engine post-processes every line:
|
||||||
resample to 48000 Hz, trim leading silence (<100 ms), 5-10 ms fades, DC removal, and
|
resample to 48000 Hz, trim leading silence (<100 ms), 5-10 ms fades, DC removal, and
|
||||||
level normalization (peak about -3 dBFS, integrated loudness -16 to -20 LUFS).
|
level normalization (peak about -3 dBFS, integrated loudness -16 to -20 LUFS).
|
||||||
- Proposed implementation, engine-side, with ffmpeg (already installed on the dev host):
|
- Implemented in `setup/vekslop-tts.sh` with ffmpeg: high-pass at 40 Hz, silence trim at
|
||||||
`ffmpeg -i raw.wav -af "highpass=f=40,<trim><fade>,loudnorm=..." -ar 48000 -ac 1 out.wav`.
|
both ends (trim-start, reverse, trim-start, reverse), 8 ms fades, then a **fixed gain**
|
||||||
The WAV handed to Veskslop is then compliant; the "Veskslop does not normalize" rule holds.
|
computed from an EBU R128 measurement (`ebur128=peak=true`):
|
||||||
|
`gain = min(-16 LUFS target, -3 dBFS true-peak clamp)`, then 48 kHz mono s16le.
|
||||||
|
- `loudnorm` was rejected: on short lines (under about 3 s) the loudness range is 0 and
|
||||||
|
dynamic mode attenuated a 2.8 s line to -37.9 LUFS instead of about -18 LUFS; two-pass
|
||||||
|
linear mode showed the same result. The fixed gain is steady for one-line utterances,
|
||||||
|
as Veskslop suggested.
|
||||||
|
- Verified: Keith Bell -18.4 LUFS, Kerry Watson -17.9 LUFS, Sam -20.6 LUFS; every file is
|
||||||
|
48 kHz mono s16le at -3.0 dBFS true peak. The WAV handed to Veskslop is compliant; the
|
||||||
|
"Veskslop does not normalize" rule holds.
|
||||||
|
|
||||||
### Voice IDs
|
### Voice IDs
|
||||||
|
|
||||||
@@ -258,15 +266,22 @@ record what the engine needs to interpret, add, or hide._
|
|||||||
|
|
||||||
### Transport and latency
|
### Transport and latency
|
||||||
|
|
||||||
|
- Installation is one command: `setup/install.sh` (system dependencies with sudo, wine
|
||||||
|
prefix + SAPI4 runtime + MSTTS voices, Flextalk extraction/registration, host build).
|
||||||
|
Re-running is safe; a fresh machine needs nothing else.
|
||||||
- Command provider, implemented as `setup/vekslop-tts.sh`:
|
- Command provider, implemented as `setup/vekslop-tts.sh`:
|
||||||
`VESKSLOP_TTS_CMD="<repo>/setup/vekslop-tts.sh {out} {text_file}"` and
|
`VESKSLOP_TTS_CMD="<repo>/setup/vekslop-tts.sh {out} {text_file}"` and
|
||||||
`VESKSLOP_TTS_VOICES="$(<repo>/setup/vekslop-tts.sh --voices)"`. The wrapper reads the
|
`VESKSLOP_TTS_VOICES="$(<repo>/setup/vekslop-tts.sh --voices)"`. The wrapper reads the
|
||||||
text file, transliterates UTF-8 to CP1252, starts or reuses an Xvfb when `DISPLAY` is
|
text file, transliterates UTF-8 to CP1252, starts or reuses an Xvfb when `DISPLAY` is
|
||||||
unset, calls the engine, then post-processes (trim, fades, two-pass `loudnorm`, 48 kHz
|
unset, calls the engine, then post-processes (trim, fades, measured fixed gain, 48 kHz
|
||||||
mono s16le). Verified: -17.7 LUFS integrated, -3.0 dBFS true peak.
|
mono s16le). A stale private Xvfb is retried once.
|
||||||
- Measured on the dev host (warm Wine): Sam line about 288 ms wall, Flextalk line about
|
- Measured on the dev host: engine-only synthesis is about 290 ms wall for Sam and about
|
||||||
41 ms wall, including process start, synthesis, and file write. Both are inside the
|
40 ms for Flextalk, including process start; the full wrapper adds the ffmpeg
|
||||||
500 ms budget.
|
measure/apply passes, about 630-880 ms per short line. That is above the 500 ms target;
|
||||||
|
the known optimization is a per-voice static gain (skip the measurement pass), expected
|
||||||
|
to land around 400-500 ms.
|
||||||
|
- Manual checks: `setup/run.sh -l`, `setup/run.sh -v "Keith Bell" -t "Hello." -o out.wav`
|
||||||
|
(raw engine WAV), and the wrapper above for normalized output.
|
||||||
- HTTP provider (later): a persistent process returning `audio/wav` bytes and `/voices`,
|
- HTTP provider (later): a persistent process returning `audio/wav` bytes and `/voices`,
|
||||||
with optional caching by `hash(text + voice + speed + pitch)`.
|
with optional caching by `hash(text + voice + speed + pitch)`.
|
||||||
|
|
||||||
|
|||||||
Executable
+84
@@ -0,0 +1,84 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# One-shot installer for MicroslopSam. Runs all setup steps, idempotently:
|
||||||
|
# 1. system dependencies (Wine, Winelib, helpers; needs sudo)
|
||||||
|
# 2. wine prefix + SAPI4 runtime + MSTTS voices + registration
|
||||||
|
# 3. Flextalk extraction + voices + registration
|
||||||
|
# 4. host build (Winelib and PE)
|
||||||
|
# 5. quick voice check
|
||||||
|
#
|
||||||
|
# Usage: setup/install.sh
|
||||||
|
# Re-running is safe.
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
ROOT=$(CDPATH= cd -- "$HERE/.." && pwd)
|
||||||
|
ASSETS=${ASSETS:-$ROOT/../Microsoft-Sam-Mary-Mike-TruVoice-WSAPI4}
|
||||||
|
FLEXTALK_DIR=${FLEXTALK_DIR:-$ROOT/../flextalk}
|
||||||
|
|
||||||
|
log() { printf '\n== %s\n' "$*"; }
|
||||||
|
|
||||||
|
# 1) system dependencies -----------------------------------------------------
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
log "installing system dependencies"
|
||||||
|
"$HERE/install-deps.sh"
|
||||||
|
else
|
||||||
|
log "installing system dependencies (sudo)"
|
||||||
|
sudo "$HERE/install-deps.sh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 2) SAPI4 runtime + MSTTS voices --------------------------------------------
|
||||||
|
log "setting up wine prefix, SAPI4 runtime and MSTTS voices"
|
||||||
|
"$HERE/setup-prefix.sh" "$ASSETS"
|
||||||
|
|
||||||
|
# 3) Flextalk voices ----------------------------------------------------------
|
||||||
|
EXTRACTED="$FLEXTALK_DIR/extracted/TTS_Executables"
|
||||||
|
if [ ! -d "$EXTRACTED/EngineDLLs" ]; then
|
||||||
|
CAB=""
|
||||||
|
for c in "$FLEXTALK_DIR/installer/flextalk/data1.cab" \
|
||||||
|
"$ASSETS/flextalk/data1.cab"; do
|
||||||
|
if [ -f "$c" ]; then CAB="$c"; break; fi
|
||||||
|
done
|
||||||
|
if [ -z "$CAB" ]; then
|
||||||
|
echo "Flextalk data1.cab not found; set FLEXTALK_DIR to the archive dir" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
command -v unshield >/dev/null 2>&1 || {
|
||||||
|
echo "unshield is required to extract the Flextalk installer" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
log "extracting Flextalk installer ($CAB)"
|
||||||
|
rm -rf "$FLEXTALK_DIR/extracted"
|
||||||
|
unshield -O -d "$FLEXTALK_DIR/extracted" x "$CAB" >/dev/null
|
||||||
|
fi
|
||||||
|
log "installing Flextalk voices"
|
||||||
|
"$HERE/setup-flextalk.sh" "$EXTRACTED"
|
||||||
|
|
||||||
|
# 4) host build ---------------------------------------------------------------
|
||||||
|
log "building the host"
|
||||||
|
mkdir -p "$ROOT/build"
|
||||||
|
winegcc -m32 -O2 -o "$ROOT/build/sapi4host-winlib" "$ROOT/host/sapi4host.c" \
|
||||||
|
-I"$ROOT/../reference" -lole32 -luser32 -ladvapi32
|
||||||
|
if command -v i686-w64-mingw32-gcc >/dev/null 2>&1; then
|
||||||
|
i686-w64-mingw32-gcc -O2 -static -o "$ROOT/build/sapi4host.exe" \
|
||||||
|
"$ROOT/host/sapi4host.c" -I"$ROOT/../reference" \
|
||||||
|
-lole32 -luser32 -ladvapi32 -luuid
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 5) check --------------------------------------------------------------------
|
||||||
|
log "installed voices"
|
||||||
|
"$HERE/run.sh" -l || true
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
|
||||||
|
Done.
|
||||||
|
|
||||||
|
Veskslop configuration:
|
||||||
|
VESKSLOP_TTS_CMD="$HERE/vekslop-tts.sh {out} {text_file}"
|
||||||
|
VESKSLOP_TTS_VOICES="\$($HERE/vekslop-tts.sh --voices)"
|
||||||
|
|
||||||
|
Manual test:
|
||||||
|
$HERE/run.sh -v Sam -t "Hello." -o /tmp/hello.wav
|
||||||
|
|
||||||
|
Normalized 48 kHz output (what Veskslop hears):
|
||||||
|
VESKSLOP_TTS_VOICE=keith-bell $HERE/vekslop-tts.sh /tmp/keith.wav /tmp/text.txt
|
||||||
|
EOF
|
||||||
Reference in New Issue
Block a user