Skip to content

refactor(processor): move pre-gain calculation before Pass 3#59

Merged
flexiondotorg merged 4 commits intomainfrom
pregain-order
Mar 15, 2026
Merged

refactor(processor): move pre-gain calculation before Pass 3#59
flexiondotorg merged 4 commits intomainfrom
pregain-order

Conversation

@flexiondotorg
Copy link
Contributor

Summary

Move ceiling and pre-gain calculation before Pass 3 so loudnorm measures the post-limiter signal directly, closing the 1.3 LU LUFS measurement gap.

Changes

  • Extract calculatePreGain() and buildPreLimiterPrefix() for reuse
  • Simplify buildLoudnormFilterSpec() to accept pre-computed ceiling/pre-gain values
  • Reorder ApplyNormalisation() to compute ceiling before Pass 3 measurement
  • Thread pre-computed values through applyLoudnormAndMeasure()
  • Add Pass3FilterPrefix field to NormalisationResult for diagnostics
  • Update AGENTS.md to document optional volume+alimiter prefix
  • Update LUFS-GAP-SUMMARY.md with resolution notes

Testing

  • All existing unit tests pass
  • New tests for calculatePreGain() and buildPreLimiterPrefix()
  • Lint and build verification clean

Technical Details

Pass 2 produces ebur128 measurements (OutputI, OutputTP). Previously, Pass 3 measured the raw signal and Pass 4 applied pre-gain/limiting without reflecting those changes in Pass 3's measurements. This created a 1.3 LU gap because loudnorm used unadjusted InputI as measured_I while the actual audio entering loudnorm had been modified.

Now: compute ceiling/pre-gain from Pass 2's ebur128 before Pass 3. Pass 3 measures through the same volume+alimiter prefix that Pass 4 applies, so its measurement.InputI reflects the post-limiter signal. loudnorm receives the correct measured values, eliminating the adjustment arithmetic.

- Extract pre-gain calculation logic into calculatePreGain()
- Extract filter prefix building logic into buildPreLimiterPrefix()
- Wire functions into ApplyNormalisation() and buildLoudnormFilterSpec()
- Add comprehensive test coverage for both functions

Signed-off-by: Martin Wimpress <code@wimpress.io>
…ures

- Move ceiling and pre-gain calculation before Pass 3 using Pass 2
  measurements
- Simplify buildLoudnormFilterSpec() to accept pre-computed values,
  return string only
- Thread pre-computed values through applyLoudnormAndMeasure()
- Remove redundant parameter passing and intermediate adjustments

Signed-off-by: Martin Wimpress <code@wimpress.io>
…hitecture

- Add Pass3FilterPrefix field to NormalisationResult struct
- Display prefix in writeDiagnosticPeakLimiter report when active
- Update AGENTS.md to explain optional volume+alimiter in Pass 3
  measurement

Signed-off-by: Martin Wimpress <code@wimpress.io>
Signed-off-by: Martin Wimpress <code@wimpress.io>
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 4 files

Confidence score: 4/5

  • This PR looks safe to merge with minimal risk: the reported issue is in a test assertion rather than production logic, so runtime behavior is unlikely to break directly.
  • The most significant concern is in internal/processor/normalise_test.go: the assertion still checks Pass 2 values even though buildLoudnormFilterSpec now expects Pass 3 post-limiter measurements, which can mask regressions in limiting edge cases.
  • Given the moderate severity (5/10) and high confidence (9/10), this is worth fixing soon to restore accurate coverage, but it is not strongly merge-blocking by itself.
  • Pay close attention to internal/processor/normalise_test.go - assertion is validating outdated pass metrics and may miss real behavior changes.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="internal/processor/normalise_test.go">

<violation number="1" location="internal/processor/normalise_test.go:444">
P2: This assertion checks the old Pass 2 values, but `buildLoudnormFilterSpec` now expects Pass 3's post-limiter measurements. In limiting cases that makes the test validate the wrong behavior and weakens coverage for the regression this PR is fixing.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

@flexiondotorg flexiondotorg merged commit 733af3d into main Mar 15, 2026
7 checks passed
@flexiondotorg flexiondotorg deleted the pregain-order branch March 15, 2026 15:14
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