Эх сурвалжийг харах

parser appears to work (oh my)

Graham Northup 8 жил өмнө
parent
commit
7eef21b3b9

+ 32 - 0
src/lang/mod.rs

@@ -1,6 +1,10 @@
 pub mod tokenizer;
 pub use self::tokenizer::Tokenizer;
+pub mod parser;
+pub use self::parser::Parser;
 
+// NB: No Eq due to embedded f32
+#[derive(Debug,PartialEq,Clone)]
 pub enum Token {
     Ident(String),
     Integer(isize),
@@ -10,3 +14,31 @@ pub enum Token {
     EOF,
 }
 
+#[derive(Debug,PartialEq,Eq,Clone,Copy)]
+pub enum TokType {
+    Ident,
+    Integer,
+    Float,
+    Oper,
+    String,
+    EOF,
+}
+
+impl Token {
+    pub fn to_type(&self) -> TokType {
+        match *self {
+            Token::Ident(_) => TokType::Ident,
+            Token::Integer(_) => TokType::Integer,
+            Token::Float(_) => TokType::Float,
+            Token::Oper(_) => TokType::Oper,
+            Token::String(_) => TokType::String,
+            Token::EOF => TokType::EOF,
+        }
+    }
+}
+
+impl<'a> From<&'a Token> for TokType {
+    fn from(tok: &'a Token) -> TokType {
+        tok.to_type()
+    }
+}

+ 175 - 0
src/lang/parser.rs

@@ -0,0 +1,175 @@
+use std::{mem, fmt};
+use std::error::Error;
+use std::collections::HashMap;
+use super::*;
+use synth::*;
+
+#[derive(Debug)]
+pub enum ErrorKind {
+    Unexpected(TokType, TokType),
+    ExpectedOp(char, TokType),
+    UnknownGen(String),
+}
+
+#[derive(Debug)]
+pub struct ErrorType {
+    pub kind: ErrorKind,
+    desc: String,
+}
+
+impl ErrorType {
+    pub fn new(kind: ErrorKind) -> ErrorType {
+        let mut ret = ErrorType {
+            kind: kind,
+            desc: "".to_string(),
+        };
+
+        ret.desc = match &ret.kind {
+            &ErrorKind::Unexpected(found, expected) => format!("Found {:?}, expected {:?}", found, expected),
+            &ErrorKind::ExpectedOp(c, found) => format!("Expected {:?}, found {:?}", c, found),
+            &ErrorKind::UnknownGen(ref s) => format!("Unknown generator name {}", s),
+        };
+
+        ret
+    }
+
+    pub fn with_description(kind: ErrorKind, desc: String) -> ErrorType {
+        ErrorType {
+            kind: kind,
+            desc: desc,
+        }
+    }
+}
+
+impl Error for ErrorType {
+    fn description<'a>(&'a self) -> &'a str {
+        &self.desc
+    }
+}
+
+impl fmt::Display for ErrorType {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(f, "{}", self.description())
+    }
+}
+
+pub struct Parser<T: Iterator<Item=char>> {
+    tzr: Tokenizer<T>,
+    token: Token,
+    pushback: Option<Token>,
+    factories: HashMap<String, &'static GeneratorFactory>,
+}
+
+impl<T: Iterator<Item=char>> Parser<T> {
+    pub fn new(mut tzr: Tokenizer<T>) -> Result<Parser<T>, Box<Error>> {
+        let token = tzr.next_token()?;
+        Ok(Parser {
+            tzr: tzr,
+            token: token,
+            pushback: None,
+            factories: all_factories(),
+        })
+    }
+
+    pub fn push_back(&mut self, tok: Token) {
+        match self.pushback {
+            None => {
+                self.pushback = Some(mem::replace(&mut self.token, tok));
+            },
+            Some(_) => panic!("too many pushbacks on Parser"),
+        }
+    }
+
+    pub fn expect(&mut self, ty: TokType) -> Result<Token, Box<Error>> {
+        if ty == self.token.to_type() {
+            Ok(mem::replace(&mut self.token, match self.pushback {
+                Some(_) => mem::replace(&mut self.pushback, None).unwrap(),
+                None => self.tzr.next_token()?,
+            }))
+        } else {
+            Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), ty)).into())
+        }
+    }
+
+    pub fn expect_ident(&mut self) -> Result<String, Box<Error>> {
+        match self.expect(TokType::Ident)? {
+            Token::Ident(s) => Ok(s),
+            _ => unreachable!(),
+        }
+    }
+
+    pub fn expect_op(&mut self, oper: char) -> Result<(), Box<Error>> {
+        match self.token {
+            Token::Oper(c) if c == oper => { self.expect(TokType::Oper)?; Ok(()) },
+            _ => Err(ErrorType::new(ErrorKind::ExpectedOp(oper, self.token.to_type())).into()),
+        }
+    }
+
+    pub fn parse(&mut self) -> Result<GenBox, Box<Error>> {
+        self.parse_gen()
+    }
+
+    pub fn parse_gen(&mut self) -> Result<GenBox, Box<Error>> {
+        let name = self.expect_ident()?;
+
+        self.expect_op('(')?;
+        let mut params: FactoryParameters = Default::default();
+        let mut ctr = 0;
+        loop {
+            if self.expect_op(')').is_ok() {
+                break;
+            }
+            let (nm, vl, new_ctr) = self.parse_param(ctr)?;
+            params.vars.insert(nm, vl);
+            ctr = new_ctr;
+
+            if self.expect_op(',').is_err() {
+                eprintln!("No comma: {:?}", self.token);
+                self.expect_op(')')?;
+                break;
+            }
+        }
+
+        let factory = match self.factories.get(&name) {
+            Some(fac) => fac,
+            None => return Err(ErrorType::new(ErrorKind::UnknownGen(name)).into()),
+        };
+        factory.new(&mut params).map_err(Into::into)
+    }
+
+    pub fn parse_param(&mut self, pos: usize) -> Result<(String, ParamValue, usize), Box<Error>> {
+        let mut ctr = pos;
+        let name = match self.expect_ident() {
+            Ok(nm) => {
+                if self.expect_op('=').is_ok() {
+                    nm
+                } else {
+                    match &self.token {
+                        &Token::Oper(c) if c == '(' => {
+                            self.push_back(Token::Ident(nm));
+                            ctr += 1;
+                            (ctr - 1).to_string()
+                        },
+                        _ => return Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), TokType::Ident)).into()),
+                    }
+                }
+            },
+            Err(_) => {
+                ctr += 1;
+                (ctr - 1).to_string()
+            },
+        };
+
+        let ret = match self.token {
+            Token::Integer(v) => Ok((name, ParamValue::Integer(v), ctr)),
+            Token::Float(v) => Ok((name, ParamValue::Float(v), ctr)),
+            Token::String(ref v) => Ok((name, ParamValue::String(v.clone()), ctr)),
+            Token::Ident(_) => return Ok((name, ParamValue::Generator(self.parse_gen()?), ctr)),
+            _ => return Err(ErrorType::new(ErrorKind::Unexpected(self.token.to_type(), TokType::Ident)).into()),
+        };
+
+        let tp = self.token.to_type();
+        self.expect(tp);
+        ret
+    }
+}

