summaryrefslogtreecommitdiff
path: root/src/args.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/args.rs')
-rw-r--r--src/args.rs140
1 files changed, 140 insertions, 0 deletions
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<PathBuf>,
+
+ /// Output device
+ #[arg(long)]
+ pub outdev: Option<Option<String>>
+}
+
+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(), &notes)),
+ OutputerTypes::Tui => Outputers::Tui(TuiOutputer::new().unwrap()),
+ }
+ }
+
+ pub fn get_outdev(&self) -> Option<String> {
+ match &self.outdev {
+ Some(outdev) => outdev.clone(),
+ None => Some(String::from("default")),
+ }
+ }
+
+ pub fn get_colours(&self) -> Result<ColourScheme, Box<dyn Error>> {
+ 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)
+ }
+ }
+ }
+
+}
+