From ed97aa806cf18f5ac441735f5894ffa8b945bf57 Mon Sep 17 00:00:00 2001 From: annieversary Date: Mon, 11 Oct 2021 23:27:34 +0200 Subject: [PATCH] [cronchy bits] make and implement crate --- README.md | 17 ++++++ crates/cronchy_bits/Cargo.toml | 12 +++++ crates/cronchy_bits/src/lib.rs | 99 ++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 crates/cronchy_bits/Cargo.toml create mode 100644 crates/cronchy_bits/src/lib.rs diff --git a/README.md b/README.md index 9e2dded..4a53330 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ the following is the current list of plugins - `opiate`: spectral morphing between two audio signals - `sample - 10/10`: sample rate changer - `lotr`: ring modulator +- `cronchy bits`: gay-forward bit crusher there's a bit of an explanation of each of the plugins below, but it's not a thorough documentation or a manual, it's just a bunch of notes i've written and a short description of the parameters @@ -343,6 +344,22 @@ ring modulator plugin params: - `modulation`: controls the modulation ammount. 0 for no modulation, 1 for full modulation +### cronchy bits + +bit crusher + +params: +- `cronch`: the ammount of bitcrushing. 1 is extreme crushing, 500 is basically no crushing +- `kind`: type of rounding to use in the crushing + +changing the kind will not affect the tone much, but it's still a nice option to have + +there's 4 available kinds: +- `[0.0, 0.25)`: round +- `[0.25, 0.5)`: truncate +- `[0.5, 0.75)`: ceiling +- `[0.75, 1.0)`: floor + ## 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. if you are fine with that, ig go ahead i'm not your mum diff --git a/crates/cronchy_bits/Cargo.toml b/crates/cronchy_bits/Cargo.toml new file mode 100644 index 0000000..1547c4d --- /dev/null +++ b/crates/cronchy_bits/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "cronchy_bits" +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/cronchy_bits/src/lib.rs b/crates/cronchy_bits/src/lib.rs new file mode 100644 index 0000000..749cfd1 --- /dev/null +++ b/crates/cronchy_bits/src/lib.rs @@ -0,0 +1,99 @@ +#![allow(incomplete_features)] +#![feature(generic_associated_types)] + +use baseplug::{Plugin, ProcessContext}; +use serde::{Deserialize, Serialize}; + +baseplug::model! { + #[derive(Debug, Serialize, Deserialize)] + struct CronchyBitsModel { + #[model(min = 1.0, max = 500.0)] + #[parameter(name = "cronch")] + cronch: f32, + #[model(min = 0.0, max = 1.0)] + #[parameter(name = "kind")] + kind: f32, + } +} + +impl Default for CronchyBitsModel { + fn default() -> Self { + Self { + cronch: 500.0, + kind: 0.0, + } + } +} + +struct CronchyBits; + +impl Plugin for CronchyBits { + const NAME: &'static str = "cronchy bits"; + const PRODUCT: &'static str = "cronchy bits"; + const VENDOR: &'static str = "unnieversal"; + + const INPUT_CHANNELS: usize = 2; + const OUTPUT_CHANNELS: usize = 2; + + type Model = CronchyBitsModel; + + #[inline] + fn new(_sample_rate: f32, _model: &CronchyBitsModel) -> Self { + Self + } + + #[inline] + fn process(&mut self, model: &CronchyBitsModelProcess, ctx: &mut ProcessContext) { + let input = &ctx.inputs[0].buffers; + let output = &mut ctx.outputs[0].buffers; + + for i in 0..ctx.nframes { + let cronch = model.cronch[i]; + let cronch_inv = 1.0 / cronch; + + let l = input[0][i]; + let r = input[1][i]; + + match model.kind[0].into() { + Kind::Round => { + output[0][i] = l.signum() * (l.abs() * cronch).round() * cronch_inv; + output[1][i] = r.signum() * (r.abs() * cronch).round() * cronch_inv; + } + Kind::Trunc => { + output[0][i] = l.signum() * (l.abs() * cronch).trunc() * cronch_inv; + output[1][i] = r.signum() * (r.abs() * cronch).trunc() * cronch_inv; + } + Kind::Ciel => { + output[0][i] = l.signum() * (l.abs() * cronch).ceil() * cronch_inv; + output[1][i] = r.signum() * (r.abs() * cronch).ceil() * cronch_inv; + } + Kind::Floor => { + output[0][i] = l.signum() * (l.abs() * cronch).floor() * cronch_inv; + output[1][i] = r.signum() * (r.abs() * cronch).floor() * cronch_inv; + } + } + } + } +} + +enum Kind { + Round, + Trunc, + Ciel, + Floor, +} +impl From for Kind { + fn from(v: f32) -> Self { + if v < 0.25 { + Self::Round + } else if v < 0.5 { + Self::Trunc + } else if v < 0.75 { + Self::Ciel + } else { + Self::Floor + } + } +} + +baseplug::vst2!(CronchyBits, b"bits");