Fork of wolfgangmeyers/freeflow-linux (originally a Linux port of FreeFlow by Zach Latta). This fork adds on-demand mic streaming (privacy / zero-idle-CPU), WAV-based sound effects, and configurable stream modes.
Push-to-talk voice dictation for Linux using Groq Whisper + LLM post-processing.
A Linux equivalent of FreeFlow (macOS). Hold a configurable hotkey (default: Right Ctrl) to record your voice — the audio is transcribed by Groq Whisper and cleaned up by a Groq LLM, then pasted into whatever app you have focused.
- Hold the hotkey for 1 second (a beep confirms recording has started)
- Speak
- Release the hotkey — the transcript is cleaned up and pasted into the focused window
The 1-second hold threshold prevents accidental triggers.
# Audio (PortAudio runtime)
sudo apt install libportaudio2 pipewire-alsa
# Paste — X11
sudo apt install xdotool xclip
# Paste — Wayland
sudo apt install wl-clipboard wtype # wlroots compositors (Sway, Hyprland, KDE)
sudo apt install ydotool # GNOME Wayland (also needs ydotoold daemon)python3 -m venv .venv
.venv/bin/pip install -r requirements.txtGet a free API key at console.groq.com.
Set it in the config file (created automatically on first run):
~/.config/freeflow-linux/config.tomlOr export it as an environment variable:
export GROQ_API_KEY=gsk_...freeflow-linux reads keyboard events directly from /dev/input via evdev. This requires
membership in the input group:
sudo usermod -aG input $USER
# Log out and back in for the group to take effectIf you use GNOME on Wayland, you need ydotool for paste to work:
sudo apt install ydotool
echo 'KERNEL=="uinput", GROUP="input", MODE="0660"' | sudo tee /etc/udev/rules.d/80-uinput.rules
sudo udevadm control --reload-rules
sudo systemctl enable --now ydotool
# Log out and back incd ~/code/freeflow-linux
.venv/bin/python freeflow_linux.py.venv/bin/python freeflow_linux.py --dry-runConfig file: ~/.config/freeflow-linux/config.toml (created automatically on first run)
api_key = "gsk_..." # Groq API key (or use GROQ_API_KEY env var)
hotkey = "KEY_RIGHTCTRL" # Right Ctrl — change to KEY_F9 etc. if preferred
# audio_device = "" # Leave empty to use system default micTo find available hotkey names, run evtest and press the key you want.
The stream_mode setting controls whether the audio stream stays open at all times:
ondemand(default): Mic is opened only when you hold the hotkey past the 1s threshold, and closed after transcription. CPU usage at idle is ~0%. Privacy benefit: the mic hardware is electrically inactive when you're not dictating. Adds ~100ms of stream-init latency on first utterance.persistent: Audio stream runs continuously, the callback discards samples when not recording. Instant recording start. Idle CPU is ~3% (PortAudio poll loop). Mic hardware stays active while the daemon runs.
Example config:
stream_mode = "ondemand" # or "persistent"You can also comment/uncomment the option in ~/.config/freeflow-linux/config.toml.
freeflow-linux plays a sound when recording starts and when it finishes. WAV files are stored in sounds/ next to the script, played via pw-play (PipeWire).
Includes two sets:
- Bird — rising chirp on start, falling chirp on stop (
start_voice_bird.wav,stop_voice_bird.wav) - macOS-style — bright ascending pings on start, glassy descending sweep on stop (
start_macos.wav,stop_macos.wav)
Swap between them by copying the file you want over the active name:
cp sounds/start_macos.wav sounds/start_voice.wav
cp sounds/stop_macos.wav sounds/stop_voice.wavDrop any WAV file (48kHz, mono or stereo) into sounds/start_voice.wav or sounds/stop_voice.wav to use your own.
mkdir -p ~/.config/systemd/user
cp freeflow-linux.service.example ~/.config/systemd/user/freeflow-linux.service
# Edit the ExecStart path if needed
systemctl --user daemon-reload
systemctl --user enable --now freeflow-linuxExample service file:
[Unit]
Description=FreeFlow Linux voice dictation daemon
After=graphical-session.target
[Service]
ExecStart=/path/to/freeflow-linux/.venv/bin/python /path/to/freeflow-linux/freeflow_linux.py
Restart=on-failure
RestartSec=3
Environment=XDG_SESSION_TYPE=x11
Environment=DISPLAY=:0
[Install]
WantedBy=default.target- Fn key: Does not work — handled by keyboard firmware, never reaches the kernel
- Right Ctrl (default): Reliable, rarely used for other shortcuts
- F9, ScrollLock, media keys: All work well as alternatives
| Feature | X11 | Wayland |
|---|---|---|
| Hotkey capture (evdev) | Yes | Yes |
| Paste | xclip + xdotool | wl-copy + wtype/ydotool |
| Window context | Yes (xdotool) | No |
| Terminal detection (Ctrl+Shift+V) | Yes | No |
Inspired by FreeFlow by Zach Latta.
This is a fork of wolfgangmeyers/freeflow-linux (the initial Linux port).
Uses Groq for fast Whisper transcription and LLM post-processing.