+ 14 - 1
src/lang/tokenizer.rs

@@ -173,13 +173,20 @@ impl<T: Iterator<Item=char>> Tokenizer<T> {
         }
     }
 
-    fn next_token(&mut self) -> Result<Token, ErrorType> {
+    pub fn next_token(&mut self) -> Result<Token, ErrorType> {
+        let res = self._next_token();
+        eprintln!("next_token: {:?}", res);
+        res
+    }
+
+    fn _next_token(&mut self) -> Result<Token, ErrorType> {
         let mut c = self.next_char();
         if c == None {
             return Ok(Token::EOF);
         }
         let mut cc = c.unwrap();
 
+        /* Whitespace */
         while cc.is_whitespace() {
             c = self.next_char();
             if c == None {
@@ -315,10 +322,16 @@ impl<T: Iterator<Item=char>> Tokenizer<T> {
                     radix = 16;
                 } else if ncc == self.lexemes.esc_oct {
                     radix = 8;
+                } else if ncc == self.lexemes.radix_point {
+                    floating = true;
+                    buffer.push(cc);
+                    buffer.push(ncc);
                 } else {
                     buffer.push(cc);
                     buffer.push(ncc);
                 }
+            } else {
+                buffer.push(cc);
             }
 
             loop {

+ 1 - 0
src/lib.rs

@@ -1,5 +1,6 @@
 #![feature(associated_consts)]
 #![feature(unicode)]
+#![feature(drop_types_in_const)]
 
 extern crate byteorder;
 extern crate rand;

+ 4 - 18
src/main.rs

@@ -2,32 +2,18 @@ use std::io;
 use std::io::*;
 
 extern crate rand;
-use rand::{Rng, SeedableRng};
 extern crate synfone;
 use synfone::synth::*;
+use synfone::lang::*;
 
 const FRAMES: usize = 44100 * 2;
 
+const GEN: &'static str = "add(mul(sine(param('freq', 440)), 0.5), mul(sine(param('freq2', 660)), 0.5))";
+
 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 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) });
-
-    let mut half1: GenBox = Box::new(Param { name: "half".to_string(), default: 1.0, buf: SampleBuffer::new(1) });
-    let mut half2: GenBox = Box::new(Param { name: "half".to_string(), default: 0.0, buf: SampleBuffer::new(1) });
-    let mut sc1: GenBox = Box::new(Mul { factors: vec![sg, half1], buf: SampleBuffer::new(params.env.default_buffer_size) });
-    let mut sc2: GenBox = Box::new(Mul { factors: vec![sg2, half2], buf: SampleBuffer::new(params.env.default_buffer_size) });
-    let mut gen: GenBox = Box::new(Add { terms: vec![sc1, sc2], buf: SampleBuffer::new(params.env.default_buffer_size) });
+    let mut gen = Parser::new(Tokenizer::new(GEN.chars())).expect("Failed to get first token").parse().expect("Failed to compile generator");
 
     let mut counter = 0;
     let mut out = io::stdout();

+ 17 - 2
src/synth/logic.rs

@@ -15,11 +15,11 @@ impl Generator for IfElse {
         let iftrue_buf = self.iftrue.eval(params);
         let iffalse_buf = self.iffalse.eval(params);
         
-        if (
+        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 {
@@ -57,7 +57,22 @@ impl Generator for IfElse {
 
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct IfElseFactory;
+
+impl GeneratorFactory for IfElseFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        let cond = params.remove_param("cond", 0)?.as_gen()?;
+        let iftrue = params.remove_param("iftrue", 1)?.as_gen()?;
+        let iffalse = params.remove_param("iffalse", 2)?.as_gen()?;
+        let buf = SampleBuffer::new(cmp::max(cmp::max(cond.buffer().len(), iftrue.buffer().len()), iffalse.buffer().len()));
+        Ok(Box::new(IfElse { cond: cond, iftrue: iftrue, iffalse: iffalse, buf: buf }))
+    }
+}
+
+pub static Factory: IfElseFactory = IfElseFactory;

+ 60 - 0
src/synth/math.rs

@@ -20,11 +20,25 @@ impl Generator for Add {
         }
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
 
+pub struct AddFactory;
+
+impl GeneratorFactory for AddFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        Ok(Box::new(Add {
+            terms: params.get_pos_params().into_iter().map(|x| x.as_gen()).collect::<Result<Vec<_>, _>>()?,
+            buf: SampleBuffer::new(params.env.default_buffer_size),
+        }))
+    }
+}
+
+pub static FactoryAdd: AddFactory = AddFactory;
+
 #[derive(Debug)]
 pub struct Mul {
     pub factors: Vec<GenBox>,
@@ -44,11 +58,25 @@ impl Generator for Mul {
         }
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
 
+pub struct MulFactory;
+
+impl GeneratorFactory for MulFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        Ok(Box::new(Mul {
+            factors: params.get_pos_params().into_iter().map(|x| x.as_gen()).collect::<Result<Vec<_>, _>>()?,
+            buf: SampleBuffer::new(params.env.default_buffer_size),
+        }))
+    }
+}
+
+pub static FactoryMul: MulFactory = MulFactory;
+
 #[derive(Debug)]
 pub struct Negate {
     pub value: GenBox,
@@ -70,11 +98,27 @@ impl Generator for Negate {
         }
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
 
+pub struct NegateFactory;
+
+impl GeneratorFactory for NegateFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        let mut gen = params.remove_param("value", 0)?.as_gen()?;
+        let len = gen.buffer().len();
+        Ok(Box::new(Negate {
+            value: gen,
+            buf: SampleBuffer::new(len),
+        }))
+    }
+}
+
+pub static FactoryNegate: NegateFactory = NegateFactory;
+
 #[derive(Debug)]
 pub struct Reciprocate {
     pub value: GenBox,
@@ -96,7 +140,23 @@ impl Generator for Reciprocate {
         }
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct ReciprocateFactory;
+
+impl GeneratorFactory for ReciprocateFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        let mut gen = params.remove_param("value", 0)?.as_gen()?;
+        let len = gen.buffer().len();
+        Ok(Box::new(Reciprocate {
+            value: gen,
+            buf: SampleBuffer::new(len),
+        }))
+    }
+}
+
+pub static FactoryReciprocate: ReciprocateFactory = ReciprocateFactory;

