Skip to content

Commit 87ca1be

Browse files
committed
feat(processor): add LA-2A hot-input protection
- Add configurable constants to detect hot inputs: la2aHotInputTPThreshold, la2aHotInputTPSevere, la2aHotInputRatioReduction, la2aHotInputHeadroomReduction - Back off LA-2A ratio when measured true peak exceeds the threshold. Use a square-root scaled severity to apply a smooth, non-linear reduction up to the configured maximum. - Reduce LA-2A headroom (raise threshold) for loud inputs using the same severity curve so the compressor applies gentler gain reduction. - Rationale: the downstream limiter handles peak control; backing off the compressor for already-hot material avoids unnecessary dynamics crushing and preserves perceived dynamics. IMPACT: gentler compression on files with high true peaks; reduces over-compression without changing limiter behaviour. No breaking changes. Signed-off-by: Martin Wimpress <martin@wimpress.org>
1 parent 9e2b2b4 commit 87ca1be

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

internal/processor/adaptive.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,15 @@ const (
225225
la2aKurtosisLowPeak = 5.0 // Below: flat spectrum, firmer ratio
226226
la2aDynamicRangeWide = 35.0 // dB - above: add ratio boost
227227

228+
// LA-2A hot input protection
229+
// When input true peak >= -1 dBTP, the signal is already loud enough that
230+
// aggressive compression crushes dynamics unnecessarily. The downstream
231+
// limiter handles peak control, so the compressor can afford to be gentler.
232+
la2aHotInputTPThreshold = -1.0 // dBTP: above this, start backing off
233+
la2aHotInputTPSevere = -0.5 // dBTP: above this, maximum backoff
234+
la2aHotInputRatioReduction = 1.0 // Maximum ratio reduction (e.g. 3.5 → 2.5)
235+
la2aHotInputHeadroomReduction = 5.0 // Maximum headroom reduction in dB
236+
228237
// LA-2A Threshold: Relative to peak level (like Peak Reduction knob)
229238
// LA-2A's threshold is effectively signal-relative
230239
// Headroom from peak level determines compression depth
@@ -1405,6 +1414,17 @@ func tuneLA2ARatio(config *FilterChainConfig, measurements *AudioMeasurements) {
14051414
ratio += la2aRatioDynamicBoost
14061415
}
14071416

1417+
// Hot input protection: back off ratio when true peak is high.
1418+
// The limiter downstream handles peak control, so the compressor
1419+
// can afford to be gentler on already-loud material.
1420+
if measurements.InputTP >= la2aHotInputTPThreshold {
1421+
severity := (measurements.InputTP - la2aHotInputTPThreshold) /
1422+
(la2aHotInputTPSevere - la2aHotInputTPThreshold)
1423+
severity = clamp(severity, 0.0, 1.0)
1424+
severity = math.Sqrt(severity)
1425+
ratio -= la2aHotInputRatioReduction * severity
1426+
}
1427+
14081428
// Clamp to reasonable range
14091429
config.LA2ARatio = clamp(ratio, 2.0, 5.0)
14101430
}
@@ -1434,6 +1454,17 @@ func tuneLA2AThreshold(config *FilterChainConfig, measurements *AudioMeasurement
14341454
headroom = la2aThresholdHeadroomLight
14351455
}
14361456

1457+
// Hot input protection: reduce headroom (raise threshold) for loud inputs.
1458+
// When peaks are already near 0 dBTP, less compression depth is needed
1459+
// because the limiter downstream handles peak control.
1460+
if measurements.InputTP >= la2aHotInputTPThreshold {
1461+
severity := (measurements.InputTP - la2aHotInputTPThreshold) /
1462+
(la2aHotInputTPSevere - la2aHotInputTPThreshold)
1463+
severity = clamp(severity, 0.0, 1.0)
1464+
severity = math.Sqrt(severity)
1465+
headroom -= la2aHotInputHeadroomReduction * severity
1466+
}
1467+
14371468
// Calculate threshold relative to peak level
14381469
// threshold = peak - headroom
14391470
// e.g., peak -5dB with 15dB headroom → threshold -20dB

0 commit comments

Comments
 (0)