Each soundboard clip creates a new AudioContext, against a per-document limit of ~6 #14

Closed
opened 2026-09-12 02:13:04 -04:00 by jared · 0 comments
Owner

Severity: medium · Type: performance · Confidence: medium

Location: src/lotus/lotusAudioInject.ts:144, 221

Problem

playInjectedClip does new AudioContext() per clip and closes it in cleanup(). An in-call page already holds close to Chrome's per-document AudioContext limit (~6): three from useAudioContext (InCallView.tsx:258, CallEventAudioRenderer.tsx:63, ReactionAudioRenderer.tsx:36), one from MatrixAudioRenderer.tsx:117, one per LiveKit Room (acquireAudioContext), plus one owned by LotusDenoiseProcessor. close() is asynchronous, so rapid clip replacement (replace-mode aborts the previous clip and closes its context in the background) can transiently push past the cap, at which point new AudioContext() throws and the clip silently fails with only a logger.warn.

How to trigger

Spam soundboard buttons with lotusDenoiseSource=1 active, on Chrome.

Suggested fix

Keep one lazily-created module-level AudioContext (plus one MediaStreamAudioDestinationNode) for all injected clips and reuse it, disposing only the BufferSource/GainNode per clip.


Filed from the September 2026 audit (branch lotus).

**Severity:** medium · **Type:** performance · **Confidence:** medium **Location:** `src/lotus/lotusAudioInject.ts:144`, `221` ### Problem `playInjectedClip` does `new AudioContext()` per clip and closes it in `cleanup()`. An in-call page already holds close to Chrome's per-document `AudioContext` limit (~6): three from `useAudioContext` (`InCallView.tsx:258`, `CallEventAudioRenderer.tsx:63`, `ReactionAudioRenderer.tsx:36`), one from `MatrixAudioRenderer.tsx:117`, one per LiveKit `Room` (`acquireAudioContext`), plus one owned by `LotusDenoiseProcessor`. `close()` is asynchronous, so rapid clip replacement (replace-mode aborts the previous clip and closes its context in the background) can transiently push past the cap, at which point `new AudioContext()` throws and the clip silently fails with only a `logger.warn`. ### How to trigger Spam soundboard buttons with `lotusDenoiseSource=1` active, on Chrome. ### Suggested fix Keep one lazily-created module-level `AudioContext` (plus one `MediaStreamAudioDestinationNode`) for all injected clips and reuse it, disposing only the `BufferSource`/`GainNode` per clip. --- _Filed from the September 2026 audit (branch `lotus`)._
jared added this to the EC fork audit 2026-09 · Medium & Low milestone 2026-09-12 02:13:04 -04:00
jared added the bugpriority: mediumperformancearea: soundboard-inject labels 2026-09-12 02:13:04 -04:00
jared self-assigned this 2026-09-12 02:13:04 -04:00
jared closed this issue 2026-09-13 01:22:56 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
2026-11-14
Dependencies

No dependencies set.

Reference: LotusGuild/element-call#14