What broke when I shipped a local Whisper dictation app to real Windows hardware
Description and use
The author built VoxScribe, a local Whisper‑based dictation app. Hardware and driver issues caused silent transcriptions and crashes. Fixes: select WASAPI device, record at native rate and resample to 16 kHz, switch to hold‑to‑talk, and buffer initial audio. The app now works reliably across microphones.
Problem
Audio hardware and driver issues caused failures in a local Whisper dictation app on Windows.
Outcome
The app now reliably transcribes speech from various microphones on Windows, handling sample rate differences, Bluetooth latency, and voice activity detection issues.
Workflow
- 1. Detect and select the WASAPI default input device instead of the generic default.
- 2. Record audio at the device’s native sample rate.
- 3. Resample recorded audio to 16 kHz using linear interpolation before feeding it to Whisper.
- 4. Replace automatic VAD with a hold‑to‑talk mechanism; keep VAD code for future use.
- 5. Optionally keep the mic stream open and buffer the last half‑second to avoid clipping the first word.
Evidence
The first was a Bluetooth headset that recorded near silence. On my machine the sounddevice library picked a default input device that landed on an MME driver, and for my headset that produced audio so quiet that Whisper transcribed almost nothing.
The fix was to ask for the WASAPI default input device explicitly instead of trusting the generic default.
The second was a crash when forcing 16 kHz. Whisper wants 16 kHz audio, so my first version opened the microphone at 16 kHz. That worked on my headset, then failed with an invalid sample rate error on a laptop's internal mic running at 48 kHz.
The fix was to record at the device's own native rate and resample to 16 kHz in software afterward.
I switched to hold-to-talk, so the user decides when speech starts and stops and there is nothing to guess.
I added an opt-in mode that keeps the stream open and holds the last half second in a small in-memory buffer, so a recording starts with audio that is already there.
- Record date: 2026-10-03T20:55:46.150Z