Sync with Veskslop integration: Flextalk profile support, words/echo/highpass, wrapper rename

This commit is contained in:
Fisto
2026-09-15 15:04:46 +02:00
parent 57cf5485ce
commit 643cdc38bf
6 changed files with 382 additions and 170 deletions
+56
View File
@@ -419,3 +419,59 @@ _Added 2026-09-15._
untouched, so the voice keeps its engine default.
- **Licensing**: keep the engine DLLs and voice data local and out of any repository; Veskslop
never bundles or redistributes them.
## Current integration path (Veskslop side, 2026-09-15)
Everything below is implemented. The engine stays unchanged; the wrapper and the daemon do the work.
### Voice metadata
`VESKSLOP_TTS_VOICES` entries may carry flags after the language field:
id|Name|gender|language|flags
Flags are `+`-separated:
- `no-pitch` - hide the pitch control for this voice.
- `expression=NN` - Flextalk profile voice; NN is the default Expression value.
- `defaults=pitch:27:rate:33:prominences:17:head_size:46:lowering:40:expression:59` -
per-voice engine defaults. The UI shows "default" at these values and snaps to them
within +/-2 units.
### Wrapper contract (`microslopsam/setup/veskslop-tts.sh`)
Inputs: `{out}`, `{text_file}`, optional positional voice/speed/pitch/expression, and:
| Env | Meaning |
| --- | --- |
| `VESKSLOP_TTS_PROFILE` | `pitch:27:...`/`key=value,...` overrides; the wrapper writes the full profile (defaults + overrides) to the Wine registry with `wine reg import` before every synthesis. |
| `VESKSLOP_TTS_HIGHPASS` | High-pass Hz, 40-400 (default 40). |
| `VESKSLOP_TTS_ECHO` | Mono echo 0-100 (`aecho`), default 0. |
| `VESKSLOP_TTS_WORDS` / `VESKSLOP_TTS_WORD_GAP_MS` | Word-by-word synthesis with silence gaps (Flextalk only). |
Placeholders `{profile}`, `{highpass}`, `{echo}`, `{words}`, `{word_gap_ms}` mirror the env vars.
`wine regedit` fails headlessly but returns 0: use `wine reg import`. A missing profile value
must always write the engine default so no stale registry state survives.
### Daemon and UI path
1. Preferences (`tts`): `profile` (changed keys only), `profilePresets` (5 named slots),
`highpass`, `echo`, `words`, `wordGapMs`, plus `speed`, `pitch`, `expression`, `voice`.
2. `/api/audio/speak` and MCP `speak` accept all of them per line; the request overrides the
preferences and empty fields are omitted so the engine default applies.
3. The TTS panel opens the **Flextalk voice profile** window (movable, recentered on open) with
profile sliders, named presets, radio-kit controls, and test lines (Attention, Laboratory,
Critical, Health, Radiation, plus two persisted custom lines). Test buttons post the same
options as `speak`, so they audition the current profile.
### Known pitfalls
- The daemon runs from `tsx`: restart it after protocol, preference, or metadata changes.
- Static web files can be cached; hard-reload the browser after UI changes.
- `Number(null)` is 0: preference normalizers must treat null/undefined/"" as unset.
- The renderer log spam on a dead client is throttled in the bridge; background polls fail with
`CORE_UNAVAILABLE` and retry.
- Generate the Flextalk profile `.reg` with `printf`, never `echo`: dash's `echo` interprets
`\2` in `...\Watson\2.0\...` as an escape (0x02), so the key is corrupted and
`wine reg import` becomes a silent no-op (it still returns 0). The wrapper now rejects a
generated profile that contains control characters. This was the 2026-09-15 profile bug.