unnieversal/crates/threebandwidth/src/lib.rs

107 lines
2.9 KiB
Rust

#![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 ThreeBandWidthModel {
#[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 ThreeBandWidthModel {
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 = ThreeBandWidthModel;
#[inline]
fn new(_sample_rate: f32, _model: &ThreeBandWidthModel) -> Self {
// Default cause we want to start with 0s in everything
Self::default()
}
#[inline]
fn process(&mut self, model: &ThreeBandWidthModelProcess, ctx: &mut ProcessContext<Self>) {
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");