From 83ba18c99184ef01648de96c4a40954a889526a5 Mon Sep 17 00:00:00 2001 From: annieversary Date: Sat, 24 Jul 2021 23:44:27 +0200 Subject: [PATCH] [threebandwidth] create and implement crate --- README.md | 16 ++++- crates/threebandeq/src/lib.rs | 4 +- crates/threebandwidth/Cargo.toml | 13 ++++ crates/threebandwidth/src/lib.rs | 106 +++++++++++++++++++++++++++++++ crates/utils/src/threeband.rs | 2 + 5 files changed, 137 insertions(+), 4 deletions(-) create mode 100644 crates/threebandwidth/Cargo.toml create mode 100644 crates/threebandwidth/src/lib.rs diff --git a/README.md b/README.md index cad32fc..33d4737 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,7 @@ the following is the current list of plugins - robotuna: automatic pitch correction - hysteria: hysteresis nonlinear effect - threebandeq: 3 band eq +- threebandwidth: 3 band stereo widener ### basic_gain @@ -132,7 +133,7 @@ original source [here](https://ccrma.stanford.edu/~jatin/ComplexNonlinearities/H turn the values up for loud and distorted. don't set them all to the max at once though, that doesn't sound as interesting -### threebandeq [WIP] +### threebandeq simple three band equalizer @@ -145,6 +146,19 @@ parameters: low band goes from 0hz to `low band`, mid band goes from `low band` to `high band`, high band goes from `high band` to half the sample rate +### threebandwidth + +three band stereo widener + +parameters: +- `low band`: frequency at which the low band ends +- `high band`: frequency at which the high band starts +- `low width`: width for the low band +- `mid width`: width for the mid band +- `high width`: width for the high band + +bands work as they do in `threebandeq`. the width parameters control how wide an audio signal should be in the stereo field. `width` of 1 leaves the audio as is, `width` of 0 makes it mono, values between 0 and 1 decrease the stereo width, values over 1 increase it. + ## 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/threebandeq/src/lib.rs b/crates/threebandeq/src/lib.rs index 52989bd..1ab6aaf 100644 --- a/crates/threebandeq/src/lib.rs +++ b/crates/threebandeq/src/lib.rs @@ -1,8 +1,6 @@ #![allow(incomplete_features)] #![feature(generic_associated_types)] -// https://www.musicdsp.org/en/latest/Filters/236-3-band-equaliser.html - use baseplug::{Plugin, ProcessContext}; use serde::{Deserialize, Serialize}; @@ -108,4 +106,4 @@ impl Plugin for ThreeBandEq { } } -baseplug::vst2!(ThreeBandEq, b"tAnE"); +baseplug::vst2!(ThreeBandEq, b"3beq"); diff --git a/crates/threebandwidth/Cargo.toml b/crates/threebandwidth/Cargo.toml new file mode 100644 index 0000000..26ea031 --- /dev/null +++ b/crates/threebandwidth/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "threebandwidth" +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/threebandwidth/src/lib.rs b/crates/threebandwidth/src/lib.rs new file mode 100644 index 0000000..0ed9fb1 --- /dev/null +++ b/crates/threebandwidth/src/lib.rs @@ -0,0 +1,106 @@ +#![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 ThreeBandEqModel { + #[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 = 3.0)] + #[parameter(name = "low width")] + low_width: f32, + #[model(min = 0.0, max = 3.0)] + #[parameter(name = "mid width")] + mid_width: f32, + #[model(min = 0.0, max = 3.0)] + #[parameter(name = "high width")] + high_width: f32, + } +} + +impl Default for ThreeBandEqModel { + fn default() -> Self { + Self { + low_band: 800.0, + high_band: 5000.0, + + low_width: 1.0, + mid_width: 1.0, + high_width: 1.0, + } + } +} + +#[derive(Default)] +struct ThreeBandWidth { + l: ThreeBandSplitter, + r: ThreeBandSplitter, +} + +impl Plugin for ThreeBandWidth { + const NAME: &'static str = "threebandwidth"; + const PRODUCT: &'static str = "threebandwidth"; + const VENDOR: &'static str = "unnieversal"; + + const INPUT_CHANNELS: usize = 2; + const OUTPUT_CHANNELS: usize = 2; + + type Model = ThreeBandEqModel; + + #[inline] + fn new(_sample_rate: f32, _model: &ThreeBandEqModel) -> Self { + // Default cause we want to start with 0s in everything + Self::default() + } + + #[inline] + fn process(&mut self, model: &ThreeBandEqModelProcess, 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) = wide(model.low_width[i], low_l, low_r); + let (mid_l, mid_r) = wide(model.mid_width[i], mid_l, mid_r); + let (high_l, high_r) = wide(model.high_width[i], high_l, high_r); + + output[0][i] = low_l + mid_l + high_l; + output[1][i] = low_r + mid_r + high_r; + } + } +} + +// From https://www.musicdsp.org/en/latest/Effects/256-stereo-width-control-obtained-via-transfromation-matrix.html + +fn wide(width: f32, l: f32, r: f32) -> (f32, f32) { + let tmp = 1.0 / f32::max(1.0 + width, 2.0); + let coef_m = tmp; + let coef_s = width * tmp; + + let m = (l + r) * coef_m; + let s = (r - l) * coef_s; + + (m - s, m + s) +} + +baseplug::vst2!(ThreeBandWidth, b"3bsw"); diff --git a/crates/utils/src/threeband.rs b/crates/utils/src/threeband.rs index 1e7832e..89aedd3 100644 --- a/crates/utils/src/threeband.rs +++ b/crates/utils/src/threeband.rs @@ -1,3 +1,5 @@ +// https://www.musicdsp.org/en/latest/Filters/236-3-band-equaliser.html + /// Very small amount const VSA: f32 = 1.0 / 4294967295.0;