const FULL_IMPULSE: f32 = 25.0;
pub(crate) fn gain(impulse: f32) -> f32 {
(impulse.max(0.0) / FULL_IMPULSE).sqrt().min(1.0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn gain_is_monotonic_and_clamped() {
assert_eq!(gain(0.0), 0.0);
assert_eq!(gain(-5.0), 0.0, "negative impulse clamps silent");
let mut prev = 0.0;
for i in 1..100 {
let g = gain(i as f32);
assert!(g >= prev && g <= 1.0, "monotonic in [0,1]: {g}");
prev = g;
}
assert_eq!(gain(FULL_IMPULSE), 1.0);
assert_eq!(gain(1000.0), 1.0, "hard hits saturate");
}
#[test]
fn light_taps_are_audible_but_quiet() {
let g = gain(1.0);
assert!(g > 0.1 && g < 0.4, "gate-level impact: {g}");
}
}