diff options
author | Graham Northup <grissess@nexusg.org> | 2017-09-18 23:12:14 -0400 |
---|---|---|
committer | Graham Northup <grissess@nexusg.org> | 2017-09-18 23:12:14 -0400 |
commit | 85925d69e08455bd91d32a27cd3690c9cb634a6b (patch) | |
tree | 1023c044a3350aadb4eb06bf73e209f81f21f8ae /src/synth/mod.rs |
Initial work on modular synthesis
Diffstat (limited to 'src/synth/mod.rs')
-rw-r--r-- | src/synth/mod.rs | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/src/synth/mod.rs b/src/synth/mod.rs new file mode 100644 index 0000000..d0c837a --- /dev/null +++ b/src/synth/mod.rs @@ -0,0 +1,155 @@ +use std::{iter, cmp, slice, mem}; +use std::ops::{Index, IndexMut}; +use std::collections::HashMap; +use super::*; + +#[derive(PartialEq,Eq,Clone,Copy)] +pub enum Rate { + Sample, + Control, +} + +pub struct SampleBuffer { + pub samples: Vec<Sample>, + pub rate: Rate, +} + +pub struct Environment { + pub sample_rate: f32, + pub default_buffer_size: usize, +} + +impl Default for Environment { + fn default() -> Environment { + Environment { + sample_rate: 44100.0, + default_buffer_size: 64, + } + } +} + +pub struct Parameters { + pub env: Environment, + pub vars: HashMap<String, f32>, +} + +impl Default for Parameters { + fn default() -> Parameters { + Parameters { + env: Default::default(), + vars: HashMap::new(), + } + } +} + +impl SampleBuffer { + pub fn new(sz: usize) -> SampleBuffer { + let mut samples = Vec::with_capacity(sz); + samples.extend(iter::repeat(0 as Sample).take(sz)); + SampleBuffer { + samples: samples, + rate: Rate::Sample, + } + } + + pub fn len(&self) -> usize { + self.samples.len() + } + + pub fn first(&self) -> Sample { + *self.samples.first().unwrap() + } + + pub fn set(&mut self, val: Sample) { + self.samples[0] = val; + self.rate = Rate::Control; + } + + pub fn update_from(&mut self, other: &SampleBuffer) { + self.rate = other.rate; + match self.rate { + Rate::Sample => { + for i in 0..cmp::min(self.len(), other.len()) { + self.samples[i] = other.samples[i]; + } + }, + Rate::Control => { + self.samples[0] = other.samples[0]; + }, + } + } + + pub fn sum_into(&mut self, other: &SampleBuffer) { + match self.rate { + Rate::Sample => { + for i in 0..cmp::min(self.len(), other.len()) { + self.samples[i] += match other.rate { + Rate::Sample => other.samples[i], + Rate::Control => other.samples[0], + }; + } + }, + Rate::Control => { + self.samples[0] += other.samples[0]; + }, + } + } + + pub fn mul_into(&mut self, other: &SampleBuffer) { + match self.rate { + Rate::Sample => { + for i in 0..cmp::min(self.len(), other.len()) { + self.samples[i] *= match other.rate { + Rate::Sample => other.samples[i], + Rate::Control => other.samples[0], + }; + } + }, + Rate::Control => { + self.samples[0] *= other.samples[0]; + }, + } + } + + pub fn zero(&mut self) { + for i in 0..self.len() { + self.samples[i] = 0.0; + } + } + + pub fn bytes<'a>(&'a self) -> &'a [u8] { + unsafe { + slice::from_raw_parts( + self.samples.as_ptr() as *const u8, + self.samples.len() * mem::size_of::<Sample>(), + ) + } + } +} + +impl Index<usize> for SampleBuffer { + type Output = Sample; + fn index(&self, idx: usize) -> &Sample { &self.samples[idx] } +} + +impl IndexMut<usize> for SampleBuffer { + fn index_mut(&mut self, idx: usize) -> &mut Sample { &mut self.samples[idx] } +} + +pub trait Generator { + fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer; +} + +pub type GenBox = Box<Generator>; + +pub mod param; +pub use self::param::Param; +pub mod math; +pub use self::math::{Add, Mul}; +pub mod sine; +pub use self::sine::Sine; +//pub mod saw; +//pub use saw::Saw; +//pub mod triangle; +//pub use triangle::Triangle; + |