Skip to content

Size the native device buffer in real frames, and relabel the latency table - #77

Merged
mparrett merged 4 commits into
mainfrom
wt/fix-device-buffer-check
Oct 27, 2026
Merged

mparrett merged 4 commits into
mainfrom
wt/fix-device-buffer-check

Conversation

@mparrett

@mparrett mparrett commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

Follow-up to #74. The first commit is superseded by the third; the last labels the 821 ms header figure as a browser measurement.

Device frames. deviceBuffer converted frames to a duration at 4 bytes a frame, but oto converts BufferSize back at 8 (stereo float32, context.go). So deviceFrames = 512 opened a 1024-frame device, and UNDERTONE_DEVICE_FRAMES=N opened 2N. The round-trip tests modeled oto at 4 bytes as well, so they agreed with the bug.

  • deviceBuffer and the tests now use oto's 8 bytes (otoBytesPerFrame). The round-trip test now fails against the old arithmetic.
  • deviceFrames is now 1024, the size the device has always had, so default behavior is unchanged. A speaker-to-mic loopback at this head gave a 147 ms median, against 149–158 ms before.
  • The read-ahead check is Give letgo's browser output an 80 ms queue, and add knobs for tuning latency #74's, now correct for the right reason: 12 ms passes at 512 frames and 11 ms doesn't (new test).
  • My first commit here (deviceLatency) misread the conversion in the other direction; the third commit removes it.

Latency table. latency.go's "90 ms + 1.4×" table and the README's 820 → 130 ms were measured 2026-08-24 in headless Chromium through oto's web backend, timed by Playwright, but read as native. Both now give native medians from a speaker-to-mic loopback on a MacBook Air, 2026-10-26 (15 blips each, matched-filter onset), in real device frames:

Read-ahead / device frames Trigger to sound
40 ms / 1024 (defaults) 147–158 ms
24 ms / 512 112–117 ms
12 ms / 512 97–100 ms
6 or 12 ms / 256 broke up

🤖 Generated with Claude Code

mparrett and others added 2 commits October 26, 2026 23:16
The check added in #74 compared UNDERTONE_PLAYER_BUFFER against
deviceBuffer, the duration handed to oto. oto converts that duration at the
int16 rate but sizes the buffer in float32 samples, so it is twice the time
the buffer holds: 23.2 ms for 512 frames at 44.1 kHz, which plays in 11.6 ms.
Read-aheads of 12-23 ms at the default device size were refused.

deviceLatency gives the play time, and the check and its message use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The table in latency.go and the README's 820 -> 130 ms figures were
measured 2026-08-24 in headless Chromium through oto's web backend, timed
by Playwright, and read as native numbers. Replace them with medians from a
speaker-to-mic loopback on a MacBook Air, 2026-10-26, and say where the old
figures came from.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mparrett mparrett changed the title Bound the read-ahead override by the device buffer's play time Fix the native read-ahead check, and date the latency table as a browser measurement Oct 27, 2026
The first commit here had oto's conversion backwards. oto turns
BufferSize into bytes at 8 a frame (stereo float32, context.go), so
deviceBuffer's duration was the buffer's true play time, and its 4-byte
arithmetic was what doubled the frame count: deviceFrames = 512 opened a
1024-frame device, and UNDERTONE_DEVICE_FRAMES=N opened 2N. The
round-trip tests modeled oto at 4 bytes too, so they agreed.

deviceBuffer and the tests now convert at oto's 8 bytes, deviceLatency
is gone, and deviceFrames is 1024 so the device stays the size it has
been. The override check is the one #74 shipped. The measured table and
the README now give the frame counts the device actually got.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mparrett mparrett changed the title Fix the native read-ahead check, and date the latency table as a browser measurement Size the native device buffer in real frames, and relabel the latency table Oct 27, 2026
…est comment from 512 frames

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mparrett
mparrett merged commit 9d505fc into main Oct 27, 2026
4 checks passed
@mparrett
mparrett deleted the wt/fix-device-buffer-check branch October 27, 2026 04:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant