Skip to main content

dirtydata_dsp_destruction/
lib.rs

1//! Destruction and Distortion Civilization
2
3pub struct BitCrush {
4    acc: f32,
5    count: f32,
6}
7
8impl BitCrush {
9    pub fn new() -> Self { Self { acc: 0.0, count: 0.0 } }
10    pub fn process(&mut self, input: f32, bits: f32, sr_div: f32) -> f32 {
11        // Bit reduction
12        let levels = 2.0f32.powf(bits.clamp(1.0, 24.0));
13        let out = (input * levels).round() / levels;
14        
15        // Sample rate reduction
16        self.count += 1.0;
17        if self.count >= sr_div.max(1.0) {
18            self.acc = out;
19            self.count = 0.0;
20        }
21        self.acc
22    }
23}
24
25pub struct WaveShaper {}
26
27impl WaveShaper {
28    pub fn process(&self, input: f32, amount: f32) -> f32 {
29        // Hard clipping with tanh flavoring
30        (input * (1.0 + amount)).tanh()
31    }
32}
33
34pub struct Pll {
35    phase: f32,
36    vco_freq: f32,
37}
38
39impl Pll {
40    pub fn new() -> Self { Self { phase: 0.0, vco_freq: 100.0 } }
41    pub fn process(&mut self, input: f32, lock_speed: f32, sample_rate: f32) -> f32 {
42        let vco_out = self.phase.sin();
43        let error = input * vco_out; // Phase detector
44        
45        // Update frequency based on error
46        self.vco_freq += error * lock_speed;
47        self.vco_freq = self.vco_freq.clamp(20.0, 5000.0);
48        
49        self.phase += 2.0 * std::f32::consts::PI * self.vco_freq / sample_rate;
50        if self.phase > std::f32::consts::PI * 2.0 { self.phase -= std::f32::consts::PI * 2.0; }
51        
52        vco_out
53    }
54}