diff --git a/Cargo.lock b/Cargo.lock index 3132c66..0ae3058 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,9 +69,11 @@ checksum = "000444226fcff248f2bc4c7625be32c63caccfecc2723a2b9f78a7487a49c407" name = "apt-decoder" version = "0.1.0" dependencies = [ + "clap", "eframe", "hound", "image", + "indicatif", "rfd", "thiserror", ] @@ -200,6 +202,17 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -319,6 +332,22 @@ dependencies = [ "libc", ] +[[package]] +name = "clap" +version = "3.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c" +dependencies = [ + "atty", + "bitflags", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", +] + [[package]] name = "clipboard-win" version = "3.1.1" @@ -375,6 +404,19 @@ dependencies = [ "cache-padded", ] +[[package]] +name = "console" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "terminal_size", + "winapi", +] + [[package]] name = "copypasta" version = "0.7.1" @@ -696,6 +738,12 @@ version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55673de2eb96660dde25ba7b2d36a7054beead1a2bec74dcfd5eb05a1e1ba76d" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding" version = "0.2.33" @@ -1200,6 +1248,12 @@ version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + [[package]] name = "heck" version = "0.4.0" @@ -1223,9 +1277,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hound" -version = "2.0.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e971fe26207d3ccdc66806fd9154508b28101fccb53fe152695e3ebcb53bd0f" +checksum = "8a164bb2ceaeff4f42542bdb847c41517c78a60f5649671b2a07312b6e117549" [[package]] name = "ident_case" @@ -1253,6 +1307,28 @@ dependencies = [ "tiff", ] +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "indicatif" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" +dependencies = [ + "console", + "lazy_static", + "number_prefix", + "regex", +] + [[package]] name = "inflate" version = "0.4.5" @@ -1617,6 +1693,12 @@ dependencies = [ "syn", ] +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + [[package]] name = "objc" version = "0.2.7" @@ -1671,6 +1753,15 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "os_str_bytes" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" +dependencies = [ + "memchr", +] + [[package]] name = "osmesa-sys" version = "0.1.2" @@ -2159,6 +2250,31 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36ae8932fcfea38b7d3883ae2ab357b0d57a02caaa18ebb4f5ece08beaec4aa0" +[[package]] +name = "termcolor" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" + [[package]] name = "thiserror" version = "1.0.30" @@ -2451,6 +2567,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 9334143..8cf5617 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,8 +4,16 @@ version = "0.1.0" authors = ["Sebastian "] [dependencies] -hound = "*" +clap = {version = "3.1.8", features = ["cargo"]} +indicatif = "0.16.2" +hound = "3.4.0" image = "0.24.0" -eframe = "0.16.0" +eframe = {version = "0.16.0", optional = true} rfd = "0.7.0" thiserror = "1.0.30" + + +[features] +# Defines a feature named `webp` that does not enable any other features. +default = ["ui"] +ui = ["dep:eframe"] diff --git a/noaa19_short.png b/noaa19_short.png index 70573c9..90229bb 100644 Binary files a/noaa19_short.png and b/noaa19_short.png differ diff --git a/src/aptsyncer.rs b/src/aptsyncer.rs index 62832a8..890cf36 100644 --- a/src/aptsyncer.rs +++ b/src/aptsyncer.rs @@ -48,10 +48,10 @@ impl<'a> APTSyncer<'a> { } APTSyncer { - state: state, + state, pos: 0, nones_read: 0, - avg_level: avg_level, + avg_level, iterator: Box::new(iterator), } } diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..8188ace --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,26 @@ +use indicatif::{ProgressBar, ProgressStyle}; + +use decoder; + +const STEPS: u64 = 100; + +pub fn decode(input_path: &str, output_path: &str) { + println!("Decoding {} to {}", input_path, output_path); + + let bar = ProgressBar::new(STEPS).with_style( + ProgressStyle::default_bar() + .template("{spinner:.green} [{wide_bar}] {percent}% ({eta})") + .progress_chars("=> "), + ); + let res = decoder::decode(input_path, output_path, |progress, _| { + bar.set_position((progress * STEPS as f32) as u64); + (true, STEPS as u32) + }); + bar.finish(); + + if let Err(error) = res { + println!("Unable to decode file: {}", error); + } else { + println!("Done!") + } +} diff --git a/src/firfilter.rs b/src/firfilter.rs index 39baae9..bb9cbbd 100644 --- a/src/firfilter.rs +++ b/src/firfilter.rs @@ -16,8 +16,8 @@ impl<'a> FIRFilter<'a> { } FIRFilter { - coeffs: coeffs, - state: state, + coeffs, + state, pos: 0, iterator: Box::new(iterator), } diff --git a/src/main.rs b/src/main.rs index 6142678..e42cc48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,33 +1,93 @@ #![windows_subsystem = "windows"] -extern crate eframe; +extern crate clap; extern crate hound; extern crate image; +extern crate indicatif; extern crate rfd; extern crate thiserror; +#[cfg(feature = "ui")] +extern crate eframe; + mod amdemod; mod aptsyncer; +mod cli; mod decoder; mod errors; mod firfilter; mod resamplers; -mod ui; mod utils; +use clap::{arg, command}; + +#[cfg(not(feature = "ui"))] +fn main() { + let matches = command!() + .arg( + arg!([wavfile] "Input wav file with 48kHz samplingrate") + .required(true) + .allow_invalid_utf8(true), + ) + .arg( + arg!([pngfile] "Output png file") + .default_value("output.png") + .allow_invalid_utf8(true), + ) + .get_matches(); + + let input_file = matches + .value_of_os("wavfile") + .expect("No input file given") + .to_str() + .unwrap(); + let output_file = matches + .value_of_os("pngfile") + .expect("No output file given") + .to_str() + .unwrap(); + + cli::decode(input_file, output_file); +} + +#[cfg(feature = "ui")] +mod ui; + +#[cfg(feature = "ui")] use ui::DecoderApp; +#[cfg(feature = "ui")] fn main() { - let app = DecoderApp::default(); - let native_options = eframe::NativeOptions::default(); - eframe::run_native(Box::new(app), native_options); + let matches = command!() + .arg( + arg!([wavfile] "Input wav file with 48kHz samplingrate") + .default_value("input.wav") + .allow_invalid_utf8(true), + ) + .arg( + arg!([pngfile] "Output png file") + .default_value("output.png") + .allow_invalid_utf8(true), + ) + .arg(arg!(-n --nogui ... "Disable gui and run in command line mode")) + .get_matches(); - //let args: Vec = std::env::args().collect(); + let input_file = matches + .value_of_os("wavfile") + .expect("No input file given") + .to_str() + .unwrap(); + let output_file = matches + .value_of_os("pngfile") + .expect("No output file given") + .to_str() + .unwrap(); - /* - if args.len() != 3 { - println!("Usage: {} ", args[0]); - return; + if matches.is_present("nogui") { + cli::decode(input_file, output_file); + } else { + let app = DecoderApp::new(input_file, output_file); + let native_options = eframe::NativeOptions::default(); + eframe::run_native(Box::new(app), native_options); } - */ } diff --git a/src/ui.rs b/src/ui.rs index 950046e..e74305d 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -47,12 +47,11 @@ pub struct DecoderApp { decoding_state: Arc>, } -impl Default for DecoderApp { - fn default() -> Self { +impl DecoderApp { + pub fn new(input_path: &str, output_path: &str) -> Self { Self { - // Example stuff: - input_path: "input.wav".to_owned(), - output_path: "output.png".to_owned(), + input_path: input_path.to_owned(), + output_path: output_path.to_owned(), decoding_state: Arc::new(Mutex::new(DecoderJobState::default())), } }