Skip to content

feat: respect AudioContextOptions.latencyHint when opening the Android output stream - #1232

Open
DanielOrmeno wants to merge 1 commit into
software-mansion:mainfrom
DanielOrmeno:feat/audio-context-latency-hint
Open

feat: respect AudioContextOptions.latencyHint when opening the Android output stream#1232
DanielOrmeno wants to merge 1 commit into
software-mansion:mainfrom
DanielOrmeno:feat/audio-context-latency-hint

Conversation

@DanielOrmeno

Copy link
Copy Markdown

Summary

Implements AudioContextOptions.latencyHint (category form) and maps it to Oboe performance modes on Android, so playback-heavy apps can opt out of the underrun-prone low-latency stream on low-end devices.

Closes #1231 — full measurements there: on an entry-level Samsung, the hard-coded LowLatency stream is granted 192 frames (4 ms) of buffer and misses ~210–230 render deadlines per second while an 11-source graph plays (continuous audible crackle); the same graph on a PerformanceMode::None stream plays clean.

What changed

latencyHint Android (Oboe PerformanceMode) iOS Web
'interactive' (default) LowLatency — current behaviour, unchanged unchanged forwarded to browser
'balanced' None accepted, no stream change yet forwarded to browser
'playback' PowerSaving accepted, no stream change yet forwarded to browser
  • AudioContextLatencyHint enum (common/cpp/audioapi/core/types/), carried by AudioContext and consumed by the Android AudioPlayer when opening the stream.
  • JSI createAudioContext gains an optional second string argument; unknown/omitted values fall back to INTERACTIVE, matching how browsers treat an unrecognized latencyHint.
  • TS: AudioContextOptions.latencyHint?: AudioContextLatencyCategory; web passthrough hands it to the browser's AudioContext.
  • Docs: audio-context.mdx constructor table.

Non-breaking: the new constructor parameters are defaulted (existing callers, including the WPT harness, compile unchanged) and the default mode is exactly today's behaviour.

Out of scope (follow-ups noted in #1231): numeric hints (would map to setBufferSizeInFrames on Android), iOS stream wiring (preferredIOBufferDuration).

Test plan

  • yarn workspace react-native-audio-api run typecheck / lint:js / format:check — clean
  • yarn workspace react-native-audio-api run test:js — 79/79
  • cpplint + clang-format over the touched C++ — clean
  • Behaviour validated on the device that reproduced [Android] Hard-coded PerformanceMode::LowLatency causes continuous underruns (crackle) for multi-source playback on low-end devices #1231, via a backport of this change to 0.13.2: interactive reproduces the underruns, balanced plays the same 11-source session clean (verified with AudioStream::getXRunCount() logging)
  • C++ compile on Android/iOS relies on CI — no NDK available in my dev environment; the change follows the existing constructor-threading patterns

🤖 Generated with Claude Code

…d output stream

AudioContext now accepts the Web Audio latencyHint category and the
Android backend maps it to Oboe performance modes: interactive ->
LowLatency (unchanged default), balanced -> None, playback ->
PowerSaving. On web the hint is forwarded to the browser AudioContext;
on iOS it is accepted but does not change the stream yet. Numeric
hints are not supported yet.

Motivation: the hard-coded LowLatency stream is granted a very small
buffer (192 frames / 4 ms on an entry-level Samsung) and misses
~220 render deadlines per second when a multi-source graph renders,
heard as continuous crackle. The same graph on a PerformanceMode::None
stream plays clean. Measured via AudioStream::getXRunCount on device.
@closetcaiman closetcaiman added feature New user-facing features or major capabilities web-api-spec Implementations, updates, or parity alignment with the W3C Web Audio API specification labels Aug 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature New user-facing features or major capabilities web-api-spec Implementations, updates, or parity alignment with the W3C Web Audio API specification

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] Hard-coded PerformanceMode::LowLatency causes continuous underruns (crackle) for multi-source playback on low-end devices

2 participants