feat(tts): Aussprache-Normalisierung vor Piper (Ordinalia/Einheiten/Abk./Lexikon)

In-Process-Layer ausgebaut statt neuer Lib/CLI. Leitprinzip: nicht duplizieren,
was espeak-ng schon kann (Kardinal-/Dezimalzahlen bleiben unangetastet) -- nur die
belegten Luecken fuellen.

- german_numbers.py: deutsche Ordinalzahlen 1.-31. (attributiv/adverbial)
- tts_normalizer.py: Ordinalia (Datum '1. Mai'->'erster Mai', Folgen '1. 2. 3.'->
  'erstens, zweitens, ...'), Einheiten nach Zahl (kg/km/km-h/...), Abkuerzungen
  (Dr./z.B./usw.), optionales YAML-Lexikon (config/pronunciation.<lang>.yaml).
  Provider-abhaengige Stufen auto|full|light|off (TTS_NORMALIZE_LEVEL): piper=full,
  Cloud=light (laesst Zahlen/Abk. fuer das Cloud-Modell in Ruhe).
- spoken_response_adapter.py: nummerierte Listen -> Ordinalwoerter statt Loeschen.
- sentence_chunker.py: trennt nicht mehr nach Ziffer+Punkt, Einzelbuchstabe+Punkt
  ('z. B.', Initialen) oder bekannten Abkuerzungen -> behebt das Streaming-Symptom
  ('1.' wurde als eigener 'Satz' zu 'eins').
- orchestrator/dependencies: normalize_level durchgereicht (auto: piper->full).
- Tests: tests/test_tts_normalizer.py + Chunker-Faelle (85 gruen).
- Doku: BEDIENUNGSANLEITUNG (Aussprache verbessern), .env.example.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-17 23:01:41 +02:00
commit c9d8552ec7
13 changed files with 411 additions and 56 deletions

View file

@ -11,6 +11,12 @@ OPENROUTER_API_KEY=
# false = Antwort erst komplett synthetisieren, dann abspielen.
AUDIO_STREAM_DEFAULT=true
# Text-Normalisierung vor dem TTS (Aussprache): auto|full|light|off.
# auto = piper bekommt 'full' (Ordinalia/Einheiten/Abk./Lexikon), Cloud-TTS 'light'
# (nur Glaettung; Cloud spricht Zahlen/Abkuerzungen selbst gut). Lexikon:
# config/pronunciation.de.yaml (erweitert die eingebauten Defaults).
TTS_NORMALIZE_LEVEL=auto
# --- Authentifizierung -----------------------------------------------------
# AUTH_ENABLED=true (Standard) schuetzt chat/speak/transcribe/sessions per Bearer-Token.
# Fuer lokale Entwicklung/Tests auf false setzen (dann gilt ein anonymer Nutzer).