On 10 November 2026 ElevenLabs shipped Scribe v3 and its realtime sibling Scribe v3 Live. The batch model claims 27 % fewer word errors than Scribe v2 across 102 languages. The live model cuts semantic word-error rate 43 % versus Scribe v2 Realtime, adds speaker diarization for the first time in their streaming path, and does turn detection from conversation context rather than silence alone. Coval’s latest numbers put Scribe v3 Live at roughly 93 ms mean time-to-final-segment and 2.2 % WER.

Those are strong numbers once clean PCM is already at the model. They do not change the capture budget on a Windows desktop when you need a private translation overlay for an interview or support call.

What a cloud STT endpoint cannot see

Scribe v3 Live (and every other hosted realtime model) receives the stream you send it. It does not sit on your local audio endpoints. It does not give you a second, private track of your own microphone that never enters the call. It does not let you paint a translation overlay that is invisible to screen share. And it does not run when you prefer not to send audio off-box at all, or when the platform you are on has not been integrated.

For a developer who needs real-time speech-to-text and translation during a technical interview, a sales call, or a support session in another language, those constraints matter. The useful path is still local capture of two tracks, local or BYOK processing, and an overlay that never appears in the shared desktop.

Multiple waveforms

Multiple waveforms. Dual-track capture keeps the mic and the remote side separate so each can be biased, timed, and translated independently.

Dual-track capture is still the practical floor

A single mixed stream loses speaker identity. For live translation you need:

  • Mic track — your voice (private, never sent to the remote side unless you choose to)
  • Loopback track — everything the other person says (WASAPI loopback of the render device)

That separation lets the STT engine produce clean transcripts for each side and the UI show them side-by-side without injecting a bot into the meeting.

On modern Windows the practical stack is:

  1. Endpoint device (USB headset, Bluetooth HFP/A2DP, built-in mic, or WASAPI loopback).
  2. Windows Audio Engine (audiodg.exe + audioeng.dll) in shared mode: mixing, any “communications” enhancements, spatial audio, vendor APOs. This routinely adds 10–40+ ms and is fragile under load or with Bluetooth.
  3. Your capture client buffer (10–40 ms is the common practical range; lower values drop under DPC spikes or heavy system load).
  4. Format conversion and ring-buffer copy off the audio callback (float32 → int16, 48 kHz → 16 kHz).
  5. VAD or simple energy gate.
  6. STT (local faster-whisper / Whisper.cpp / Qwen3-ASR GGUF, or a BYOK cloud endpoint such as Scribe v3 Live) + optional translation.
  7. Overlay paint on a dedicated thread (<16 ms if you stay off the UI thread).

A “sub-100 ms time-to-final” cloud model is real once it has clean PCM. It is almost irrelevant if the samples have already been delayed or dropped inside the audio engine. End-to-end partials on a good day land in the 80–150 ms range; Bluetooth or a busy shared-mode session pushes that higher.

Minimal capture sketch

// Pseudocode shape of a dual-track WASAPI client // Real code uses the Windows Audio Session API or a thin wrapper struct DualCapture { mic: WasapiCapture, // exclusive or shared, low-latency loopback: WasapiCapture, // render-device loopback mic_ring: RingBuffer<i16>, lb_ring: RingBuffer<i16>, } impl DualCapture { fn on_mic_callback(&mut self, data: &[f32]) { // convert, resample if needed, push to ring // never block; drop or expand under pressure self.mic_ring.push_pcm(data); } fn on_loopback_callback(&mut self, data: &[f32]) { self.lb_ring.push_pcm(data); } fn drain_for_stt(&mut self) -> Option<(Vec<i16>, Vec<i16>)> { // pull fixed frames (e.g. 20–40 ms) from both rings // align by timestamp if the devices are independent Some((self.mic_ring.drain_frame(), self.lb_ring.drain_frame())) } } 

The callback must stay short. Anything heavier (resampling, VAD, network send) belongs on a worker. Shared-mode sessions inherit the system mix and any communications enhancements; exclusive mode can drop the latency but breaks system sounds and requires careful format negotiation.

Trade-offs that still matter

  • Cloud vs local. Scribe v3 Live (or Soniox, Deepgram Nova-3, etc.) gives you the latest accuracy and diarization without shipping a GPU. Local GGUF models (Qwen3-ASR 1.7B Q4_K_M at ~1.3 GB, faster-whisper, Whisper.cpp) keep the audio on-box and remove the network RTT. Hybrid (local VAD + cloud STT only on speech) is the practical middle.
  • Bluetooth. HFP is still a latency and quality tax. Prefer USB or the built-in mic + loopback of the speakers when you can.
  • Overlay thread. Painting the translation on the UI thread will hitch. Keep the overlay on its own thread and only push text deltas.
  • Speaker identity. Even with realtime diarization on a mixed stream, a private dual-track setup gives you hard separation without relying on the model’s clustering.

Practical path for interview and call overlays

Keep the mic and the remote side separate. Run VAD locally. Send each track (or only the remote track) to the STT of your choice—local or BYOK cloud. Render the result in an overlay that is excluded from screen share. The model latency numbers look great in isolation; the Windows audio graph still sets the floor you actually feel.

I'm building Talkaside, a Windows app for job interviews and calls in another language.
Drafted with AI assistance from this project's code and logs.