Skip to content

fix(audio): use monotonic time for the JS queue - #1597

Merged
Lorenzobattistela merged 1 commit into
bendlang:mainfrom
vicmcorrea:fix/audio-monotonic-clock
Oct 16, 2026
Merged

Lorenzobattistela merged 1 commit into
bendlang:mainfrom
vicmcorrea:fix/audio-monotonic-clock

Conversation

@vicmcorrea

Copy link
Copy Markdown
Contributor

Problem and fix

The silent JS Audio ring measures elapsed time with Date.now(). A one-second wall-clock rollback at 48 kHz makes an empty write report 48,000 queued frames, exceeding the 4,096-frame ring and causing later writes to be dropped. A forward jump can drain queued frames prematurely.

Use performance.now() for the existing open/write timestamps, matching JS IO.now and IO.sleep. The queue calculation needs no other change.

Blast radius

Two production-line changes in bend2/effs/audio_open.js and audio_write.js, plus one regression in tests/io/audio_monotonic_clock.bend with its JS foreign twin. This affects the source IO runner and generated JS's silent Audio model. Native Audio, sample-rate validation, ring capacity, sample policy and public API remain unchanged; no API migration is required.

Regression evidence

The fixture simulates a one-second rollback, opens Audio at 48 kHz and writes no samples. It prints 48000 on main, failing its expected #|0, and 0 with the fix through the actual CLI and generated JS under Bun and Node. It restores Date.now immediately after the write. A following module in the same --checkup process verifies the original function identity is restored on both paths.

Checks

  • Repository gate: PASS: 54 / 54, using CI-pinned ttok 0.3.
  • New regression and existing Audio open/write/close reachability fixtures pass through the CLI and generated Bun/Node JS.
  • Deterministic Audio controls pass those three lanes: wall-clock jumps, monotonic draining, rate bounds, refill and full-ring dropped writes.
  • Existing IO.now control passes through the CLI and generated Bun JS.
  • Baseline-sensitive regression, shared-process clock restoration and staged whitespace checks pass.

Validation limits

Local checks used macOS arm64, Bun 1.3.11 and Node 26.8.2. The adjacent IO.now control's generated Node run fails to load bun:ffi; main emits byte-identical JS and fails the same way. The Audio regression and controls pass under Node.

Browser execution, native audio-device playback, full cluster gates and GPU execution were not run. The tests simulate clock readings; they do not change the machine clock or play audio.

@Lorenzobattistela Lorenzobattistela self-assigned this Oct 16, 2026
@Lorenzobattistela
Lorenzobattistela merged commit 7e120d5 into bendlang:main Oct 16, 2026
1 check passed
@Lorenzobattistela Lorenzobattistela mentioned this pull request Oct 20, 2026
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.

2 participants