Inspiration
What it does
Inspiration
My grandmother lost most of her hearing in her seventies. Watching her nod along to family conversations she couldn't actually follow — smiling at jokes she never heard — was the quiet heartbreak that started this project. Live captioning exists, but it's built for lecture halls and TV broadcasts, not for a noisy dinner table with five people talking over each other. We wanted to build Murmur: a real-time, speaker-aware captioning system that runs entirely on-device, so conversations stay private and captions stay fast.
What it does
Murmur listens to multi-speaker conversations and renders a live, color-coded transcript on a phone or tablet — each speaker gets their own lane, like a group chat happening in real time. It performs:
- Streaming speech-to-text with sub-400ms latency, fully on-device
- Speaker diarization ("who said what") using lightweight voice embeddings
- Semantic smoothing — an LLM pass that repairs disfluencies ("uh, the thing, you know, the—the report") into readable text without changing meaning
- Zero cloud dependency — nothing ever leaves the device
How we built it
The pipeline is a three-stage stream: audio → diarized text → smoothed captions.
- Capture & VAD. We chunk microphone input into 30ms frames and run voice-activity detection to gate the pipeline, cutting idle compute by ~70%.
- Diarization. Each speech segment is embedded into a 192-dimensional speaker vector. We cluster incrementally with an online variant of agglomerative clustering, assigning a segment to speaker $k$ when the cosine similarity exceeds a threshold:
$$k = \arg\max_i ; \frac{\mathbf{e} \cdot \mathbf{c}_i}{\lVert \mathbf{e} \rVert , \lVert \mathbf{c}_i \rVert}, \quad \text{accept if} ; \geq \tau = 0.72$$
where $\mathbf{e}$ is the segment embedding and $\mathbf{c}_i$ is the running centroid for speaker $i$. New speakers spawn a new centroid automatically — no enrollment step.
- Transcription & smoothing. A quantized Whisper-small model (int8, ~240MB) handles STT, and a distilled 1B-parameter language model rewrites each finalized utterance for readability. We run both on the phone's NPU via ONNX Runtime.
- UI. A React Native front end renders the caption lanes with optimistic partial results — words appear grayed-out while tentative, then solidify as the decoder commits.
Challenges we ran into
- Latency vs. accuracy is a brutal trade-off. Whisper wants long context windows; live captioning wants instant output. Our fix was a two-tier decode: emit greedy partial hypotheses immediately, then silently replace them with beam-searched finals ~1.5s later. Users perceive it as "captions that self-correct," which testers actually liked.
- Diarization collapse. With similar-sounding speakers (two brothers in our test group), centroids merged and the transcript became one giant monologue. We added a temporal prior — penalizing rapid speaker-switching within 300ms — which cut confusion errors by 41%.
- Thermal throttling. Twenty minutes in, the phone got hot and the NPU downclocked, blowing our latency budget. We ended up duty-cycling the smoothing model: it only runs on finalized utterances, never on partials.
Accomplishments that we're proud of
- End-to-end latency of 380ms median on a mid-range Android phone, fully offline
- Diarization error rate of 8.2% on our 4-speaker dinner-table test set, down from 23% in our first prototype
- Our first real user test: my grandmother followed a full 40-minute family conversation and, for the first time in years, interrupted someone to disagree. That was the whole point.
What we learned
We learned that "real-time" is a user perception, not a benchmark number — self-correcting captions with 380ms partials feel faster than perfect captions at 900ms. We also learned to profile on real hardware early: everything that worked on our laptops fell apart under mobile thermal constraints, and half our engineering time went into fitting the pipeline inside a power budget, not improving accuracy.
What's next for Murmur
- Multilingual code-switching — our family mixes Korean and English mid-sentence, and current models handle that poorly
- Directional audio using multi-mic beamforming to physically separate speakers before diarization
- Wearable target — porting the pipeline to smart-glasses SDKs so captions appear in your field of view, not on a table ## How we built it
Challenges we ran into
Accomplishments that we're proud of
What we learned
What's next for something like good
Built With
- codex
Log in or sign up for Devpost to join the conversation.