+ 201 - 1
src/synth/mod.rs

@@ -1,5 +1,6 @@
-use std::{iter, cmp, slice, mem};
+use std::{iter, cmp, slice, mem, fmt};
 use std::fmt::Debug;
+use std::error::Error;
 use std::ops::{Index, IndexMut};
 use std::collections::HashMap;
 use super::*;
@@ -154,11 +155,191 @@ impl IndexMut<usize> for SampleBuffer {
 
 pub trait Generator : Debug {
     fn eval<'a>(&'a mut self, params: &Parameters) -> &'a SampleBuffer;
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer;
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer;
 }
 
 pub type GenBox = Box<Generator>;
 
+#[derive(Debug)]
+pub enum GenFactoryError {
+    MissingRequiredParam(String, usize),
+    CannotConvert(ParamKind, ParamKind),
+    BadType(ParamKind),
+}
+
+#[derive(Debug)]
+pub struct GenFactoryErrorType {
+    pub kind: GenFactoryError,
+    desc: String
+}
+
+impl GenFactoryErrorType {
+    pub fn new(kind: GenFactoryError) -> GenFactoryErrorType {
+        let mut ret = GenFactoryErrorType {
+            kind: kind,
+            desc: "".to_string(),
+        };
+
+        ret.desc = match &ret.kind {
+            &GenFactoryError::MissingRequiredParam(ref name, pos) => format!("Needed a parameter named {} or at pos {}", name, pos),
+            &GenFactoryError::CannotConvert(from, to) => format!("Cannot convert {:?} to {:?}", from, to),
+            &GenFactoryError::BadType(ty) => format!("Bad parameter type {:?}", ty),
+        };
+
+        ret
+    }
+
+    pub fn with_description(kind: GenFactoryError, desc: String) -> GenFactoryErrorType {
+        GenFactoryErrorType {
+            kind: kind,
+            desc: desc,
+        }
+    }
+}
+
+impl From<GenFactoryError> for GenFactoryErrorType {
+    fn from(e: GenFactoryError) -> GenFactoryErrorType {
+        GenFactoryErrorType::new(e)
+    }
+}
+
+impl Error for GenFactoryErrorType {
+    fn description<'a>(&'a self) -> &'a str {
+        &self.desc
+    }
+}
+
+impl fmt::Display for GenFactoryErrorType {
+    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+        write!(f, "{}", self.description())
+    }
+}
+
+impl Into<Box<Error>> for GenFactoryError {
+    fn into(self) -> Box<Error> {
+        Box::new(GenFactoryErrorType::new(self))
+    }
+}
+
+#[derive(Debug,PartialEq,Eq,Clone,Copy)]
+pub enum ParamKind {
+    Integer,
+    Float,
+    String,
+    Generator,
+}
+
+pub enum ParamValue {
+    Integer(isize),
+    Float(f32),
+    String(String),
+    Generator(GenBox),
+}
+
+impl ParamValue {
+    pub fn kind(&self) -> ParamKind {
+        match *self {
+            ParamValue::Integer(_) => ParamKind::Integer,
+            ParamValue::Float(_) => ParamKind::Float,
+            ParamValue::String(_) => ParamKind::String,
+            ParamValue::Generator(_) => ParamKind::Generator,
+        }
+    }
+
+    pub fn as_isize(&self) -> Result<isize, GenFactoryError> {
+        match *self {
+            ParamValue::Integer(v) => Ok(v),
+            ParamValue::Float(v) => Ok(v as isize),
+            ParamValue::String(ref v) => v.parse().map_err(|_| GenFactoryError::CannotConvert(ParamKind::String, ParamKind::Integer)),
+            ParamValue::Generator(_) => Err(GenFactoryError::CannotConvert(ParamKind::Generator, ParamKind::Integer)),
+        }
+    }
+
+    pub fn as_f32(&self) -> Result<f32, GenFactoryError> {
+        match *self {
+            ParamValue::Integer(v) => Ok(v as f32),
+            ParamValue::Float(v) => Ok(v),
+            ParamValue::String(ref v) => v.parse().map_err(|_| GenFactoryError::CannotConvert(ParamKind::String, ParamKind::Float)),
+            ParamValue::Generator(_) => Err(GenFactoryError::CannotConvert(ParamKind::Generator, ParamKind::Float)),
+        }
+    }
+
+    pub fn as_string(&self) -> Result<String, GenFactoryError> {
+        match *self {
+            ParamValue::Integer(v) => Ok(v.to_string()),
+            ParamValue::Float(v) => Ok(v.to_string()),
+            ParamValue::String(ref v) => Ok(v.clone()),
+            ParamValue::Generator(_) => Err(GenFactoryError::CannotConvert(ParamKind::Generator, ParamKind::String)),
+        }
+    }
+
+    pub fn as_gen(self) -> Result<GenBox, GenFactoryError> {
+        match self {
+            ParamValue::Integer(v) => Ok(Box::new(self::param::Param { name : "_".to_string(), default: v as f32, buf: SampleBuffer::new(1) })),
+            ParamValue::Float(v) => Ok(Box::new(self::param::Param { name : "_".to_string(), default: v, buf: SampleBuffer::new(1) })),
+            ParamValue::String(_) => Err(GenFactoryError::CannotConvert(ParamKind::String, ParamKind::Generator)),
+            ParamValue::Generator(g) => Ok(g),
+        }
+    }
+}
+
+impl<'a> From<&'a ParamValue> for ParamKind {
+    fn from(val: &'a ParamValue) -> ParamKind {
+        val.kind()
+    }
+}
+
+#[derive(Default)]
+pub struct FactoryParameters {
+    pub env: Environment,
+    pub vars: HashMap<String, ParamValue>,
+}
+
+impl FactoryParameters {
+    pub fn get_param<'a, 'b : 'a>(&'a self, name: &str, position: usize, default: &'b ParamValue) -> &'a ParamValue {
+        (
+            self.vars.get(name).or_else(||
+                self.vars.get(&position.to_string()).or(Some(default))
+            )
+        ).unwrap()
+    }
+
+    pub fn get_req_param(&self, name: &str, position: usize) -> Result<&ParamValue, GenFactoryError> {
+        match self.vars.get(name).or_else(|| self.vars.get(&position.to_string())) {
+            Some(v) => Ok(v),
+            None => Err(GenFactoryError::MissingRequiredParam(name.to_string(), position)),
+        }
+    }
+
+    pub fn remove_param(&mut self, name: &str, position: usize) -> Result<ParamValue, GenFactoryError> {
+        match self.vars.remove(name).or_else(|| self.vars.remove(&position.to_string())) {
+            Some(v) => Ok(v),
+            None => Err(GenFactoryError::MissingRequiredParam(name.to_string(), position)),
+        }
+    }
+
+    pub fn get_pos_params(&mut self) -> Vec<ParamValue> {
+        let mut ret = Vec::new();
+
+        for i in 0.. {
+            match self.vars.remove(&i.to_string()) {
+                Some(v) => ret.push(v),
+                None => return ret,
+            }
+        }
+
+        unreachable!()
+    }
+}
+
+pub trait GeneratorFactory {
+    // NB: Like above, &self is for object safety. This should have an associated type, but that
+    // would compromise object safety; for the same reason, the return of this may only be a
+    // Box<Generator>, which necessitates allocation.
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError>;
+}
+
 pub mod param;
 pub use self::param::Param;
 pub mod math;
