Last active
May 4, 2019 01:47
-
-
Save flazz/57ebac8f459157b1d03f2d5b97217598 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[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"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#[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