From de5717a61a29241bef283f491e9c23c7e4a6248f Mon Sep 17 00:00:00 2001 From: Bel LaPointe <153096461+breel-render@users.noreply.github.com> Date: Fri, 13 Mar 2026 11:34:10 -0600 Subject: [PATCH] panic if shell desired as not impl --- Cargo.lock | 7 +++++ Cargo.toml | 1 + src/flags.rs | 2 +- src/main.rs | 32 +++++++++++++++----- src/play.rs | 52 ++++++++++++++++---------------- src/syn.rs | 18 +++++++++--- src/tone.rs | 83 +++++++++++++++++++++++++++++----------------------- 7 files changed, 121 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bf44a3b..b55d7b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -242,6 +242,7 @@ dependencies = [ "chrono", "clap", "env_logger", + "io-prompt-prototype", "itertools 0.14.0", "midir", "regex", @@ -412,6 +413,12 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "io-prompt-prototype" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca9d71ad6b790f2522eeb0a4f207fa7ef21826777d4714c7ff09483bf17b0ab8" + [[package]] name = "is_terminal_polyfill" version = "1.70.2" diff --git a/Cargo.toml b/Cargo.toml index 04d4408..07abe8a 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ edition = "2024" chrono = "0.4.44" clap = { version = "4.5.60", features = ["derive"] } env_logger = "0.11.9" +io-prompt-prototype = "1.0.0" itertools = "0.14.0" midir = "0.10.3" regex = "1.12.3" diff --git a/src/flags.rs b/src/flags.rs index 50e81a2..eee9b56 100644 --- a/src/flags.rs +++ b/src/flags.rs @@ -14,7 +14,7 @@ pub struct Flags { #[arg(long, default_value = "super_small_font.sf2")] pub sound_font: String, - #[arg(short, long, default_value = "c 2e+")] + #[arg(short, long, default_value = "c 2*e+")] pub play: Vec, } diff --git a/src/main.rs b/src/main.rs index 2e054f4..49002ae 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +use io_prompt_prototype::prompt; use itertools::Itertools; mod flags; @@ -12,11 +13,22 @@ fn main() { eprintln!("{:?}", flags); } + let once = flags.play.iter().filter(|x| x.len() > 0).count() > 0; + loop { + play_with_flags(&flags); + if once { + break; + } + } +} + +fn play_with_flags(flags: &flags::Flags) { let mut syn_seq = seq::new_syn(syn::Syn::new( - flags.debug, - flags.sound_font, - flags.sample_rate, + flags.debug.clone(), + flags.sound_font.clone(), + flags.sample_rate.clone(), )); + let mut i = 0; for p in flags.play.iter() { for p in play::new(p.clone()) { @@ -24,11 +36,15 @@ fn main() { i += 1; } } + if i == 0 { + let s: String = prompt!("> ").parse().expect("failed to readline"); + panic!("not impl"); + } - play(syn_seq, flags.sample_rate, flags.bpm); + play(syn_seq, flags.sample_rate, flags.bpm, true); } -fn play(mut s: seq::SynSeq, sample_rate: usize, bpm: usize) { +fn play(mut s: seq::SynSeq, sample_rate: usize, bpm: usize, sync: bool) { let samples_per_beat = sample_rate / bpm * 60; let params = tinyaudio::prelude::OutputDeviceParameters { channels_count: 2, @@ -52,6 +68,8 @@ fn play(mut s: seq::SynSeq, sample_rate: usize, bpm: usize) { }) .unwrap(); - // Wait it out - std::thread::sleep(std::time::Duration::from_secs(duration as u64)); + if sync { + // Wait it out + std::thread::sleep(std::time::Duration::from_secs(duration as u64)); + } } diff --git a/src/play.rs b/src/play.rs index 17ae3bb..8688bdc 100644 --- a/src/play.rs +++ b/src/play.rs @@ -20,21 +20,22 @@ fn from_string(s: String) -> String { fn parse(s: String) -> Vec { let s = s .split("\n") - .filter(|x: &&str| !x // doesnt start with # - .split_whitespace() - .collect::>() - .join("") - .starts_with("#") - ) - .map(|x| x - .split("#") - .take(1) // drop after # - .collect::>() - .join("") - .split_whitespace() - .collect::>() - .join(" ") - ) + .filter(|x: &&str| { + !x // doesnt start with # + .split_whitespace() + .collect::>() + .join("") + .starts_with("#") + }) + .map(|x| { + x.split("#") + .take(1) // drop after # + .collect::>() + .join("") + .split_whitespace() + .collect::>() + .join(" ") + }) .collect::>() .join("\n"); let mut channels = vec![]; @@ -44,21 +45,23 @@ fn parse(s: String) -> Vec { match lines[i] { "" => { j = 0; - }, + } _ => { while channels.len() <= j { channels.push("".to_string()); } - channels[{ let tmp = j; j += 1; tmp }] += &(" ".to_string() + lines[i]); - }, + channels[{ + let tmp = j; + j += 1; + tmp + }] += &(" ".to_string() + lines[i]); + } }; } channels .iter() - .map(|x| x.split_whitespace().collect::>() - .join(" ") - ) - .collect() + .map(|x| x.split_whitespace().collect::>().join(" ")) + .collect() } #[cfg(test)] @@ -111,9 +114,6 @@ mod test { #[test] fn drop_comment_trailer() { - assert_eq!( - super::new("a b c # hello world")[0], - "a b c".to_string() - ); + assert_eq!(super::new("a b c # hello world")[0], "a b c".to_string()); } } diff --git a/src/syn.rs b/src/syn.rs index 18d6abe..de06fbc 100644 --- a/src/syn.rs +++ b/src/syn.rs @@ -74,10 +74,20 @@ impl Syn { match self { Syn::Real(syn) => syn.render(a, b), Syn::Text { m, i } => { - eprintln!("{} | render[{}]({:?})", chrono::prelude::Utc::now(), i, m - .iter() - .map(|tuple| (tuple.0, tuple.1.iter().map(|v| tone::new(v.0.to_string()).string()).collect::>())) - .collect::>(), + eprintln!( + "{} | render[{}]({:?})", + chrono::prelude::Utc::now(), + i, + m.iter() + .map(|tuple| ( + tuple.0, + tuple + .1 + .iter() + .map(|v| tone::new(v.0.to_string()).string()) + .collect::>() + )) + .collect::>(), ); *i += 1; } diff --git a/src/tone.rs b/src/tone.rs index 5857bce..7e7f8d1 100644 --- a/src/tone.rs +++ b/src/tone.rs @@ -20,27 +20,31 @@ impl Tone { let mut result = match captures.name("letter") { Some(letter) => Tone::char_to_middle_i32(letter.as_str()), None => match captures.name("major") { - Some(major) => Tone::char_to_middle_i32(&major.as_str()[..1]) + match &major.as_str()[2..] { - "0" => 0, - "1" => 2, - "2" => 4, - "3" => 5, - "4" => 7, - "5" => 9, - _ => 11, - }, + Some(major) => { + Tone::char_to_middle_i32(&major.as_str()[..1]) + + match &major.as_str()[2..] { + "0" => 0, + "1" => 2, + "2" => 4, + "3" => 5, + "4" => 7, + "5" => 9, + _ => 11, + } + } None => { let minor = captures.name("minor").unwrap(); - Tone::char_to_middle_i32(&minor.as_str()[..1]) + match &minor.as_str()[2..] { - "0" => 0, - "1" => 2, - "2" => 3, - "3" => 5, - "4" => 7, - "5" => 8, - _ => 10, - } - }, + Tone::char_to_middle_i32(&minor.as_str()[..1]) + + match &minor.as_str()[2..] { + "0" => 0, + "1" => 2, + "2" => 3, + "3" => 5, + "4" => 7, + "5" => 8, + _ => 10, + } + } }, } as i32; @@ -85,23 +89,30 @@ impl Tone { pub fn string(&self) -> String { let v = self.i32(); - let modifier = if v > 0 && v < 57 { "-" } else if v >= 69 { "+" } else { "" }; - modifier.to_string() + match v { - 45|57|69 => "a", - 46|58|70 => "a+", - 47|59|71 => "b", - 48|60|72 => "c", - 49|61|73 => "c+", - 50|62|74 => "d", - 51|63|75 => "d+", - 52|64|76 => "e", - 53|65|77 => "f", - 54|66|78 => "f+", - 55|67|79 => "g", - 56|68|80 => "g+", - 0 => " ", - _ => "?", - } + let modifier = if v > 0 && v < 57 { + "-" + } else if v >= 69 { + "+" + } else { + "" + }; + modifier.to_string() + + match v { + 45 | 57 | 69 => "a", + 46 | 58 | 70 => "a+", + 47 | 59 | 71 => "b", + 48 | 60 | 72 => "c", + 49 | 61 | 73 => "c+", + 50 | 62 | 74 => "d", + 51 | 63 | 75 => "d+", + 52 | 64 | 76 => "e", + 53 | 65 | 77 => "f", + 54 | 66 | 78 => "f+", + 55 | 67 | 79 => "g", + 56 | 68 | 80 => "g+", + 0 => " ", + _ => "?", + } } }