use rand;
use rand_xorshift::XorShiftRng;
use derive_more::{From, TryInto};
#[derive(Clone, Debug)]
pub struct Generator {
pub freq : f64,
pub kind : Kind,
pub rng : XorShiftRng
}
pub trait Generate {
fn generate (&mut self,
rng : &mut XorShiftRng,
samples : &mut [i16],
freq : f64);
}
#[derive(Clone, Debug, Eq, PartialEq, From, TryInto)]
pub enum Kind {
Wave (Wave),
Noise (Noise)
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Wave {
Sin,
Tri,
Saw,
Square {
width : u32
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Noise {
White,
Brown { intensity : i16 },
Pink
}
impl Generator {
#[inline]
pub fn new (kind : Kind, freq : f64) -> Self {
use rand::SeedableRng;
let rng = XorShiftRng::seed_from_u64 (0);
Generator { kind, freq, rng }
}
#[inline]
pub fn generate (&mut self, samples : &mut [i16]) {
self.kind.generate (&mut self.rng, samples, self.freq)
}
}
impl Generate for Kind {
fn generate (&mut self, rng : &mut XorShiftRng, samples : &mut [i16], freq : f64) {
match self {
Kind::Wave (wave) => wave.generate (rng, samples, freq),
Kind::Noise (noise) => noise.generate (rng, samples, freq)
}
}
}
impl Generate for Wave {
fn generate (&mut self, _rng : &mut XorShiftRng, _samples : &mut [i16], _freq : f64) {
unimplemented!("TODO")
}
}
impl Generate for Noise {
fn generate (&mut self, rng : &mut XorShiftRng, samples : &mut [i16], _freq : f64) {
use rand::Rng;
match self {
Noise::White => for sample in samples.iter_mut() {
*sample = rng.random()
}
Noise::Brown { intensity } => {
let mut level = 0i16;
for sample in samples.iter_mut() {
*sample = level;
let delta = rng.random_range(-(intensity.abs())..intensity.abs());
level = level.saturating_add (delta);
}
}
Noise::Pink => unimplemented!("TODO")
}
}
}