Skip to main content

dirtydata_dsp_cv/
lib.rs

1//! CV and Logic Civilization
2
3pub struct Slew {
4    state: f32,
5}
6
7impl Slew {
8    pub fn new() -> Self { Self { state: 0.0 } }
9    pub fn process(&mut self, input: f32, rise: f32, fall: f32, sample_rate: f32) -> f32 {
10        let diff = input - self.state;
11        let rate = if diff > 0.0 { rise } else { fall };
12        // rate is time in seconds to reach target
13        let step = 1.0 / (rate.max(0.001) * sample_rate);
14        if diff.abs() < step {
15            self.state = input;
16        } else {
17            self.state += diff.signum() * step;
18        }
19        self.state
20    }
21}
22
23pub struct Comparator {
24    state: bool,
25}
26
27impl Comparator {
28    pub fn new() -> Self { Self { state: false } }
29    pub fn process(&mut self, input: f32, threshold: f32, hysteresis: f32) -> f32 {
30        if input > threshold + hysteresis {
31            self.state = true;
32        } else if input < threshold - hysteresis {
33            self.state = false;
34        }
35        if self.state { 1.0 } else { 0.0 }
36    }
37}
38
39pub struct ClockDivider {
40    count: u32,
41    prev_clock: f32,
42}
43
44impl ClockDivider {
45    pub fn new() -> Self { Self { count: 0, prev_clock: 0.0 } }
46    pub fn process(&mut self, clock: f32, divisor: u32) -> f32 {
47        if clock > 0.5 && self.prev_clock <= 0.5 {
48            self.count += 1;
49        }
50        self.prev_clock = clock;
51        if (self.count % divisor) == 0 && clock > 0.5 { 1.0 } else { 0.0 }
52    }
53}
54
55pub struct EuclideanSequencer {
56    pub steps: u32,
57    pub hits: u32,
58    pub offset: u32,
59    idx: u32,
60    prev_clock: f32,
61}
62
63impl EuclideanSequencer {
64    pub fn new() -> Self { Self { steps: 16, hits: 4, offset: 0, idx: 0, prev_clock: 0.0 } }
65    pub fn process(&mut self, clock: f32) -> f32 {
66        let mut trigger = 0.0;
67        if clock > 0.5 && self.prev_clock <= 0.5 {
68            let i = (self.idx + self.offset) % self.steps.max(1);
69            if ((i * self.hits) % self.steps.max(1)) < self.hits {
70                trigger = 1.0;
71            }
72            self.idx = (self.idx + 1) % self.steps.max(1);
73        }
74        self.prev_clock = clock;
75        trigger
76    }
77}