Compare commits

...

2 Commits

Author SHA1 Message Date
annieversary 59b3b9c822 [reverter] create and implement crate 2021-08-05 18:04:27 +02:00
annieversary 7b004c8e38 idk 2021-08-05 18:04:17 +02:00
6 changed files with 117 additions and 2 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
@ -261,3 +273,9 @@ issues and prs are welcome, but please open an issue before making any big pr, i
gpl3 or something, i need to check which one to use and the add the correct file
consider it gpl3 for now
## naming
uhhhh yeah cause the plugins are universal or something, but uni is spelled like annie. also sounds like 언니, which is fun
the plugins are named very lazily, it's just whatever name i could come up with before creating the crate, so yeah many are not good

View File

@ -9,3 +9,5 @@ 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,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");

View File

@ -140,7 +140,7 @@ impl Plugin for Sosten {
let idx = self.buffers.idx.min(len - 1);
// Play from Buffer
let (l, r) = self.buffers.read((LEN - len) + idx);
let (l, r) = self.buffers.read_at((LEN - len) + idx);
output[0][i] = l;
output[1][i] = r;

View File

@ -47,7 +47,12 @@ impl<const LEN: usize> Buffers<LEN> {
})
}
pub fn read(&self, idx: usize) -> (f32, f32) {
/// Reads buffer, advances idx, returns true if buffer is full
pub fn read(&self) -> (f32, f32) {
(self.l[self.idx], self.r[self.idx])
}
pub fn read_at(&self, idx: usize) -> (f32, f32) {
let idx = idx % LEN;
(self.l[idx], self.r[idx])
}