diff --git a/README.md b/README.md index 844a385..6c908bd 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ the following is the current list of plugins - threebandeq: 3 band eq - threebandwidth: 3 band stereo widener - tritu: say-goodbye-to-your-audio distortion +- threebandfolding: 3 band wave folding distortion ### basic_gain @@ -173,6 +174,19 @@ distortion affects lower volumes more than higher volumes, so if you crank up `d i like this plugin a lot +### threebandfolding + +three band wavefolding distortion + +parameters: +- `low band`: frequency at which the low band ends +- `high band`: frequency at which the high band starts +- `low folding freq`: folding frequency for the low band +- `mid folding freq`: folding frequency for the mid band +- `high folding freq`: folding frequency for the high band + +bands work as they do in `threebandeq`. the `folding freq` parameters control the frequency of the wavefolding. higher is more distortion. use values over 40 if you want to hear white noise + ## contributing issues and prs are welcome, but please open an issue before making any big pr, i don't wanna have to reject a pr where you have put a lot of effort on diff --git a/crates/threebandfolding/Cargo.toml b/crates/threebandfolding/Cargo.toml new file mode 100644 index 0000000..bd5ca31 --- /dev/null +++ b/crates/threebandfolding/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "threebandfolding" +version = "0.1.0" +edition = "2018" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +baseplug = { git = "https://github.com/wrl/baseplug.git", rev = "9cec68f31cca9c0c7a1448379f75d92bbbc782a8" } +serde = "1.0.126" + +utils = { path = "../utils" } diff --git a/crates/threebandfolding/src/lib.rs b/crates/threebandfolding/src/lib.rs new file mode 100644 index 0000000..60437b5 --- /dev/null +++ b/crates/threebandfolding/src/lib.rs @@ -0,0 +1,100 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +use baseplug::{Plugin, ProcessContext}; +use serde::{Deserialize, Serialize}; + +use utils::threeband::*; + +baseplug::model! { + #[derive(Debug, Serialize, Deserialize)] + struct ThreeBandFoldingModel { + #[model(min = 0.0, max = 15000.0)] + #[parameter(name = "low band")] + low_band: f32, + #[model(min = 0.0, max = 15000.0)] + #[parameter(name = "mid band")] + high_band: f32, + + #[model(min = 0.0, max = 100.0)] + #[parameter(name = "low folding freq", gradient = "Power(3.0)")] + low_freq: f32, + #[model(min = 0.0, max = 100.0)] + #[parameter(name = "mid folding freq", gradient = "Power(3.0)")] + mid_freq: f32, + #[model(min = 0.0, max = 100.0)] + #[parameter(name = "high folding freq", gradient = "Power(3.0)")] + high_freq: f32, + } +} + +impl Default for ThreeBandFoldingModel { + fn default() -> Self { + Self { + low_band: 800.0, + high_band: 5000.0, + + low_freq: 1.0, + mid_freq: 1.0, + high_freq: 1.0, + } + } +} + +#[derive(Default)] +struct ThreeBandFolding { + l: ThreeBandSplitter, + r: ThreeBandSplitter, +} + +impl Plugin for ThreeBandFolding { + const NAME: &'static str = "threebandfolding"; + const PRODUCT: &'static str = "threebandfolding"; + const VENDOR: &'static str = "unnieversal"; + + const INPUT_CHANNELS: usize = 2; + const OUTPUT_CHANNELS: usize = 2; + + type Model = ThreeBandFoldingModel; + + #[inline] + fn new(_sample_rate: f32, _model: &ThreeBandFoldingModel) -> Self { + // Default cause we want to start with 0s in everything + Self::default() + } + + #[inline] + fn process(&mut self, model: &ThreeBandFoldingModelProcess, ctx: &mut ProcessContext) { + let input = &ctx.inputs[0].buffers; + let output = &mut ctx.outputs[0].buffers; + + let sr = ctx.sample_rate; + + for i in 0..ctx.nframes { + // frequencies + let lf = model.low_band[i]; + let hf = model.high_band[i]; + + // split into bands + let (low_l, mid_l, high_l) = self.l.process(input[0][i], lf, hf, sr); + let (low_r, mid_r, high_r) = self.r.process(input[1][i], lf, hf, sr); + + // widen each band + let (low_l, low_r) = fold(model.low_freq[i], low_l, low_r); + let (mid_l, mid_r) = fold(model.mid_freq[i], mid_l, mid_r); + let (high_l, high_r) = fold(model.high_freq[i], high_l, high_r); + + output[0][i] = low_l + mid_l + high_l; + output[1][i] = low_r + mid_r + high_r; + } + } +} + +fn fold(freq: f32, l: f32, r: f32) -> (f32, f32) { + let l = (l * freq).sin(); + let r = (r * freq).sin(); + + (l, r) +} + +baseplug::vst2!(ThreeBandFolding, b"3bsf");