Problem
WebAudioAdapter.setupOutputAnalysis() creates a new AudioContext (and reloads the audio worklet module) every time it's called. If the agent reconnects and republishes a track, TrackSubscribed fires again, calling setupAudioCapture → setupOutputAnalysis, which creates a second AudioContext without closing the first — leaking it.
The same pattern exists in setupInputAnalysis.
Proposed solution
Reuse the AudioContext across calls instead of closing and recreating it:
- Keep the
AudioContext alive for the lifetime of the adapter
- On re-call, disconnect old nodes and create new ones on the existing context
- The worklet module is already loaded on the context, so subsequent calls skip the expensive
loadRawAudioProcessor() await
- Only close the context in
cleanup()
This would also simplify the class by removing the need for cleanup-on-re-call guards.
Context
Identified during the platform isolation review (#784). The current code works for the common single-call case, but leaks resources in reconnection scenarios.
Files
packages/client/src/platform/web/webAudioAdapter.ts — setupOutputAnalysis() and setupInputAnalysis()
Problem
WebAudioAdapter.setupOutputAnalysis()creates a newAudioContext(and reloads the audio worklet module) every time it's called. If the agent reconnects and republishes a track,TrackSubscribedfires again, callingsetupAudioCapture→setupOutputAnalysis, which creates a secondAudioContextwithout closing the first — leaking it.The same pattern exists in
setupInputAnalysis.Proposed solution
Reuse the
AudioContextacross calls instead of closing and recreating it:AudioContextalive for the lifetime of the adapterloadRawAudioProcessor()awaitcleanup()This would also simplify the class by removing the need for cleanup-on-re-call guards.
Context
Identified during the platform isolation review (#784). The current code works for the common single-call case, but leaks resources in reconnection scenarios.
Files
packages/client/src/platform/web/webAudioAdapter.ts—setupOutputAnalysis()andsetupInputAnalysis()