Skip to content

fix(producer): the audio peak correction sizes its cut from the PCM it re-encodes - #6312

Merged
miguel-heygen merged 1 commit into
mainfrom
fix/audio-peak-from-pcm
Oct 25, 2026
Merged

miguel-heygen merged 1 commit into
mainfrom
fix/audio-peak-from-pcm

Conversation

@miguel-heygen

@miguel-heygen miguel-heygen commented Oct 25, 2026 •

Copy link
Copy Markdown
Collaborator

What changes for users

A render whose audio is mixed from several loud, full-scale tracks no longer fails with "Audio true-peak check failed ... after 3 correction passes". It now gets the one larger volume cut it needs and renders.

Cause

The mixer keeps its float mix as a PCM file, and the true-peak correction re-encodes that PCM with a volume cut. The cut was sized from the AAC the first encode produced. When the mix is louder than full scale, that first encode clips at 0 dBFS, so the AAC reads quieter than the PCM really is. Example: several unity-gain full-scale tracks give a PCM peak of +10 dBFS but an AAC peak of +5.2 dBFS. The cut sized from +5.2 leaves the PCM still over full scale, the encoder clips it again, and the AAC peak sits near -0.4 dBFS however many passes run. Three passes ended, and the whole render failed.

Fix

enforceAacTruePeak (shared by every correction) now also measures the PCM source when one is given, and sizes each cut from the louder of the AAC reading and the PCM peak after the cut so far. The PCM is measured once, and only on the path where the AAC is over the ceiling. Corrections that decode the AAC (no PCM source) are unchanged.

constrainAacTruePeak gets the same optional probe and encoder seams padOrTrimAudioToVideoFrameCount already has, so the PCM path can be tested without ffmpeg.

Verification

  • New test in audioPadTrim.test.ts: a +10 dBFS PCM read as +5.2 by the AAC, with an encoder model that clips what the cut leaves above full scale. It fails on the previous code (39 pass, 1 fail) and passes with the change; the file passes 3 runs in a row (40 tests).
  • Reproduced with the producer's own mixer on a real five-track composition (all tracks near full scale, unity gain): before, the exact failure message with the stalled peak; after, success with an 11.5 dB cut.
  • tsc --noEmit, oxlint and oxfmt clean.

Not covered

The attenuation is sized from true-peak readings only; a mix that stays over the ceiling after the three passes still fails as before.

Package size

Raises the producer packed budget from 768601 to 768916 bytes (+315): the CI build of this change measured 776605, and 768916 is the smallest budget the 1% tolerance accepts for it. It buys the PCM-peak read in the true-peak correction (about +270 bytes).

Size budget: unchanged. Main measures 781312 packed / 2840135 unpacked; this PR adds its own +288 packed / +1185 unpacked, within the budget tolerance, so no budget line moves and nothing here conflicts with the other producer PRs.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE · 0 blocker · 1 important · 0 nits · head 1f5b5d2f

The PCM reference only changes the first cut on the PCM path. Later passes fall back to the AAC reading, since PCM + attenuation is then at ceiling minus headroom. The no-PCM pad/trim path is unchanged.

Scope / evidence
  • Read audioPadTrim.ts (constrainAacTruePeak, enforceAacTruePeak, defaultAacEncoder), audioTruePeak.ts, audioStage.ts, and mixThroughFloatSum in the engine. The kept audio-source.wav is the exact encoder input (master FX already applied, no extra filter), so sizing the cut from its peak is sound.
  • Silent PCM gives -Infinity, which falls back to the AAC reading. A NaN or +Inf PCM peak makes checkedDbfs throw, and that error is caught and reported.
  • The new test fails first: with referenceDbfs = truePeakDbfs the file gives 39 pass / 1 fail; at head it gives 40 / 0 (bun).
  • Real ffmpeg run on a +8.3 dBTP float pink-noise mix (its AAC read +5.1): the new code succeeds with a 9.8 dB cut and the PCM probe works on a real WAV.
  • CI at review time: required checks still running; non-required Comments is red (inline).

