Architektur und Ausführungsmodell
Threads und Warteschlange, die Kaskade der Texteingabe, der Steuer-Socket und die sprachabhängige Typografie.
Drei Threads, eine Warteschlange
Audioaufnahme, Erkennung und die Terminal-Oberfläche laufen in src/main.py auf getrennten Daemon-Threads, verbunden durch eine thread-sichere queue.Queue.
audio_capture.py liest 16-kHz-Mono-PCM von PortAudio und legt es ab; recognition.py zieht es in einen lokalen KaldiRecognizer.
Gerät die Erkennung in Rückstand, wird der älteste Audioblock verworfen, statt die Latenz driften zu lassen — der Überlaufzähler erscheint in --status und --diagnose.
Texteingabe: ein Einfügen über die Zwischenablage, mit Backend-Kaskade
Sobald text_processing.py eine erkannte Äußerung formatiert hat, legt system_control.py sie in die Zwischenablage und simuliert ein Einfügen. Das Backend wird einmalig beim Start gewählt.
| Weg | Werkzeuge | Bedingung |
|---|---|---|
| Wayland | wtype + wl-clipboard | Unabhängig vom Tastaturlayout (wtype arbeitet über Keysyms). Braucht einen Compositor, der das Virtual-Keyboard-Protokoll bereitstellt (wlroots-Desktops); andernfalls Fallback auf ydotool. |
| X11 | xdotool + xclip | Standardweg unter X11. |
| Fallback | ydotool + wl-clipboard | Fügt auf Treiberebene ein (/dev/uinput) über den Daemon ydotoold; Keycodes sind layoutabhängig; verlangt Mitgliedschaft in der Gruppe input. |
Neben dem Tastendruck-Werkzeug wird ein Zwischenablage-Werkzeug benötigt: wl-clipboard unter Wayland — auch beim ydotool-Fallback erforderlich — und xclip unter X11. Die nativen Pakete ziehen wl-clipboard mit (das Debian-Paket empfiehlt zusätzlich xclip); eine Quellinstallation fügt sie selbst hinzu. Ohne eines davon erreicht der diktierte Text die Zwischenablage nie, und das Einfügen fügt erneut ein, was zuletzt von Hand kopiert wurde.
Der vorherige Inhalt der Zwischenablage wird nach dem Einfügen zurückgelesen und wiederhergestellt (einstellbar über clipboard.restore, standardmäßig an). Nicht-textueller Inhalt — Bilder, Dateien — bleibt unangetastet. Unter Wayland mit einer GTK-Anwendung kann die Wiederherstellung dem Lesen der Zwischenablage durch das Fenster zuvorkommen; clipboard.defer_restore verschiebt die Wiederherstellung auf das Ende der Diktiersitzung, damit das Einfügen nie den alten Inhalt übernimmt.
Funktioniert kein Backend für die aktuelle Sitzung, stürzt das Werkzeug nicht ab und verwirft auch nichts still: es geht in den reduzierten Modus. Der erkannte Text wird weiterhin im Terminal ausgegeben, das automatische Tippen wird für den Rest der Sitzung deaktiviert, statt es bei jedem Wort erneut — und erfolglos — zu versuchen.
Einige Fenster verweigern das Einfügen ebenfalls — manche Java-Anwendungen, geschützte Felder. Beim ersten Mal wechselt das Werkzeug auf dieselbe Weise in den reduzierten Modus.
Der Steuer-Socket
Eine laufende Sitzung öffnet einen privaten Unix-Socket unter $XDG_RUNTIME_DIR/vosk-cli-dictation.sock (Modus 0600). Derselbe Befehl mit --toggle, --finalize, --sleep-toggle, --status oder --stop verbindet sich mit diesem Socket, statt eine zweite Sitzung zu starten.
Das lässt Tastaturkürzel des Desktops unter Wayland überall funktionieren, auch für die nativen Wayland-Fenster, die die globalen pynput-Hotkeys nie sehen.
Pro Benutzer läuft nur eine Sitzung gleichzeitig; ein von einem Absturz zurückgelassener Socket wird beim nächsten Start erkannt und ersetzt.
Zwei Ebenen der Vokabelkorrektur
Ein falsches Wort und ein falsch geschriebenes Wort sind zwei verschiedene Fehler, und config.yaml hält ihre Korrekturen bewusst getrennt.
recognition_aliases
Das Modell hat die falschen Wörter gehört; diese werden direkt ersetzt ("tirez" → "tiret").
custom_vocabulary
Das Modell hat richtig gehört, aber einen Namen kleingeschrieben; die Schreibweise wird erzwungen ("vosk" → "Vosk").
Sprachabhängige Typografie
text_processing.py wendet die Ausgaberegeln der diktierten Sprache an, nicht nur ihre Satzzeichenwörter.
- Französisch — fügt ein schmales, nicht umbrechendes Leerzeichen (U+202F) vor
? ! : ;und»ein. - Deutsch — verwendet die Anführungszeichen
„ "und schreibt nur Satzanfänge groß. - Spanisch — fügt
¿und¡nur auf ausdrücklichen Befehl ein.
Jeder Satz liegt unter language_settings.<lang>.typography, weil sich das korrekte Verhalten tatsächlich je Sprache unterscheidet, nicht nur im Vokabular.
Übersetzung der Oberfläche
Die Oberflächensprache des Werkzeugs und seine Diktiersprache sind zwei getrennte Einstellungen.
Oberflächensprache
Die Texte des Werkzeugs selbst nutzen die GNU-gettext-Kette — .po-Kataloge, zu .mo kompiliert, mit Babel aus dem Python-Quelltext extrahiert.
Diktiersprache
language_settings in config.yaml steuert die Sprache, die Sie sprechen, ihre Satzzeichenwörter und ihre Typografie — nicht die Sprache der Oberfläche.
Siehe docs/configuration.md für jeden Schlüssel und Anleitungen für den Einstieg.