diff --git a/plugins/aw_soft_vacuum/src/lib.rs b/plugins/aw_soft_vacuum/src/lib.rs index 3698d24f..d4599367 100644 --- a/plugins/aw_soft_vacuum/src/lib.rs +++ b/plugins/aw_soft_vacuum/src/lib.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . +use std::f32::consts::PI; use std::sync::Arc; use nih_plug::prelude::*; @@ -28,12 +29,78 @@ struct SoftVacuum { hard_vacuum_processors: Vec, } +// The parameters are the same as in the original plugin, except that they have different value +// names #[derive(Params)] -struct SoftVacuumParams {} +struct SoftVacuumParams { + /// The drive/multistage parameter. Goes from `[0, 2]`, which is displayed as `0%` through + /// `200%`. Above 100% up to four distortion stages are applied. + #[id = "drive"] + drive: FloatParam, + /// The 'warmth' DC bias parameter. Shown as a percentage in this version. + #[id = "warmth"] + warmth: FloatParam, + /// The 'aura' parameter which is essentially extra input gain. Shown as a percentage, but maps + /// to a `[0, pi]` value. + #[id = "aura"] + aura: FloatParam, + + /// The output gain, shown in decibel. + #[id = "output_gain"] + pub output_gain: FloatParam, + /// A linear dry/wet mix parameter. + #[id = "dry_wet_ratio"] + pub dry_wet_ratio: FloatParam, +} impl Default for SoftVacuumParams { fn default() -> Self { - Self {} + Self { + // Goes up to 200%, with the second half being nonlinear + drive: FloatParam::new("Drive", 0.0, FloatRange::Linear { min: 0.0, max: 2.0 }) + .with_unit("%") + .with_smoother(SmoothingStyle::Linear(20.0)) + .with_value_to_string(formatters::v2s_f32_percentage(0)) + .with_string_to_value(formatters::s2v_f32_percentage()), + warmth: FloatParam::new("Warmth", 0.0, FloatRange::Linear { min: 0.0, max: 1.0 }) + .with_unit("%") + .with_smoother(SmoothingStyle::Linear(10.0)) + .with_value_to_string(formatters::v2s_f32_percentage(0)) + .with_string_to_value(formatters::s2v_f32_percentage()), + aura: FloatParam::new("Aura", 0.0, FloatRange::Linear { min: 0.0, max: PI }) + .with_unit("%") + .with_smoother(SmoothingStyle::Linear(10.0)) + // We're displaying the value as a percentage even though it goes from `[0, pi]` + .with_value_to_string({ + let formatter = formatters::v2s_f32_percentage(0); + Arc::new(move |value| formatter(value / PI)) + }) + .with_string_to_value({ + let formatter = formatters::s2v_f32_percentage(); + Arc::new(move |string| formatter(string).map(|value| value * PI)) + }), + + output_gain: FloatParam::new( + "Output Gain", + util::db_to_gain(0.0), + FloatRange::Skewed { + // This doesn't go down to 0.0 so we can use logarithmic smoothing + min: util::MINUS_INFINITY_GAIN, + max: util::db_to_gain(0.0), + factor: FloatRange::gain_skew_factor(util::MINUS_INFINITY_DB, 0.0), + }, + ) + .with_unit(" dB") + // The value does not go down to 0 so we can do logarithmic here + .with_smoother(SmoothingStyle::Logarithmic(10.0)) + .with_value_to_string(formatters::v2s_f32_gain_to_db(2)) + .with_string_to_value(formatters::s2v_f32_gain_to_db()), + dry_wet_ratio: FloatParam::new("Mix", 1.0, FloatRange::Linear { min: 0.0, max: 1.0 }) + .with_unit("%") + .with_smoother(SmoothingStyle::Linear(10.0)) + .with_value_to_string(formatters::v2s_f32_percentage(0)) + .with_string_to_value(formatters::s2v_f32_percentage()), + } } } @@ -107,18 +174,21 @@ impl Plugin for SoftVacuum { // TODO: Dry/wet mixing and output scaling // TODO: Oversampling for channel_samples in buffer.iter_samples() { + let output_gain = self.params.output_gain.smoothed.next(); + let dry_wet_ratio = self.params.dry_wet_ratio.smoothed.next(); + let hard_vacuum_params = hard_vacuum::Params { + drive: self.params.drive.smoothed.next(), + warmth: self.params.warmth.smoothed.next(), + aura: self.params.aura.smoothed.next(), + }; + for (sample, hard_vacuum) in channel_samples .into_iter() .zip(self.hard_vacuum_processors.iter_mut()) { - *sample = hard_vacuum.process( - *sample, - &hard_vacuum::Params { - drive: 2.0, - warmth: 0.0, - aura: 0.879_645_94, - }, - ); + let distorted = hard_vacuum.process(*sample, &hard_vacuum_params); + *sample = + (distorted * output_gain * dry_wet_ratio) + (*sample * (1.0 - dry_wet_ratio)); } }