feat(voice_loop): --voice-Option + saubere Default-Stimme je TTS-Provider

- voice_loop.py: --voice reicht die Stimme im Start-Frame durch (nur wenn gesetzt),
  sonst greift der Provider-Default. Beispiele in Docstring/Help.
- ws.py/speak.py/chat.py: ohne explizite Stimme None durchreichen statt die
  OpenRouter-Stimme zu erzwingen -> jeder Provider nimmt SEINEN Default
  (OPENROUTER_TTS_VOICE bzw. PIPER_VOICE). Ungenutzten settings-Import in speak.py
  entfernt.
- Doku: BEDIENUNGSANLEITUNG (--voice + Default-Stimme je Provider).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Dieter Schlüter 2026-06-17 23:42:23 +02:00
commit 9d0019274a
5 changed files with 22 additions and 7 deletions

View file

@ -10,6 +10,7 @@ Beispiele:
python scripts/voice_loop.py --url ws://localhost:8003/ws/voice --session oma-anna
python scripts/voice_loop.py --device hw:1,0 # bestimmtes Mikrofon (arecord -L)
python scripts/voice_loop.py --llm-provider openrouter --tts-provider openrouter
python scripts/voice_loop.py --tts-provider openrouter --voice Puck # Cloud-Stimme testen
python scripts/voice_loop.py --file frage.wav # ohne Mikrofon (Test)
Voraussetzungen: laufendes Gateway, `arecord` (Aufnahme), ein Player
@ -211,7 +212,7 @@ def _start_frame(args) -> dict:
frame["audio_stream"] = args.stream_audio
if getattr(args, "stream_text", False):
frame["stream"] = True
for key in ("stt_provider", "llm_provider", "tts_provider", "language"):
for key in ("stt_provider", "llm_provider", "tts_provider", "language", "voice"):
value = getattr(args, key, None)
if value:
frame[key] = value
@ -346,6 +347,9 @@ def main() -> None:
p.add_argument("--stt-provider", dest="stt_provider", default=None)
p.add_argument("--llm-provider", dest="llm_provider", default=None)
p.add_argument("--tts-provider", dest="tts_provider", default=None)
p.add_argument("--voice", default=None,
help="TTS-Stimme (provider-spezifisch; ohne Angabe gilt der Provider-Default, "
"z. B. OPENROUTER_TTS_VOICE bzw. PIPER_VOICE)")
p.add_argument("--language", default=None)
# Audio-Streaming: Default entscheidet der Server (AUDIO_STREAM_DEFAULT, i. d. R. an).
audio_grp = p.add_mutually_exclusive_group()