Repository navigation
fix(studio): the Volume control changes the whole clip, fades included - #7587
Conversation
The media panel's Volume slider wrote a keyframe at the playhead, so a clip with a fade (or none) changed only around where the playhead sat. Volume now sets the clip's gain, the whole fade moves with it, and the keyframe toggle still adds automation on purpose. The separate Gain slider is folded into it, and the Audio Gain dialog no longer refuses clips that have a volume lane.
There was a problem hiding this comment.
Requesting changes at 802c5029. The only blocker is the description, not the code.
Blocker: no Fails without the fix: line. A fix PR in this lane has to name, on a line starting Fails without the fix:, a test that fails without the fix. The Tests section says "Red on main, green here", but it never names a failing test and its error on that line. I checked locally, so the line can be added as is:
Fails without the fix:
- propertyPanelFlatMediaSection.test.tsx › "Volume sets the whole clip's gain and never writes a keyframe (fade: true)" — expected [ 'Gain', 'Volume' ] to deeply equal [ 'Volume' ]
- audioGainApply.test.ts › "writes data-volume on a clip with a volume lane, which the gain stacks on" — throws "This clip's volume is automated. Remove its volume automation to normalize it."
Once the body has this line I'll approve. The code itself has no blockers:
- Volume now writes
data-volumethroughonSetAttribute. The removed Gain slider wrote the same attribute through the same call, so nothing new is written. The lane toggle is unchanged. writeClipGainsno longer refuses a clip with a volume lane.normalizeClipsLoudnessstill refuses one on its own check (audioGainApply.ts:43), andvolumeLaneOwnsGainandVOLUME_LANE_REFUSALare still used there.- The speed slider still uses the shared lane hook's
onCommitAtandautomatedValue. Only the volume part of that binding was removed. - I ran the three changed test files locally: 65 out of 65 pass. With main's three source files put back, 4 tests fail, including the two above. The newest CI, PR captures and regression runs at this head are green.
There was a problem hiding this comment.
Approving at 802c5029. The head is the same and the code hasn't changed. The description now has the Fails without the fix: line, and it matches what I reproduced locally. With main's three source files put back, 4 tests fail and 46 pass, with the same errors the line quotes. All 65 tests pass on this branch. The code review from my previous review still holds, and the newest CI at this head is green.
What was wrong
A creator reported that raising a sound effect's volume in Studio only changed the level around the playhead, as if a keyframe had been added.
That is what the media panel's Volume slider did on main: it wrote a point into the clip's volume automation at the playhead, starting a lane when the clip had none. A separate Gain slider held the whole-clip level. Agents often write a fade on sound effects, so clips with a volume lane are the normal case.
What changes
data-volume). If the clip has a fade or volume keyframes, the whole curve moves together: the fade keeps its shape and every moment gets louder or quieter by the same amount. Preview and render already multiplydata-volumeby the lane, so no level math changes.data-volume. Normalize loudness still refuses such clips, unchanged.Existing projects with a fade now get whole-clip changes from the control. Nothing in a saved file changes until a person edits it.
Before
Real Studio in Chrome on main: a 6 s sound effect with a fade (0 at 0 s, 1 at 1 s, 1 at 5 s, 0 at 6 s), playhead at 3 s, Volume dragged to +6 dB. Two sliders, and only the moment at the playhead changes.
After
Same project and drag on this branch. One Volume slider; the whole clip is 200 %.
What Studio saved:
data-volume1t=3, v=1.995, the other points untouched1.995262A clip with no lane: main created a two-point lane it was never asked for; this branch writes only
data-volume.Rendered level of the fade clip (RMS over 0.2 s windows, same project rendered unedited, with main's edit and with this branch's edit):
Tests
Fails without the fix:
propertyPanelFlatMediaSection.test.tsx> "Volume sets the whole clip's gain and never writes a keyframe (fade: true)" and "(fade: false)" fail on main withexpected [ 'Gain', 'Volume' ] to deeply equal [ 'Volume' ](main shows a Gain slider and a Volume slider that writes a keyframe);audioGainApply.test.ts> "writes data-volume on a clip with a volume lane, which the gain stacks on" fails on main withError: This clip's volume is automated. Remove its volume automation to normalize it.; the existing "commits +12 dB of boost from the upper half of the gain fader" test, now aimed at the Volume slider, fails on main withexpected "vi.fn()" to be called with arguments: [ 'volume', '3.981072' ]. All three pass on this branch (checked against main's source of the three changed files, 4 failed | 46 passed).propertyPanelFlatMediaSection.test.tsx: Volume writesdata-volumeand no keyframe, with and without a fade, and there is one Volume slider. Red on main, green here.audioGainApply.test.ts:writeClipGainswritesdata-volumefor a clip with a volume lane. Red on main, green here.useVolumeAutomation.test.tsx: tests of the removed point writer are gone with it.src/components/editorandsrc/player/components: 305 files passed, 1 skipped.tsc --noEmitandoxlintclean.Search first: the level math already lives in
gainTimesLane(packages/core/src/audioGain.ts) and the runtime and render paths that call it (#6068); no new helper is added.