Split compressor params into up/downwards
This commit is contained in:
parent
e68bb8d632
commit
b8525cac4d
|
@ -23,19 +23,30 @@ use nih_plug::prelude::*;
|
|||
/// will have a capacity of `MAX_WINDOW_SIZE / 2 + 1` and a size that matches the current complex
|
||||
/// FFT buffer size. This is stored as a struct of arrays to make SIMD-ing easier in the future.
|
||||
pub struct CompressorBank {
|
||||
// TODO: The thresholds and ratios need to be split up in downwards and upwards variants
|
||||
/// If set, then the thresholds should be updated on the next processing cycle. Can be set from
|
||||
/// a parameter value change listener, and is also set when calling `.reset_for_size`.
|
||||
pub should_update_thresholds: Arc<AtomicBool>,
|
||||
/// If set, then the ratios should be updated on the next processing cycle. Can be set from a
|
||||
/// parameter value change listener, and is also set when calling `.reset_for_size`.
|
||||
pub should_update_ratios: Arc<AtomicBool>,
|
||||
/// If set, then the downwards thresholds should be updated on the next processing cycle. Can be
|
||||
/// set from a parameter value change listener, and is also set when calling `.reset_for_size`.
|
||||
pub should_update_downwards_thresholds: Arc<AtomicBool>,
|
||||
/// The same as `should_update_downwards_thresholds`, but for upwards thresholds.
|
||||
pub should_update_upwards_thresholds: Arc<AtomicBool>,
|
||||
/// If set, then the downwards ratios should be updated on the next processing cycle. Can be set
|
||||
/// from a parameter value change listener, and is also set when calling `.reset_for_size`.
|
||||
pub should_update_downwards_ratios: Arc<AtomicBool>,
|
||||
/// The same as `should_update_downwards_ratios`, but for upwards ratios.
|
||||
pub should_update_upwards_ratios: Arc<AtomicBool>,
|
||||
|
||||
/// Downwards compressor thresholds, in linear space.
|
||||
downwards_thresholds: Vec<f32>,
|
||||
/// Upwards compressor thresholds, in linear space.
|
||||
upwards_thresholds: Vec<f32>,
|
||||
/// Downwards compressor ratios. At 1.0 the cmopressor won't do anything. If
|
||||
/// [`CompressorBankParams::high_freq_ratio_rolloff`] is set to 1.0, then this will be the same
|
||||
/// for each compressor.
|
||||
downwards_ratios: Vec<f32>,
|
||||
/// Upwards compressor ratios. At 1.0 the cmopressor won't do anything. If
|
||||
/// [`CompressorBankParams::high_freq_ratio_rolloff`] is set to 1.0, then this will be the same
|
||||
/// for each compressor.
|
||||
upwards_ratios: Vec<f32>,
|
||||
|
||||
/// Compressor thresholds, in linear space.
|
||||
thresholds: Vec<f32>,
|
||||
/// Compressor ratios. If [`CompressorBankParams::high_freq_ratio_rolloff`] is set to 1.0, then
|
||||
/// this will be the same for each compressor.
|
||||
ratios: Vec<f32>,
|
||||
/// The current envelope value for this bin, in linear space. Indexed by
|
||||
/// `[channel_idx][compressor_idx]`.
|
||||
envelopes: Vec<Vec<f32>>,
|
||||
|
@ -113,9 +124,14 @@ impl ThresholdParams {
|
|||
/// Create a new [`ThresholdParams`] object. Changing any of the threshold parameters causes the
|
||||
/// passed compressor bank's thresholds to be updated.
|
||||
pub fn new(compressor_bank: &CompressorBank) -> Self {
|
||||
let should_update_thresholds = compressor_bank.should_update_thresholds.clone();
|
||||
let set_update_thresholds =
|
||||
Arc::new(move |_| should_update_thresholds.store(true, Ordering::SeqCst));
|
||||
let should_update_downwards_thresholds =
|
||||
compressor_bank.should_update_downwards_thresholds.clone();
|
||||
let should_update_upwards_thresholds =
|
||||
compressor_bank.should_update_upwards_thresholds.clone();
|
||||
let set_update_both_thresholds = Arc::new(move |_| {
|
||||
should_update_downwards_thresholds.store(true, Ordering::SeqCst);
|
||||
should_update_upwards_thresholds.store(true, Ordering::SeqCst);
|
||||
});
|
||||
|
||||
ThresholdParams {
|
||||
center_frequency: FloatParam::new(
|
||||
|
@ -127,7 +143,7 @@ impl ThresholdParams {
|
|||
factor: FloatRange::skew_factor(-2.0),
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_thresholds.clone())
|
||||
.with_callback(set_update_both_thresholds.clone())
|
||||
// This includes the unit
|
||||
.with_value_to_string(formatters::v2s_f32_hz_then_khz(0))
|
||||
.with_string_to_value(formatters::s2v_f32_hz_then_khz()),
|
||||
|
@ -141,7 +157,7 @@ impl ThresholdParams {
|
|||
max: 50.0,
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_thresholds.clone())
|
||||
.with_callback(set_update_both_thresholds.clone())
|
||||
.with_unit(" dB")
|
||||
.with_step_size(0.1),
|
||||
curve_slope: FloatParam::new(
|
||||
|
@ -152,7 +168,7 @@ impl ThresholdParams {
|
|||
max: 24.0,
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_thresholds.clone())
|
||||
.with_callback(set_update_both_thresholds.clone())
|
||||
.with_unit(" dB/oct")
|
||||
.with_step_size(0.1),
|
||||
curve_curve: FloatParam::new(
|
||||
|
@ -163,7 +179,7 @@ impl ThresholdParams {
|
|||
max: 24.0,
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_thresholds)
|
||||
.with_callback(set_update_both_thresholds)
|
||||
.with_unit(" dB/oct²")
|
||||
.with_step_size(0.1),
|
||||
}
|
||||
|
@ -174,12 +190,27 @@ impl CompressorBankParams {
|
|||
/// Create a new [`CompressorBankParams`] object. Changing any of the threshold or ratio
|
||||
/// parameters causes the passed compressor bank's parameters to be updated.
|
||||
pub fn new(compressor_bank: &CompressorBank) -> Self {
|
||||
let should_update_thresholds = compressor_bank.should_update_thresholds.clone();
|
||||
let set_update_thresholds =
|
||||
Arc::new(move |_| should_update_thresholds.store(true, Ordering::SeqCst));
|
||||
let should_update_ratios = compressor_bank.should_update_ratios.clone();
|
||||
let set_update_ratios =
|
||||
Arc::new(move |_| should_update_ratios.store(true, Ordering::SeqCst));
|
||||
let should_update_downwards_thresholds =
|
||||
compressor_bank.should_update_downwards_thresholds.clone();
|
||||
let set_update_downwards_thresholds =
|
||||
Arc::new(move |_| should_update_downwards_thresholds.store(true, Ordering::SeqCst));
|
||||
let should_update_upwards_thresholds =
|
||||
compressor_bank.should_update_upwards_thresholds.clone();
|
||||
let set_update_upwards_thresholds =
|
||||
Arc::new(move |_| should_update_upwards_thresholds.store(true, Ordering::SeqCst));
|
||||
let should_update_downwards_ratios = compressor_bank.should_update_downwards_ratios.clone();
|
||||
let set_update_downwards_ratios =
|
||||
Arc::new(move |_| should_update_downwards_ratios.store(true, Ordering::SeqCst));
|
||||
let should_update_upwards_ratios = compressor_bank.should_update_upwards_ratios.clone();
|
||||
let set_update_upwards_ratios =
|
||||
Arc::new(move |_| should_update_upwards_ratios.store(true, Ordering::SeqCst));
|
||||
|
||||
let should_update_downwards_ratios = compressor_bank.should_update_downwards_ratios.clone();
|
||||
let should_update_upwards_ratios = compressor_bank.should_update_upwards_ratios.clone();
|
||||
let set_update_both_ratios = Arc::new(move |_| {
|
||||
should_update_downwards_ratios.store(true, Ordering::SeqCst);
|
||||
should_update_upwards_ratios.store(true, Ordering::SeqCst);
|
||||
});
|
||||
|
||||
CompressorBankParams {
|
||||
// TODO: Set nicer default values for these things
|
||||
|
@ -192,7 +223,7 @@ impl CompressorBankParams {
|
|||
max: 50.0,
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_thresholds.clone())
|
||||
.with_callback(set_update_downwards_thresholds)
|
||||
.with_unit(" dB")
|
||||
.with_step_size(0.1),
|
||||
upwards_threshold_offset_db: FloatParam::new(
|
||||
|
@ -203,7 +234,7 @@ impl CompressorBankParams {
|
|||
max: 50.0,
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_thresholds)
|
||||
.with_callback(set_update_upwards_thresholds)
|
||||
.with_unit(" dB")
|
||||
.with_step_size(0.1),
|
||||
|
||||
|
@ -212,7 +243,7 @@ impl CompressorBankParams {
|
|||
0.5,
|
||||
FloatRange::Linear { min: 0.0, max: 1.0 },
|
||||
)
|
||||
.with_callback(set_update_ratios.clone())
|
||||
.with_callback(set_update_both_ratios)
|
||||
.with_unit("%")
|
||||
.with_value_to_string(formatters::v2s_f32_percentage(0))
|
||||
.with_string_to_value(formatters::s2v_f32_percentage()),
|
||||
|
@ -225,7 +256,7 @@ impl CompressorBankParams {
|
|||
factor: FloatRange::skew_factor(-2.0),
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_ratios.clone())
|
||||
.with_callback(set_update_downwards_ratios)
|
||||
.with_step_size(0.1)
|
||||
.with_value_to_string(formatters::v2s_compression_ratio(1))
|
||||
.with_string_to_value(formatters::s2v_compression_ratio()),
|
||||
|
@ -238,7 +269,7 @@ impl CompressorBankParams {
|
|||
factor: FloatRange::skew_factor(-2.0),
|
||||
},
|
||||
)
|
||||
.with_callback(set_update_ratios)
|
||||
.with_callback(set_update_upwards_ratios)
|
||||
.with_step_size(0.1)
|
||||
.with_value_to_string(formatters::v2s_compression_ratio(1))
|
||||
.with_string_to_value(formatters::s2v_compression_ratio()),
|
||||
|
@ -300,11 +331,16 @@ impl CompressorBank {
|
|||
let complex_buffer_len = max_window_size / 2 + 1;
|
||||
|
||||
CompressorBank {
|
||||
should_update_thresholds: Arc::new(AtomicBool::new(true)),
|
||||
should_update_ratios: Arc::new(AtomicBool::new(true)),
|
||||
should_update_downwards_thresholds: Arc::new(AtomicBool::new(true)),
|
||||
should_update_upwards_thresholds: Arc::new(AtomicBool::new(true)),
|
||||
should_update_downwards_ratios: Arc::new(AtomicBool::new(true)),
|
||||
should_update_upwards_ratios: Arc::new(AtomicBool::new(true)),
|
||||
|
||||
downwards_thresholds: Vec::with_capacity(complex_buffer_len),
|
||||
upwards_thresholds: Vec::with_capacity(complex_buffer_len),
|
||||
downwards_ratios: Vec::with_capacity(complex_buffer_len),
|
||||
upwards_ratios: Vec::with_capacity(complex_buffer_len),
|
||||
|
||||
thresholds: Vec::with_capacity(complex_buffer_len),
|
||||
ratios: Vec::with_capacity(complex_buffer_len),
|
||||
envelopes: vec![Vec::with_capacity(complex_buffer_len); num_channels],
|
||||
}
|
||||
}
|
||||
|
@ -314,10 +350,15 @@ impl CompressorBank {
|
|||
pub fn update_capacity(&mut self, num_channels: usize, max_window_size: usize) {
|
||||
let complex_buffer_len = max_window_size / 2 + 1;
|
||||
|
||||
self.thresholds
|
||||
.reserve_exact(complex_buffer_len.saturating_sub(self.thresholds.len()));
|
||||
self.ratios
|
||||
.reserve_exact(complex_buffer_len.saturating_sub(self.ratios.len()));
|
||||
self.downwards_thresholds
|
||||
.reserve_exact(complex_buffer_len.saturating_sub(self.downwards_thresholds.len()));
|
||||
self.upwards_thresholds
|
||||
.reserve_exact(complex_buffer_len.saturating_sub(self.upwards_thresholds.len()));
|
||||
self.downwards_ratios
|
||||
.reserve_exact(complex_buffer_len.saturating_sub(self.downwards_ratios.len()));
|
||||
self.upwards_ratios
|
||||
.reserve_exact(complex_buffer_len.saturating_sub(self.upwards_ratios.len()));
|
||||
|
||||
self.envelopes.resize_with(num_channels, Vec::new);
|
||||
for envelopes in self.envelopes.iter_mut() {
|
||||
envelopes.reserve_exact(complex_buffer_len.saturating_sub(envelopes.len()));
|
||||
|
@ -330,15 +371,24 @@ impl CompressorBank {
|
|||
pub fn resize(&mut self, window_size: usize) {
|
||||
let complex_buffer_len = window_size / 2 + 1;
|
||||
|
||||
self.thresholds.resize(complex_buffer_len, 1.0);
|
||||
self.ratios.resize(complex_buffer_len, 1.0);
|
||||
self.downwards_thresholds.resize(complex_buffer_len, 1.0);
|
||||
self.upwards_thresholds.resize(complex_buffer_len, 1.0);
|
||||
self.downwards_ratios.resize(complex_buffer_len, 1.0);
|
||||
self.upwards_ratios.resize(complex_buffer_len, 1.0);
|
||||
|
||||
for envelopes in self.envelopes.iter_mut() {
|
||||
envelopes.resize(complex_buffer_len, 0.0);
|
||||
}
|
||||
|
||||
// The compressors need to be updated on the next processing cycle
|
||||
self.should_update_thresholds.store(true, Ordering::SeqCst);
|
||||
self.should_update_ratios.store(true, Ordering::SeqCst);
|
||||
self.should_update_downwards_thresholds
|
||||
.store(true, Ordering::SeqCst);
|
||||
self.should_update_upwards_thresholds
|
||||
.store(true, Ordering::SeqCst);
|
||||
self.should_update_downwards_ratios
|
||||
.store(true, Ordering::SeqCst);
|
||||
self.should_update_upwards_ratios
|
||||
.store(true, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
/// Clear out the envelope followers.
|
||||
|
|
Loading…
Reference in a new issue