Push-to-talk transcription with clipboard paste injection. Hold a hotkey, speak, release — the text appears at your cursor. Works in any app: VS Code, Cursor, Copilot terminal, chat windows, browsers.
Fully local. No API calls, no telemetry. faster-whisper runs on-device. The model stays loaded between uses so transcription starts immediately.
- Python 3.9+
- A microphone
setup.batThat creates a .venv and installs all Python dependencies. On first run the
Whisper model weights are downloaded from Hugging Face (~500 MB for small).
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txtLinux note: pynput needs access to
/dev/inputor X11. On X11 it works out of the box. Wayland requires additional setup (XWayland or uinput).
# Windows — activate venv first, or use full path
.venv\Scripts\python voice_type.py
# With options
.venv\Scripts\python voice_type.py --model base --hotkey scroll_lockOn first launch the model loads (5–15 s). After that it stays in memory.
| Action | Default (hold mode) |
|---|---|
| Record | Hold Right Ctrl (ctrl_r) |
| Transcribe + paste | Release Right Ctrl |
| Exit | Ctrl+C in the terminal |
The transcript is pasted via clipboard (Ctrl+V simulation). Focus stays on your target window — type your question, hold the key, speak, release, done.
--model SIZE Model size: tiny, base, small (default), medium, large-v3
--hotkey KEY Hotkey name (pynput Key name or single char, default: ctrl_r)
--mode MODE hold (default) or toggle
--no-paste Copy to clipboard only; skip Ctrl+V simulation
--append Append newline after text (submits message in chat UIs)
--device N Audio input device index
--list-devices Show available audio devices and exit
| Model | Size | First-transcription latency (CPU) |
|---|---|---|
| tiny | ~75 MB | ~1–2 s |
| base | ~150 MB | ~2–4 s |
| small | ~500 MB | ~4–8 s |
| medium | ~1.5 GB | ~10–20 s |
| large-v3 | ~3 GB | ~20–40 s |
For dictating to an AI chat window small is the sweet spot.
ctrl_r (Right Ctrl) is the default. It rarely conflicts with editor bindings.
Some alternatives if you have collisions:
| Key name | Notes |
|---|---|
ctrl_r |
Right Ctrl — default |
scroll_lock |
Almost never bound in modern apps |
pause |
Pause/Break key |
f13 – f24 |
Extended keys, absent on most keyboards |
caps_lock |
Familiar but breaks normal caps use |
If --mode toggle, one press starts recording, a second press stops and
transcribes. Useful for longer dictation where holding is uncomfortable.
python voice_type.py --appendAppends \n to the pasted text, which submits the message in Claude Code,
Cursor chat, GitHub Copilot chat, and most browser chat UIs.
python voice_type.py --list-devices
python voice_type.py --device 2sounddeviceopens an always-on audio stream (silent until recording starts).- Hotkey press: audio frames are buffered in memory.
- Hotkey release: buffering stops. A background thread runs
WhisperModel.transcribe(). - Transcript is written to the clipboard via
pyperclip. pynput.keyboard.Controllersimulates Ctrl+V to paste into the focused window.
The model is instantiated once at startup and reused for every transcription.
"Could not open audio device"
Run --list-devices and pass the correct index with --device N.
Paste goes to wrong window
The Ctrl+V fires ~80 ms after release. Don't click away during transcription.
Use --no-paste to copy-only if this is a problem.
Whisper transcribes nothing / gibberish
Try a larger model (--model medium). Check mic levels — whisper is sensitive
to very quiet or clipped input. The small model works well for English; for
other languages medium or large-v3 is recommended.
pynput listener stops capturing keys On Windows this can happen if another application installs a global keyboard hook. Restart voice_type.py.
"No module named faster_whisper"
Make sure you're running from the virtual environment:
.venv\Scripts\python voice_type.py
This directory is fully self-contained. To extract:
cp -r tools/voice-type /path/to/new-repo
cd /path/to/new-repo
git init && git add . && git commit -m "init"No references to fmod-mcp or any other project.