mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-11-11 19:09:20 +00:00
A preset's nodes share no automatable parameter, and its worklet effects (compressor, limiter) expose no AudioParams at all — Clean Voice could only ever have automated 3 of its 5 nodes. So there was nothing to aim a lane at, and no way to bring a preset in gradually. **The graph wraps each preset's run in a wet/dry pair.** The rest of the chain stays a strict series, which is right for an effect the author placed: it is either in the path or it is not. A preset is not one effect — it is several added as a unit, and "how much of it is applied" is a question about the unit. One crossfade answers it for every preset including the worklet ones, and it cannot go half-wrong the way seven lanes can. The dry leg bridges the whole run, so amount 0 is the untouched signal rather than a quieter version of the processed one. Consecutive nodes only, matching what the rack already brackets: a preset pulled apart by a reorder is no longer a unit, and wrapping across the gap would route the effect between its members through the dry leg too. **`fx.preset.<id>` is a new lane target.** Parsed before the 3-part fx form, which it structurally is — with a reserved node id an effect can never have, since ids are minted `n1`, `n2`, …. It resolves only for a preset the chain actually carries, so a lane left behind by a removed preset is dropped at read time, the same contract an orphaned node lane has. **Off is amount 0, not `enabled: false`.** The switch and the lane are now the same value — one notion of how much of a preset is applied, with the switch at its two ends. Writing `enabled` would take the nodes out of the graph, which a lane cannot do part-way and cannot do without a rebuild that restarts the audio. The panel also grows an Amount slider, so half-applied is something an author can just set. Changing the amount is a values-only update, pushed into the running graph. A `presetAmount` in a chain is clamped to 0..1 on the way in: two gains in opposition, so past 1 the dry leg goes negative rather than the preset getting louder. Falsified: a blend ignoring the stored amount, an amount not pushed on update, and the clamp each fail a test. The round-trip — the §4 invariant that a new node field must be in BOTH the parser and the writer — had no test until a mutation survived one; dropping it from either half now fails. core 1770 (113 files) · studio 3703 + 18 todo · engine services 739 + 3.