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)] |