feat(studio,core,player): stream VST-processed audio in the studio player - #2922
feat(studio,core,player): stream VST-processed audio in the studio player#2922vanceingalls wants to merge 1 commit into
Conversation
…ayer Wires the browser half of the pipeline. The sidecar returns processed PCM over one WebSocket, which a ring buffer feeds to an AudioWorklet so a track plays its wet signal in preview. The whole app shares exactly one sidecar connection, mounted once in NLEProvider and handed to consumers through context. The wire protocol cannot safely tell two independent connections apart, so a second connection is a correctness problem, not just overhead. Because the worklet now owns a VST track's audio, the element itself must stay muted. Every place that writes .muted or .volume across media elements — the runtime control bridge, the player's parent-media adoption, the timeline scrub helper — skips elements marked data-vst-chain. Without that, an unrelated volume or mute change silently swaps the processed stream back for the untreated one. STUDIO_VST_ENABLED gates the surface off by default from its first commit, so no partially-wired FX UI is reachable while the stack lands. The VstHostApi contract lives in propertyPanelVstShared (a plain module) rather than in the panel component, so these hooks no longer import their own interface back out of the UI layer.
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
Superseded by the Web Audio implementation. The sidecar approach is replaced by running Web Audio graphs on both ends: the studio previews in a live AudioContext, and the engine renders the same graphs in an OfflineAudioContext inside the headless browser it already drives. One implementation per effect, so preview matching render is a property of the architecture rather than a tolerance to police — which is what made the four effects that diverged under JUCE (compressor, limiter, chorus, phaser) stop being a problem. That also retires the reasons this was cancelled in the first place: no spawned sidecar process, no external GPL repo, no Measurements behind the decision: https://claude.ai/code/artifact/219fd332-0542-4bcf-a4b7-7b7202e63fde Branch left intact. |

Stack 4/5 — replaces #2602–#2605. Base: #2921.
The browser half of the pipeline. The sidecar returns processed PCM over one WebSocket; a ring buffer feeds it to an
AudioWorkletso a track plays its wet signal in preview.The whole app shares exactly one sidecar connection, mounted once in
NLEProviderand handed to consumers through context. The wire protocol cannot safely tell two independent connections apart, so a second connection is a correctness problem, not just overhead.Because the worklet now owns a VST track's audio, the element itself must stay muted. Every place that writes
.mutedor.volumeacross media elements — the runtime control bridge, the player's parent-media adoption, the timeline scrub helper — skips elements markeddata-vst-chain. Without that, an unrelated volume or mute change silently swaps the processed stream back for the untreated one.STUDIO_VST_ENABLEDgates the surface off from this commit, not from a trailing PR, so no partially-wired FX UI is reachable while the stack lands.One structural change vs. the original
The
VstHostApicontract now lives inpropertyPanelVstShared(a plain module) instead of being re-exported from the panel component. The transport hooks were importing their own interface back out of the UI layer, which made this layer impossible to land without the panel. The types were already defined inpropertyPanelVstShared; only the import path changed.Deletions in this PR: 15 lines.
🤖 Generated with Claude Code