Compare commits

...

2 Commits

Author SHA1 Message Date
annieversary 3cce56550e dctortion 2022-12-17 01:22:34 +01:00
annieversary ed97aa806c [cronchy bits] make and implement crate 2021-10-11 23:27:34 +02:00
5 changed files with 191 additions and 0 deletions

View File

@ -69,6 +69,7 @@ the following is the current list of plugins
- `opiate`: spectral morphing between two audio signals - `opiate`: spectral morphing between two audio signals
- `sample - 10/10`: sample rate changer - `sample - 10/10`: sample rate changer
- `lotr`: ring modulator - `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 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: params:
- `modulation`: controls the modulation ammount. 0 for no modulation, 1 for full modulation - `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 ## 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 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

View File

@ -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" }

View File

@ -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<Self>) {
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<f32> 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");

View File

@ -0,0 +1,12 @@
[package]
name = "dctortion"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
baseplug = { git = "https://github.com/wrl/baseplug.git", rev = "9cec68f31cca9c0c7a1448379f75d92bbbc782a8" }
serde = "1.0.126"
utils = { path = "../utils" }

View File

@ -0,0 +1,51 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
use baseplug::{Plugin, ProcessContext};
use serde::{Deserialize, Serialize};
baseplug::model! {
#[derive(Debug, Serialize, Deserialize)]
struct GainModel {
#[model(min = 0.0, max = 1.0)]
#[parameter(name = "offset")]
offset: f32,
}
}
impl Default for GainModel {
fn default() -> Self {
Self { offset: 0.0 }
}
}
struct Gain;
impl Plugin for Gain {
const NAME: &'static str = "dctortion";
const PRODUCT: &'static str = "dctortion";
const VENDOR: &'static str = "unnieversal";
const INPUT_CHANNELS: usize = 2;
const OUTPUT_CHANNELS: usize = 2;
type Model = GainModel;
#[inline]
fn new(_sample_rate: f32, _model: &GainModel) -> Self {
Self
}
#[inline]
fn process(&mut self, model: &GainModelProcess, ctx: &mut ProcessContext<Self>) {
let input = &ctx.inputs[0].buffers;
let output = &mut ctx.outputs[0].buffers;
for i in 0..ctx.nframes {
output[0][i] = input[0][i] + model.offset[i];
output[1][i] = input[1][i] - model.offset[i];
}
}
}
baseplug::vst2!(Gain, b"tAnE");