@@ -179,3 +360,22 @@ pub mod noise;
 pub use self::noise::Noise;
 //pub mod adsr;
 //pub use self::adsr::ADSR;
+
+pub fn all_factories() -> HashMap<String, &'static GeneratorFactory> {
+    let mut ret = HashMap::new();
+
+    ret.insert("param".to_string(), &self::param::Factory as &GeneratorFactory);
+    ret.insert("add".to_string(), &self::math::FactoryAdd as &GeneratorFactory);
+    ret.insert("mul".to_string(), &self::math::FactoryMul as &GeneratorFactory);
+    ret.insert("negate".to_string(), &self::math::FactoryNegate as &GeneratorFactory);
+    ret.insert("reciprocate".to_string(), &self::math::FactoryReciprocate as &GeneratorFactory);
+    ret.insert("rel".to_string(), &self::rel::Factory as &GeneratorFactory);
+    ret.insert("ifelse".to_string(), &self::logic::Factory as &GeneratorFactory);
+    ret.insert("sine".to_string(), &self::sine::Factory as &GeneratorFactory);
+    ret.insert("saw".to_string(), &self::saw::Factory as &GeneratorFactory);
+    ret.insert("triangle".to_string(), &self::triangle::Factory as &GeneratorFactory);
+    ret.insert("square".to_string(), &self::square::Factory as &GeneratorFactory);
+    ret.insert("noise".to_string(), &self::noise::Factory as &GeneratorFactory);
+
+    ret
+}

