Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions internal/processor/adaptive.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,15 @@ const (
la2aKurtosisLowPeak = 5.0 // Below: flat spectrum, firmer ratio
la2aDynamicRangeWide = 35.0 // dB - above: add ratio boost

// LA-2A hot input protection
// When input true peak >= -1 dBTP, the signal is already loud enough that
// aggressive compression crushes dynamics unnecessarily. The downstream
// limiter handles peak control, so the compressor can afford to be gentler.
la2aHotInputTPThreshold = -1.0 // dBTP: above this, start backing off
la2aHotInputTPSevere = -0.5 // dBTP: above this, maximum backoff
la2aHotInputRatioReduction = 1.0 // Maximum ratio reduction (e.g. 3.5 → 2.5)
la2aHotInputHeadroomReduction = 5.0 // Maximum headroom reduction in dB

// LA-2A Threshold: Relative to peak level (like Peak Reduction knob)
// LA-2A's threshold is effectively signal-relative
// Headroom from peak level determines compression depth
Expand Down Expand Up @@ -1405,6 +1414,17 @@ func tuneLA2ARatio(config *FilterChainConfig, measurements *AudioMeasurements) {
ratio += la2aRatioDynamicBoost
}

// Hot input protection: back off ratio when true peak is high.
// The limiter downstream handles peak control, so the compressor
// can afford to be gentler on already-loud material.
if measurements.InputTP >= la2aHotInputTPThreshold {
severity := (measurements.InputTP - la2aHotInputTPThreshold) /
(la2aHotInputTPSevere - la2aHotInputTPThreshold)
severity = clamp(severity, 0.0, 1.0)
severity = math.Sqrt(severity)
ratio -= la2aHotInputRatioReduction * severity
}

// Clamp to reasonable range
config.LA2ARatio = clamp(ratio, 2.0, 5.0)
}
Expand Down Expand Up @@ -1434,6 +1454,17 @@ func tuneLA2AThreshold(config *FilterChainConfig, measurements *AudioMeasurement
headroom = la2aThresholdHeadroomLight
}

// Hot input protection: reduce headroom (raise threshold) for loud inputs.
// When peaks are already near 0 dBTP, less compression depth is needed
// because the limiter downstream handles peak control.
if measurements.InputTP >= la2aHotInputTPThreshold {
severity := (measurements.InputTP - la2aHotInputTPThreshold) /
(la2aHotInputTPSevere - la2aHotInputTPThreshold)
severity = clamp(severity, 0.0, 1.0)
severity = math.Sqrt(severity)
headroom -= la2aHotInputHeadroomReduction * severity
}

// Calculate threshold relative to peak level
// threshold = peak - headroom
// e.g., peak -5dB with 15dB headroom → threshold -20dB
Expand Down