Skip to content

fix(worklet-base): Stop the processor after a dispose message - #91

Open
tzzo wants to merge 1 commit into
cutterbl:masterfrom
tzzo:fix/dispose-message
Open

tzzo wants to merge 1 commit into
cutterbl:masterfrom
tzzo:fix/dispose-message

Conversation

@tzzo

@tzzo tzzo commented Sep 23, 2026

Copy link
Copy Markdown

An AudioWorkletProcessor is kept alive for as long as its process() returns true, and SoundTouchProcessorBase.process() always did. So once an app disconnects a node and drops it, the processor keeps rendering every quantum and keeps its buffers until the AudioContext closes. Apps that create a fresh node per track — the way to start a new track from empty FIFOs — accumulate one live processor per track for the life of the context.

This adds a { type: 'dispose' } port message. The base processor flips a flag on receipt and returns false from the next render quantum, so the browser can release it. SoundTouchNode, PhaseVocoderNode and FormantCorrectionNode gain dispose(), which posts the message and disconnects the node. None of the subclass processors override process(), so the base change covers all three worklets. DisposeMessage joins the ProcessorMessage union and is exported from @soundtouchjs/worklet-base.

Specs: the base spec covers the flag, the false return and that the pipe is not touched after disposal; the audio-worklet processor spec drives the real processor through a dispose message; each node spec checks that dispose() posts the message and disconnects.

Docs: the four READMEs list the new message and method.

Noticed but left alone, to keep this to one change: the worklet-base README's runtime-message examples use camelCase names (setInterpolationStrategy, value) while the processor matches kebab-case (set-interpolation-strategy, strategy / params).

Model used: Anthropic Fable 5.1

🤖 Generated with Claude Code

process() always returned true, so a SoundTouch processor stayed alive for
the life of the AudioContext even after every connection to its node was
gone: it kept rendering and kept its buffers. Apps that create a fresh node
per track (to start from empty FIFOs) accumulated one live processor per
track.

The processor now flips a flag on { type: 'dispose' } and returns false
from the next render quantum, so the browser can release it. SoundTouchNode,
PhaseVocoderNode and FormantCorrectionNode gain dispose(), which posts the
message and disconnects the node.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant