# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. > Sprache: Code-Kommentare, Doku und Commits auf Deutsch (Umlaute in Code/Kommentaren bisher meist als ae/oe/ue). ## Projektziel Lokale, schnelle, zuverlässige Spracherkennung (Sprache → Text), nicht blockierend. Soll später als Baustein in Smarthome-Szenarien dienen (Home Assistant, Mikrocontroller wie ESP32/Arduino als Audio-Clients) und das **STT-Pendant zum TTS-Projekt `chatterbox-tts-cli`** werden (https://kitux.de/forgejo/dschlueter/chatterbox-tts-cli, lokaler Klon `~/chatterbox-tts-cli`: CLI-Kern + FastAPI-Service mit Job-Queue/Worker-Thread + MCP-Adapter + systemd-User-Service). Referenz für bewährtes STT: `~/my_voice_assistant_v3` (https://kitux.de/forgejo/dschlueter/my_voice_assistant_v3), v. a. `app/providers/stt/faster_whisper.py` (Modell einmal laden + cachen, Inferenz via `asyncio.to_thread`, CPU-Fallback), `app/audio/vad.py` (Äußerungsende per Stille), `app/api/ws.py` (`/ws/voice`), `app/core/warmup.py`. ## Dateien - `stt.py` — **aktueller Stand**, eigenständige CLI (einzige relevante Datei). - `stt_respeaker.py` — **historisch**, nicht weiterentwickeln und nicht als Vorlage nutzen. Kein Build, keine Tests, keine Linter-Konfiguration. Git-Remote auf kitux.de (Forgejo) ist geplant, aber noch nicht eingerichtet. ## Befehle ```bash pip install faster-whisper sounddevice numpy scipy requests # plus Systemtools: espeak-ng, ffmpeg, pactl/paplay, ollama python3 stt.py --list-devices # Geräte inkl. nativer Sampleraten aus /proc/asound python3 stt.py # Live-Aufnahme, Sprache de, Stoppwort "finito" python3 stt.py en -i respeaker -m large-v3 # Positional-Arg = Sprache python3 stt.py --file audio.wav --no-llm # Datei-Modus (nur int16-Mono-WAV korrekt) python3 -m py_compile stt.py # Syntax-Check ``` Rauchtest ohne Mikrofon/GPU: `python3 stt.py --file --no-llm -m tiny --device cpu`. ## GPU-Umgebung T600 + 2× RTX 3090. `nvidia-smi` zählt in PCI-Reihenfolge, CUDA/torch/ctranslate2 standardmäßig „fastest first“ — Indizes stimmen nicht überein. Andere Dienste (llama.cpp, chatterbox, open-notebook-stt auf :8902) pinnen GPUs per `CUDA_VISIBLE_DEVICES=GPU-` (`nvidia-smi -L`); so auch hier verfahren statt per Index. ## Architektur `stt.py` (Ist-Zustand) Ablauf in `main()`: `detect_compute()` → ein `WhisperModel` (für Stoppwort-Chunks **und** finale Transkription) → `resolve_device()` (Default via `pactl` → `alsa.card` → sounddevice-Index `hw:N`) → `play_announcement()` (espeak-ng → ffmpeg → `sd.play`, Fallback `paplay`) → `record_until_stopword()` (Callback-Stream schreibt 2-s-Blöcke in Queue; Hauptthread: Mono → 16 kHz → RMS-Gate → Whisper-Stoppwortprüfung) → Peak-Normalisierung → WAV in `/tmp/stt_*.wav` → `transcribe()` → `llm_correct()` (Ollama `/api/chat`, `localhost:11434`). - `stereo_to_mono()`: ReSpeaker XVF3800 → nur rechter Kanal (ASR-Output); Mischen verschlechtert die Erkennung. - Stoppwort-Entfernung aus dem Text übernimmt nur der LLM-Prompt (`LLM_SYSTEM_PROMPT`, nur de/en). - Alle Ausgaben per `print`; das Endergebnis steht nach der Zeile `FINALES ERGEBNIS` auf stdout.