From beb6595f426b2873112a950ab737ddfcffcb262f Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:32:22 -0600 Subject: [PATCH] reststs AND rustfmt changed whitespace --- src/main.rs | 2 +- src/seq.rs | 240 ++++++++++++++++++++++++++-------------------------- src/syn.rs | 192 +++++++++++++++++++++-------------------- src/tone.rs | 114 ++++++++++++++----------- 4 files changed, 285 insertions(+), 263 deletions(-) diff --git a/src/main.rs b/src/main.rs index 69bd32f..c4f2c28 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,7 +15,7 @@ fn main() { )); syn_seq.append(1, "3c1"); if let Some(play) = flags.play { - syn_seq.append(0, play); + syn_seq.append(0, play); } play(syn_seq, flags.sample_rate, flags.bpm); diff --git a/src/seq.rs b/src/seq.rs index 0639a41..7b09272 100644 --- a/src/seq.rs +++ b/src/seq.rs @@ -1,158 +1,160 @@ -use crate::tone; use crate::syn; +use crate::tone; pub struct SynSeq { - seqs: std::collections::HashMap, - syn: syn::Syn, + seqs: std::collections::HashMap, + syn: syn::Syn, } pub fn new_syn(syn: syn::Syn) -> SynSeq { - SynSeq{ - seqs: std::collections::HashMap::new(), - syn: syn, - } + SynSeq { + seqs: std::collections::HashMap::new(), + syn: syn, + } } impl SynSeq { - pub fn append(&mut self, ch: i32, s: S) { - match self.seqs.get_mut(&ch) { - Some(seq) => seq.append(s), - None => { - let mut seq = new(); - seq.append(s); - self.seqs.insert(ch, seq); - }, - }; - } + pub fn append(&mut self, ch: i32, s: S) { + match self.seqs.get_mut(&ch) { + Some(seq) => seq.append(s), + None => { + let mut seq = new(); + seq.append(s); + self.seqs.insert(ch, seq); + } + }; + } - pub fn render(&mut self, left: &mut [f32], right: &mut [f32]) { - for (ch, seq) in self.seqs.iter_mut() { - let ch = ch.clone(); - match seq.pop() { - (Some(tone), changed) if changed => { - self.syn.set(ch, Some(tone.clone())) - }, - (None, changed) if changed => { - self.syn.set(ch, None); - }, - _ => {}, - }; - } - self.syn.render(left, right); - } + pub fn render(&mut self, left: &mut [f32], right: &mut [f32]) { + for (ch, seq) in self.seqs.iter_mut() { + let ch = ch.clone(); + match seq.pop() { + (Some(tone), changed) if changed => self.syn.set(ch, Some(tone.clone())), + (None, changed) if changed => { + self.syn.set(ch, None); + } + _ => {} + }; + } + self.syn.render(left, right); + } - pub fn beats(&self) -> usize { - let mut longest = 0 as usize; - for (_, seq) in self.seqs.iter() { - longest = if seq.len() > longest { - seq.len() - } else { - longest - }; - } - longest - } + pub fn beats(&self) -> usize { + let mut longest = 0 as usize; + for (_, seq) in self.seqs.iter() { + longest = if seq.len() > longest { + seq.len() + } else { + longest + }; + } + longest + } } #[derive(PartialEq)] pub struct Seq { - beats: Vec<(usize, tone::Tone)>, - state: Option, + beats: Vec<(usize, tone::Tone)>, + state: Option, } fn new() -> Seq { - Seq::new() + Seq::new() } impl Seq { - fn new() -> Seq { - Seq{ - beats: vec![], - state: None, - } - } + fn new() -> Seq { + Seq { + beats: vec![], + state: None, + } + } - fn len(&self) -> usize { - let mut sum = 0 as usize; - for beat in self.beats.iter() { - sum += beat.0 as usize; - } - sum - } + fn len(&self) -> usize { + let mut sum = 0 as usize; + for beat in self.beats.iter() { + sum += beat.0 as usize; + } + sum + } - fn pop(&mut self) -> (Option, bool) { - let state_before = self.state.clone(); - let tone_after = self._pop(); - if state_before != tone_after { - self.state = tone_after.clone(); - } - (tone_after, self.state != state_before) - } + fn pop(&mut self) -> (Option, bool) { + let state_before = self.state.clone(); + let tone_after = self._pop(); + if state_before != tone_after { + self.state = tone_after.clone(); + } + (tone_after, self.state != state_before) + } - fn _pop(&mut self) -> Option { - match self.beats.len() { - 0 => None, - _ => match self.beats[0].0 { - 1 => Some(self.beats.remove(0).1), - _ => { - self.beats[0].0 -= 1; - Some(self.beats[0].1.clone()) + fn _pop(&mut self) -> Option { + match self.beats.len() { + 0 => None, + _ => match self.beats[0].0 { + 1 => Some(self.beats.remove(0).1), + _ => { + self.beats[0].0 -= 1; + Some(self.beats[0].1.clone()) + } }, - }, - } - } + } + } - fn append(&mut self, s: S) { - let s: String = s.to_string(); - let s: &str = s.as_ref(); - for split in s.split_whitespace() { - self.append_one(split.to_string()); - } - } + fn append(&mut self, s: S) { + let s: String = s.to_string(); + let s: &str = s.as_ref(); + for split in s.split_whitespace() { + self.append_one(split.to_string()); + } + } - fn append_one(&mut self, s: String) { - let re = regex::Regex::new(r"^(?[0-9]*)(?[a-z].*)$").unwrap(); - let captures = re.captures(&s).unwrap(); + fn append_one(&mut self, s: String) { + let re = regex::Regex::new(r"^(?[0-9]*)(?.*)$").unwrap(); + let captures = re.captures(&s).unwrap(); - let n = match captures.name("count") { - Some(number) if number.as_str().len() > 0 => number.as_str().parse::().unwrap(), - _ => 1, - } as usize; + let n = match captures.name("count") { + Some(number) if number.as_str().len() > 0 => number.as_str().parse::().unwrap(), + _ => 1, + } as usize; - let tone = tone::new(captures.name("tone").unwrap().as_str()); - self.beats.push((n, tone)); - } + let tone = tone::new(captures.name("tone").unwrap().as_str()); + self.beats.push((n, tone)); + } } #[cfg(test)] mod test { - use super::*; + use super::*; - #[test] - fn test_seq() { - let mut seq = new(); + #[test] + fn test_seq() { + let mut seq = new(); - seq.append("c"); - seq.append("4d"); - seq.append("g 2e"); + seq.append("c"); + seq.append("4d"); + seq.append("2-"); + seq.append("g 2e"); - assert_eq!(seq.beats.len(), 4); - assert_eq!(seq.len(), 8); + assert_eq!(seq.beats.len(), 5); + assert_eq!(seq.len(), 10); - assert_eq!(seq.beats[0], (1 as usize, tone::new("c"))); - assert_eq!(seq.beats[1], (4 as usize, tone::new("d"))); - assert_eq!(seq.beats[2], (1 as usize, tone::new("g"))); - assert_eq!(seq.beats[3], (2 as usize, tone::new("e"))); + assert_eq!(seq.beats[0], (1 as usize, tone::new("c"))); + assert_eq!(seq.beats[1], (4 as usize, tone::new("d"))); + assert_eq!(seq.beats[2], (2 as usize, tone::new("!"))); + assert_eq!(seq.beats[3], (1 as usize, tone::new("g"))); + assert_eq!(seq.beats[4], (2 as usize, tone::new("e"))); - assert_eq!(seq.pop(), (Some(tone::new("c")), true)); - assert_eq!(seq.pop(), (Some(tone::new("d")), true)); - for _ in 1..4 { - assert_eq!(seq.pop(), (Some(tone::new("d")), false)); - } - assert_eq!(seq.pop(), (Some(tone::new("g")), true)); - assert_eq!(seq.pop(), (Some(tone::new("e")), true)); - assert_eq!(seq.pop(), (Some(tone::new("e")), false)); - assert_eq!(seq.pop(), (None, true)); - assert_eq!(seq.pop(), (None, false)); - } + assert_eq!(seq.pop(), (Some(tone::new("c")), true)); + assert_eq!(seq.pop(), (Some(tone::new("d")), true)); + for _ in 1..4 { + assert_eq!(seq.pop(), (Some(tone::new("d")), false)); + } + assert_eq!(seq.pop(), (Some(tone::new(".")), true)); + assert_eq!(seq.pop(), (Some(tone::new("?")), false)); + assert_eq!(seq.pop(), (Some(tone::new("g")), true)); + assert_eq!(seq.pop(), (Some(tone::new("e")), true)); + assert_eq!(seq.pop(), (Some(tone::new("e")), false)); + assert_eq!(seq.pop(), (None, true)); + assert_eq!(seq.pop(), (None, false)); + } } diff --git a/src/syn.rs b/src/syn.rs index dd532b0..83cb2c2 100644 --- a/src/syn.rs +++ b/src/syn.rs @@ -1,123 +1,129 @@ -use rustysynth::Synthesizer; use rustysynth::SoundFont; +use rustysynth::Synthesizer; use rustysynth::SynthesizerSettings; use std::sync::Arc; use crate::tone; pub enum Syn { - Real(Synthesizer), - Text{ - m: std::collections::HashMap>, - i: u32, - }, + Real(Synthesizer), + Text { + m: std::collections::HashMap>, + i: u32, + }, } impl Syn { - pub fn new(debug: bool, sound_font: String, sample_rate: usize) -> Syn { - match debug { - false => Syn::new_real(sound_font, sample_rate), - true => Syn::Text{m: std::collections::HashMap::new(), i: 0}, - } - } + pub fn new(debug: bool, sound_font: String, sample_rate: usize) -> Syn { + match debug { + false => Syn::new_real(sound_font, sample_rate), + true => Syn::Text { + m: std::collections::HashMap::new(), + i: 0, + }, + } + } - fn new_real(sound_font: String, sample_rate: usize) -> Syn { - let mut sf2 = std::fs::File::open(sound_font).unwrap(); - let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap()); + fn new_real(sound_font: String, sample_rate: usize) -> Syn { + let mut sf2 = std::fs::File::open(sound_font).unwrap(); + let sound_font = Arc::new(SoundFont::new(&mut sf2).unwrap()); - let settings = SynthesizerSettings::new(sample_rate as i32); + let settings = SynthesizerSettings::new(sample_rate as i32); - let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap(); - Syn::Real(synthesizer) - } + let synthesizer = Synthesizer::new(&sound_font, &settings).unwrap(); + Syn::Real(synthesizer) + } - pub fn set(&mut self, ch: i32, b: Option) { - match self { - // channel=[0..16) - // velocity=[0..128) - Syn::Real(syn) => { - syn.note_off_all_channel(ch, false); - }, - Syn::Text{m, ..} => { - m.remove(&ch); - }, - }; - if let Some(tone) = b { - self.tone_on(ch, tone); - }; - } + pub fn set(&mut self, ch: i32, b: Option) { + match self { + // channel=[0..16) + // velocity=[0..128) + Syn::Real(syn) => { + syn.note_off_all_channel(ch, false); + } + Syn::Text { m, .. } => { + m.remove(&ch); + } + }; + if let Some(tone) = b { + self.tone_on(ch, tone); + }; + } - fn tone_on(&mut self, ch: i32, b: tone::Tone) { - match self { - // channel=[0..16) - // velocity=[0..128) - Syn::Real(syn) => syn.note_on(ch, b.i32(), 127), - Syn::Text{m, ..} => { - match m.get_mut(&ch) { - Some(m2) => { m2.insert(b.i32(), 127); }, - None => { - let mut m2 = std::collections::HashMap::new(); - m2.insert(b.i32(), 127); - m.insert(ch, m2); - }, - }; - }, - }; - } + fn tone_on(&mut self, ch: i32, b: tone::Tone) { + match self { + // channel=[0..16) + // velocity=[0..128) + Syn::Real(syn) => syn.note_on(ch, b.i32(), 127), + Syn::Text { m, .. } => { + match m.get_mut(&ch) { + Some(m2) => { + m2.insert(b.i32(), 127); + } + None => { + let mut m2 = std::collections::HashMap::new(); + m2.insert(b.i32(), 127); + m.insert(ch, m2); + } + }; + } + }; + } - fn tone_off(&mut self, ch: i32, b: tone::Tone) { - match self { - Syn::Real(syn) => syn.note_off(ch, b.i32()), - Syn::Text{m, ..} => { - match m.get_mut(&ch) { - Some(m) => { m.remove(&b.i32()); }, - None => {}, - }; + fn tone_off(&mut self, ch: i32, b: tone::Tone) { + match self { + Syn::Real(syn) => syn.note_off(ch, b.i32()), + Syn::Text { m, .. } => { + match m.get_mut(&ch) { + Some(m) => { + m.remove(&b.i32()); + } + None => {} + }; + } + }; + } - }, - }; - } - - pub fn render(&mut self, a: &mut [f32], b: &mut [f32]) { - match self { - Syn::Real(syn) => syn.render(a, b), - Syn::Text{m, i} => { - eprintln!("{} | render[{}]({:?})", chrono::prelude::Utc::now(), i, m); - *i += 1; - }, - }; - } + pub fn render(&mut self, a: &mut [f32], b: &mut [f32]) { + match self { + Syn::Real(syn) => syn.render(a, b), + Syn::Text { m, i } => { + eprintln!("{} | render[{}]({:?})", chrono::prelude::Utc::now(), i, m); + *i += 1; + } + }; + } } #[cfg(test)] mod test { - use super::*; + use super::*; - #[test] - fn test_new_real() { - let mut syn = Syn::new(false, "super_small_font.sf2".to_string(), 44100); + #[test] + fn test_new_real() { + let mut syn = Syn::new(false, "super_small_font.sf2".to_string(), 44100); - syn.tone_on(0, tone::new("c")); - syn.tone_on(0, tone::new("d")); + syn.tone_on(0, tone::new("c")); + syn.tone_on(0, tone::new("d")); - syn.tone_off(0, tone::new("d")); + syn.tone_off(0, tone::new("d")); - let mut buffer1 = Vec::::new(); - let mut buffer2 = Vec::::new(); - syn.render(&mut buffer1, &mut buffer2); - } + let mut buffer1 = Vec::::new(); + let mut buffer2 = Vec::::new(); + syn.render(&mut buffer1, &mut buffer2); + } - #[test] - fn test_text() { - let mut syn = Syn::new(true, ".sf2".to_string(), 1); + #[test] + fn test_text() { + let mut syn = Syn::new(true, ".sf2".to_string(), 1); - syn.tone_on(0, tone::new("c")); - syn.tone_on(0, tone::new("d")); + syn.tone_on(0, tone::new("c")); + syn.tone_on(0, tone::new("d")); - syn.tone_off(0, tone::new("d")); + syn.tone_off(0, tone::new("d")); - let mut buffer1 = Vec::::new(); - let mut buffer2 = Vec::::new(); - syn.render(&mut buffer1, &mut buffer2); - } + let mut buffer1 = Vec::::new(); + let mut buffer2 = Vec::::new(); + syn.render(&mut buffer1, &mut buffer2); + } } diff --git a/src/tone.rs b/src/tone.rs index 2a0f7df..ae76ff0 100644 --- a/src/tone.rs +++ b/src/tone.rs @@ -3,69 +3,83 @@ pub struct Tone(i32); // new parses [a-g][+-]?[1-5]? to tone, sharp or flat, down 2 octave..up 1 octave pub fn new(s: S) -> Tone { - Tone::new(s.to_string()) + Tone::new(s.to_string()) } impl Tone { - fn new(s: String) -> Tone { - let re = regex::Regex::new(r"^((?^[a-g])(?[+-]?)(?[1-5]?)|(?[0-9]+))$").unwrap(); - let captures = re.captures(s.as_ref()).unwrap(); - Tone (match captures.name("numeric") { - Some(number) => number.as_str().parse::().unwrap(), - None => { - let mut result = match captures.name("letter").unwrap().as_str() { - "a" => 57, - "b" => 59, - "c" => 60, - "d" => 62, - "e" => 64, - "f" => 65, - _ => 67, - } as i32; + fn new(s: String) -> Tone { + let re = regex::Regex::new(r"^((?^[a-g])(?[+-]?)(?[1-5]?)|(?[0-9]+)|(?[^a-zA-Z0-9]))$").unwrap(); + let captures = re + .captures(&s) + .expect(format!("tone '{}' does not match regex", s).as_ref()); + Tone(match captures.name("numeric") { + Some(number) => number.as_str().parse::().unwrap(), + None => match captures.name("rest") { + Some(_) => 0, + _ => { + let mut result = match captures.name("letter").unwrap().as_str() { + "a" => 57, + "b" => 59, + "c" => 60, + "d" => 62, + "e" => 64, + "f" => 65, + _ => 67, + } as i32; - result += match captures.name("sharpness") { - Some(sharpness) => match sharpness.as_str() { - "+" => 1, - "-" => -1, - _ => 0, - }, - None => 0, - } as i32; + result += match captures.name("sharpness") { + Some(sharpness) => match sharpness.as_str() { + "+" => 1, + "-" => -1, + _ => 0, + }, + None => 0, + } as i32; - result += match captures.name("octave") { - Some(octave) => match octave.as_str() { - "" => 0, - _ => (octave.as_str().parse::().unwrap() - 3) * 12, - }, - None => 0, - } as i32; + result += match captures.name("octave") { + Some(octave) => match octave.as_str() { + "" => 0, + _ => (octave.as_str().parse::().unwrap() - 3) * 12, + }, + None => 0, + } as i32; - result - }, - }) - } + result + } + }, + }) + } - pub fn i32(&self) -> i32 { - self.0 - } + pub fn i32(&self) -> i32 { + self.0 + } } #[cfg(test)] mod test { - #[test] - fn test_tone_new() { - assert_eq!(super::new("60").i32(), 60); + #[test] + fn test_tone_new() { + eprintln!("numeric"); + assert_eq!(super::new("60").i32(), 60); - assert_eq!(super::new("c").i32(), 60); - assert_eq!(super::new("e").i32(), 64); - assert_eq!(super::new("g").i32(), 67); + eprintln!("rests"); + assert_eq!(super::new("-").i32(), 0); + assert_eq!(super::new(".").i32(), 0); - assert_eq!(super::new("c+").i32(), 60+1); - assert_eq!(super::new("c-").i32(), 60-1); + eprintln!("alpha"); + assert_eq!(super::new("c").i32(), 60); + assert_eq!(super::new("e").i32(), 64); + assert_eq!(super::new("g").i32(), 67); - assert_eq!(super::new("c3").i32(), 60); - assert_eq!(super::new("c4").i32(), 60+12); + eprintln!("alpha mod"); + assert_eq!(super::new("c+").i32(), 60 + 1); + assert_eq!(super::new("c-").i32(), 60 - 1); - assert_eq!(super::new("c+4").i32(), 60+12+1); - } + eprintln!("alpha octave"); + assert_eq!(super::new("c3").i32(), 60); + assert_eq!(super::new("c4").i32(), 60 + 12); + + eprintln!("alpha mod octave"); + assert_eq!(super::new("c+4").i32(), 60 + 12 + 1); + } }