// whose peak can stall or rise over a few dB of attenuation instead of falling dB for dB.
const headroomDb = AAC_TRUE_PEAK_CORRECTION_HEADROOM_DB * 2 ** pass;
attenuationDb += AAC_DELIVERY_TRUE_PEAK_DBFS - headroomDb - truePeakDbfs;
// The encoder clips what is left above full scale, so the AAC under-reads a hotter PCM and a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

important: the Comments workflow fails on this head. The comment ratchet reports audioPadTrim.ts rising from 15.7% to 15.9% (4 comment lines added). It is not a required check, but it stays red until the file is back at or under the base share. Cutting 2 of the added comment lines is enough (105/673 = 15.6%). For example, fold this 2-line comment into one line, or drop the /** Test seams … */ docstring. A name such as sourcePeakDbfs already carries most of it.

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Edit accuracy: accurate 271 (base branch 271), smooth 150 of those

The gate passes.
Smoothness is reported in the artifact, not gated. A case fails only if it fails 2 of 3 runs.

Quarantined, measured but not gated (0)

@miguel-heygen
miguel-heygen force-pushed the fix/audio-peak-from-pcm branch from 1f5b5d2 to 1eeea3d Compare October 25, 2026 14:36
@miguel-heygen

Copy link
Copy Markdown
Collaborator Author

Three red checks, one root each, pushed as 1eeea3d (single commit on main 9b80c2d): (1) Build: the producer package was over its size budget by this change's ~270 bytes, so the budget is main's 768601 + 271 = 768872 (the smallest value the 1% rule accepts for the 776560 CI measured). (2) Comments: the ratchet saw this file's comment share rise; I dropped two doc comments that only restated the types, and comment-ratchet now reports the file at or under its merge-base share. (3) Studio edit-accuracy gate: its 5 shards never ran behind the failed Build; nothing to change, it reruns at this head. Code is the approved head's; the audioPadTrim test file passes 3 runs in a row (40 tests).

@miguel-heygen

Copy link
Copy Markdown
Collaborator Author

Build was 45 bytes over: after the comment trim the CI build measures 776605 (not 776560), and the 1% rule needs a budget of at least 768916. Raised to that (main's 768601 + 315). The Studio edit-accuracy gate failed behind Build in both runs and needs no change.

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES · 1 blocker · 0 important · 0 nits · head 0797cc92

  • blocker — the PR now conflicts with main on the line this head changes. #6304 (merged 15:13Z, after this rebase) raised the producer packed budget in scripts/package-size-budgets.json to 770990, and this head sets it to 768916. GitHub reports it CONFLICTING, so it can't merge. 768916 was also sized from a CI build on the old base, so taking either side as-is is wrong. Fix: rebase onto main, then size the budget from a CI build of the rebased head (that is, 770990 plus this change's growth, rounded to the smallest value the 1% tolerance accepts).
Scope

Code is unchanged since the approved head 1f5b5d2f. In audioPadTrim.ts, the only change is that two JSDoc lines were dropped, and the test file is byte-identical. The earlier approval of the PCM-referenced cut still holds. CI on this head (old base) is green.

@miguel-heygen
miguel-heygen force-pushed the fix/audio-peak-from-pcm branch from 0797cc9 to 053b336 Compare October 25, 2026 16:14

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE — 1 resolved, 0 open, 0 new · 0797cc92 → 147d6a83 (rebased onto main: no conflict, audioPadTrim files byte-identical to the approved code, the size-budget check passes in Build)

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 25, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 25, 2026
@miguel-heygen
miguel-heygen force-pushed the fix/audio-peak-from-pcm branch from 147d6a8 to 769b889 Compare October 25, 2026 18:17

@heygengenesis heygengenesis Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE — 0 resolved, 0 open, 0 new · 147d6a83 → 769b8895 (rebased; audioPadTrim files byte-identical to the approved head; no budget change, size check passes in CI; all workflows green)

@miguel-heygen
miguel-heygen added this pull request to the merge queue Oct 25, 2026
Merged via the queue into main with commit 1a37db4 Oct 25, 2026
117 of 118 checks passed
@miguel-heygen
miguel-heygen deleted the fix/audio-peak-from-pcm branch October 25, 2026 19:12
@heygengenesis heygengenesis Bot mentioned this pull request Oct 25, 2026
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