1
0
Fork 0

Fix sidechain matching + soft knee in SC

These coefficients change with the thresholds.
This commit is contained in:
Robbert van der Helm 2023-03-27 17:26:38 +02:00
parent 732cfdfa3a
commit b9031ecd2f
2 changed files with 21 additions and 18 deletions

View file

@ -16,6 +16,9 @@ Versioning](https://semver.org/spec/v2.0.0.html).
### Fixed ### Fixed
- Fixed the soft-knee options in the sidechain matching mode. They previously
didn't account for the changing compressor thresholds, which could result in
unexpected loud volume spikes.
- The sidechain matching mode now caps the relative thresholds to behave more - The sidechain matching mode now caps the relative thresholds to behave more
consistently with quiet inputs. consistently with quiet inputs.

View file

@ -953,12 +953,8 @@ impl CompressorBank {
assert!(self.sidechain_spectrum_magnitudes[channel_idx].len() == buffer.len()); assert!(self.sidechain_spectrum_magnitudes[channel_idx].len() == buffer.len());
assert!(self.downwards_thresholds_db.len() == buffer.len()); assert!(self.downwards_thresholds_db.len() == buffer.len());
assert!(self.downwards_ratios.len() == buffer.len()); assert!(self.downwards_ratios.len() == buffer.len());
assert!(self.downwards_knee_parabola_scale.len() == buffer.len());
assert!(self.downwards_knee_parabola_intercept.len() == buffer.len());
assert!(self.upwards_thresholds_db.len() == buffer.len()); assert!(self.upwards_thresholds_db.len() == buffer.len());
assert!(self.upwards_ratios.len() == buffer.len()); assert!(self.upwards_ratios.len() == buffer.len());
assert!(self.upwards_knee_parabola_scale.len() == buffer.len());
assert!(self.upwards_knee_parabola_intercept.len() == buffer.len());
for (bin_idx, (bin, envelope)) in buffer for (bin_idx, (bin, envelope)) in buffer
.iter_mut() .iter_mut()
.zip(self.envelopes[channel_idx].iter()) .zip(self.envelopes[channel_idx].iter())
@ -991,40 +987,44 @@ impl CompressorBank {
unsafe { self.downwards_thresholds_db.get_unchecked(bin_idx) + sidechain_scale_db } unsafe { self.downwards_thresholds_db.get_unchecked(bin_idx) + sidechain_scale_db }
.max(util::MINUS_INFINITY_DB); .max(util::MINUS_INFINITY_DB);
let downwards_ratio = unsafe { self.downwards_ratios.get_unchecked(bin_idx) }; let downwards_ratio = unsafe { self.downwards_ratios.get_unchecked(bin_idx) };
let downwards_knee_parabola_scale = // Because the thresholds are scaled based on the sidechain input, we also need to
unsafe { self.downwards_knee_parabola_scale.get_unchecked(bin_idx) }; // recompute the knee coefficients
let downwards_knee_parabola_intercept = unsafe { let (downwards_knee_parabola_scale, downwards_knee_parabola_intercept) =
self.downwards_knee_parabola_intercept downwards_soft_knee_coefficients(
.get_unchecked(bin_idx) downwards_threshold_db,
}; downwards_knee_width_db,
*downwards_ratio,
);
let downwards_compressed = compress_downwards( let downwards_compressed = compress_downwards(
envelope_db, envelope_db,
downwards_threshold_db, downwards_threshold_db,
*downwards_ratio, *downwards_ratio,
downwards_knee_width_db, downwards_knee_width_db,
*downwards_knee_parabola_scale, downwards_knee_parabola_scale,
*downwards_knee_parabola_intercept, downwards_knee_parabola_intercept,
); );
let upwards_threshold_db = let upwards_threshold_db =
unsafe { self.upwards_thresholds_db.get_unchecked(bin_idx) + sidechain_scale_db } unsafe { self.upwards_thresholds_db.get_unchecked(bin_idx) + sidechain_scale_db }
.max(util::MINUS_INFINITY_DB); .max(util::MINUS_INFINITY_DB);
let upwards_ratio = unsafe { self.upwards_ratios.get_unchecked(bin_idx) }; let upwards_ratio = unsafe { self.upwards_ratios.get_unchecked(bin_idx) };
let upwards_knee_parabola_scale =
unsafe { self.upwards_knee_parabola_scale.get_unchecked(bin_idx) };
let upwards_knee_parabola_intercept =
unsafe { self.upwards_knee_parabola_intercept.get_unchecked(bin_idx) };
let upwards_compressed = if bin_idx >= first_non_dc_bin let upwards_compressed = if bin_idx >= first_non_dc_bin
&& *upwards_ratio != 1.0 && *upwards_ratio != 1.0
&& envelope_db > util::MINUS_INFINITY_DB && envelope_db > util::MINUS_INFINITY_DB
{ {
let (upwards_knee_parabola_scale, upwards_knee_parabola_intercept) =
upwards_soft_knee_coefficients(
upwards_threshold_db,
upwards_knee_width_db,
*upwards_ratio,
);
compress_upwards( compress_upwards(
envelope_db, envelope_db,
upwards_threshold_db, upwards_threshold_db,
*upwards_ratio, *upwards_ratio,
upwards_knee_width_db, upwards_knee_width_db,
*upwards_knee_parabola_scale, upwards_knee_parabola_scale,
*upwards_knee_parabola_intercept, upwards_knee_parabola_intercept,
) )
} else { } else {
envelope_db envelope_db