1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//! Signal synthesizers.

use super::{Sample, MonoSource, UninitializedSource};
use std::f64::consts::PI_2;
use std::iter::{Range, Cycle};
use std::num::{NumCast, Float, FromPrimitive};
use std::rand::Rng;
use std::rand::distributions::{IndependentSample, Normal};
#[cfg(test)]
use test::Bencher;

/// Pure silence.
pub struct Null<F> {
    src: UninitializedSource<F>
}

impl<F: Sample> Null<F> {
    /// Create a source of pure silence for buffers of `size` samples.
    pub fn new(size: usize) -> Null<F> {
        Null {
            src: UninitializedSource::new(size)
        }
    }
}

impl<F: Sample> MonoSource for Null<F> {
    type Output = F;

    fn next<'a>(&'a mut self) -> Option<&'a mut [F]> {
        self.src.next().map(|buf| {
            for x in buf.iter_mut() {
                *x = FromPrimitive::from_uint(0).unwrap();
            }
            buf
        })
    }
}

#[bench]
fn generate_silence(b: &mut Bencher) {
    let bufsize = 4096;
    let mut src = Null::<i16>::new(bufsize);
    b.bytes = ::std::mem::size_of::<i16>() as u64 * bufsize as u64;
    b.iter(|| {
        src.next();
    });
}

/// A pure tone.
/// 
/// The emitted signal is a full-scale (spans the entire range of the output
/// type) sin wave, starting at zero.
///
/// The optional type parameter `P` specifies the type in which the sin wave
/// will be generated. Some users may wish to use `f64` for greater precision
/// in signals with long period, or other types according to the application's
/// required precision.
pub struct Tone<F, P> {
    src: UninitializedSource<F>,
    timebase: Cycle<Range<usize>>,
    period: usize
}

impl<F: Sample, P = f32> Tone<F, P> {
    /// Create a pure tone generator with a specified period in samples for
    /// buffers of `size` samples.
    pub fn new(size: usize, period: usize) -> Tone<F, P> {
        Tone {
            src: UninitializedSource::new(size),
            timebase: range(0, period).cycle(),
            period: period
        }
    }
}

// TODO Float is kinda slow-feeling. Prefer a custom Sinusoid
// trait that can avoid floats sometimes.
impl<F: Sample, P: Sample+Float> MonoSource for Tone<F, P> {
    type Output = F;

    fn next<'a>(&'a mut self) -> Option<&'a mut [F]> {
        let buf = match self.src.next() {
            Some(b) => b,
            None => return None
        };

        for (x, t) in buf.iter_mut().zip(self.timebase.by_ref()) {
            let mut y: P = NumCast::from(t).unwrap();
            y = y * NumCast::from(PI_2).unwrap();
            y = y / NumCast::from(self.period).unwrap();
            *x = Sample::convert::<F>(y.sin());
        }
        Some(buf)
    }
}

#[bench]
fn generate_a440_44100(b: &mut Bencher) {
    let bufsize = 4096;
    let mut src = Tone::<i16>::new(bufsize, 100);
    b.bytes = ::std::mem::size_of::<i16>() as u64 * bufsize as u64;
    b.iter(|| {
        src.next();
    });
}

/// Pure Gaussian white noise.
pub struct WhiteNoise<F, R> {
    rng: R,
    normal: Normal,
    src: UninitializedSource<F>
}

impl<R: Rng> WhiteNoise<f64, R> {
    /// Create a white noise generator for buffers of `size` samples.
    pub fn new(size: usize, rng: R) -> WhiteNoise<f64, R> {
        WhiteNoise {
            rng: rng,
            normal: Normal::new(0f64, 0.25),
            src: UninitializedSource::new(size)
        }
    }
}

impl<R: Rng> MonoSource for WhiteNoise<f64, R> {
    type Output = f64;

    fn next<'a>(&'a mut self) -> Option<&'a mut [f64]> {
        let buf = match self.src.next() {
            Some(b) => b,
            None => return None
        };

        for x in buf.iter_mut() {
            *x = self.normal.ind_sample(&mut self.rng).clip();
        }
        Some(buf)
    }
}

#[bench]
fn generate_xorshift_noise_44100(b: &mut Bencher) {
    let bufsize = 4096;
    let mut src = WhiteNoise::new(bufsize,
            ::std::rand::XorShiftRng::new_unseeded());
    b.bytes = ::std::mem::size_of::<f64>() as u64 * bufsize as u64;

    b.iter(|| {
        src.next();
    });
}