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