diff --git a/src/lib.rs b/src/lib.rs index 08af373..70b9fe0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,6 @@ #![no_std] -mod wavetable; +pub mod synthesizer; +pub mod wavetable; + +//TODO: +// * patch mod w/ trait Input and trait Output(?) diff --git a/src/synthesizer.rs b/src/synthesizer.rs new file mode 100644 index 0000000..fa448ca --- /dev/null +++ b/src/synthesizer.rs @@ -0,0 +1,54 @@ +use crate::wavetable::Wavetable; + +pub trait Synthesizer {} + +pub struct SimpleWavetableSynthesizer { + wavetable: W, + clock_freq_hz: usize, + output_freq_hz: usize, + enable: bool, + pub counter: usize, + clock_per_sample: usize, + current_output: ::OutputType, + output_flag: bool, +} + +impl SimpleWavetableSynthesizer { + pub fn new(wavetable: W, clock_freq_hz: usize) -> Self { + Self { + wavetable, + clock_freq_hz, + output_freq_hz: 1, + enable: false, + counter: 0, + clock_per_sample: 0, + current_output: ::OutputType::default(), + output_flag: false, + } + } + + pub fn has_new_output(&self) -> bool { + self.output_flag + } + + pub fn get_output(&mut self) -> ::OutputType { + self.output_flag = false; + self.wavetable.get_value() + } + + pub fn set_freq(&mut self, freq_hz: usize) { + self.output_freq_hz = freq_hz; + // probably a better way to do this with modulos or something... + // FIXME: use the length of the square table.. or whatever wavetable tbh + self.clock_per_sample = self.clock_freq_hz / self.output_freq_hz / self.wavetable.size(); + } + + pub fn tick(&mut self) { + if self.counter >= self.clock_per_sample { + self.wavetable.next(); + self.output_flag = true; + self.counter = 0; + } + self.counter = self.counter.wrapping_add(1) + } +} diff --git a/src/wavetable.rs b/src/wavetable.rs index 5105607..b934e48 100644 --- a/src/wavetable.rs +++ b/src/wavetable.rs @@ -1,7 +1,9 @@ pub trait Wavetable { - type OutputType; + type OutputType: Default + Copy; /// get next sample - fn next(&mut self) -> Self::OutputType; + fn next(&mut self); + fn get_value(&self) -> Self::OutputType; + fn size(&self) -> usize; } /// non-interpolated, simple wavetable that produces the next sample @@ -13,19 +15,25 @@ pub struct SimpleWavetable<'a, T: Copy> { index: usize, } -impl<'a, T: Copy> Wavetable for SimpleWavetable<'a, T> { +impl<'a, T: Copy + Default> Wavetable for SimpleWavetable<'a, T> { type OutputType = T; - fn next(&mut self) -> Self::OutputType { - let value = self.table[self.index]; + fn next(&mut self) { self.index += 1; - if self.index > self.table.len() { + if self.index > self.table.len() - 1 { self.index = 0; } - value + } + + fn get_value(&self) -> Self::OutputType { + self.table[self.index] + } + + fn size(&self) -> usize { + self.table.len() } } -impl<'a, T: Copy> SimpleWavetable<'a, T> { +impl<'a, T: Copy + Default> SimpleWavetable<'a, T> { pub fn new(table: &'a [T]) -> Self { Self { table, index: 0 } }