docs: § 6.5.4 Aussprache-Lexika vollständig dokumentiert (alle 8 Sprachen)

- YAML-Dateistruktur für alle Sprachen erklärt (de/en/fr/es/it/nl/ru/zh)
- Drei Sektionen (abbreviations/units/terms) mit Matching-Regeln
- Anleitung "Eigennamen in Fremdsprachen" — Textersetzungs-Prinzip statt IPA
  mit Klangäquivalent-Tabelle (ʃ, y/ü, x, ts in je 6 Sprachen)
- Sonderfall RU/ZH: Kyrillisch/Hanzi notwendig, Lateinschrift unzuverlässig
- Drei Wege dokumentiert: Web-UI (de/en), REST-API (alle Sprachen, sofort),
  direkte YAML-Bearbeitung (alle Sprachen, Neustart nötig)
- Test-Befehle: Admin-Test-Button, curl, Normalizer-Skript
- § 7.5 Wörterbuch-Tab: Hinweis auf de/en-Beschränkung + Verweis auf § 6.5.4
- API-Referenz: lang-Parameter auf alle Sprachcodes erweitert
- Stichwortverzeichnis: zwei neue Einträge

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-19 14:34:08 +02:00
commit dc8ac80505

View file

@ -1060,12 +1060,12 @@ Vor dem TTS läuft ein Normalizer, der Ausspracheprobleme des Phonemizers behebt
- **Ordinalzahlen:** „1. Mai" → „erster Mai", „1. 2. 3." → „erstens, zweitens, drittens" - **Ordinalzahlen:** „1. Mai" → „erster Mai", „1. 2. 3." → „erstens, zweitens, drittens"
- **Einheiten nach Zahl:** „10 kg" → „zehn Kilogramm", „km/h" → „Kilometer pro Stunde" - **Einheiten nach Zahl:** „10 kg" → „zehn Kilogramm", „km/h" → „Kilometer pro Stunde"
- **Abkürzungen:** „Dr." → „Doktor", „z. B." → „zum Beispiel" - **Abkürzungen:** „Dr." → „Doktor", „z. B." → „zum Beispiel"
- **YAML-Lexikon:** eigene Begriffe in `config/pronunciation.de.yaml` - **YAML-Lexikon:** eigene Begriffe — für jede Sprache eine eigene Datei
Stärke: `TTS_NORMALIZE_LEVEL=auto|full|light|off` Stärke: `TTS_NORMALIZE_LEVEL=auto|full|light|off`
`auto` = piper bekommt `full`, Cloud-TTS bekommt `light` (Cloud kann Zahlen selbst). `auto` = piper bekommt `full`, Cloud-TTS bekommt `light` (Cloud kann Zahlen selbst).
Eigene Aussprache hinzufügen — **zwei Wege:** ##### Eigene Aussprache hinzufügen (Deutsch / Englisch)
**Web-UI (empfohlen):** Admin-Panel → Tab „🔤 Wörterbuch" (→ § 7.5). Kein Neustart nötig. **Web-UI (empfohlen):** Admin-Panel → Tab „🔤 Wörterbuch" (→ § 7.5). Kein Neustart nötig.
@ -1077,6 +1077,159 @@ python scripts/add_pronunciation.py kWh "Kilowattstunden" --section units
``` ```
Danach Server neu starten (damit der Cache geleert wird). Danach Server neu starten (damit der Cache geleert wird).
##### Aussprache für alle Sprachen — YAML-Lexika
Für jede aktive Sprache gibt es eine separate YAML-Datei im Verzeichnis `config/`:
```
config/
pronunciation.de.yaml # Deutsch
pronunciation.en.yaml # Englisch
pronunciation.fr.yaml # Französisch
pronunciation.es.yaml # Spanisch
pronunciation.it.yaml # Italienisch
pronunciation.nl.yaml # Niederländisch
pronunciation.ru.yaml # Russisch
pronunciation.zh.yaml # Chinesisch
```
Fehlende Dateien werden stillschweigend übersprungen (keine Pflicht für jede Sprache).
Jede Datei hat drei Sektionen:
```yaml
# config/pronunciation.de.yaml (Beispiel)
abbreviations: # Abkürzungen — ganze Token, wortgrenzen-sicher
"ggf.": "gegebenenfalls"
"inkl.": "inklusive"
units: # Einheiten — nur DIREKT nach einer Zahl ersetzt
"kWh": "Kilowattstunden"
terms: # Eigennamen / Begriffe — Groß-/Kleinschreibung egal
"Linux": "Linuks"
"Mond": "Mohnd"
```
| Sektion | Trifft | Beispiel |
|---------|--------|---------|
| `abbreviations` | ganze Wörter / Token mit Wortgrenze | `"z.B."``"zum Beispiel"` |
| `units` | nur nach einer Zahl (`\d\s*Einheit`) | `"kg"``"Kilogramm"` (nur nach Zahl!) |
| `terms` | beliebiger Teiltext, Groß/Klein egal | `"Linux"``"Linuks"` |
**Längerer Eintrag gewinnt** — `"z. B."` wird vor `"B."` geprüft. Reihenfolge im YAML spielt keine Rolle.
##### Eigennamen in Fremdsprachen korrekt aussprechen
Das Lexikon arbeitet mit **Textersetzung** — kein IPA nötig. Der eingetragene Text
wird von espeak-ng (in Piper) nach den Phonemregeln der **Zielsprache** gelesen.
Das Ziel ist also: den Namen so schreiben, wie ihn ein Muttersprachler der Zielsprache
schreiben würde, damit er richtig klingt.
**Grundprinzip:**
```
Original: "Schlüter"
DE: kein Eintrag nötig (nativ)
FR: "Chluteur" → ch=/ʃ/ u=/y/ (= ü!) eur=/œʁ/ → /ʃlytœʁ/ ≈ /ʃlyːtɐ/
EN: "Schlueter" → espeak-en liest "ue" als /uː/ → /ˈʃluːtər/ ✓
NL: "Schluuter" → nl "uu"=/yː/ (= ü) sch=/sx/
RU: "Шлютер" → Kyrillisch für exakte Phoneme (Latein wird schlecht gelesen)
ZH: "施吕特" → 施=Shī=/ʃɨ/ 吕=lǚ=/ly/ (≈ lü!) 特=tè=/tɛ/
```
**Praktische Anleitung für einen neuen Eigennamen:**
1. Überlege, welche Laute der Name enthält.
2. Finde in der Zielsprache Buchstaben/Buchstabenkombinationen, die diese Laute erzeugen.
3. Trage den Ersatztext in `terms:` der passenden Sprachdatei ein.
4. Teste (→ unten).
**Häufige Klangäquivalente je Sprache:**
| Laut | DE | EN | FR | NL | RU | ZH |
|------|----|----|----|----|----|----|
| /ʃ/ | sch | sh | ch | sch (≈) | Ш | sh → 施/书 |
| /y/ (= ü) | ü | — | u | uu | Ю/Ю | ü → 吕/绿 |
| /x/ (= ch) | ch | kh | — | g/ch | Х | h → 哈 |
| /ts/ | z | ts | ts | ts | Ц | ts → 茨 |
**Sonderfall Russisch und Chinesisch:** espeak-ng liest lateinische Buchstaben
in russischem / chinesischem Modus schlecht. Immer Kyrillisch (RU) bzw. Hanzi (ZH) verwenden:
```yaml
# config/pronunciation.ru.yaml
terms:
"Schlüter": "Шлютер" # Ш=/ʃ/ лю=/lʲu/ тер=/tʲɛr/
"Dieter": "Дитер"
# config/pronunciation.zh.yaml
terms:
"Schlüter": "施吕特" # 施=Shī=/ʃɨ/ 吕=lǚ=/ly/ 特=tè=/tɛ/
"Dieter": "迪特"
```
##### Einträge hinzufügen — alle Wege im Überblick
**Weg 1 — Admin-Web-UI** (de/en, sofort wirksam):
Admin-Panel → Tab „🔤 Wörterbuch" → Sprache und Sektion wählen → Eintrag hinzufügen.
Der Cache wird automatisch geleert.
**Weg 2 — REST-API** (alle Sprachen, sofort wirksam):
```bash
# Französischen Eintrag hinzufügen (kein Neustart nötig):
curl -X POST http://localhost:8080/api/admin/pronunciation/fr \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{"section":"terms","key":"Schlüter","value":"Chluteur"}'
# Eintrag löschen:
curl -X DELETE http://localhost:8080/api/admin/pronunciation/fr/terms/Schlüter \
-H "Authorization: Bearer <admin-token>"
# Alle Einträge einer Sprache anzeigen:
curl http://localhost:8080/api/admin/pronunciation/ru \
-H "Authorization: Bearer <admin-token>"
```
**Weg 3 — YAML-Datei direkt editieren** (alle Sprachen):
```bash
nano config/pronunciation.fr.yaml # oder vim, gedit …
```
Danach **Server neu starten**, damit der In-Memory-Cache geleert wird:
```bash
make restart # oder: systemctl --user restart voice-assistant
```
##### Aussprache testen
Nach dem Hinzufügen eines Eintrags kannst du den Effekt sofort prüfen:
**Admin-Panel → Tab „⚙ Einstellungen" → Feld „Piper-Stimme" → Test-Button:**
Spricht den Testsatz mit der aktuell eingestellten Stimme und Sprache.
**Oder via curl:**
```bash
curl -s -X POST http://localhost:8080/api/speak \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"text":"Hallo, ich bin Dieter Schlüter.","tts_provider":"piper","language":"fr"}' \
--output /tmp/test.wav && aplay /tmp/test.wav
```
**Oder mit dem Normalizer-Skript allein** (kein Server nötig):
```bash
source .venv/bin/activate
python3 -c "
import asyncio
from app.pipeline.tts_normalizer import TTSNormalizer
t = TTSNormalizer()
result = asyncio.run(t.run('Schlüter kommt.', language='fr', level='full'))
print(result) # → 'Chluteur kommt.'
"
```
--- ---
### 6.6 Sprache wechseln ### 6.6 Sprache wechseln
@ -1456,12 +1609,17 @@ und CSS-Balkendiagramm.
Aussprache-Lexikon direkt im Browser bearbeiten — kein Kommandozeilen-Skript nötig: Aussprache-Lexikon direkt im Browser bearbeiten — kein Kommandozeilen-Skript nötig:
1. Sprache wählen (Deutsch / Englisch). 1. Sprache wählen (Dropdown: **Deutsch** / **Englisch**).
2. Sektion wählen: **Abkürzungen**, **Einheiten**, **Begriffe / Aussprache**. 2. Sektion wählen: **Abkürzungen**, **Einheiten**, **Begriffe / Aussprache**.
3. Vorhandene Einträge: Maus drüber → **✕** erscheint → löschen. 3. Vorhandene Einträge: Maus drüber → **✕** erscheint → löschen.
4. Neuer Eintrag: Schlüssel + Ersetzung eingeben → **+ Hinzufügen**. 4. Neuer Eintrag: Schlüssel + Ersetzung eingeben → **+ Hinzufügen**.
Die Änderung greift sofort (Server-Cache wird automatisch geleert). Die Änderung greift sofort (Server-Cache wird automatisch geleert).
> **Andere Sprachen (fr, es, it, nl, ru, zh):** Das Wörterbuch-Tab zeigt aktuell nur
> Deutsch und Englisch. Für andere Sprachen die YAML-Datei direkt editieren
> (`config/pronunciation.<lang>.yaml`) oder die REST-API nutzen — beides ohne Neustart
> möglich (API) bzw. mit Neustart (YAML direkt). Vollständige Anleitung → § 6.5.4.
#### Log #### Log
Zeigt den systemd-Journal-Log des `voice-assistant.service` live im Browser: Zeigt den systemd-Journal-Log des `voice-assistant.service` live im Browser:
@ -1960,8 +2118,8 @@ Body-Felder: `input_endpoint`, `output_endpoint`, `stt_provider`, `llm_provider`
| `GET` | `/api/admin/users/{user_id}/usage` | Admin | Nutzungsstatistik eines Nutzers | | `GET` | `/api/admin/users/{user_id}/usage` | Admin | Nutzungsstatistik eines Nutzers |
| `GET` | `/api/admin/usage` | Admin | Aggregierte Nutzungsstatistik aller Nutzer | | `GET` | `/api/admin/usage` | Admin | Aggregierte Nutzungsstatistik aller Nutzer |
| `GET` | `/api/admin/db-export` | Admin | SQLite-Datenbank als Datei-Download (Backup) | | `GET` | `/api/admin/db-export` | Admin | SQLite-Datenbank als Datei-Download (Backup) |
| `GET` | `/api/admin/pronunciation/{lang}` | Admin | Aussprache-Lexikon lesen (`lang`: `de`\|`en`) | | `GET` | `/api/admin/pronunciation/{lang}` | Admin | Aussprache-Lexikon lesen (`lang`: `de`, `en`, `fr`, `es`, `it`, `nl`, `ru`, `zh`, …) |
| `POST` | `/api/admin/pronunciation/{lang}` | Admin | Eintrag hinzufügen/überschreiben (`{"section":"…","key":"…","value":"…"}`) | | `POST` | `/api/admin/pronunciation/{lang}` | Admin | Eintrag hinzufügen/überschreiben (`{"section":"terms","key":"Schlüter","value":"Chluteur"}`) |
| `DELETE` | `/api/admin/pronunciation/{lang}/{section}/{key}` | Admin | Eintrag löschen | | `DELETE` | `/api/admin/pronunciation/{lang}/{section}/{key}` | Admin | Eintrag löschen |
| `WS` | `/api/admin/log` | Admin | Live-Log via WebSocket (journalctl stream) | | `WS` | `/api/admin/log` | Admin | Live-Log via WebSocket (journalctl stream) |
@ -2020,6 +2178,8 @@ in `app/dependencies.py` + Implementierung in `app/providers/`. → [Architektur
| Authentifizierung / Bearer-Token | § 7.1, § 7.3, Anhang B.4 | | Authentifizierung / Bearer-Token | § 7.1, § 7.3, Anhang B.4 |
| Audio-Geräte / Mikrofon / Lautsprecher | § 6.7 | | Audio-Geräte / Mikrofon / Lautsprecher | § 6.7 |
| Aussprache verbessern | § 6.5.4 | | Aussprache verbessern | § 6.5.4 |
| Aussprache — Eigennamen in Fremdsprachen | § 6.5.4 |
| Aussprache — YAML-Lexika (alle Sprachen) | § 6.5.4 |
| Automatische Erinnerungen | § 8.3 | | Automatische Erinnerungen | § 8.3 |
| Barge-in (Unterbrechung) | § 6.8, Anhang B.6 | | Barge-in (Unterbrechung) | § 6.8, Anhang B.6 |
| Bluetooth | § 6.7 | | Bluetooth | § 6.7 |