Skip to content

Keep the shape when compressing a curve, so a step is not a ramp - #8

Merged
Slicit merged 1 commit into
mainfrom
fix-compress-keeps-the-shape
Sep 9, 2026
Merged

Slicit merged 1 commit into
mainfrom
fix-compress-keeps-the-shape

Conversation

@Slicit

@Slicit Slicit commented Sep 9, 2026

Copy link
Copy Markdown
Owner

compress() dropped a point when it was within --threshold of the last kept one. That is the right rule for noticing a change and the wrong one for a series read back by interpolation: a long flat stretch was dropped whole, so nothing held the flat value just before a step, and the reader slid all the way from the last kept point up to it.

hack/windramp.py is the smallest case. A hundred seconds of silence, then a four-second gust at 0.55:

frames in: 496   points kept: 4
seconds the fan should blow:  4
seconds it will blow:        94

At second 50 the score says 0.0 and the fan reads 0.275.

A point kept because it differs now brings the frame before it along, at the old value. The reader holds flat and steps, which is what the samples said. A curve that genuinely ramps is untouched: there the frame before was itself kept, and there is nothing to add. scenes.snap has done exactly this at scene cuts since it was written, for exactly this reason — it could only ever help where a change landed on a cut, and a cue starting or a gust ending rarely does.

Measured

Same fifteen minutes, four builds, identical arguments but for the two variables:

silent points
vision, old compressor, no gate 24.1% 1386
vision, fixed, no gate 28.2% 2021
vision, fixed, gate 0.25 59.1% 947

The two changes only work as a pair. The gate alone did nothing, because the compressor put back every silence it created. The compressor alone does little, because without the gate the curve has few hard steps to preserve. Together they are the difference between a fan on for three quarters of a film and one on for two fifths — and 59.1% is what the offline simulation predicted (59.3%) before either landed.

Size is not the worry it looked like: more points where there are steps, +46% on this cut without the gate, and fewer with it (947 against 1386), because a gate makes long silences that compress to almost nothing.

Tests

Four new ones, asking a different question from the four that were already there. Those asked which points were kept. These read the curve back through the interpolation a fan actually experiences — which is how a four-second gust came to blow for ninety-four seconds without a single test noticing. Mutation-checked against the old rule.

329 composer tests, 758 unit, 18 browser.

🤖 Generated with Claude Code

compress() dropped a point when it was within --threshold of the last kept
one. That is the right rule for noticing a change and the wrong one for a
series read back by interpolation: a long flat stretch was dropped whole, so
nothing held the flat value just before a step and the reader slid all the way
from the last kept point up to it.

hack/windramp.py is the smallest case. A hundred seconds of silence then a
four second gust at 0.55: 496 frames became 4 points, and a fan that should
have blown for four seconds blew for ninety-four, reaching half power a full
minute before anything happened.

A point kept because it differs now brings the frame before it along, at the
old value. The reader holds flat and steps, which is what the samples said. A
curve that genuinely ramps is untouched, because there the frame before was
itself kept and there is nothing to add. scenes.snap has done exactly this at
scene cuts since it was written, for exactly this reason; it could only ever
help where a change landed on a cut, and a cue starting or a gust ending
rarely does.

Four tests, and they ask a different question from the four that were already
there. Those asked which points were kept. These read the curve back through
the interpolation a fan actually experiences, which is how a four second gust
came to blow for ninety-four seconds without a single test noticing.

Measured on the same fifteen minutes, four builds, identical arguments but for
the two variables:

    vision, old compressor, no gate     silent 24.1%   1386 points
    vision, fixed, no gate              silent 28.2%   2021 points
    vision, fixed, gate 0.25            silent 59.1%    947 points

The two changes only work as a pair. The gate alone did nothing, because the
compressor put back every silence it created; the compressor alone does little,
because without the gate the curve has few hard steps to preserve. Together
they are the difference between a fan that is on for three quarters of a film
and one that is on for two fifths.

Size is not the worry it looked like. More points where there are steps, 46
per cent on this cut without the gate, and fewer with it: 947 against 1386,
because a gate makes long silences that compress to almost nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Slicit
Slicit merged commit 3d814a3 into main Sep 9, 2026
9 checks passed
@Slicit
Slicit deleted the fix-compress-keeps-the-shape branch September 9, 2026 22:43
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