diff --git a/plugins/aw_soft_vacuum/src/hard_vacuum.rs b/plugins/aw_soft_vacuum/src/hard_vacuum.rs new file mode 100644 index 00000000..f02b7e22 --- /dev/null +++ b/plugins/aw_soft_vacuum/src/hard_vacuum.rs @@ -0,0 +1,32 @@ +// Soft Vacuum: Airwindows Hard Vacuum port with oversampling +// Copyright (C) 2023 Robbert van der Helm +// Copyright (c) 2018 Chris Johnson +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +/// Single-channel port of the Hard Vacuum algorithm from +/// . +#[derive(Debug, Default)] +pub struct HardVacuum { + last_sample: f32, +} + +impl HardVacuum { + /// Reset the processor's state. In this case this only resets the discrete derivative + /// calculation. Doesn't make a huge difference but it's still useful to make the effect + /// deterministic. + pub fn reset(&mut self) { + self.last_sample = 0.0; + } +} diff --git a/plugins/aw_soft_vacuum/src/lib.rs b/plugins/aw_soft_vacuum/src/lib.rs index 66d1960d..1b3a79b9 100644 --- a/plugins/aw_soft_vacuum/src/lib.rs +++ b/plugins/aw_soft_vacuum/src/lib.rs @@ -18,8 +18,14 @@ use std::sync::Arc; use nih_plug::prelude::*; +mod hard_vacuum; + struct SoftVacuum { params: Arc, + + /// Stores implementations of the Hard Vacuum algorithm for each channel, since each channel + /// needs to maintain its own state. + hard_vacuum_processors: Vec, } #[derive(Params)] @@ -35,6 +41,8 @@ impl Default for SoftVacuum { fn default() -> Self { Self { params: Arc::new(SoftVacuumParams::default()), + + hard_vacuum_processors: Vec::new(), } } } @@ -69,15 +77,24 @@ impl Plugin for SoftVacuum { fn initialize( &mut self, - _audio_io_layout: &AudioIOLayout, - buffer_config: &BufferConfig, + audio_io_layout: &AudioIOLayout, + _buffer_config: &BufferConfig, _context: &mut impl InitContext, ) -> bool { + let num_channels = audio_io_layout + .main_output_channels + .expect("Plugin was initialized without any outputs") + .get() as usize; + self.hard_vacuum_processors + .resize_with(num_channels, hard_vacuum::HardVacuum::default); + true } fn reset(&mut self) { - // TODO: + for hard_vacuum in &mut self.hard_vacuum_processors { + hard_vacuum.reset(); + } } fn process(