diff options
| author | Graham Northup <grissess@nexusg.org> | 2017-09-20 01:49:04 -0400 | 
|---|---|---|
| committer | Graham Northup <grissess@nexusg.org> | 2017-09-20 01:49:04 -0400 | 
| commit | dcfc4e82386f41bd36c3b102512bd225fc5331b6 (patch) | |
| tree | b0b4e8ee6bf95be9970cfad37ef087cce472393b | |
| parent | 9866c0f34c268a09ecaaa9a4361c1c267799358e (diff) | |
more of the same for the night :)
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/main.rs | 12 | ||||
| -rw-r--r-- | src/proto.rs | 24 | ||||
| -rw-r--r-- | src/synth/logic.rs | 63 | ||||
| -rw-r--r-- | src/synth/math.rs | 52 | ||||
| -rw-r--r-- | src/synth/mod.rs | 16 | ||||
| -rw-r--r-- | src/synth/noise.rs | 26 | ||||
| -rw-r--r-- | src/synth/rel.rs | 78 | ||||
| -rw-r--r-- | src/synth/triangle.rs | 1 | 
10 files changed, 269 insertions, 5 deletions
| @@ -5,3 +5,4 @@ authors = ["Graham Northup <grissess@nexusg.org>"]  [dependencies]  byteorder = "1.1.0" +rand = "0.3" @@ -1,6 +1,7 @@  #![feature(associated_consts)]  extern crate byteorder; +extern crate rand;  pub mod types;  pub use types::*; diff --git a/src/main.rs b/src/main.rs index 05538e9..c284820 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,8 @@  use std::io;  use std::io::*; +extern crate rand; +use rand::{Rng, SeedableRng};  extern crate synfone;  use synfone::synth::*; @@ -9,8 +11,14 @@ const FRAMES: usize = 44100 * 2;  fn main() {      let mut params = Parameters::default(); -    let mut freq: GenBox = Box::new(Param { name: "freq".to_string(), default: 440.0, buf: SampleBuffer::new(1) }); -    let mut sg: GenBox = Box::new(Saw { freq: freq, phase: 0.0, buf: SampleBuffer::new(params.env.default_buffer_size) }); +    //let mut freq: GenBox = Box::new(Param { name: "freq".to_string(), default: 440.0, buf: SampleBuffer::new(1) }); +    //let mut sg: GenBox = Box::new(Saw { freq: freq, phase: 0.0, buf: SampleBuffer::new(params.env.default_buffer_size) }); +    let mut osrng = rand::os::OsRng::new().expect("Couldn't initialize OS RNG"); +    let mut seed: [u32; 4] = Default::default(); +    for i in seed.iter_mut() { +        *i = osrng.next_u32(); +    } +    let mut sg: GenBox = Box::new(Noise { rng: rand::XorShiftRng::from_seed(seed), buf: SampleBuffer::new(params.env.default_buffer_size) });      let mut freq2: GenBox = Box::new(Param { name: "freq2".to_string(), default: 660.0, buf: SampleBuffer::new(1) });      let mut sg2: GenBox = Box::new(Sine { freq: freq2, phase: 0.0, buf: SampleBuffer::new(params.env.default_buffer_size) }); diff --git a/src/proto.rs b/src/proto.rs index 06d7b49..c202a10 100644 --- a/src/proto.rs +++ b/src/proto.rs @@ -48,6 +48,30 @@ impl<'a> From<&'a [u8; 36]> for Command {                  data.copy_from_slice(&packet[4..]);                  Command::Ping{data: data}              } +            2 => Command::Quit, +            3 => Command::Play{ +                sec: fields_u32[1], +                usec: fields_u32[2], +                freq: fields_u32[3], +                amp: fields_f32[4], +                voice: fields_u32[5], +            }, +            4 => { +                let mut tp: [u8; 4] = unsafe { mem::uninitialized() }; +                let mut ident: [u8; 24] = unsafe { mem::uninitialized() }; +                tp.copy_from_slice(&packet[8..12]); +                ident.copy_from_slice(&packet[12..]); +                Command::Caps{ +                    voices: fields_u32[1], +                    tp: tp, +                    ident: ident, +                } +            }, +            5 => { +                let mut samples: [i16; 16] = unsafe { mem::uninitialized() }; +                ::byteorder::LittleEndian::read_i16_into(&packet[4..], &mut samples); +                Command::PCM{samples: samples} +            },              _ => {                  let mut data: [u8; 36] = unsafe { mem::uninitialized() };                  data.copy_from_slice(packet); diff --git a/src/synth/logic.rs b/src/synth/logic.rs new file mode 100644 index 0000000..5071d95 --- /dev/null +++ b/src/synth/logic.rs @@ -0,0 +1,63 @@ +use std::{mem, cmp}; +use super::*; + +#[derive(Debug)] +pub struct IfElse { +    pub cond: GenBox, +    pub iftrue: GenBox, +    pub iffalse: GenBox, +    pub buf: SampleBuffer, +} + +impl Generator for IfElse { +    fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { +        let cond_buf = self.cond.eval(params); +        let iftrue_buf = self.iftrue.eval(params); +        let iffalse_buf = self.iffalse.eval(params); +         +        if ( +            cond_buf.rate == Rate::Control && +            iftrue_buf.rate == Rate::Control && +            iffalse_buf.rate == Rate::Control +        ) { +            self.buf.set(if cond_buf.first() >= 0.5 { +                iftrue_buf.first() +            } else { +                iffalse_buf.first() +            }); +            return &self.buf; +        } + +        self.buf.rate = Rate::Sample; + +        let mut bound = self.buf.len(); +        if cond_buf.rate == Rate::Sample { bound = cmp::min(bound, cond_buf.len()); } +        if iftrue_buf.rate == Rate::Sample { bound = cmp::min(bound, iftrue_buf.len()); } +        if iffalse_buf.rate == Rate::Sample { bound = cmp::min(bound, iffalse_buf.len()); } + +        for i in 0..bound { +            let tv = match iftrue_buf.rate { +                Rate::Sample => iftrue_buf[i], +                Rate::Control => iftrue_buf.first(), +            }; +            let fv = match iffalse_buf.rate { +                Rate::Sample => iffalse_buf[i], +                Rate::Control => iffalse_buf.first(), +            }; +            let cv = match cond_buf.rate { +                Rate::Sample => cond_buf[i], +                Rate::Control => cond_buf.first(), +            }; +            self.buf[i] = if cv >= 0.5 { +                tv +            } else { +                fv +            }; +        } + +        &self.buf +    } +    fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { +        mem::replace(&mut self.buf, buf) +    } +} diff --git a/src/synth/math.rs b/src/synth/math.rs index 91e58e3..8adad4b 100644 --- a/src/synth/math.rs +++ b/src/synth/math.rs @@ -48,3 +48,55 @@ impl Generator for Mul {          mem::replace(&mut self.buf, buf)      }  } + +#[derive(Debug)] +pub struct Negate { +    pub value: GenBox, +    pub buf: SampleBuffer, +} + +impl Generator for Negate { +    fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { +        self.buf.update_from(self.value.eval(params)); +        match self.buf.rate { +            Rate::Sample => { +                for v in self.buf.iter_mut() { +                    *v *= -1.0; +                } +            }, +            Rate::Control => { +                self.buf[0] *= -1.0; +            }, +        } +        &self.buf +    } +    fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { +        mem::replace(&mut self.buf, buf) +    } +} + +#[derive(Debug)] +pub struct Reciprocate { +    pub value: GenBox, +    pub buf: SampleBuffer, +} + +impl Generator for Reciprocate { +    fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { +        self.buf.update_from(self.value.eval(params)); +        match self.buf.rate { +            Rate::Sample => { +                for v in self.buf.iter_mut() { +                    *v = v.powf(-1.0); +                } +            }, +            Rate::Control => { +                self.buf[0] = self.buf[0].powf(-1.0); +            }, +        } +        &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 bf73200..4f23a01 100644 --- a/src/synth/mod.rs +++ b/src/synth/mod.rs @@ -60,6 +60,10 @@ impl SampleBuffer {          self.samples.len()      } +    pub fn iter_mut<'a>(&'a mut self) -> slice::IterMut<'a, f32> { +        self.samples.iter_mut() +    } +      pub fn first(&self) -> Sample {          *self.samples.first().unwrap()      } @@ -158,7 +162,11 @@ pub type GenBox = Box<Generator>;  pub mod param;  pub use self::param::Param;  pub mod math; -pub use self::math::{Add, Mul}; +pub use self::math::{Add, Mul, Negate, Reciprocate}; +pub mod rel; +pub use self::rel::{Rel, RelOp}; +pub mod logic; +pub use self::logic::IfElse;  pub mod sine;  pub use self::sine::Sine;  pub mod saw; @@ -167,5 +175,7 @@ pub mod triangle;  pub use self::triangle::Triangle;  pub mod square;  pub use self::square::Square; -//pub mod asdr; -//pub use self::asdr::ASDR; +pub mod noise; +pub use self::noise::Noise; +//pub mod adsr; +//pub use self::adsr::ADSR; diff --git a/src/synth/noise.rs b/src/synth/noise.rs new file mode 100644 index 0000000..4d90f3b --- /dev/null +++ b/src/synth/noise.rs @@ -0,0 +1,26 @@ +use std::mem; +use super::*; + +use ::rand::{XorShiftRng, Rng}; + +#[derive(Debug)] +pub struct Noise { +    pub rng: XorShiftRng, +    pub buf: SampleBuffer, +} + +impl Generator for Noise { +    fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { +        self.buf.rate = Rate::Sample; + +        for i in 0..self.buf.len() { +            self.buf[i] = self.rng.next_f32(); +        } + +        &self.buf +    } +    fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer { +        mem::replace(&mut self.buf, buf) +    } +} + diff --git a/src/synth/rel.rs b/src/synth/rel.rs new file mode 100644 index 0000000..76b6c04 --- /dev/null +++ b/src/synth/rel.rs @@ -0,0 +1,78 @@ +use std::{cmp, mem}; +use super::*; + +#[derive(Debug)] +pub enum RelOp { +    Greater, +    GreaterEqual, +    Equal, +    NotEqual, +    LessEqual, +    Less, +} + +#[derive(Debug)] +pub struct Rel { +    pub left: GenBox, +    pub right: GenBox, +    pub op: RelOp, +    pub buf: SampleBuffer, +} + +impl Generator for Rel { +    fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer { +        let left_buf = self.left.eval(params); +        let right_buf = self.right.eval(params); + +        match left_buf.rate { +            Rate::Sample => { +                self.buf.rate = Rate::Sample; + +                let bound = match right_buf.rate { +                    Rate::Sample => cmp::min(left_buf.len(), right_buf.len()), +                    Rate::Control => left_buf.len(), +                }; +                for i in 0..bound { +                    let val = left_buf[i]; +                    let thres = match right_buf.rate { +                        Rate::Sample => right_buf[i], +                        Rate::Control => right_buf.first(), +                    }; +                    self.buf[i] = if match self.op { +                        RelOp::Greater => val > thres, +                        RelOp::GreaterEqual => val >= thres, +                        RelOp::Equal => val == thres, +                        RelOp::NotEqual => val != thres, +                        RelOp::LessEqual => val <= thres, +                        RelOp::Less => val < thres, +                    } { +                        1.0 +                    } else { +                        0.0 +                    }; +                } +            }, +            Rate::Control => { +                let val = left_buf.first(); +                let thres = right_buf.first(); +                self.buf.set(if match self.op { +                    RelOp::Greater => val > thres, +                    RelOp::GreaterEqual => val >= thres, +                    RelOp::Equal => val == thres, +                    RelOp::NotEqual => val != thres, +                    RelOp::LessEqual => val <= thres, +                    RelOp::Less => val < thres, +                } { +                    1.0 +                } else { +                    0.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 index c8380a1..5c0c69a 100644 --- a/src/synth/triangle.rs +++ b/src/synth/triangle.rs @@ -1,3 +1,4 @@ +use std::mem;  use super::*;  #[derive(Debug)] | 