+ 26 - 1
src/synth/noise.rs

@@ -1,7 +1,8 @@
 use std::mem;
 use super::*;
 
-use ::rand::{XorShiftRng, Rng};
+use ::rand::{XorShiftRng, Rng, SeedableRng};
+use ::rand::os::OsRng;
 
 #[derive(Debug)]
 pub struct Noise {
@@ -19,8 +20,32 @@ impl Generator for Noise {
 
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
 
+static mut _rand_gen: Option<OsRng> = None;
+
+pub struct NoiseFactory;
+
+impl GeneratorFactory for NoiseFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        if unsafe { &_rand_gen }.is_none() {
+            unsafe {_rand_gen = Some(OsRng::new().expect("Couldn't initialize OS random")); }
+        }
+
+        let mut seed: [u32; 4] = Default::default();
+        for i in seed.iter_mut() {
+            *i = unsafe { &mut _rand_gen }.as_mut().unwrap().next_u32();
+        }
+
+        Ok(Box::new(Noise {
+            rng: XorShiftRng::from_seed(seed),
+            buf: SampleBuffer::new(params.env.default_buffer_size),
+        }))
+    }
+}
+
+pub static Factory: NoiseFactory = NoiseFactory;

+ 15 - 0
src/synth/param.rs

@@ -12,7 +12,22 @@ impl Generator for Param {
         self.buf.set(*params.vars.get(&self.name).unwrap_or(&self.default));
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct ParamFactory;
+
+impl GeneratorFactory for ParamFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        Ok(Box::new(Param {
+            name: params.get_req_param("name", 0)?.as_string()?,
+            default: params.get_param("default", 1, &ParamValue::Float(0.0)).as_f32()?,
+            buf: SampleBuffer::new(1),
+        }))
+    }
+}
+
+pub static Factory: ParamFactory = ParamFactory;

