Docs: point at the pronunciation dictionary in chatterbox-tts-cli

German TTS mispronounced English terms and foreign names. The fix lives upstream in
~/chatterbox-tts-cli (pronunciation.py + pronunciation/de.json), and services/tts_server.py
picks it up with no code change here — worth recording, since nothing in this repo hints
that the mechanism exists.

Also records why it is respelling and not phonetics: chatterbox is grapheme-based, and
the [ipa] token found in its vocabulary was tested and does not speak IPA.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-07-11 16:52:59 +02:00
commit 9bcd11af66

View file

@ -302,6 +302,27 @@ Reachability from the `open_notebook` container requires **two things**, both al
Registered in Open Notebook as `openai_compatible` credentials with `base_url=http://host.docker.internal:8901` (TTS) / `:8902` (STT), and set as `default_text_to_speech_model` / `default_speech_to_text_model`.
#### Pronunciation (English terms, proper names)
German TTS mispronounces English technical terms and foreign names ("Repository", "Donald Trump").
The fix lives **upstream in `~/chatterbox-tts-cli/`**, not here: `pronunciation.py` (a torch-free
module) plus the curated `pronunciation/de.json`, which `chatterbox_cli_v4.preprocess_tts_text()`
applies automatically for `lang="de"`. `services/tts_server.py` needs **no code** for this — it
already calls that function, so podcasts get the corrections for free.
The mechanism is **respelling in German orthography** ("Repository" → "Ripositori"), not phonetics.
Chatterbox is grapheme-based (tokenizer: `grapheme_mtl_merged_expanded_v1`); its vocabulary does
contain IPA symbols and an `[ipa]` language token, but that was tested and does **not** work —
ɪˈpɑzɪˌtɔɹi` comes out audibly as "Ripacitari". Splitting the sentence and switching to `[en]`
per term works phonetically but glues segments together without crossfade: 4 seams cost 0.50.8 s
of silence each, growing a 3.9 s sentence to 7.1 s. Respelling is the only usable route.
To add project-specific terms without touching the shared file, point
`CHATTERBOX_PRONUNCIATION_DICT` at a JSON file (it is read by `load_pronunciation_dict()` and
overrides the shipped list). Find candidates in a real transcript with
`~/chatterbox-tts-cli/pronunciation_candidates.py` (lists words hunspell's German dictionary
doesn't know and that aren't in the dictionary yet).
#### Voice cloning
`tts_server.py` resolves the incoming `voice` field via `services/voices/*.wav` (gitignored — personal voice recordings): `<name>.wav` becomes a selectable voice `"<name>"`, cloned via chatterbox's `audio_prompt_path`. Unknown/omitted voices fall back to `"default"`; a bare language code (e.g. `"en"`) still works and skips cloning (built-in voice for that language). All cloned voices are generated in German (`CLONE_LANG` in the script) since only German reference clips exist here — add entries to `VOICE_LANG_OVERRIDES` in the script if you add clips in other languages.