diff options
author | Graham Northup <grissess@nexusg.org> | 2017-09-19 23:56:15 -0400 |
---|---|---|
committer | Graham Northup <grissess@nexusg.org> | 2017-09-19 23:56:15 -0400 |
commit | 9866c0f34c268a09ecaaa9a4361c1c267799358e (patch) | |
tree | d10bea3717c25105ced7457535412072d343686f /src/synth | |
parent | 26e95364ad9073dd7cb571454cd52ae66f320a73 (diff) |
Starting work on proto decode
Diffstat (limited to 'src/synth')
-rw-r--r-- | src/synth/math.rs | 9 | ||||
-rw-r--r-- | src/synth/mod.rs | 48 | ||||
-rw-r--r-- | src/synth/param.rs | 4 | ||||
-rw-r--r-- | src/synth/saw.rs | 25 | ||||
-rw-r--r-- | src/synth/sine.rs | 6 | ||||
-rw-r--r-- | src/synth/square.rs | 29 | ||||
-rw-r--r-- | src/synth/triangle.rs | 32 |
7 files changed, 136 insertions, 17 deletions
diff --git a/src/synth/math.rs b/src/synth/math.rs index 66a86a0..91e58e3 100644 --- a/src/synth/math.rs +++ b/src/synth/math.rs @@ -1,5 +1,7 @@ use super::*; +use std::mem; +#[derive(Debug)] pub struct Add { pub terms: Vec<GenBox>, pub buf: SampleBuffer, @@ -18,8 +20,12 @@ impl Generator for Add { } &self.buf } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } } +#[derive(Debug)] pub struct Mul { pub factors: Vec<GenBox>, pub buf: SampleBuffer, @@ -38,4 +44,7 @@ impl Generator for Mul { } &self.buf } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } } diff --git a/src/synth/mod.rs b/src/synth/mod.rs index d0c837a..bf73200 100644 --- a/src/synth/mod.rs +++ b/src/synth/mod.rs @@ -1,14 +1,18 @@ use std::{iter, cmp, slice, mem}; +use std::fmt::Debug; use std::ops::{Index, IndexMut}; use std::collections::HashMap; use super::*; -#[derive(PartialEq,Eq,Clone,Copy)] +use ::byteorder::ByteOrder; + +#[derive(PartialEq,Eq,Clone,Copy,Debug)] pub enum Rate { Sample, Control, } +#[derive(Debug)] pub struct SampleBuffer { pub samples: Vec<Sample>, pub rate: Rate, @@ -82,7 +86,11 @@ impl SampleBuffer { pub fn sum_into(&mut self, other: &SampleBuffer) { match self.rate { Rate::Sample => { - for i in 0..cmp::min(self.len(), other.len()) { + let bound = match other.rate { + Rate::Sample => cmp::min(self.len(), other.len()), + Rate::Control => self.len(), + }; + for i in 0..bound { self.samples[i] += match other.rate { Rate::Sample => other.samples[i], Rate::Control => other.samples[0], @@ -98,7 +106,11 @@ impl SampleBuffer { pub fn mul_into(&mut self, other: &SampleBuffer) { match self.rate { Rate::Sample => { - for i in 0..cmp::min(self.len(), other.len()) { + let bound = match other.rate { + Rate::Sample => cmp::min(self.len(), other.len()), + Rate::Control => self.len(), + }; + for i in 0..bound { self.samples[i] *= match other.rate { Rate::Sample => other.samples[i], Rate::Control => other.samples[0], @@ -117,13 +129,13 @@ impl SampleBuffer { } } - 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>(), - ) - } + pub fn size(&self) -> usize { + mem::size_of::<Sample>() * self.samples.len() + } + + pub fn bytes(&self, buf: &mut [u8]) { + // FIXME: Depends on f32 instead of Sample alias + ::byteorder::LittleEndian::write_f32_into(&self.samples, buf); } } @@ -136,8 +148,9 @@ impl IndexMut<usize> for SampleBuffer { fn index_mut(&mut self, idx: usize) -> &mut Sample { &mut self.samples[idx] } } -pub trait Generator { +pub trait Generator : Debug { fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer; + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer; } pub type GenBox = Box<Generator>; @@ -148,8 +161,11 @@ 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; - +pub mod saw; +pub use self::saw::Saw; +pub mod triangle; +pub use self::triangle::Triangle; +pub mod square; +pub use self::square::Square; +//pub mod asdr; +//pub use self::asdr::ASDR; diff --git a/src/synth/param.rs b/src/synth/param.rs index ced5900..f679b56 100644 --- a/src/synth/param.rs +++ b/src/synth/param.rs @@ -1,5 +1,6 @@ use super::*; +#[derive(Debug)] pub struct Param { pub name: String, pub default: Sample, @@ -11,4 +12,7 @@ impl Generator for Param { self.buf.set(*params.vars.get(&self.name).unwrap_or(&self.default)); &self.buf } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } } diff --git a/src/synth/saw.rs b/src/synth/saw.rs new file mode 100644 index 0000000..bfd3cb0 --- /dev/null +++ b/src/synth/saw.rs @@ -0,0 +1,25 @@ +use super::*; + +#[derive(Debug)] +pub struct Saw { + pub freq: GenBox, + pub phase: f32, + pub buf: SampleBuffer, +} + +impl Generator for Saw { + fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { + self.buf.rate = Rate::Sample; + + let pvel = self.freq.eval(params).first() / params.env.sample_rate; + for i in 0..self.buf.len() { + self.buf[i] = 2.0 * ((self.phase + pvel * (i as f32)) % 1.0) - 1.0; + } + + self.phase = (self.phase + pvel * (self.buf.len() as f32)) % 1.0; + &self.buf + } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } +} diff --git a/src/synth/sine.rs b/src/synth/sine.rs index 212ab21..90f3200 100644 --- a/src/synth/sine.rs +++ b/src/synth/sine.rs @@ -3,6 +3,7 @@ use super::*; const TAU: f32 = 2f32 * PI; +#[derive(Debug)] pub struct Sine { pub freq: GenBox, pub phase: f32, @@ -11,7 +12,7 @@ pub struct Sine { impl Generator for Sine { fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { - self.buf.rate = Rate::Control; + self.buf.rate = Rate::Sample; let pvel = TAU * self.freq.eval(params).first() / params.env.sample_rate; for i in 0..self.buf.len() { @@ -21,4 +22,7 @@ impl Generator for Sine { self.phase = (self.phase + pvel * (self.buf.len() as f32)) % TAU; &self.buf } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } } diff --git a/src/synth/square.rs b/src/synth/square.rs new file mode 100644 index 0000000..8197110 --- /dev/null +++ b/src/synth/square.rs @@ -0,0 +1,29 @@ +use super::*; + +#[derive(Debug)] +pub struct Square { + pub freq: GenBox, + pub phase: f32, + pub buf: SampleBuffer, +} + +impl Generator for Square { + fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { + self.buf.rate = Rate::Sample; + + let pvel = self.freq.eval(params).first() / params.env.sample_rate; + for i in 0..self.buf.len() { + self.buf[i] = if ((self.phase + pvel * (i as f32)) % 1.0) < 0.5 { + -1.0 + } else { + 1.0 + }; + } + + self.phase = (self.phase + pvel * (self.buf.len() as f32)) % 1.0; + &self.buf + } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } +} diff --git a/src/synth/triangle.rs b/src/synth/triangle.rs new file mode 100644 index 0000000..c8380a1 --- /dev/null +++ b/src/synth/triangle.rs @@ -0,0 +1,32 @@ +use super::*; + +#[derive(Debug)] +pub struct Triangle { + pub freq: GenBox, + pub phase: f32, + pub buf: SampleBuffer, +} + +impl Generator for Triangle { + fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { + self.buf.rate = Rate::Sample; + + let pvel = self.freq.eval(params).first() / params.env.sample_rate; + for i in 0..self.buf.len() { + let ph = (self.phase + pvel * (i as f32)) % 1.0; + self.buf[i] = if ph < 0.25 { + 4.0 * ph + } else if ph > 0.75 { + 4.0 * ph - 4.0 + } else { + -4.0 * ph + 2.0 + }; + } + + self.phase = (self.phase + pvel * (self.buf.len() as f32)) % 1.0; + &self.buf + } + fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { + mem::replace(&mut self.buf, buf) + } +} |