Stop the master clipping, and test the chain that hid it - #37
Merged
Conversation
The mixer and the master were the last untested part: the render tests pass chain settings through without ever asking what the chain does with them, so three bands of EQ, a tilt, a send, a room, the level, the loudness and the limiter were all exercised as far as "something came out". Fifteen tests measured on the way out, and they found something. The limiter was being handed a copy of the mix that had already been clamped to plus or minus one — `scaled` went through `applyMaster`, which clamps as a last resort before a file is written. So however loud the mix really was, the limiter saw a peak of one and asked for the single decibel that takes one down to the ceiling. Everything above that was then flattened by the clamp. A mix peaking at two and a half times full scale, at three targets: -14 LUFS 4 samples flat against the top, reduction "1.00 dB" -9 LUFS 628 samples flat against the top, reduction "1.00 dB" -6 LUFS 2160 samples flat against the top, reduction "1.00 dB" Exactly 1.00 every time, because that is what takes a clamped one down to 0.891. That number is what gave it away. Quiet targets were always fine, which is why nothing had noticed. Scaling for analysis no longer clamps. The same three targets now come back at the ceiling exactly, with no flat samples and reductions of 2.46, 11.71 and 17.44 dB — and the report's loudness matches what the samples actually measure, which matters because the interface prints that number after every export. The rest of the fifteen: the level turns the whole thing down and silences it at zero, each band moves its own part of the spectrum and leaves the others where they were, cutting takes away rather than adding elsewhere, the tone tilts top against bottom, the send is what puts a tail after a sound and does not change the sound itself, and a cathedral rings for longer than a booth. Every one checked by putting its fault back: the clamp restored fails two, ignoring the level fails two, ignoring the send fails two, dropping the tilt fails one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ux1kydvUkLRoMbHp82ofDi
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The mixer and the master were the last untested part. The render tests pass chain settings through without ever asking what the chain does with them, so three bands of EQ, a tilt, a send, a room, the level, the loudness and the limiter were all exercised as far as "something came out".
Fifteen tests measured on the way out, and they found something.
The bug
The limiter was being handed a copy of the mix that had already been clamped to plus or minus one —
scaledwent throughapplyMaster, which clamps as a last resort before a file is written. So however loud the mix really was, the limiter saw a peak of one and asked for the single decibel that takes one down to the ceiling. Everything above that was then flattened by the clamp.A mix peaking at two and a half times full scale, at three targets:
Exactly 1.00 every time, because that is what takes a clamped one down to 0.891. That number is what gave it away. Quiet targets were always fine, which is why nothing had noticed.
Scaling for analysis no longer clamps. The same three targets now come back at the ceiling exactly, with no flat samples and reductions of 2.46, 11.71 and 17.44 dB — and the report's loudness matches what the samples actually measure, which matters because the interface prints that number after every export.
The rest of the fifteen
Spectrum is measured by running a render back through the same kind of filter the mixer is built from, since the question is only ever "more or less than the other one".
Checking
Every test checked by putting its fault back: the clamp restored fails two, ignoring the level fails two, ignoring the send fails two, dropping the tilt fails one.
251 unit tests (was 236), 77 browser tests, build clean.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Ux1kydvUkLRoMbHp82ofDi
Generated by Claude Code