1
0
Fork 0

Split compressor params into up/downwards

This commit is contained in:
Robbert van der Helm 2022-07-22 17:29:23 +02:00
parent e68bb8d632
commit b8525cac4d

View file

@ -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.