firefly_audio/
sources.rs

1//! Processors that have 0 inputs and produce new values.
2//!
3//! Includes oscillators, file readers, audio samples, etc.
4use crate::*;
5use alloc::vec::Vec;
6use micromath::F32Ext;
7
8/// A sound source that is always stopped.
9pub struct Empty {}
10
11impl Empty {
12    #[must_use]
13    pub const fn new() -> Self {
14        Self {}
15    }
16}
17
18impl Processor for Empty {
19    fn process_children(&mut self, _cn: &mut Vec<Node>) -> Option<Frame> {
20        None
21    }
22}
23
24/// A sound source that produces zeros. Forever.
25pub struct Zero {}
26
27impl Zero {
28    #[must_use]
29    pub const fn new() -> Self {
30        Self {}
31    }
32}
33
34impl Processor for Zero {
35    fn process_children(&mut self, _cn: &mut Vec<Node>) -> Option<Frame> {
36        Some(Frame::zero())
37    }
38}
39
40/// Sine wave oscillator.
41pub struct Sine {
42    step: f32,
43    phase: f32,
44    initial_phase: f32,
45}
46
47impl Sine {
48    #[must_use]
49    pub fn new(freq: f32, phase: f32) -> Self {
50        Self {
51            step: freq * SAMPLE_DURATION,
52            phase,
53            initial_phase: phase,
54        }
55    }
56}
57
58impl Processor for Sine {
59    fn reset(&mut self) {
60        self.phase = self.initial_phase;
61    }
62
63    fn set(&mut self, param: u8, val: f32) {
64        if param == 0 {
65            self.step = val * SAMPLE_DURATION;
66        }
67    }
68
69    fn process_children(&mut self, _cn: &mut Vec<Node>) -> Option<Frame> {
70        let mut element = [0f32; 8];
71        let mut phase = self.phase;
72        for sample in &mut element {
73            *sample = phase;
74            phase = F32Ext::fract(phase + self.step);
75        }
76        self.phase = phase;
77        let element = Sample::new(element);
78        let s = element * Sample::TAU;
79        let s = s.sin();
80        Some(Frame::mono(s))
81    }
82}
83
84/// Square wave oscillator.
85pub struct Square {
86    step: f32,
87    phase: f32,
88    initial_phase: f32,
89}
90
91impl Square {
92    #[must_use]
93    pub fn new(freq: f32, phase: f32) -> Self {
94        Self {
95            step: freq * SAMPLE_DURATION,
96            phase,
97            initial_phase: phase,
98        }
99    }
100}
101
102impl Processor for Square {
103    fn reset(&mut self) {
104        self.phase = self.initial_phase;
105    }
106
107    fn set(&mut self, param: u8, val: f32) {
108        if param == 0 {
109            self.step = val * SAMPLE_DURATION;
110        }
111    }
112
113    fn process_children(&mut self, _cn: &mut Vec<Node>) -> Option<Frame> {
114        let mut samples = [0f32; 8];
115        let mut phase = self.phase;
116        for sample in &mut samples {
117            let dec = F32Ext::fract(phase);
118            *sample = if dec >= 0.5 { 1. } else { -1. };
119            phase = F32Ext::fract(phase + self.step);
120        }
121        self.phase = phase;
122        let s = Sample::new(samples);
123        Some(Frame::mono(s))
124    }
125}
126
127/// Sawtooth wave oscillator.
128pub struct Sawtooth {
129    step: f32,
130    phase: f32,
131    initial_phase: f32,
132}
133
134impl Sawtooth {
135    #[must_use]
136    pub fn new(freq: f32, phase: f32) -> Self {
137        Self {
138            step: freq * SAMPLE_DURATION,
139            phase,
140            initial_phase: phase,
141        }
142    }
143}
144
145impl Processor for Sawtooth {
146    fn reset(&mut self) {
147        self.phase = self.initial_phase;
148    }
149
150    fn set(&mut self, param: u8, val: f32) {
151        if param == 0 {
152            self.step = val * SAMPLE_DURATION;
153        }
154    }
155
156    fn process_children(&mut self, _cn: &mut Vec<Node>) -> Option<Frame> {
157        let mut samples = [0f32; 8];
158        let mut phase = self.phase;
159        for sample in &mut samples {
160            *sample = phase;
161            phase = F32Ext::fract(phase + self.step);
162        }
163        self.phase = phase;
164        let s = Sample::new(samples);
165        let s = s * 2. - 1.;
166        Some(Frame::mono(s))
167    }
168}
169
170/// Triangle wave oscillator.
171pub struct Triangle {
172    step: f32,
173    phase: f32,
174    initial_phase: f32,
175}
176
177impl Triangle {
178    #[must_use]
179    pub fn new(freq: f32, phase: f32) -> Self {
180        Self {
181            step: freq * SAMPLE_DURATION,
182            phase,
183            initial_phase: phase,
184        }
185    }
186}
187
188impl Processor for Triangle {
189    fn reset(&mut self) {
190        self.phase = self.initial_phase;
191    }
192
193    fn set(&mut self, param: u8, val: f32) {
194        if param == 0 {
195            self.step = val * SAMPLE_DURATION;
196        }
197    }
198
199    fn process_children(&mut self, _cn: &mut Vec<Node>) -> Option<Frame> {
200        let mut samples = [0f32; 8];
201        let mut phase = self.phase;
202        for sample in &mut samples {
203            *sample = phase;
204            phase = F32Ext::fract(phase + self.step);
205        }
206        self.phase = phase;
207        let s = Sample::new(samples);
208        let s = (s * 4. - 2.).abs() - 1.;
209        Some(Frame::mono(s))
210    }
211}
212
213/// Generate a white noise
214pub struct Noise {
215    prev: wide::i32x8,
216}
217
218impl Noise {
219    #[must_use]
220    pub const fn new(seed: i32) -> Self {
221        Self {
222            prev: wide::i32x8::new([
223                seed,
224                seed + 1,
225                seed + 2,
226                seed + 3,
227                seed + 4,
228                seed + 5,
229                seed + 6,
230                seed + 7,
231            ]),
232        }
233    }
234}
235
236impl Processor for Noise {
237    fn process_children(&mut self, _cn: &mut Vec<Node>) -> Option<Frame> {
238        // xorshift RNG algorithm
239        // TODO: spectogram shows that it might be not uniformly distributed.
240        let mut x = self.prev;
241        x ^= x << 13;
242        x ^= x >> 17;
243        x ^= x << 5;
244        self.prev = x;
245        let s = Sample::from_i32x8(x);
246        let s = s / i32::MAX as f32;
247        Some(Frame::mono(s))
248    }
249}
250
251// TODO: pulse (https://github.com/NibbleRealm/twang/blob/v0/src/osc/pulse.rs)