Skip to content

Instantly share code, notes, and snippets.

@flazz
Last active May 4, 2019 01:47
Show Gist options
  • Save flazz/57ebac8f459157b1d03f2d5b97217598 to your computer and use it in GitHub Desktop.
Save flazz/57ebac8f459157b1d03f2d5b97217598 to your computer and use it in GitHub Desktop.
[package]
name = "digidist"
version = "0.1.0"
authors = ["flazz"]
edition = "2018"
[dependencies]
vst = { git = "https://github.com/rust-dsp/rust-vst.git" }
rustfft = "3.0.0"
[lib]
crate-type = ["cdylib"]
#[macro_use]
extern crate vst;
use std::sync::Arc;
use vst::buffer::AudioBuffer;
use vst::plugin::{Category, Info, Plugin, PluginParameters};
use vst::util::AtomicFloat;
struct DigiDistParameters {
threshold: AtomicFloat,
}
struct DigiDist {
params: Arc<DigiDistParameters>,
}
impl Plugin for DigiDist {
fn get_info(&self) -> Info {
Info {
name: "DigiDist".to_string(),
vendor: "flazz.me".to_string(),
unique_id: 26092019,
version: 2,
inputs: 2,
outputs: 2,
parameters: 1,
category: Category::Effect,
// fill in the rest with the default values
// ..Info::default()
..Default::default()
}
}
fn process(&mut self, buffer: &mut AudioBuffer<f32>) {
let _threshold = self.params.threshold.get();
for (input_buffer, output_buffer) in buffer.zip() {
play(input_buffer, output_buffer);
// distort(threshold, input_buffer, output_buffer);
}
}
fn get_parameter_object(&mut self) -> Arc<dyn PluginParameters> {
Arc::clone(&self.params) as Arc<dyn PluginParameters>
}
}
use rustfft::num_complex::Complex;
use rustfft::num_traits::Zero;
use rustfft::FFTplanner;
fn play(input_buffer: &[f32], output_buffer: &mut [f32]) {
let n_samples = input_buffer.len();
let n_fft_bins = n_samples;
println!("A {:?} {:?}", n_samples, n_fft_bins);
// forward fft
let mut planner: FFTplanner<f32> = FFTplanner::new(false);
let fft = planner.plan_fft(input_buffer.len());
// inverse fft
let mut planner_inv: FFTplanner<f32> = FFTplanner::new(true);
let fft_inv = planner_inv.plan_fft(n_fft_bins);
// get input freq
let mut ic: Vec<Complex<f32>> = input_buffer.iter().map(Complex::from).collect();
println!("B {:?}", [input_buffer[0], input_buffer[2], input_buffer[2]]);
let mut input_freq = vec![Complex::zero(); n_fft_bins];
fft.process(ic.as_mut_slice(), input_freq.as_mut_slice());
println!("C {:?}", [input_freq[0], input_freq[2], input_freq[2]]);
// do stuff with frequency
// let filter = vec![Complex:zero(); n_fft_bins];
let mut output_freq = vec![Complex::zero(); n_fft_bins];
for i in 0..output_freq.len() {
output_freq[i] = input_freq[i];
}
println!("D {:?}", [output_freq[0], output_freq[2], output_freq[2]]);
let mut oc = vec![Complex::zero(); n_fft_bins];
fft_inv.process(output_freq.as_mut_slice(), oc.as_mut_slice());
println!("E {:?}", [oc[0], oc[2], oc[2]]);
oc.iter().enumerate().for_each(|(i,x)| output_buffer[i] = x.re);
println!()
}
fn distort(threshold: f32, input_buffer: &[f32], output_buffer: &mut [f32]) {
for (input_sample, output_sample) in input_buffer.iter().zip(output_buffer) {
*output_sample = if *input_sample > 0.0 {
input_sample.min(threshold) / threshold
} else {
input_sample.max(-threshold) / threshold
};
}
}
impl PluginParameters for DigiDistParameters {
fn get_parameter(&self, index: i32) -> f32 {
match index {
0 => self.threshold.get(),
_ => 0.0,
}
}
fn set_parameter(&self, index: i32, value: f32) {
match index {
0 => self.threshold.set(value.max(0.01)),
_ => (),
}
}
fn get_parameter_name(&self, index: i32) -> String {
match index {
0 => "Threshold".to_string(),
_ => "".to_string(),
}
}
fn get_parameter_text(&self, index: i32) -> String {
match index {
// Convert to a percentage
0 => format!("{}", self.threshold.get() * 100.0),
_ => "".to_string(),
}
}
fn get_parameter_label(&self, index: i32) -> String {
match index {
0 => "%".to_string(),
_ => "".to_string(),
}
}
}
impl Default for DigiDist {
fn default() -> DigiDist {
DigiDist {
params: Arc::new(DigiDistParameters::default()),
}
}
}
impl Default for DigiDistParameters {
fn default() -> DigiDistParameters {
DigiDistParameters {
threshold: AtomicFloat::new(0.25),
}
}
}
plugin_main!(DigiDist);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment