summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGraham Northup <grissess@nexusg.org>2017-09-20 01:49:04 -0400
committerGraham Northup <grissess@nexusg.org>2017-09-20 01:49:04 -0400
commitdcfc4e82386f41bd36c3b102512bd225fc5331b6 (patch)
treeb0b4e8ee6bf95be9970cfad37ef087cce472393b
parent9866c0f34c268a09ecaaa9a4361c1c267799358e (diff)
more of the same for the night :)
-rw-r--r--Cargo.toml1
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs12
-rw-r--r--src/proto.rs24
-rw-r--r--src/synth/logic.rs63
-rw-r--r--src/synth/math.rs52
-rw-r--r--src/synth/mod.rs16
-rw-r--r--src/synth/noise.rs26
-rw-r--r--src/synth/rel.rs78
-rw-r--r--src/synth/triangle.rs1
10 files changed, 269 insertions, 5 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 5b3f2ae..eed028b 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,3 +5,4 @@ authors = ["Graham Northup <grissess@nexusg.org>"]
[dependencies]
byteorder = "1.1.0"
+rand = "0.3"
diff --git a/src/lib.rs b/src/lib.rs
index 08d71d3..4e08724 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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)]