Voice-to-text dictation tool that types transcribed speech wherever your cursor is. Uses OpenAI's transcription API as a replacement for Windows' built-in Win+H.
# Clone and install
cd voice-dictation
pip install -e .
# Add your OpenAI API key
cp .env.example .env
# Edit .env with your keyvoice-dictation| Hotkey | Action |
|---|---|
Ctrl+Shift+Space |
Start/stop recording |
Ctrl+Shift+L |
Switch language (English / Portugues) |
Ctrl+Shift+M |
Cycle model |
Ctrl+Shift+R |
Re-paste the last transcription |
Ctrl+Shift+T |
Retry: re-send the last recording to the API (current model/language), paste without Enter |
Ctrl+C |
Quit |
- Click wherever you want text to appear
- Press
Ctrl+Shift+Space(beep = recording) - Speak
- Press
Ctrl+Shift+Spaceagain (beep = stopped) - Text is transcribed and pasted at your cursor
| Model | Cost/min | Notes |
|---|---|---|
gpt-4o-mini-transcribe |
$0.003 | Default, fastest, cheapest |
gpt-4o-transcribe |
$0.006 | Best quality |
whisper-1 |
$0.006 | Legacy |
The app logs each transcription with colored output:
- Recording start/stop indicators
- Transcription text preview
- Latency, token usage, and estimated cost per request
- Session summary on exit (total requests, audio, tokens, cost)
All transcriptions are logged to a local SQLite database (voice_dictation.db in the repo root, gitignored). Each record includes:
- Timestamp, transcribed text, language, model
- Audio duration, API latency
- Input/output/total tokens
- Estimated cost
Each recording is written to recordings/ (gitignored) before the API call, so a
hallucinated or failed transcription can be retried with Ctrl+Shift+T without
speaking again. Only the last KEEP_LAST_RECORDINGS (2) are kept; older files are
deleted on every save, so the folder never grows.
The transcription is put on the clipboard and pasted with Ctrl+V; the text that
was on the clipboard before is put back CLIPBOARD_RESTORE_DELAY_SECONDS (1.5 s)
later. The delay matters: Electron/Chromium apps read the clipboard well after the
key event, and restoring sooner made them paste the old clipboard. The write is
verified (read back) before Ctrl+V is sent, so a busy clipboard can never make
the paste land stale content; if you copy something during the delay, your copy
wins and nothing is put back. Non-text clipboard content (images, files) is not
preserved.
flowchart LR
A[Hotkey Press] --> B[Recorder]
B -->|WAV bytes| C[OpenAI API]
C -->|text + tokens| D[Injector]
D -->|Ctrl+V| E[Cursor Position]
C -->|metadata| F[SQLite DB]
C -->|metadata| G[Terminal Logger]
src/voice_dictation/
app.py # Main app, hotkeys, system tray, lifecycle
config.py # Env vars, constants, hotkey bindings
recorder.py # Microphone capture (sounddevice, 16kHz mono)
transcriber.py # OpenAI API client, token extraction
injector.py # Clipboard + Ctrl+V text injection (Win32)
logger.py # Colored terminal output
db.py # SQLite logging
recordings.py # Last-N recordings on disk, for retry
- Python 3.11+
- Windows (uses Win32 APIs for clipboard and winsound)
- OpenAI API key