From 991849b32acf83dd14a5096540bb053d2572502a Mon Sep 17 00:00:00 2001 From: Wavy Harp Date: Sun, 7 May 2023 23:04:53 -0600 Subject: initial import currently everything is very tied to alsa and my system, for the moment you'll need to manually change the device names and maybe channels/period_size in src/main.rs, src/bin/smolguitar.rs and src/bin/loopbacker.rs, i'll fix that and add runtime period size/updater allocation soon, (and probably make a cpal backend as well so it can work on other platforms), but doing this initial commit to play around with stereo for now~ --- src/args.rs | 140 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 src/args.rs (limited to 'src/args.rs') diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..fe4737e --- /dev/null +++ b/src/args.rs @@ -0,0 +1,140 @@ +use clap::{Parser, ValueEnum, Args}; +use crate::outputers::{ColourScheme, Outputers, SimpleOutputer, LineLayout, TuiOutputer}; +use derive_more::Display; +use crate::notes::Note; +use std::path::{PathBuf, Path}; +use std::error::Error; +use std::fs::File; +use std::io::BufReader; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Debug, Display)] +pub enum OutputerTypes { + #[display(fmt="simple")] + Simple, + #[display(fmt="line-layout")] + LineLayout, + #[display(fmt="tui")] + Tui, +} + +// TODO: it might make sense to add a step and quanitize values (they're quanitized to 1/i16::MAX +// anyway because it's 16bit signed ints from alsa), but i think just scaling by +// max_threshold will work for now + +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +pub struct SimpleArgs { + /// outputter to use + #[arg(short, long, default_value_t = OutputerTypes::Simple)] + pub outputer: OutputerTypes, + + /// threshold for displaying the value, the values have a range of + /// 0 - 1 for the most part, a square wave at the max volume + /// of a single note will be ~1 (pure sine will be ~sqrt(0.5) or ~0.707ish) + /// but in practice most sounds won't get close to that, normally being in + /// the range of 0.005-0.10 will give you something usable without being too noisy, + /// highly depending on your input though + #[arg(short, long, default_value_t = 0.00526532149076897)] + pub threshold: f32, + + /// max (saturating) threshold, for colour output in LineLayout and maybe with + /// certain other outputers this is used as a value for which any values higher + /// then this is considered a max value and displayed at full brightness. + /// + /// For LineLayout this contols the brightness of the colour output, + /// anything >= max_threshold will display at full brightness and anything below + /// will be scaled linearly, like brightness = min(1, note_val / max_threshold) and of course + /// r = r_max * brightness, g = g_max * brightness, b = b_max * brightness. + /// + /// it's recommended to set this somewhat close to what you + /// expect your highest value is going to be (you can play with that by experimenting + /// with the Simple output, in Simple output each value is scaled by 10,000 so 2000 for + /// example would be 0.2) + /// + /// because the max sine wave volume is sqrt(0.5) for now this defaults to sqrt(0.5), but + /// it's recommended to set it lower especially if the brightness of the bars seems too low for + /// your input. + /// + /// 0.2 - 0.3 seems like an actual good value in practice, but it's worth playing with + #[arg(short, long, default_value_t = 0.7071067811865476)] + pub max_threshold: f32, + + /// don't use colour to output for outputers that support it + /// (currently LineLayout) + #[arg(long, default_value_t = false)] + pub plain: bool, + + /*/// max brightness colour for LineLayout and maybe other outputers, + /// this is the r/g/b colour at >= max_threshold, values + /// threshold > val > max_threshold will scale linearly from + /// brightness = threshold to brightness = 1, currently + /// threshold just determines if the value is displayed and not + /// its colour, that's purely from the max threshold + /// (though that could be something to change, make the calculation something like + /// diff = note_val - threshold + /// max_diff = max_threshold - threshold + /// brightness = diff / max_diff) + /// + /// These should have a range of (0.0 - 255.0) because each value gets converted + /// to a u8 to determine the final rgb colour + #[arg(long, default_value_t = String::from("78ffdc"))] + pub colour: String,*/ + + + /// File that contains the colourscheme as JSON, see the colourschemes/ directory for examples + /// we'll use adam neely's as the default for the moment, but this should be changed + /// TODO + /// NOTE (The default here is set at compile time, so you have to recompile if you change the + /// dir you're in) + #[arg(short, long)] + colours: Option, + + /// Output device + #[arg(long)] + pub outdev: Option> +} + +impl SimpleArgs { + pub fn get_outputer(&self, notes: &[Note]) -> Outputers { + match self.outputer { + OutputerTypes::Simple => Outputers::Simple(SimpleOutputer), + // TODO: change this unwrap to a ? and a Result return value + OutputerTypes::LineLayout => Outputers::LineLayout(LineLayout::new(self.max_threshold, !self.plain, self.get_colours().unwrap(), ¬es)), + OutputerTypes::Tui => Outputers::Tui(TuiOutputer::new().unwrap()), + } + } + + pub fn get_outdev(&self) -> Option { + match &self.outdev { + Some(outdev) => outdev.clone(), + None => Some(String::from("default")), + } + } + + pub fn get_colours(&self) -> Result> { + match (self.plain, &self.colours) { + (true, _) => Ok(ColourScheme::default()), + (false, None) => Ok(ColourScheme::default()), + (false, Some(cf)) => { + // first check if the file exists either as an absolute path or in the current + // directory, if it does try to load it + let mut fres = File::open(&cf); + // otherwise try to load the colourscheme from colourschemes/ in the project directory + if fres.is_err() { + //let pth: PathBuf = [env!("CARGO_MANIFEST_DIR"), "colourschemes", cf.as_path()].iter().collect(); + let mut pth: PathBuf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + pth.push("colourschemes"); + pth.push(&cf); + fres = File::open(pth); + } + let file = fres?; + let reader = BufReader::new(file); + let colours: ColourScheme = serde_json::from_reader(reader)?; + // if either loaded successfully, make sure all of the colours are Rgb for later + Ok(colours) + } + } + } + +} + -- cgit v1.1