summaryrefslogtreecommitdiff
path: root/src/synth/mod.rs
diff options
context:
space:
mode:
authorGraham Northup <grissess@nexusg.org>2017-09-18 23:12:14 -0400
committerGraham Northup <grissess@nexusg.org>2017-09-18 23:12:14 -0400
commit85925d69e08455bd91d32a27cd3690c9cb634a6b (patch)
tree1023c044a3350aadb4eb06bf73e209f81f21f8ae /src/synth/mod.rs
Initial work on modular synthesis
Diffstat (limited to 'src/synth/mod.rs')
-rw-r--r--src/synth/mod.rs155
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;
+