+ 62 - 0
src/synth/rel.rs

@@ -11,6 +11,39 @@ pub enum RelOp {
     Less,
 }
 
+/* TODO
+impl<T: PartialEq<isize>> From<T> for RelOp {
+    fn from(i: T) -> RelOp {
+        match i {
+            0 => RelOp::Greater,
+            1 => RelOp::GreaterEqual,
+            _ => RelOp::Equal,
+            3 => RelOp::NotEqual,
+            4 => RelOp::LessEqual,
+            5 => RelOp::Less,
+        }
+    }
+}
+*/
+
+impl<'a> From<&'a str> for RelOp {
+    fn from(s: &'a str) -> RelOp {
+        if s == ">" {
+            RelOp::Greater
+        } else if s == ">=" {
+            RelOp::GreaterEqual
+        } else if s == "!=" {
+            RelOp::NotEqual
+        } else if s == "<=" {
+            RelOp::LessEqual
+        } else if s == "<" {
+            RelOp::Less
+        } else {
+            RelOp::Equal
+        }
+    }
+}
+
 #[derive(Debug)]
 pub struct Rel {
     pub left: GenBox,
@@ -72,7 +105,36 @@ impl Generator for Rel {
 
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct RelFactory;
+
+impl GeneratorFactory for RelFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        let op = match params.get_req_param("rel", 1)? {
+            /* TODO
+            &ParamValue::Integer(v) => v.into(),
+            &ParamValue::Float(v) => (v as isize).into(),
+            */
+            &ParamValue::Integer(_) => return Err(GenFactoryError::BadType(ParamKind::Integer)),
+            &ParamValue::Float(_) => return Err(GenFactoryError::BadType(ParamKind::Float)),
+            &ParamValue::String(ref v) => (&*v as &str).into(),
+            &ParamValue::Generator(_) => return Err(GenFactoryError::BadType(ParamKind::Generator)),
+        };
+        let left = params.remove_param("left", 0)?.as_gen()?;
+        let right = params.remove_param("right", 2)?.as_gen()?;
+        let buf = SampleBuffer::new(cmp::max(left.buffer().len(), right.buffer().len()));
+        Ok(Box::new(Rel {
+            left: left,
+            right: right,
+            op: op,
+            buf: buf,
+        }))
+    }
+}
+
+pub static Factory: RelFactory = RelFactory;

