58 lines
1.3 KiB
Rust
58 lines
1.3 KiB
Rust
pub trait Wavetable {
|
|
type OutputType: Default + Copy;
|
|
/// get next sample
|
|
fn next(&mut self);
|
|
fn get_value(&self) -> Self::OutputType;
|
|
fn size(&self) -> usize;
|
|
}
|
|
|
|
/// non-interpolated, simple wavetable that produces the next sample
|
|
/// every time [`Wavetable::next()`] is called.
|
|
pub struct SimpleWavetable<'a, T: Copy> {
|
|
// byte array for waveform
|
|
table: &'a [T],
|
|
// index in the waveform
|
|
index: usize,
|
|
}
|
|
|
|
impl<'a, T: Copy + Default> Wavetable for SimpleWavetable<'a, T> {
|
|
type OutputType = T;
|
|
fn next(&mut self) {
|
|
self.index += 1;
|
|
if self.index > self.table.len() - 1 {
|
|
self.index = 0;
|
|
}
|
|
}
|
|
|
|
fn get_value(&self) -> Self::OutputType {
|
|
self.table[self.index]
|
|
}
|
|
|
|
fn size(&self) -> usize {
|
|
self.table.len()
|
|
}
|
|
}
|
|
|
|
impl<'a, T: Copy + Default> SimpleWavetable<'a, T> {
|
|
pub fn new(table: &'a [T]) -> Self {
|
|
Self { table, index: 0 }
|
|
}
|
|
}
|
|
|
|
// TESTS
|
|
#[cfg(test)]
|
|
pub mod test {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn wavetable_t1() {
|
|
let table_data = [0, 255];
|
|
let mut w = SimpleWavetable::<u32>::new(&table_data);
|
|
for point in table_data {
|
|
assert!(w.next() == point);
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO:
|
|
// - interpolated wavetable
|