caw_utils/
noise.rs

1use caw_core::{Sig, SigT};
2use rand::{rngs::StdRng, Rng, SeedableRng};
3
4pub fn white() -> Sig<impl SigT<Item = f32>> {
5    let mut rng = StdRng::from_entropy();
6    Sig::from_fn(move |_| rng.gen::<f32>() * 2. - 1.)
7}
8
9/// Approximation of brown noise made by integrating white noise with a leaky integrator and
10/// hand-tuning.
11pub fn brown() -> Sig<impl SigT<Item = f32>> {
12    let mut total = 0.;
13    white().map_mut(move |x| {
14        total = (total * 0.99) + (x * 0.1);
15        total
16    })
17}
18
19/// Based on some of the code snippets from https://www.firstpr.com.au/dsp/pink-noise/
20pub fn pink() -> Sig<impl SigT<Item = f32>> {
21    let mut b = [0.; 7];
22    white().map_mut(move |x| {
23        b[0] = 0.99886 * b[0] + x * 0.0555179;
24        b[1] = 0.99332 * b[1] + x * 0.0750759;
25        b[2] = 0.96900 * b[2] + x * 0.153852;
26        b[3] = 0.86650 * b[3] + x * 0.3104856;
27        b[4] = 0.55000 * b[4] + x * 0.5329522;
28        b[5] = -0.7616 * b[5] - x * 0.0168980;
29        let pink = b[0] + b[1] + b[2] + b[3] + b[4] + b[5] + b[6] + x * 0.5362;
30        b[6] = x * 0.115926;
31        pink * 0.25
32    })
33}