From 2b52914aa95e9af4402ee3d4e4d5fb3640defaaf Mon Sep 17 00:00:00 2001 From: Michiel Roos Date: Mon, 7 Oct 2024 10:51:42 +0200 Subject: [PATCH] Update noise.rs (#24) * Update noise.rs Add brown noise generator * Use more readable clamp code --- knyst/src/gen/noise.rs | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/knyst/src/gen/noise.rs b/knyst/src/gen/noise.rs index bacab38..2d94fa6 100644 --- a/knyst/src/gen/noise.rs +++ b/knyst/src/gen/noise.rs @@ -6,7 +6,7 @@ use super::GenState; use crate as knyst; use crate::Sample; -/// Whate noise (fastrand RNG based on wyrand) +/// White noise (fastrand RNG based on wyrand) pub struct WhiteNoise { rng: fastrand::Rng, } @@ -98,3 +98,39 @@ impl PinkNoise { GenState::Continue } } + +/// Brown noise (also known as red noise) +/// +/// Brown noise is generated by integrating white noise. +/// This implementation uses a simple integration of white noise samples with a small step size, +/// and clamps the output to prevent it from exceeding the [-1.0, 1.0] range. +pub struct BrownNoise { + rng: fastrand::Rng, + last_output: Sample, +} + +#[impl_gen(range = normal)] +impl BrownNoise { + #[allow(missing_docs)] + pub fn new() -> Self { + let mut rng = fastrand::Rng::new(); + rng.seed(next_randomness_seed()); + Self { + rng, + last_output: 0.0, + } + } + + #[allow(missing_docs)] + pub fn process(&mut self, output: &mut [Sample]) -> GenState { + for out in output.iter_mut() { + let white = self.rng.f32() as Sample * 2.0 - 1.0; + // Adjust the coefficient to control the step size + self.last_output += white * 0.1; + // Clamp to [-1.0, 1.0] to prevent output from exceeding the range + self.last_output = self.last_output.clamp(-1.0, 1.0); + *out = self.last_output; + } + GenState::Continue + } +}