Repository navigation
fix: data-volume multiplies the volume lane in preview and render - #6068
miguel-heygen wants to merge 6 commits into
Conversation
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Automations to automatically generate PRs for you. |
7f4eed9 to
e8e01b4
Compare
jrusso1020
left a comment
There was a problem hiding this comment.
Reviewed at e8e01b4, after #6057 landed and the branch was rebased onto main cfff449. The audio implementation and tests are byte-identical to the first requested head, 7f4eed9. I did not re-audit the unrelated CLI deadline changes that came in with the rebase. Both failure probes were re-run at this head.
Zero gain and ordinary multiplication work. The documented behavior change for existing projects is called out explicitly. Two parity defects remain in the boost range.
P2: a routed clip's preview goes above the ceiling render uses (packages/core/src/runtime/media.ts:461-463, webAudioTransport.ts:102-108).
- A routed clip now sends
data-volumeto its gain node, and the lane node schedules the raw lane separately. - Probe through the real
syncRuntimeMedia→WebAudioTransport:data-volume=2with a constant lane of3gives a graph gain of 2×3 = 6. - The shared
gainTimesLaneand render cap that product atMAX_AUDIO_GAIN≈ 3.981. - Each authored value is valid on its own; it is only the product that goes over.
Fix: apply the same combined-gain and ceiling rule on the routed path, and add tests for products above the ceiling. Clamping each factor separately does not enforce the ceiling on the product.
P2: clamping the breakpoint products bends a ramp that used to be linear (packages/core/src/runtime/audioFx.ts:145-146, packages/engine/src/services/audioMixer.ts:514-515).
- Case: gain
2with a lane ramping 0→3 over 10 s. - These paths scale and clamp the endpoints to 0→3.981, then interpolate between them.
- At 5 s, the group schedule and the render envelope give 1.9905, while
gainTimesLane(2, sampleLane(5))gives 3. - So the ramp is quieter than it should be well before the product actually reaches the ceiling, and it also differs from the routed clip preview.
Fix: keep the product-then-clamp rule at every point through interpolation, including where the ramp crosses the ceiling, instead of clipping only the authored breakpoints. Add ramps that cross the ceiling to the preview-group and render tests.
How this was checked:
- Preview probes ran the current
syncRuntimeMedia,WebAudioTransportandscheduleVolumewith recordingAudioContext/GainNodestubs. - Render probes ran the current
volumeLaneKeyframesand interpolation code, extracted from source, with the actual gain and automation modules. - No real audio device, generated WAV or audible distortion was tested.
- The standard core test command stopped before collecting tests: its audio-runtime prebuild couldn't resolve a parser export from the borrowed dependencies. That is a limit of this validation, not a failure in the PR.
Review by Rames (hf-review)
Edit accuracy: accurate 271 (base branch 271), smooth 159 of thoseThe gate passes. Quarantined, measured but not gated (0) Unstable (1)
|
|
Fixed both ceiling findings in 1f41ecf.
Failing first against the preceding committed implementation: transport exit 1, 4 failed / 95 passed; render envelope exit 1, 3 failed / 8 passed; mixer exit 1, 1 failed / 73 passed. With the fix, all four changed test files passed three serial runs: automation 40, transport 99, render envelope 11, mixer 74, each exit 0 and no skips. Three deliberate mutations also failed: removing crossing breakpoints, removing the upstream-gain correction, and replacing zero gain with unity. Core and engine typechecks passed; commit hooks passed. These checks execute the real scheduling and mixer code with recorded AudioParams and mixer collaborators. This ceiling delta has not been checked through an audio device or an encoded output file. This push also preserves the separate Studio Gain control change. Its two changed test files passed three runs (46 and 21 tests, exit 0); fixture panel captures are still pending before the UI part is ready for review. |
jrusso1020
left a comment
There was a problem hiding this comment.
Re-reviewed at 1f41ecf. Both ceiling findings from my request for changes at e8e01b4 are fixed in the scheduling and envelope paths I checked.
- Routed preview: running the real
syncRuntimeMedia→WebAudioTransportwith recording GainNodes, gain 2 × a constant lane of 3 now gives 3.9810717055 instead of 6. Zero gain and 0.5 gain also match render. - Straight ramps:
gainedVolumePointsnow inserts the point where the ramp crosses the ceiling. With gain 2 on a lane ramping 0→3 over 10 s, both the group schedule and the current render-envelope function (extracted from source) give 3 at 5 s and reach the ceiling at 6.6351195092 s. The ramp is no longer bent toward a clipped endpoint. Curved crossings use bounded sampling, so this doesn't claim exact parity in continuous time.
The added clip-gain change looks right:
- The preview gain node sits before FX, and the new node has matching teardown paths.
- Render applies input gain in both the whole-file and windowed paths.
- Studio keeps the static Gain separate from the lane Volume, and new volume lanes start at unity.
- Studio's production caller supplies the lane commit callback.
Non-blocking, pre-existing: removing a live volume lane leaves its dedicated AudioParam at its last value instead of resetting it to unity (packages/core/src/runtime/audioFx.ts:232-243; scheduleVolume, lines 142-148). A replay of lane removal on a recording param keeps 0.25 after the lane is removed. With clip gain 2, preview stays at 0.5 while an export with no lane uses 2. The previous implementation had the same gap, so it doesn't reopen the ceiling findings. Worth tracking separately.
What was run:
- 139 focused tests pass (40 automation, 99 transport), against current-source aliases with borrowed dependencies.
- I re-ran the original preview and render-envelope probes, plus the lane-removal replay.
What was not run:
- The Engine and Studio suites couldn't collect locally, because generated runtime and dependency exports were unavailable.
- Real audio-device playback, an encoded WAV, compressor output and a full render were not verified.
The panel screenshots are still pending from the author, so this approves the code, not the UI.
Review by Rames (hf-review)
|
The lane-removal finding is fixed at bfe42fd. The shared FX scheduler now clears the removed lane's held events and schedules the static baseline: unity downstream of clip gain, or the group's static gain. The two new transport witnesses fail without the reset (2 failed / 99 passed). Restored: transport 101 and FX runtime 37 pass in three serial runs. A native browser OfflineAudioContext rendered PCM at 0.5 before removal and 2 afterward for both the clip and group paths. Core typecheck, lint, format and commit hooks passed. The PR body now includes separate Before and After capture sections and the saved-file/reload control checks. The panel captures are unchanged by this audio-only follow-up. |
jrusso1020
left a comment
There was a problem hiding this comment.
Re-reviewed at bfe42fd. The lane-removal follow-up I raised when approving at 1f41ecf is fixed.
packages/core/src/runtime/audioFx.ts:151-158,251-260 now clears the removed lane's held events and resets the gain after clip gain to unity, or to the clamped static group gain. One shared scheduler covers both clips and groups. My original replay on a recording param now resets 0.25 → 1, which restores a total gain of 2 for the clip. Both new transport regression tests fail on the previous scheduler and pass at this head.
What ran
- 178 focused tests pass: 40 automation, 101 transport, 37 FX runtime. These ran against current-source aliases with borrowed dependencies.
- The earlier ceiling fix is unchanged in source, and its regression tests still pass. Curved crossings are still bounded approximations.
What changed besides that: the budget JSON only raises core's unpacked allowance, from 3,938,103 to 3,942,104 bytes. I didn't rebuild the package to check its measured size.
Not verified: native audio output, encoded output, the full Engine and Studio suites, and the panel screenshots. Recording AudioParam calls proves the scheduling behaviour, not what a device plays.
Review by Rames (hf-review)
What
data-volumeis clip gain that multiplies the volume lane. Projects setting both now sound at gain × lane. Reset gain to1to retain a lane's former absolute level.Clip gain plays before clip effects; the lane plays after them. Dynamics effects therefore react to the gained signal. Group gain stays after group effects. Studio exposes separate Gain and Volume controls: Gain edits
data-volume; Volume edits a lane point at the playhead, creating a lane when needed.Why
A lane previously discarded
data-volume. The shared contract now caps their product at the existing +12 dB authored-gain ceiling. It preserves the ramp below that ceiling: gain 2 × lane 0→3 over 10 seconds is 3 at 5 seconds and reaches the ceiling at 6.6351195092 seconds. Clamping endpoints alone incorrectly made the midpoint 1.9905358528.How
gainTimesLaneowns the capped product.gainedVolumePointsinserts ceiling-crossing breakpoints for straight ramps and bounds sampling for bent crossings. Preview clips, groups and render consume that envelope. A pre-FX clip gain leaves only the lane's share of the capped product downstream.Before
The same synthetic audio fixture, with gain 0.5 and lane 0.8 at the playhead. Only Volume is exposed.
After
Gain shows −6.0 dB independently of the lane's −1.9 dB Volume. Captures use the pre-change and current panel sources while holding the audio fixture fixed.
Test plan
What I measured
Recorded the real AudioParam schedule, native browser PCM for lane removal, mixer envelope inputs, packed artifacts, and fixture control edits with saved-file and reload checks. Unit tests and builds ran on Linux; an isolated browser drove the fixture Studio server.
What I did NOT exercise
The ceiling delta was not auditioned through a physical audio device or measured from a new encoded output. The scheduling/mixer tests record collaborators; they do not prove codec or device behavior. Touch interaction, screen-reader output, invalid text, undo/redo, and first-time-user comprehension were not exercised in this pass.
UX checklist
Job: adjust a clip's gain independently of its volume keyframes.
One action: edit Gain while retaining the lane, or edit Volume at the playhead.
Choice: the two existing gain layers are exposed as two controls; neither is hidden behind a mode.
End: the panel shows the saved gain and lane value after reload.