diff --git a/README.md b/README.md index ab4a527..aced4de 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,10 @@ A short low-level leading hum (80 ms, 75 Hz, -48 dBFS) primes Discord's audio pi 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 diff --git a/docs/NOTES.md b/docs/NOTES.md index fe520d4..afa4b91 100644 --- a/docs/NOTES.md +++ b/docs/NOTES.md @@ -129,6 +129,11 @@ without them. - VOX mode is Flextalk-only. The wrapper enables it with `VESKSLOP_TTS_VOX=1` (`VESKSLOP_TTS_VOX_CLEAN=1` drops the stutter wrapper) and it takes precedence over `VESKSLOP_TTS_WORDS`. +- Half-Life presets (`VESKSLOP_TTS_PRESET=vox|hev`) target Keith Bell only. VOX values + come from NetTTS `nettts_flextalk_vox_profile.reg`: pitch 3, rate 17, prominences 22, + head size 52, volume 70 (factory: 27/33/17/46/100); `vox` also implies VOX prosody. + `hev` (pitch 15, rate 24) is an unverified starting point - HL1 credits the suit + sounds to Kelly Bailey with no published settings. - Line-leading `/rate N` and `/pitch N` controls are consumed by the wrapper (percent, 100 = normal; `<= 2.0` means multiplier). They override the env speed/pitch and are not spoken; a controls-only line yields 100 ms of silence. diff --git a/docs/TTS-DESIGN.md b/docs/TTS-DESIGN.md index 0a18845..356fecd 100644 --- a/docs/TTS-DESIGN.md +++ b/docs/TTS-DESIGN.md @@ -387,6 +387,40 @@ Other NetTTS features and their relevance: our prefix runs the engines with builtin Wine libraries. - Win32 GUI and preset sliders: Veskslop provides the UI. +### Half-Life VOX / HEV presets + +The Half-Life announcement voice (VOX / Black Mesa Announcement System) is the Flextalk +engine's **Keith Bell** voice with an adjusted speaker profile. NetTTS publishes an +approximation of Valve's settings (`scripts/winetricks/nettts_flextalk_vox_profile.reg`, +see its issues #53/#54/#67): the profile targets Keith Bell's speaker key and leaves +Kerry Watson at factory values. The wrapper implements it as a preset: + + VESKSLOP_TTS_PRESET=vox # implies VOX prosody unless VESKSLOP_TTS_VOX is set + VESKSLOP_TTS_PRESET=hev # HEV suit starting point (see note below) + +| Profile value | Factory (Keith) | VOX preset | HEV preset (approx.) | +| --- | --- | --- | --- | +| Pitch | 27 | 3 | 15 | +| Speaking Rate | 33 | 17 | 24 | +| Prominences | 17 | 22 | 22 | +| Head Size | 46 | 52 | 52 | +| Lowering | 40 | 40 | 40 | +| Volume | 100 | 70 | 70 | +| Expression | 59 | 59 | 59 | + +- Presets apply only to `keith-bell`; every other voice keeps its defaults. +- Precedence: preset < `VESKSLOP_TTS_PROFILE` < `VESKSLOP_TTS_EXPRESSION`. +- Equivalent explicit override: + `VESKSLOP_TTS_PROFILE='pitch:3,rate:17,volume:70,prominences:22,head_size:52,lowering:40'`. +- The NetTTS profile also sets `Gender`, `Line Mode`, and a set of text-class DWORDs + (address/date/money classes, abbreviation expansion, and so on). Those affect text + normalization rather than the audible voice, so the wrapper does not write them. +- HEV suit: Half-Life 1 credits the suit sounds to Kelly Bailey; no settings were ever + published. The `hev` preset is a starting point (less extreme than VOX); tune pitch and + rate to taste. VOX prosody is optional there (`VESKSLOP_TTS_VOX=1`). +- Measured with the wrapper on the same line: VOX preset 5.83 s, HEV 3.79 s, factory + 3.35 s (the VOX preset is slower and gains the VOX cadence). + ### Inline rate/pitch controls (engine-side) The wrapper consumes NetTTS-style, line-leading controls, so Veskslop and the WebUI do diff --git a/setup/veskslop-tts.sh b/setup/veskslop-tts.sh index 24a6c90..f3c8afe 100755 --- a/setup/veskslop-tts.sh +++ b/setup/veskslop-tts.sh @@ -23,6 +23,8 @@ # VESKSLOP_TTS_HUM_MS leading low hum in ms, 0 = off (default 80) # VESKSLOP_TTS_HUM_HZ hum frequency, 30-200 (default 75) # VESKSLOP_TTS_HUM_DB hum peak level, -80..-6 (default -48) +# VESKSLOP_TTS_PRESET vox | hev (Half-Life profiles, Keith Bell; +# vox also enables VOX prosody) # # Output: 48 kHz mono s16le WAV, trimmed, faded, loudness-normalized. set -eu @@ -55,6 +57,12 @@ WORDS=${VESKSLOP_TTS_WORDS:-0} WORD_GAP=${VESKSLOP_TTS_WORD_GAP_MS:-120} VOX=${VESKSLOP_TTS_VOX:-0} VOX_CLEAN=${VESKSLOP_TTS_VOX_CLEAN:-0} +PRESET=${VESKSLOP_TTS_PRESET:-} +# The VOX preset is the Half-Life announcement voice: it implies VOX prosody +# unless the caller explicitly disables it. +if [ "$PRESET" = "vox" ] && [ -z "${VESKSLOP_TTS_VOX:-}" ]; then + VOX=1 +fi HUM_MS=${VESKSLOP_TTS_HUM_MS:-80} HUM_HZ=${VESKSLOP_TTS_HUM_HZ:-75} HUM_DB=${VESKSLOP_TTS_HUM_DB:--48} @@ -179,6 +187,25 @@ if [ -n "$SPEAKER_GUID" ]; then P_LOWER=40 P_EXPR="" + # Half-Life presets for Keith Bell (the game's announcement voice). + # "vox" is the approximated Valve VOX profile published by NetTTS + # (scripts/winetricks/nettts_flextalk_vox_profile.reg); "hev" is a starting + # point for the HEV suit voice, which has no published profile. + case "$PRESET" in + vox) + if [ "$ENGVOICE" = "Keith Bell" ]; then + P_PITCH=3; P_RATE=17; P_VOLUME=70 + P_PROM=22; P_HEAD=52; P_LOWER=40 + fi + ;; + hev) + if [ "$ENGVOICE" = "Keith Bell" ]; then + P_PITCH=15; P_RATE=24; P_VOLUME=70 + P_PROM=22; P_HEAD=52; P_LOWER=40 + fi + ;; + esac + if [ -n "$PROFILE" ]; then OLDIFS=$IFS IFS=',' diff --git a/third_party/README.md b/third_party/README.md index 399fa0b..68d80c2 100644 --- a/third_party/README.md +++ b/third_party/README.md @@ -34,3 +34,6 @@ Microsoft installers. Private archival copies; do not redistribute. [h4rm0n1c/NetTTS](https://github.com/h4rm0n1c/NetTTS), kept as the reference for validating `setup/vox_parser.py`. Upstream declares no license; these files are reference-only and are not linked into anything we ship. + +- `nettts_flextalk_vox_profile.reg` — NetTTS's approximated Valve VOX speaker profile + for Keith Bell (the source of the `vox`/`hev` presets in `setup/veskslop-tts.sh`). diff --git a/third_party/nettss-reference/nettts_flextalk_vox_profile.reg b/third_party/nettss-reference/nettts_flextalk_vox_profile.reg new file mode 100644 index 0000000..843d069 --- /dev/null +++ b/third_party/nettss-reference/nettts_flextalk_vox_profile.reg @@ -0,0 +1,127 @@ +Windows Registry Editor Version 5.00 + +[HKEY_CURRENT_USER\Software\AT&T\Watson\2.0\FlexTalk\2.0] +"Default Speaker"="{11260610-C84A-11CE-AEC4-0000C0E9CB87}" + +[HKEY_CURRENT_USER\Software\AT&T\Watson\2.0\FlexTalk\2.0\Speakers\{000031CB-3699-551F-AED0-6B4893382D57}] +"Abbreviation Expansion"=dword:00000001 +"Address Class"=dword:00000001 +"Age"=dword:0000001e +"Alphabetic Hyphen"=dword:00000000 +"Case Significance"=dword:00000001 +"Date Class"=dword:00000001 +"Expression"=dword:00000064 +"Fraction Class"=dword:00000001 +"Gender"=dword:00000001 +"Head Size"=dword:0000002d +"Line Mode"=dword:00000000 +"Lowering"=dword:00000028 +"Math Mode"=dword:00000000 +"Measurements Class"=dword:00000001 +"Mode Name"="Kerry Watson" +"Money Class"=dword:00000001 +"Numerical Hyphen"=dword:00000001 +"Ordinal Numbers Class"=dword:00000001 +"Pitch"=dword:00000041 +"Prominences"=dword:00000011 +"ProofRead Mode"=dword:00000000 +"Proper Names Class"=dword:00000001 +"Speaker Name"="Kerry Watson" +"Speaking Rate"=dword:00000020 +"Spell Mode"=dword:00000000 +"Telephone Numbers Class"=dword:00000001 +"Time Class"=dword:00000001 +"Volume"=dword:00000064 + +[HKEY_CURRENT_USER\Software\AT&T\Watson\2.0\FlexTalk\2.0\Speakers\{11260610-C84A-11CE-AEC4-0000C0E9CB87}] +"Abbreviation Expansion"=dword:00000001 +"Address Class"=dword:00000001 +"Age"=dword:0000001e +"Alphabetic Hyphen"=dword:00000000 +"Case Significance"=dword:00000001 +"Date Class"=dword:00000001 +"Expression"=dword:0000003b +"Fraction Class"=dword:00000001 +"Gender"=dword:00000002 +"Head Size"=dword:00000034 +"Line Mode"=dword:00000001 +"Lowering"=dword:00000028 +"Math Mode"=dword:00000000 +"Measurements Class"=dword:00000001 +"Mode Name"="Keith Bell" +"Money Class"=dword:00000001 +"Numerical Hyphen"=dword:00000000 +"Ordinal Numbers Class"=dword:00000001 +"Pitch"=dword:00000003 +"Prominences"=dword:00000016 +"ProofRead Mode"=dword:00000000 +"Proper Names Class"=dword:00000001 +"Speaker Name"="Keith Bell" +"Speaking Rate"=dword:00000011 +"Spell Mode"=dword:00000000 +"Telephone Numbers Class"=dword:00000001 +"Time Class"=dword:00000001 +"Volume"=dword:00000046 + +[HKEY_LOCAL_MACHINE\Software\AT&T\Watson\2.0\FlexTalk\2.0] +"Default Speaker"="{11260610-C84A-11CE-AEC4-0000C0E9CB87}" + +[HKEY_LOCAL_MACHINE\Software\AT&T\Watson\2.0\FlexTalk\2.0\Speakers\{000031CB-3699-551F-AED0-6B4893382D57}] +"Abbreviation Expansion"=dword:00000001 +"Address Class"=dword:00000001 +"Age"=dword:0000001e +"Alphabetic Hyphen"=dword:00000000 +"Case Significance"=dword:00000001 +"Date Class"=dword:00000001 +"Expression"=dword:00000064 +"Fraction Class"=dword:00000001 +"Gender"=dword:00000001 +"Head Size"=dword:0000002d +"Line Mode"=dword:00000000 +"Lowering"=dword:00000028 +"Math Mode"=dword:00000000 +"Measurements Class"=dword:00000001 +"Mode Name"="Kerry Watson" +"Money Class"=dword:00000001 +"Numerical Hyphen"=dword:00000001 +"Ordinal Numbers Class"=dword:00000001 +"Pitch"=dword:00000041 +"Prominences"=dword:00000011 +"ProofRead Mode"=dword:00000000 +"Proper Names Class"=dword:00000001 +"Speaker Name"="Kerry Watson" +"Speaking Rate"=dword:00000020 +"Spell Mode"=dword:00000000 +"Telephone Numbers Class"=dword:00000001 +"Time Class"=dword:00000001 +"Volume"=dword:00000064 + +[HKEY_LOCAL_MACHINE\Software\AT&T\Watson\2.0\FlexTalk\2.0\Speakers\{11260610-C84A-11CE-AEC4-0000C0E9CB87}] +"Abbreviation Expansion"=dword:00000001 +"Address Class"=dword:00000001 +"Age"=dword:0000001e +"Alphabetic Hyphen"=dword:00000000 +"Case Significance"=dword:00000001 +"Date Class"=dword:00000001 +"Expression"=dword:0000003b +"Fraction Class"=dword:00000001 +"Gender"=dword:00000002 +"Head Size"=dword:00000034 +"Line Mode"=dword:00000001 +"Lowering"=dword:00000028 +"Math Mode"=dword:00000000 +"Measurements Class"=dword:00000001 +"Mode Name"="Keith Bell" +"Money Class"=dword:00000001 +"Numerical Hyphen"=dword:00000000 +"Ordinal Numbers Class"=dword:00000001 +"Pitch"=dword:00000003 +"Prominences"=dword:00000016 +"ProofRead Mode"=dword:00000000 +"Proper Names Class"=dword:00000001 +"Speaker Name"="Keith Bell" +"Speaking Rate"=dword:00000011 +"Spell Mode"=dword:00000000 +"Telephone Numbers Class"=dword:00000001 +"Time Class"=dword:00000001 +"Volume"=dword:00000046