[reverter] create and implement crate

main
annieversary 2021-08-05 18:04:27 +02:00
parent 7b004c8e38
commit 59b3b9c822
3 changed files with 102 additions and 0 deletions

View File

@ -63,6 +63,7 @@ the following is the current list of plugins
- `threebandfolding`: 3 band wave folding distortion
- `double_reverse_delta_inverter`: idk, a weird distortion
- `transmute_pitch`: pitch to midi converter
- `reverter`: play sound backwards
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
@ -252,6 +253,17 @@ aside from that, it works well enough on my quick tests
you can use it to play synths using other instruments, like a guitar, or by whistling! it's quite fun
### reverter
records small grains of audio and plays them backwards
params:
- `length`: length of the grains
this plugin will introduce a delay of `length` samples, since it has to record that many samples before being able to play them backwards
in my experience values between 5000 and 8000 tend to work well, but you might want to experiment a bit to see what works for you
## 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

View File

@ -0,0 +1,13 @@
[package]
name = "reverter"
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,77 @@
#![allow(incomplete_features)]
#![feature(generic_associated_types)]
use baseplug::{Plugin, ProcessContext};
use serde::{Deserialize, Serialize};
use utils::buffers::*;
// If you change this remember to change the max on the model
const LEN: usize = 48000;
baseplug::model! {
#[derive(Debug, Serialize, Deserialize)]
struct ReverterModel {
#[model(min = 10.0, max = 48000.0)]
#[parameter(name = "length")]
length: f32,
}
}
impl Default for ReverterModel {
fn default() -> Self {
Self { length: 1.0 }
}
}
struct Reverter {
recording: Buffers<LEN>,
playing: Buffers<LEN>,
}
impl Plugin for Reverter {
const NAME: &'static str = "reverter";
const PRODUCT: &'static str = "reverter";
const VENDOR: &'static str = "unnieversal";
const INPUT_CHANNELS: usize = 2;
const OUTPUT_CHANNELS: usize = 2;
type Model = ReverterModel;
#[inline]
fn new(_sample_rate: f32, _model: &ReverterModel) -> Self {
Self {
recording: Buffers::<LEN>::new(),
playing: Buffers::<LEN>::new(),
}
}
#[inline]
fn process(&mut self, model: &ReverterModelProcess, ctx: &mut ProcessContext<Self>) {
let input = &ctx.inputs[0].buffers;
let output = &mut ctx.outputs[0].buffers;
for i in 0..ctx.nframes {
let len = model.length[i].floor() as usize;
// add to recording buffer
let finished = self.recording.write_advance(input[0][i], input[1][i]);
// we read from the playing buffer at the inverse of the recording buffer
// this ensures the two don't go out of sync
let (l, r) = self.playing.read_at(len - self.recording.idx);
// if we're done, swap the two buffers and reset the index
if finished || self.recording.idx >= len {
self.recording.reset();
std::mem::swap(&mut self.recording, &mut self.playing);
}
output[0][i] = l;
output[1][i] = r;
}
}
}
baseplug::vst2!(Reverter, b"reve");