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
//! # Sine
//! 
//! A sinusoidal sample generator.

use lazy_static::lazy_static;
use super::*;

/// The frequency used by the wavetable.
const WAVETABLE_FREQ:u64 = 10;
/// The number of elements in the wavetable.
const WAVETABLE_SIZE:u64 = SAMPLE_RATE/WAVETABLE_FREQ;

lazy_static! {
    /// Lazy static initialization of the static WAVETABLE object.
    static ref WAVETABLE: [MathT; WAVETABLE_SIZE as usize] = {
        let mut wt = [0.0 ; WAVETABLE_SIZE as usize];
        for i in 0..WAVETABLE_SIZE {
            wt[i as usize] = MathT::sin(2.0*std::f64::consts::PI*INV_SAMPLE_RATE*(WAVETABLE_FREQ as MathT)*(i as MathT));
        }
        wt
    };
}

/// Struct for generating sinusoidal samples.
pub struct Sine {
    ind:MathT,
    inc:MathT,
}

impl FreqMod for Sine {
    fn new(f: MathT) -> Self {
        Sine{
            ind: 0.0,
            inc: f/(WAVETABLE_FREQ as MathT),
        }
    }

    fn set_frequency(&mut self, f: MathT) {
        self.inc = f / (WAVETABLE_FREQ as MathT);
    }

    fn get_frequency(&self) -> MathT {
        self.inc * (WAVETABLE_FREQ as MathT)
    }
}

impl Generator for Sine {
    fn process(&mut self) -> SampleT {
        let k = MathT::floor(self.ind);
        let g:MathT = self.ind - k;
        let k1 = if k+1.0 >= WAVETABLE_SIZE as MathT {
            0.0
        } else {
            k+1.0
        } as usize;
        let k = k as usize;

        let y = ((1.0-g)*WAVETABLE[k] + g*WAVETABLE[k1]) as SampleT;

        self.ind += self.inc;

        if self.ind >= (WAVETABLE_SIZE as MathT)-1.0 {
            self.ind -= WAVETABLE_SIZE as MathT;
        }

        y
    }
}

impl Clone for Sine {
    fn clone(&self) -> Self {
        Sine {
            ind: 0.0,
            inc: self.inc
        }
    }
}