diff options
-rw-r--r-- | src/client.rs | 31 | ||||
-rw-r--r-- | src/lang/parser.rs | 15 | ||||
-rw-r--r-- | src/lib.rs | 5 | ||||
-rw-r--r-- | src/main.rs | 12 | ||||
-rw-r--r-- | src/proto.rs | 112 | ||||
-rw-r--r-- | src/seq/file/mod.rs | 1 | ||||
-rw-r--r-- | src/seq/mod.rs | 100 | ||||
-rw-r--r-- | src/seq/sequencer.rs | 16 | ||||
-rw-r--r-- | src/types.rs | 2 |
9 files changed, 215 insertions, 79 deletions
diff --git a/src/client.rs b/src/client.rs index bf661d0..89bda03 100644 --- a/src/client.rs +++ b/src/client.rs @@ -139,19 +139,32 @@ impl Client { let mut reply_buffer: [u8; Command::SIZE] = [0u8; Command::SIZE]; reply.write_into(&mut reply_buffer); self.socket.send_to(&reply_buffer, sender); - }, - Command::PCM{..} => { /* TODO */ }, - Command::PCMSyn{..} => { /* TODO */}, - Command::ArtParam{voice, index, value} => { - dprintln!("Articulation parameter voice {:?} index {} value {}", voice, index, value); + } + Command::PCM { .. } => { /* TODO */ } + Command::PCMSyn { .. } => { /* TODO */ } + Command::ArtParam { + voice, + index, + value, + } => { + dprintln!( + "Articulation parameter voice {:?} index {} value {}", + voice, + index, + value + ); for vidx in match voice { - Some(vidx) => ((vidx as usize)..((vidx+1) as usize)), + Some(vidx) => ((vidx as usize)..((vidx + 1) as usize)), None => (0..self.voices.len()), } { - *self.voices[vidx].params.vars.entry(format!("artp{}", index)).or_insert_with(Default::default) = value; + *self.voices[vidx] + .params + .vars + .entry(format!("artp{}", index)) + .or_insert_with(Default::default) = value; } - }, - Command::Unknown{data} => { + } + Command::Unknown { data } => { dprintln!("Dropping packet: unknown data {:?}", (&data as &[u8])); } } diff --git a/src/lang/parser.rs b/src/lang/parser.rs index ac7eccd..9204391 100644 --- a/src/lang/parser.rs +++ b/src/lang/parser.rs @@ -14,7 +14,9 @@ macro_rules! dprintln { */ macro_rules! dprintln { - ( $( $x:expr ),* ) => { () } + ( $( $x:expr ),* ) => { + () + }; } #[derive(Debug)] @@ -428,7 +430,11 @@ impl<T: Iterator<Item = char>> Parser<T> { ctr = new_ctr; dprintln!("before factory_params comma, tok is {:?}", self.cur_token()); - if self.expect_op(',').map_err(|_e| dprintln!("factory_params consume comma failed: {:?}", e)).is_err() { + if self + .expect_op(',') + .map_err(|_e| dprintln!("factory_params consume comma failed: {:?}", e)) + .is_err() + { dprintln!("factory_params is concluding"); self.expect_op(')')?; break; @@ -459,7 +465,10 @@ impl<T: Iterator<Item = char>> Parser<T> { } }; - dprintln!("about to consume param value, token is {:?}", self.cur_token()); + dprintln!( + "about to consume param value, token is {:?}", + self.cur_token() + ); match self.cur_token().clone() { // FIXME: Does this really need to be cloned? @@ -2,7 +2,8 @@ extern crate byteorder; extern crate rand; extern crate unicode_xid; extern crate xml; -#[macro_use] extern crate failure; +#[macro_use] +extern crate failure; pub mod types; pub use types::*; @@ -10,8 +11,8 @@ pub use types::*; pub mod client; pub mod lang; pub mod monitor; -pub mod seq; pub mod proto; +pub mod seq; pub mod synth; #[cfg(feature = "graphics")] diff --git a/src/main.rs b/src/main.rs index 38c2e78..7b0f0e6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::Read; use std::net::*; use std::sync::*; -use std::{env, iter, thread, ffi}; +use std::{env, ffi, iter, thread}; extern crate portaudio; use portaudio as pa; @@ -27,11 +27,15 @@ fn main() -> Result<(), std::io::Error> { Ok(()) } - fn main_client(args: Vec<ffi::OsString>) -> Result<(), std::io::Error> { let env = Environment::default(); - let mut genfile = File::open(args.iter().nth(1).expect("Need first argument to be a file with a generator vector")).expect("Failed to open file"); + let mut genfile = File::open( + args.iter() + .nth(1) + .expect("Need first argument to be a file with a generator vector"), + ) + .expect("Failed to open file"); let mut genstr = String::new(); genfile.read_to_string(&mut genstr)?; @@ -126,7 +130,7 @@ fn main_client(args: Vec<ffi::OsString>) -> Result<(), std::io::Error> { }; eprintln!("Network thread started."); - + net_thread.join().expect("Network thread panicked"); eprintln!("Exiting."); diff --git a/src/proto.rs b/src/proto.rs index 2bf13a6..4f70295 100644 --- a/src/proto.rs +++ b/src/proto.rs @@ -1,6 +1,6 @@ use super::Pitch; -use std::time::Duration; use std::fmt; +use std::time::Duration; use ::byteorder::{ByteOrder, NetworkEndian}; @@ -13,12 +13,32 @@ pub enum Command { data: [u8; 32], }, Quit, - Play{sec: u32, usec: u32, freq: u32, amp: f32, voice: u32}, - Caps{voices: u32, tp: [u8; 4], ident: [u8; 24]}, - PCM{samples: [i16; 16]}, - PCMSyn{buffered: u32}, - ArtParam{voice: Option<u32>, index: u32, value: f32}, - Unknown{data: [u8; Command::SIZE]}, + Play { + sec: u32, + usec: u32, + freq: u32, + amp: f32, + voice: u32, + }, + Caps { + voices: u32, + tp: [u8; 4], + ident: [u8; 24], + }, + PCM { + samples: [i16; 16], + }, + PCMSyn { + buffered: u32, + }, + ArtParam { + voice: Option<u32>, + index: u32, + value: f32, + }, + Unknown { + data: [u8; Command::SIZE], + }, } impl Command { @@ -69,15 +89,22 @@ impl Command { Command::PCM { samples } => { NetworkEndian::write_u32(&mut ret[..4], 5); NetworkEndian::write_i16_into(&samples, &mut ret[4..]); - }, - Command::PCMSyn{buffered} => { + } + Command::PCMSyn { buffered } => { NetworkEndian::write_u32_into(&[6u32, buffered], &mut ret[..8]); - }, - Command::ArtParam{voice, index, value} => { - NetworkEndian::write_u32_into(&[7u32, voice.unwrap_or(OBLIGATE_POLYPHONE), index], &mut ret[..12]); + } + Command::ArtParam { + voice, + index, + value, + } => { + NetworkEndian::write_u32_into( + &[7u32, voice.unwrap_or(OBLIGATE_POLYPHONE), index], + &mut ret[..12], + ); NetworkEndian::write_f32(&mut ret[12..16], value); - }, - Command::Unknown{data} => { + } + Command::Unknown { data } => { ret.copy_from_slice(&data); } }; @@ -93,12 +120,45 @@ impl fmt::Debug for Command { Command::KeepAlive => f.write_str("KeepAlive"), Command::Ping { data } => f.debug_struct("Ping").field("data", &data).finish(), Command::Quit => f.write_str("Quit"), - Command::Play{sec, usec, freq, amp, voice} => f.debug_struct("Play").field("sec", &sec).field("usec", &usec).field("freq", &freq).field("amp", &).field("voice", &voice).finish(), - Command::Caps{voices, tp, ident} => f.debug_struct("Caps").field("voices", &voices).field("tp", &tp).field("ident", &ident).finish(), - Command::PCM{samples} => f.debug_struct("PCM").field("samples", &samples).finish(), - Command::PCMSyn{buffered} => f.debug_struct("PCMSyn").field("buffered", &buffered).finish(), - Command::ArtParam{voice, index, value} => f.debug_struct("ArtParam").field("voice", &voice).field("index", &index).field("value", &value).finish(), - Command::Unknown{data} => f.debug_struct("Unknown").field("data", &(&data as &[u8])).finish(), + Command::Play { + sec, + usec, + freq, + amp, + voice, + } => f + .debug_struct("Play") + .field("sec", &sec) + .field("usec", &usec) + .field("freq", &freq) + .field("amp", &) + .field("voice", &voice) + .finish(), + Command::Caps { voices, tp, ident } => f + .debug_struct("Caps") + .field("voices", &voices) + .field("tp", &tp) + .field("ident", &ident) + .finish(), + Command::PCM { samples } => f.debug_struct("PCM").field("samples", &samples).finish(), + Command::PCMSyn { buffered } => f + .debug_struct("PCMSyn") + .field("buffered", &buffered) + .finish(), + Command::ArtParam { + voice, + index, + value, + } => f + .debug_struct("ArtParam") + .field("voice", &voice) + .field("index", &index) + .field("value", &value) + .finish(), + Command::Unknown { data } => f + .debug_struct("Unknown") + .field("data", &(&data as &[u8])) + .finish(), } } } @@ -139,11 +199,17 @@ impl<'a> From<&'a [u8; Command::SIZE]> for Command { 5 => { let mut samples: [i16; 16] = [0; 16]; ::byteorder::LittleEndian::read_i16_into(&packet[4..], &mut samples); - Command::PCM{samples: samples} + Command::PCM { samples: samples } + } + 6 => Command::PCMSyn { + buffered: fields_u32[1], }, - 6 => Command::PCMSyn{buffered: fields_u32[1]}, 7 => Command::ArtParam { - voice: if fields_u32[1] == OBLIGATE_POLYPHONE { None } else { Some(fields_u32[1]) }, + voice: if fields_u32[1] == OBLIGATE_POLYPHONE { + None + } else { + Some(fields_u32[1]) + }, index: fields_u32[2], value: fields_f32[3], }, diff --git a/src/seq/file/mod.rs b/src/seq/file/mod.rs index f6fd39a..1f48c82 100644 --- a/src/seq/file/mod.rs +++ b/src/seq/file/mod.rs @@ -1,3 +1,2 @@ //pub mod iv; //pub mod midi; - diff --git a/src/seq/mod.rs b/src/seq/mod.rs index a6957d3..1a4cc95 100644 --- a/src/seq/mod.rs +++ b/src/seq/mod.rs @@ -2,12 +2,12 @@ pub mod sequencer; pub use self::sequencer::*; pub mod file; -use std::{cmp, iter, ops}; -use std::collections::{hash_map, HashMap}; +use std::collections::HashMap; +use std::{cmp, ops}; -use super::*; +use super::Pitch; -#[derive(Debug,Clone,Copy,PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct Seconds(pub f32); impl Eq for Seconds {} @@ -26,27 +26,41 @@ impl Ord for Seconds { impl ops::Add for Seconds { type Output = Seconds; - fn add(self, rhs: Seconds) -> Seconds { Seconds(self.0 + rhs.0) } + fn add(self, rhs: Seconds) -> Seconds { + Seconds(self.0 + rhs.0) + } } impl ops::Sub for Seconds { type Output = Seconds; - fn sub(self, rhs: Seconds) -> Seconds { Seconds(self.0 - rhs.0) } + fn sub(self, rhs: Seconds) -> Seconds { + Seconds(self.0 - rhs.0) + } } -impl<RHS> ops::Mul<RHS> for Seconds where f32: ops::Mul<RHS, Output=f32> { +impl<RHS> ops::Mul<RHS> for Seconds +where + f32: ops::Mul<RHS, Output = f32>, +{ type Output = Seconds; - fn mul(self, rhs: RHS) -> Seconds { Seconds(self.0.mul(rhs)) } + fn mul(self, rhs: RHS) -> Seconds { + Seconds(self.0.mul(rhs)) + } } -impl<RHS> ops::Div<RHS> for Seconds where f32: ops::Div<RHS, Output=f32> { +impl<RHS> ops::Div<RHS> for Seconds +where + f32: ops::Div<RHS, Output = f32>, +{ type Output = Seconds; - fn div(self, rhs: RHS) -> Seconds { Seconds(self.0.div(rhs)) } + fn div(self, rhs: RHS) -> Seconds { + Seconds(self.0.div(rhs)) + } } pub type Ticks = u64; -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub enum Time { Seconds(Seconds), Ticks(Ticks), @@ -64,7 +78,7 @@ impl From<Ticks> for Time { } } -#[derive(Debug,Clone,Copy,PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq)] pub struct BPM(pub f32); impl Eq for BPM {} @@ -81,16 +95,26 @@ impl Ord for BPM { } } -impl<RHS> ops::Mul<RHS> for BPM where f32: ops::Mul<RHS, Output=f32> { +impl<RHS> ops::Mul<RHS> for BPM +where + f32: ops::Mul<RHS, Output = f32>, +{ type Output = BPM; - fn mul(self, rhs: RHS) -> BPM { BPM(self.0.mul(rhs)) } + fn mul(self, rhs: RHS) -> BPM { + BPM(self.0.mul(rhs)) + } } -impl<RHS> ops::Div<RHS> for BPM where f32: ops::Div<RHS, Output=f32> { +impl<RHS> ops::Div<RHS> for BPM +where + f32: ops::Div<RHS, Output = f32>, +{ type Output = BPM; - fn div(self, rhs: RHS) -> BPM { BPM(self.0.div(rhs)) } + fn div(self, rhs: RHS) -> BPM { + BPM(self.0.div(rhs)) + } } -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub struct Note { pub time: Seconds, pub dur: Seconds, @@ -100,7 +124,7 @@ pub struct Note { pub pitch: Pitch, } -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub struct Aux { pub time: Seconds, pub data: String, @@ -109,7 +133,7 @@ pub struct Aux { pub type NoteStream = Vec<Note>; pub type AuxStream = Vec<Aux>; -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub enum Stream { Note(NoteStream), Aux(AuxStream), @@ -126,14 +150,14 @@ impl Stream { pub type Group = Vec<NoteStream>; -#[derive(Debug,Clone,Copy)] +#[derive(Debug, Clone, Copy)] pub struct BPMEntry { pub abstick: Ticks, pub bpm: BPM, pub realtime: Option<Seconds>, } -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub struct BPMTableInput { pub entries: Vec<BPMEntry>, pub resolution: f32, @@ -146,10 +170,17 @@ impl From<BPMTableInput> for BPMTable { for ent in range.iter_mut() { ent.realtime = Some(Seconds(0.0)); } - for idx in 1 .. (range.len() - 1) { + for idx in 1..(range.len() - 1) { let tick = range[idx].abstick; - let BPMEntry {abstick: ptick, bpm: pbpm, realtime: ptm} = range[idx - 1]; - range[idx].realtime = Some(ptm.unwrap() + Seconds((60.0 * ((tick - ptick) as f32)) / (pbpm * input.resolution).0)); + let BPMEntry { + abstick: ptick, + bpm: pbpm, + realtime: ptm, + } = range[idx - 1]; + range[idx].realtime = Some( + ptm.unwrap() + + Seconds((60.0 * ((tick - ptick) as f32)) / (pbpm * input.resolution).0), + ); } BPMTable { range: range, @@ -171,9 +202,13 @@ impl BPMTable { Ok(idx) => self.range[idx].realtime.unwrap(), Err(idx) => { let effidx = cmp::max(0, idx - 1); - let BPMEntry {abstick: tick, bpm, realtime: sec} = self.range[effidx]; + let BPMEntry { + abstick: tick, + bpm, + realtime: sec, + } = self.range[effidx]; sec.unwrap() + Seconds((60.0 * ((t - tick) as f32)) / (bpm * self.resolution).0) - }, + } }, } } @@ -185,13 +220,20 @@ impl BPMTable { pub fn to_ticks(&self, tm: Time) -> Ticks { match tm { Time::Ticks(t) => t, - Time::Seconds(s) => match self.range.binary_search_by_key(&s, |&ent| ent.realtime.unwrap()) { + Time::Seconds(s) => match self + .range + .binary_search_by_key(&s, |&ent| ent.realtime.unwrap()) + { Ok(idx) => self.range[idx].abstick, Err(idx) => { let effidx = cmp::max(0, idx - 1); - let BPMEntry {abstick: tick, bpm, realtime: sec} = self.range[effidx]; + let BPMEntry { + abstick: tick, + bpm, + realtime: sec, + } = self.range[effidx]; tick + ((((s - sec.unwrap()).0 * bpm.0 * self.resolution) / 60.0) as Ticks) - }, + } }, } } diff --git a/src/seq/sequencer.rs b/src/seq/sequencer.rs index 753a2f1..deedc4b 100644 --- a/src/seq/sequencer.rs +++ b/src/seq/sequencer.rs @@ -1,6 +1,6 @@ -use super::{NoteStream, Note, IV}; +use super::{Note, NoteStream, IV}; -pub fn coalesce<'a, I: Iterator<Item=&'a NoteStream>>(stream_iter: I) -> NoteStream { +pub fn coalesce<'a, I: Iterator<Item = &'a NoteStream>>(stream_iter: I) -> NoteStream { let mut output = NoteStream::new(); for ns in stream_iter { @@ -16,13 +16,15 @@ pub struct SchedParams { impl Default for SchedParams { fn default() -> SchedParams { - SchedParams { - epsilon: 0.0, - } + SchedParams { epsilon: 0.0 } } } -pub fn schedule<'a, 'b: 'a, I: Iterator<Item=&'a Note>, F: FnMut(&'a Note) -> Option<&'b str>>(notes: I, mut classifier: F, params: &SchedParams) -> IV { +pub fn schedule<'a, 'b: 'a, I: Iterator<Item = &'a Note>, F: FnMut(&'a Note) -> Option<&'b str>>( + notes: I, + mut classifier: F, + params: &SchedParams, +) -> IV { let mut output: IV = Default::default(); for note in notes { @@ -41,7 +43,7 @@ pub fn schedule<'a, 'b: 'a, I: Iterator<Item=&'a Note>, F: FnMut(&'a Note) -> Op if ns.len() > 0 { let nt = &ns[ns.len() - 1]; if note.time.0 < nt.time.0 + nt.dur.0 + params.epsilon { - continue + continue; } } found = Some(idx); diff --git a/src/types.rs b/src/types.rs index ddef51e..b89c641 100644 --- a/src/types.rs +++ b/src/types.rs @@ -1,6 +1,6 @@ pub type Sample = f32; -#[derive(Debug,Clone)] +#[derive(Debug, Clone)] pub enum Pitch { Freq(f32), MIDI(f32), |