fix(audio): the clipping guard only limits a boost, never attenuates

A track that needs no boost keeps unity (or its own attenuation) even when
its peaks already sit above the -1 dBTP headroom: that is the master's
doing, not ours. Without this, every hot modern master exactly at the
target lost ~0.5-1 dB the moment the guard saw its peak.

cc
This commit is contained in:
vicrodh committed 2026-09-13 11:09:15 -06:00
1 parent 8fef2466cc
commit 8c4b140ef8
1 file changed
+12 -5
+12 -5
View File
@@ -71,14 +71,17 @@ pub fn lufs_from_replaygain(gain_db: f32) -> f32 {
}
/// Linear gain that moves a track at `lufs` to `target_lufs`: boost capped at
/// [`MAX_BOOST_DB`], and with `prevent_clipping` never above what keeps the
/// known peak [`PEAK_HEADROOM_DB`] under full scale.
/// [`MAX_BOOST_DB`], and with `prevent_clipping` a BOOST is further capped at
/// what keeps the known peak [`PEAK_HEADROOM_DB`] under full scale. The guard
/// only ever limits a boost: a track that needs none keeps unity (or its
/// attenuation) even when its own peaks already sit above the headroom —
/// that is the master's doing, not ours.
pub fn gain_for(lufs: f32, peak: Option<f32>, target_lufs: f32, prevent_clipping: bool) -> f32 {
let db = (target_lufs - lufs).min(MAX_BOOST_DB);
let mut gain = db_to_linear(db);
if prevent_clipping {
if let Some(p) = peak.filter(|p| *p > 0.0) {
let ceiling = db_to_linear(PEAK_HEADROOM_DB) / p;
let ceiling = (db_to_linear(PEAK_HEADROOM_DB) / p).max(1.0);
if gain > ceiling {
gain = ceiling;
}
@@ -281,8 +284,12 @@ mod tests {
(gain_for(-30.0, None, -14.0, true) - db_to_linear(6.0)).abs() < 1e-4,
"quiet track, no peak: +6 dB cap"
);
let ceiling = db_to_linear(-1.0) / 0.9;
assert!((gain_for(-20.0, Some(0.9), -14.0, true) - ceiling).abs() < 1e-4, "-1 dBTP over the peak");
let ceiling = db_to_linear(-1.0) / 0.5;
assert!((gain_for(-20.0, Some(0.5), -14.0, true) - ceiling).abs() < 1e-4, "-1 dBTP over the peak");
assert!(
(gain_for(-20.0, Some(0.9), -14.0, true) - 1.0).abs() < 1e-4,
"a peak already at -0.9 dBFS leaves no room to boost, but the guard never attenuates"
);
assert!(
(gain_for(-20.0, Some(0.9), -14.0, false) - db_to_linear(6.0)).abs() < 1e-4,
"no clipping guard: full boost"