Initial commit
This commit is contained in:
87
src/noise.rs
Normal file
87
src/noise.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
//! Colored noise generators.
|
||||
//!
|
||||
//! Transforms white noise into spectrally-shaped noise with different frequency
|
||||
//! characteristics. Both generators are stateful filters that process white noise
|
||||
//! sample-by-sample.
|
||||
//!
|
||||
//! # Noise Colors
|
||||
//!
|
||||
//! | Color | Slope | Character |
|
||||
//! |-------|------------|----------------------------------|
|
||||
//! | White | 0 dB/oct | Equal energy per frequency |
|
||||
//! | Pink | -3 dB/oct | Equal energy per octave |
|
||||
//! | Brown | -6 dB/oct | Rumbling, emphasizes low freqs |
|
||||
|
||||
/// Pink noise generator using the Voss-McCartney algorithm.
|
||||
///
|
||||
/// Applies a parallel bank of first-order lowpass filters to shape white noise
|
||||
/// into pink noise with -3 dB/octave rolloff. The coefficients approximate an
|
||||
/// ideal pink spectrum across the audio range.
|
||||
///
|
||||
/// Also known as 1/f noise, pink noise has equal energy per octave, making it
|
||||
/// useful for audio testing and as a natural-sounding noise source.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct PinkNoise {
|
||||
b: [f32; 7],
|
||||
}
|
||||
|
||||
impl Default for PinkNoise {
|
||||
fn default() -> Self {
|
||||
Self { b: [0.0; 7] }
|
||||
}
|
||||
}
|
||||
|
||||
impl PinkNoise {
|
||||
/// Processes one white noise sample and returns the corresponding pink noise sample.
|
||||
///
|
||||
/// The input should be uniformly distributed white noise in the range `[-1, 1]`.
|
||||
/// Output is scaled to approximately the same amplitude range.
|
||||
pub fn next(&mut self, white: f32) -> f32 {
|
||||
self.b[0] = 0.99886 * self.b[0] + white * 0.0555179;
|
||||
self.b[1] = 0.99332 * self.b[1] + white * 0.0750759;
|
||||
self.b[2] = 0.96900 * self.b[2] + white * 0.153852;
|
||||
self.b[3] = 0.86650 * self.b[3] + white * 0.3104856;
|
||||
self.b[4] = 0.55000 * self.b[4] + white * 0.5329522;
|
||||
self.b[5] = -0.7616 * self.b[5] - white * 0.0168980;
|
||||
let pink = self.b[0]
|
||||
+ self.b[1]
|
||||
+ self.b[2]
|
||||
+ self.b[3]
|
||||
+ self.b[4]
|
||||
+ self.b[5]
|
||||
+ self.b[6]
|
||||
+ white * 0.5362;
|
||||
self.b[6] = white * 0.115926;
|
||||
pink * 0.11
|
||||
}
|
||||
}
|
||||
|
||||
/// Brown noise generator using leaky integration.
|
||||
///
|
||||
/// Applies a simple first-order lowpass filter (leaky integrator) to produce
|
||||
/// noise with -6 dB/octave rolloff. Named after Robert Brown (Brownian motion),
|
||||
/// not the color.
|
||||
///
|
||||
/// Also known as red noise or random walk noise. Has a deep, rumbling character
|
||||
/// with strong low-frequency content.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct BrownNoise {
|
||||
out: f32,
|
||||
}
|
||||
|
||||
impl Default for BrownNoise {
|
||||
fn default() -> Self {
|
||||
Self { out: 0.0 }
|
||||
}
|
||||
}
|
||||
|
||||
impl BrownNoise {
|
||||
/// Processes one white noise sample and returns the corresponding brown noise sample.
|
||||
///
|
||||
/// The input should be uniformly distributed white noise in the range `[-1, 1]`.
|
||||
/// Output amplitude depends on the integration coefficient.
|
||||
pub fn next(&mut self, white: f32) -> f32 {
|
||||
self.out = (self.out + 0.02 * white) / 1.02;
|
||||
self.out
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user