EC sets stopMicTrackOnMute: false, so muting only flips MediaStreamTrack.enabled = false; the mic keeps producing (silent) frames and our AudioContext graph keeps pulling them. The RNNoise/DTLN/DeepFilterNet worklet therefore runs inference on digital silence for the entire time the user is muted — which in a large guild call is most of the call. Nothing in the processor observes TrackMuted/TrackUnmuted to suspend the context. On mobile this is a continuous battery/thermal cost for zero benefit.
How to trigger
Join with lotusDenoiseSource=1&lotusModel=deepfilternet, mute, and watch the audio worklet thread in a performance profile — CPU is unchanged from the unmuted case.
Suggested fix
Subscribe to ParticipantEvent.TrackMuted / TrackUnmuted for the mic and ctx.suspend() / ctx.resume() the processor's own context around mute (the statechange watcher must be taught to ignore that intentional suspension).
Filed from the September 2026 audit (branch lotus).
**Severity:** medium · **Type:** performance · **Confidence:** high
**Location:** `src/lotus/lotusDenoiseProcessor.ts:253-332`, `src/livekit/options.ts:28`
### Problem
EC sets `stopMicTrackOnMute: false`, so muting only flips `MediaStreamTrack.enabled = false`; the mic keeps producing (silent) frames and our `AudioContext` graph keeps pulling them. The RNNoise/DTLN/DeepFilterNet worklet therefore runs inference on digital silence for the entire time the user is muted — which in a large guild call is most of the call. Nothing in the processor observes `TrackMuted`/`TrackUnmuted` to suspend the context. On mobile this is a continuous battery/thermal cost for zero benefit.
### How to trigger
Join with `lotusDenoiseSource=1&lotusModel=deepfilternet`, mute, and watch the audio worklet thread in a performance profile — CPU is unchanged from the unmuted case.
### Suggested fix
Subscribe to `ParticipantEvent.TrackMuted` / `TrackUnmuted` for the mic and `ctx.suspend()` / `ctx.resume()` the processor's own context around mute (the `statechange` watcher must be taught to ignore that intentional suspension).
---
_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:01 -04:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: medium · Type: performance · Confidence: high
Location:
src/lotus/lotusDenoiseProcessor.ts:253-332,src/livekit/options.ts:28Problem
EC sets
stopMicTrackOnMute: false, so muting only flipsMediaStreamTrack.enabled = false; the mic keeps producing (silent) frames and ourAudioContextgraph keeps pulling them. The RNNoise/DTLN/DeepFilterNet worklet therefore runs inference on digital silence for the entire time the user is muted — which in a large guild call is most of the call. Nothing in the processor observesTrackMuted/TrackUnmutedto suspend the context. On mobile this is a continuous battery/thermal cost for zero benefit.How to trigger
Join with
lotusDenoiseSource=1&lotusModel=deepfilternet, mute, and watch the audio worklet thread in a performance profile — CPU is unchanged from the unmuted case.Suggested fix
Subscribe to
ParticipantEvent.TrackMuted/TrackUnmutedfor the mic andctx.suspend()/ctx.resume()the processor's own context around mute (thestatechangewatcher must be taught to ignore that intentional suspension).Filed from the September 2026 audit (branch
lotus).