Skip to content

Commit

Permalink
Fixed velocity modulation, reorganized modulation stacking, fixed fil…
Browse files Browse the repository at this point in the history
…ter modulation inconsistency, and ran cargo fmt
  • Loading branch information
ardura committed Jan 25, 2024
1 parent f727f15 commit dee1d01
Show file tree
Hide file tree
Showing 8 changed files with 798 additions and 571 deletions.
306 changes: 83 additions & 223 deletions src/audio_module.rs

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions src/fx.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
pub(crate) mod ArduraFilter;
pub(crate) mod StateVariableFilter;
pub(crate) mod VCFilter;
pub(crate) mod abass;
pub(crate) mod biquad_filters;
pub(crate) mod buffermodulator;
pub(crate) mod compressor;
pub(crate) mod delay;
pub(crate) mod ArduraFilter;
pub(crate) mod VCFilter;
pub(crate) mod flanger;
pub(crate) mod limiter;
pub(crate) mod phaser;
pub(crate) mod reverb;
pub(crate) mod saturation;
pub(crate) mod abass;
59 changes: 38 additions & 21 deletions src/fx/ArduraFilter.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::f32::consts::PI;
use nih_plug::params::enums::Enum;
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
use std::f32::consts::PI;

// Inspired by https://www.musicdsp.org/en/latest/Filters/267-simple-tilt-equalizer.html
// Lowpass, Bandpass, Highpass based off tilt filter code
Expand All @@ -12,7 +12,7 @@ const SLOPE_NEG: f32 = -60.0;
pub enum ResponseType {
Lowpass,
Bandpass,
Highpass
Highpass,
}

#[derive(Serialize, Deserialize, Clone)]
Expand Down Expand Up @@ -50,19 +50,19 @@ impl ArduraFilter {
ResponseType::Lowpass => {
lgain = f32::exp(0.0 / amp) - 1.0;
hgain = f32::exp(SLOPE_NEG / amp) - 1.0;
},
}
ResponseType::Bandpass => {
lgain = f32::exp(0.0 / amp) - 1.0;
hgain = f32::exp(SLOPE_NEG / amp) - 1.0;
},
}
ResponseType::Highpass => {
lgain = f32::exp(SLOPE_NEG / amp) - 1.0;
hgain = f32::exp(0.0 / amp) - 1.0;
},
}
}

let omega = 2.0 * PI * center_freq;
let n = 1.0 / (Self::scale_range(steepness,0.98,1.2) * (sample_rate_x3 + omega));
let n = 1.0 / (Self::scale_range(steepness, 0.98, 1.2) * (sample_rate_x3 + omega));
let a0 = 2.0 * omega * n;
let b1 = (sample_rate_x3 - omega) * n;
let lp_out = 0.0; // Initial value for lp_out
Expand All @@ -87,7 +87,13 @@ impl ArduraFilter {
}
}

