Fix sidechain matching + soft knee in SC
These coefficients change with the thresholds.
This commit is contained in:
parent
732cfdfa3a
commit
b9031ecd2f
|
@ -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.
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue