Compare commits
No commits in common. "synthesizer" and "main" have entirely different histories.
synthesize
...
main
3 changed files with 9 additions and 75 deletions
|
|
@ -1,6 +1,2 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
pub mod synthesizer;
|
mod wavetable;
|
||||||
pub mod wavetable;
|
|
||||||
|
|
||||||
//TODO:
|
|
||||||
// * patch mod w/ trait Input and trait Output(?)
|
|
||||||
|
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
use crate::wavetable::Wavetable;
|
|
||||||
|
|
||||||
pub trait Synthesizer {}
|
|
||||||
|
|
||||||
pub struct SimpleWavetableSynthesizer<W: Wavetable> {
|
|
||||||
wavetable: W,
|
|
||||||
clock_freq_hz: usize,
|
|
||||||
output_freq_hz: usize,
|
|
||||||
enable: bool,
|
|
||||||
pub counter: usize,
|
|
||||||
clock_per_sample: usize,
|
|
||||||
current_output: <W as Wavetable>::OutputType,
|
|
||||||
output_flag: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<W: Wavetable> SimpleWavetableSynthesizer<W> {
|
|
||||||
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: <W as Wavetable>::OutputType::default(),
|
|
||||||
output_flag: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has_new_output(&self) -> bool {
|
|
||||||
self.output_flag
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_output(&mut self) -> <W as Wavetable>::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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
pub trait Wavetable {
|
pub trait Wavetable {
|
||||||
type OutputType: Default + Copy;
|
type OutputType;
|
||||||
/// get next sample
|
/// get next sample
|
||||||
fn next(&mut self);
|
fn next(&mut self) -> Self::OutputType;
|
||||||
fn get_value(&self) -> Self::OutputType;
|
|
||||||
fn size(&self) -> usize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// non-interpolated, simple wavetable that produces the next sample
|
/// non-interpolated, simple wavetable that produces the next sample
|
||||||
|
|
@ -15,25 +13,19 @@ pub struct SimpleWavetable<'a, T: Copy> {
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Copy + Default> Wavetable for SimpleWavetable<'a, T> {
|
impl<'a, T: Copy> Wavetable for SimpleWavetable<'a, T> {
|
||||||
type OutputType = T;
|
type OutputType = T;
|
||||||
fn next(&mut self) {
|
fn next(&mut self) -> Self::OutputType {
|
||||||
|
let value = self.table[self.index];
|
||||||
self.index += 1;
|
self.index += 1;
|
||||||
if self.index > self.table.len() - 1 {
|
if self.index > self.table.len() {
|
||||||
self.index = 0;
|
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 + Default> SimpleWavetable<'a, T> {
|
impl<'a, T: Copy> SimpleWavetable<'a, T> {
|
||||||
pub fn new(table: &'a [T]) -> Self {
|
pub fn new(table: &'a [T]) -> Self {
|
||||||
Self { table, index: 0 }
|
Self { table, index: 0 }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue