# MicroslopSam Run SAPI4 text-to-speech voices on Linux. Primary approach: a **Winelib host** — a native Linux ELF that uses Wine's libraries to load the original 32-bit SAPI4 runtime and TTS engine DLLs. Voice targets: - Microsoft Sam / Mary / Mike — MSTTS engine (`msttssyn.dll` + `.vce` data) - AT&T Flextalk 2.1 — "Keith Bell" and "Kerry Watson" (`FlexTalk.dll`) Long-term: replace Wine-provided pieces with own shims (rehost) for a pure-native build, and keep a path to a fully portable engine. ## Status (working) - Winelib host builds and runs: `build/sapi4host.exe` (launcher) + `build/sapi4host.exe.so` (native 32-bit ELF). - Voices enumerate and synthesize: - MSTTS: Sam, Mary, Mike (+ telephone and effect variants) - AT&T Flextalk: Keith Bell, Kerry Watson - Test output: `build/test_sam.wav` (22.05 kHz), `build/test_Keith_Bell.wav`, `build/test_Kerry_Watson.wav` (11.025 kHz). ## Build Everything in one command (idempotent; sudo only for system packages): setup/install.sh Manual steps, if needed: sudo setup/install-deps.sh # Wine/Winelib/helpers setup/setup-prefix.sh # prefix + SAPI4 runtime + MSTTS voices setup/setup-flextalk.sh # Flextalk extraction + registry # host build: winegcc -m32 -O2 -o build/sapi4host-winlib host/sapi4host.c -Ithird_party \ -lole32 -luser32 -ladvapi32 i686-w64-mingw32-gcc -O2 -static -o build/sapi4host.exe host/sapi4host.c \ -Ithird_party -lole32 -luser32 -ladvapi32 -luuid ## Configuration `setup/install.sh` writes `setup/microslopsam.env` (generated, gitignored) with absolute paths. Environment variables take precedence over the file, so anything can be relocated without editing scripts: | Variable | Default | Meaning | | --- | --- | --- | | `MICROSLOP_ROOT` | repo root | project root | | `MICROSLOP_BUILD` | `$MICROSLOP_ROOT/build` | host binaries, samples | | `MICROSLOP_PREFIX` | `~/.wine-microslopsam` | wine prefix (exported as `WINEPREFIX`) | | `MICROSLOP_ASSETS` | `third_party/sapi4` | SAPI4/MSTTS payloads (vendored) | | `MICROSLOP_FLEXTALK_DIR` | `third_party/flextalk` | Flextalk cabinet/extraction (vendored) | | `MICROSLOP_SPEECH_H_DIR` | `$MICROSLOP_ROOT/third_party` | `speech.h` include dir (vendored) | | `MICROSLOP_DISPLAY` | `:77` | Xvfb display used for Wine | | `MICROSLOP_WINE`, `MICROSLOP_XVFB`, `MICROSLOP_PYTHON`, `MICROSLOP_FFMPEG` | tool names | tool overrides | Refresh the file after moving the tree: `MICROSLOP_UPDATE_ENV=1 setup/install.sh`. ## Usage setup/run.sh -l setup/run.sh -v Sam -t "Hello." -o sam.wav setup/run.sh -v "Keith Bell" -t "Hello." -o keith.wav -p 100 -s 150 Options: `-v` voice, `-t` text, `-o` output WAV, `-p` pitch, `-s` speed, `-V` volume (volume is engine-specific; not used by the Veskslop wrapper). ## Veskslop integration export VESKSLOP_TTS_CMD="$PWD/setup/veskslop-tts.sh {out} {text_file}" export VESKSLOP_TTS_VOICES="$(setup/veskslop-tts.sh --voices)" The wrapper maps voice IDs (`sam`, `mary`, `mike`, `keith-bell`, `kerry-watson`, plus the MSTTS variants), reads `VESKSLOP_TTS_VOICE`, `VESKSLOP_TTS_SPEED` (multiplier), `VESKSLOP_TTS_PITCH` (semitones) and `VESKSLOP_TTS_EXPRESSION` (0-100, Flextalk voices only), starts Xvfb when `DISPLAY` is unset, and writes a 48 kHz mono s16le WAV trimmed, faded and normalized to about -16 LUFS (-3 dBFS true peak). Speed and pitch apply to every voice (Flextalk's numeric settings must be `REG_DWORD`, which the setup script writes). Expression is a Flextalk profile value applied at voice load: the wrapper writes it to the Wine registry before synthesis. `--voices` marks those voices with `expression=NN`, where NN is the registry default. Mapping details are in `docs/TTS-DESIGN.md`. **VOX prosody** (NetTTS-style, Flextalk voices): set `VESKSLOP_TTS_VOX=1` in the command environment (`VESKSLOP_TTS_VOX_CLEAN=1` omits the `\!wH1/\!wH0` stutter wrapper). Line-leading `/rate N` and `/pitch N` controls are also handled by the wrapper, so the WebUI does not need to implement them. See `docs/TTS-DESIGN.md`. A short low-level leading hum (80 ms, 75 Hz, -48 dBFS) primes Discord's audio pipeline so the first word is not gated; tune with `VESKSLOP_TTS_HUM_MS` (0 = off), `VESKSLOP_TTS_HUM_HZ`, and `VESKSLOP_TTS_HUM_DB`. **Half-Life presets** (Keith Bell): `VESKSLOP_TTS_PRESET=vox` applies the approximated Valve VOX profile and enables VOX prosody; `VESKSLOP_TTS_PRESET=hev` is a starting point for the HEV suit voice. Values are in `docs/TTS-DESIGN.md`. ## Layout - `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/setup-prefix.sh` — prefix + SAPI4 runtime + MSTTS engine/voices - `setup/setup-flextalk.sh` — Flextalk files + registry - `setup/inf2reg.py` — INF AddReg -> `.reg` converter - `setup/run.sh` — run helper (prefix + Xvfb) - `setup/veskslop-tts.sh` — Veskslop command-provider wrapper (post-processing included) - `setup/vox_parser.py` — NetTTS-style VOX prosody encoder (Flextalk voices) - `docs/NOTES.md` — registry/CLSID facts, runtime RE notes, gotchas - `docs/TTS-DESIGN.md` — integration contract with Veskslop plus engine clarifications ## Known issues - `xvfb-run` is flaky on this host. `setup/run.sh` starts a persistent Xvfb (`:77`) instead; Wine needs a working X display because the runtime creates windows. - Flextalk numeric speaker settings must be `REG_DWORD` (the installer script handles this); `REG_SZ` values cause a monotone buzz. Pitch and speed work on all voices. - Flextalk extraction needs `unshield -O` (old compression). The installer is single-volume: the new decompressor reports a phantom `data2.cab`, but `-O` extracts all 450 entries with exact sizes and valid PE files (the original 1997 upload log lists `data1.cab` only). ## Reference material - `third_party/` — vendored dependencies; see `third_party/README.md`. Everything the tool needs is in the repo (SAPI4 runtime, MSTTS voices, Flextalk cabinet, `speech.h`, NetTTS parser source). - `/mnt/ghidra/decomp/{msttssyn.dll,speech.dll}/` — decompiled corpora (external, optional)