b-d.io / Notes

Live captions on smart glasses that don't flicker

Speech arrives word by word and changes its mind. The lens shouldn't jump every time it does.

Updated 2026-10-09 · From the Odasho team's work on real hardware

What goes wrong

The naive approach — send the last few sentences as one block of text whenever anything changes — looks terrible on a lens:

1. Do the layout on the phone

Break every line yourself, using the same glyph widths and line-breaking rules as the firmware, then send lines the glasses won't re-wrap. Leave a pixel or two of margin so a line you measured as fitting never wraps again on the glasses.

2. Treat the lens as a window on a stream of lines

Keep every caption wrapped into lines, newest at the end, and show a window of the last N lines. Then move the window down only, one line at a time:

3. Reserve rows for each sentence

A sentence takes the most rows it ever needed. When it settles into fewer lines — or its translation is shorter — keep the extra rows as blank lines. Nothing below it moves.

4. Mark what's still being spoken

A lens usually draws everything at one brightness, so you can't dim the words still being recognized. We open every sentence with › and close the one still being spoken with …; the closing mark disappears when the sentence is final.

5. One update per tick, always the newest

Don't send on every recognition callback. Keep the current lens text in memory and run a loop that sends at most one update per tick, of whatever is newest. A backlog collapses into a single draw instead of replaying every intermediate version.

6. Test it like a viewer, not a log

Keep a "shadow screen" on the phone that renders exactly the lines you send, at the lens's size. You'll see jumps and reflows immediately — and you can develop without wearing the glasses.