+ 15 - 0
src/synth/saw.rs

@@ -19,7 +19,22 @@ impl Generator for Saw {
         self.phase = (self.phase + pvel * (self.buf.len() as f32)) % 1.0;
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct SawFactory;
+
+impl GeneratorFactory for SawFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        Ok(Box::new(Saw {
+            freq: params.remove_param("freq", 0)?.as_gen()?,
+            phase: params.get_param("phase", 1, &ParamValue::Float(0.0)).as_f32()?,
+            buf: SampleBuffer::new(params.env.default_buffer_size),
+        }))
+    }
+}
+
+pub static Factory: SawFactory = SawFactory;

+ 15 - 0
src/synth/sine.rs

@@ -22,7 +22,22 @@ impl Generator for Sine {
         self.phase = (self.phase + pvel * (self.buf.len() as f32)) % TAU;
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct SineFactory;
+
+impl GeneratorFactory for SineFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        Ok(Box::new(Sine {
+            freq: params.remove_param("freq", 0)?.as_gen()?,
+            phase: params.get_param("phase", 1, &ParamValue::Float(0.0)).as_f32()?,
+            buf: SampleBuffer::new(params.env.default_buffer_size),
+        }))
+    }
+}
+
+pub static Factory: SineFactory = SineFactory;

+ 15 - 0
src/synth/square.rs

@@ -23,7 +23,22 @@ impl Generator for Square {
         self.phase = (self.phase + pvel * (self.buf.len() as f32)) % 1.0;
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct SquareFactory;
+
+impl GeneratorFactory for SquareFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        Ok(Box::new(Square {
+            freq: params.remove_param("freq", 0)?.as_gen()?,
+            phase: params.get_param("phase", 1, &ParamValue::Float(0.0)).as_f32()?,
+            buf: SampleBuffer::new(params.env.default_buffer_size),
+        }))
+    }
+}
+
+pub static Factory: SquareFactory = SquareFactory;

+ 15 - 0
src/synth/triangle.rs

@@ -27,7 +27,22 @@ impl Generator for Triangle {
         self.phase = (self.phase + pvel * (self.buf.len() as f32)) % 1.0;
         &self.buf
     }
+    fn buffer<'a>(&'a self) -> &'a SampleBuffer { &self.buf }
     fn set_buffer(&mut self, buf: SampleBuffer) -> SampleBuffer {
         mem::replace(&mut self.buf, buf)
     }
 }
+
+pub struct TriangleFactory;
+
+impl GeneratorFactory for TriangleFactory {
+    fn new(&self, params: &mut FactoryParameters) -> Result<GenBox, GenFactoryError> {
+        Ok(Box::new(Triangle {
+            freq: params.remove_param("freq", 0)?.as_gen()?,
+            phase: params.get_param("phase", 1, &ParamValue::Float(0.0)).as_f32()?,
+            buf: SampleBuffer::new(params.env.default_buffer_size),
+        }))
+    }
+}
+
+pub static Factory: TriangleFactory = TriangleFactory;