pub fn update(&mut self, sample_rate: f32, center_freq: f32, steepness: f32, shape: ResponseType) {
pub fn update(
&mut self,
sample_rate: f32,
center_freq: f32,
steepness: f32,
shape: ResponseType,
) {
let mut recalculate = false;
if self.sample_rate != sample_rate {
self.sample_rate = sample_rate;
Expand All @@ -111,34 +117,42 @@ impl ArduraFilter {
match self.shape {
ResponseType::Lowpass => {
let omega = 2.0 * PI * center_freq;
let n = 1.0 / (Self::scale_range(self.steepness,0.98,1.2) * (self.sample_rate_x3 + omega));
let n = 1.0
/ (Self::scale_range(self.steepness, 0.98, 1.2)
* (self.sample_rate_x3 + omega));
self.b1 = (self.sample_rate_x3 - omega) * n;
self.lgain = f32::exp(0.0 / amp) - 1.0;
self.hgain = f32::exp(SLOPE_NEG / amp) - 1.0;
},
}
ResponseType::Bandpass => {
let width = self.steepness * self.steepness * 500.0;
let l_omega = 2.0 * PI * (self.center_freq - width).clamp(20.0,16000.0);
let l_n = 1.0 / (Self::scale_range(self.steepness,0.98,1.2) * (self.sample_rate_x3 + l_omega));
let l_omega = 2.0 * PI * (self.center_freq - width).clamp(20.0, 16000.0);
let l_n = 1.0
/ (Self::scale_range(self.steepness, 0.98, 1.2)
* (self.sample_rate_x3 + l_omega));
self.band_a0_low = 2.0 * l_omega * l_n;
self.band_b1_low = (self.sample_rate_x3 - l_omega) * l_n;

let h_omega = 2.0 * PI * (self.center_freq + width).clamp(20.0,16000.0);
let h_n = 1.0 / (Self::scale_range(self.steepness,0.98,1.2) * (self.sample_rate_x3 + h_omega));

let h_omega = 2.0 * PI * (self.center_freq + width).clamp(20.0, 16000.0);
let h_n = 1.0
/ (Self::scale_range(self.steepness, 0.98, 1.2)
* (self.sample_rate_x3 + h_omega));
self.band_a0_high = 2.0 * h_omega * h_n;
self.band_b1_high = (self.sample_rate_x3 - h_omega) * h_n;

self.lgain = f32::exp(0.0 / amp) - 1.0;
self.hgain = f32::exp(SLOPE_NEG / amp) - 1.0;
},
}
ResponseType::Highpass => {
let omega = 2.0 * PI * center_freq;
let n = 1.0 / (Self::scale_range(self.steepness,0.98,1.2) * (self.sample_rate_x3 + omega));
let n = 1.0
/ (Self::scale_range(self.steepness, 0.98, 1.2)
* (self.sample_rate_x3 + omega));
self.a0 = 2.0 * omega * n;
self.b1 = (self.sample_rate_x3 - omega) * n;
self.lgain = f32::exp(SLOPE_NEG / amp) - 1.0;
self.hgain = f32::exp(0.0 / amp) - 1.0;
},
}
}
}
}
Expand All @@ -148,10 +162,13 @@ impl ArduraFilter {
// Process the input using the tilt equalizer logic
if self.shape == ResponseType::Bandpass {
self.band_out_low = self.band_a0_low * input + self.band_b1_low * self.band_out_low;
let temp = input + self.hgain * self.band_out_low + self.lgain * (input - self.band_out_low);

let temp =
input + self.hgain * self.band_out_low + self.lgain * (input - self.band_out_low);

self.band_out_high = self.band_a0_high * temp + self.band_b1_high * self.band_out_high;
temp + self.lgain * self.band_out_high + self.hgain * (temp - self.band_out_high) + denorm
temp + self.lgain * self.band_out_high
+ self.hgain * (temp - self.band_out_high)
+ denorm
} else {
self.lp_out = self.a0 * input + self.b1 * self.lp_out;
input + self.lgain * self.lp_out + self.hgain * (input - self.lp_out) + denorm
Expand Down
14 changes: 7 additions & 7 deletions src/fx/StateVariableFilter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ impl StateVariableFilter {
match resonance_mode {
ResonanceType::Default | ResonanceType::Bump => {
self.q = q.clamp(0.13, 1.0);
},
ResonanceType::Moog | ResonanceType::TB | ResonanceType::Arp => {
self.q = q.clamp(0.0, 1.0);
},
ResonanceType::Res | ResonanceType::Powf => {
self.q = q.clamp(0.0, 1.0);
},
}
ResonanceType::Moog | ResonanceType::TB | ResonanceType::Arp => {
self.q = q.clamp(0.0, 1.0);
}
ResonanceType::Res | ResonanceType::Powf => {
self.q = q.clamp(0.0, 1.0);
}
}
}
if frequency != self.frequency {
Expand Down
28 changes: 14 additions & 14 deletions src/fx/VCFilter.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use nih_plug::params::enums::Enum;
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};

// Rust port of https://www.musicdsp.org/en/latest/Filters/24-moog-vcf.html
// Ardura
Expand All @@ -8,7 +8,7 @@ use serde::{Serialize, Deserialize};
pub enum ResponseType {
Lowpass,
Bandpass,
Highpass
Highpass,
}

pub struct VCFilter {
Expand Down Expand Up @@ -42,7 +42,13 @@ impl VCFilter {
}
}

pub fn update(&mut self, center_freq: f32, resonance: f32, shape: ResponseType, sample_rate: f32) {
pub fn update(
&mut self,
center_freq: f32,
resonance: f32,
shape: ResponseType,
sample_rate: f32,
) {
let mut recalculate = false;
if self.center_freq != center_freq {
self.center_freq = center_freq;
Expand All @@ -60,7 +66,7 @@ impl VCFilter {
recalculate = true;
}
if recalculate {
self.f = 2.0 * self.center_freq/self.sample_rate;
self.f = 2.0 * self.center_freq / self.sample_rate;
self.k = 3.6 * self.f - 1.6 * self.f * self.f - 1.0;
self.p = (self.k + 1.0) * 0.5;
//let scale = (1.0 - self.p).exp() * 1.386249;
Expand All @@ -75,21 +81,15 @@ impl VCFilter {
self.y[1] = self.y[0] * self.p + self.olds[1] * self.p - self.k * self.y[1];
self.y[2] = self.y[1] * self.p + self.olds[2] * self.p - self.k * self.y[2];
self.y[3] = self.y[2] * self.p + self.olds[3] * self.p - self.k * self.y[3];
self.y[3] = self.y[3] - (self.y[3].powf(3.0))/6.0;
self.y[3] = self.y[3] - (self.y[3].powf(3.0)) / 6.0;
self.olds[0] = x;
self.olds[1] = self.y[0];
self.olds[2] = self.y[1];
self.olds[3] = self.y[2];
match self.shape {
ResponseType::Lowpass => {
self.y[3]
},
ResponseType::Highpass => {
self.y[3] - input
},
ResponseType::Bandpass => {
self.y[3] - (self.y[3] - input)
}
ResponseType::Lowpass => self.y[3],
ResponseType::Highpass => self.y[3] - input,
ResponseType::Bandpass => self.y[3] - (self.y[3] - input),
}
}
}
34 changes: 16 additions & 18 deletions src/fx/abass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,31 @@ pub fn a_bass_saturation(signal: f32, harmonic_strength: f32) -> f32 {
for j in 1..=num_harmonics {
match j {
1 => {
let harmonic_component: f32 = harmonic_strength * 170.0 * (signal * j as f32).cos() - signal;
let harmonic_component: f32 =
harmonic_strength * 170.0 * (signal * j as f32).cos() - signal;
summed += harmonic_component;
},
}
2 => {
let harmonic_component: f32 = harmonic_strength * 25.0 * (signal * j as f32).sin() - signal;
let harmonic_component: f32 =
harmonic_strength * 25.0 * (signal * j as f32).sin() - signal;
summed += harmonic_component;
},
}
3 => {
let harmonic_component: f32 = harmonic_strength * 150.0 * (signal * j as f32).cos() - signal;
let harmonic_component: f32 =
harmonic_strength * 150.0 * (signal * j as f32).cos() - signal;
summed += harmonic_component;
},
}
4 => {
let harmonic_component2: f32 = harmonic_strength * 80.0 * (signal * j as f32).sin() - signal;
let harmonic_component2: f32 =
harmonic_strength * 80.0 * (signal * j as f32).sin() - signal;
summed += harmonic_component2;
},
_ => unreachable!()
}
_ => unreachable!(),
}
}
if harmonic_strength > 0.0
{
if harmonic_strength > 0.0 {
chebyshev_tape(summed, 0.04) * util::db_to_gain(-9.0)
}
else {
} else {
0.0
}
}
Expand All @@ -46,10 +48,6 @@ fn chebyshev_tape(sample: f32, drive: f32) -> f32 {
let x3 = x * x2;
let x5 = x3 * x2;
let x6 = x3 * x3;
let y = x
- 0.166667 * x3
+ 0.00833333 * x5
- 0.000198413 * x6
+ 0.0000000238 * x6 * drive;
let y = x - 0.166667 * x3 + 0.00833333 * x5 - 0.000198413 * x6 + 0.0000000238 * x6 * drive;
dry * sample + (1.0 - dry) * y / (1.0 + y.abs())
}
12 changes: 6 additions & 6 deletions src/fx/saturation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Based off the Duro Console Saturations
// Ardura 2023

use nih_plug::{params::enums::Enum};
use nih_plug::params::enums::Enum;
use serde::{Deserialize, Serialize};
use std::f32::consts::PI;

Expand Down Expand Up @@ -44,31 +44,31 @@ impl Saturation {
// Apply the transfer curve to the input sample
output_l = transfer(input_l);
output_r = transfer(input_r);
},
}
SaturationType::Clip => {
let clipped = input_l.signum();
// Mix clipped signal with original
output_l = input_l * (1.0 - amount) + clipped * amount;
output_r = input_r * (1.0 - amount) + clipped * amount;
},
}
SaturationType::SinPow => {
let transfer = |x: f32| -> f32 { (x * (idrive)).sin().powf(2.0) };

output_l = transfer(input_l);
output_r = transfer(input_r);
},
}
SaturationType::Subtle => {
let transfer = |x: f32| -> f32 { ((idrive * (idrive * PI * x).cos()) / 4.0) + x };

output_l = transfer(input_l);
output_r = transfer(input_r);
},
}
SaturationType::Sine => {
let transfer = |x: f32| -> f32 { x.signum() * (x.abs() + idrive).sin() };

output_l = transfer(input_l);
output_r = transfer(input_r);
},
}
}

(output_l, output_r)
Expand Down

0 comments on commit dee1d01

Please sign in to comment.