summaryrefslogtreecommitdiff
path: root/klangfarbrs/src/partial.rs
blob: 336f00570c77dc94627e3b7b3a87894351abbd28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
use super::{ Amplitude, Hz, Line, Millisecond, Osc, Sample, SamplesPerSecond };

pub struct Partial {
    amplitude: Amplitude,
    relative_duration: f32,
    relative_frequency: f32,
    detune: Hz,
    osc: Osc,
    attack: Line,
    decay: Line,
}

impl Partial {
    pub fn new(
        amplitude: Amplitude,
        relative_duration: f32,
        relative_frequency: f32,
        detune: Hz,
        sample_rate: SamplesPerSecond,
        base_duration: Millisecond,
        base_frequency: Hz,
    ) -> Self {
        let freq = base_frequency * relative_frequency + detune;
        let decay_duration = base_duration as f32 * relative_duration;

        Self {
            amplitude, relative_duration, relative_frequency, detune,
            osc: Osc::new(freq, sample_rate),
            attack: Line::new(0.0, amplitude, 5, sample_rate),
            decay: Line::new(amplitude, 0.0, decay_duration as u32, sample_rate),
        }
    }
}

impl Iterator for Partial {
    type Item = Sample;

    fn next(&mut self) -> Option<Self::Item> {
        let amplitude = match self.attack.next() {
            Some(amp) => Some(amp),
            None => self.decay.next()
        };

        match amplitude {
            Some(amp) => Some(self.osc.next().unwrap() * amp),
            None => None
        }
    }
}