From b030f64344ae8442c61ac4c9e1d26398ce4e53d6 Mon Sep 17 00:00:00 2001 From: gursi26 Date: Mon, 11 Mar 2024 16:57:09 -0400 Subject: [PATCH 1/5] created config.rs, added serde_yaml and dirs deps --- Cargo.toml | 2 ++ src/args.rs | 2 +- src/config.rs | 15 +++++++++++++++ src/main.rs | 2 ++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 src/config.rs diff --git a/Cargo.toml b/Cargo.toml index a9411c4..78e91a0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,8 @@ microfft = "0.5.1" rayon = "1.9.0" rodio = "0.17.3" serde = { version = "1.0.197", features = ["derive"] } +dirs = "5.0.1" +serde_yaml = "0.9.32" spectrum-analyzer = "1.5.0" # [profile.release] diff --git a/src/args.rs b/src/args.rs index c33a80f..1a47d3a 100644 --- a/src/args.rs +++ b/src/args.rs @@ -31,7 +31,7 @@ pub struct CLIArgs { max_freq: f32, /// Volume - #[arg(long = "volume", default_value_t = 0.7)] + #[arg(long = "volume", default_value_t = 0.5)] volume: f32, /// Window width diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..079968a --- /dev/null +++ b/src/config.rs @@ -0,0 +1,15 @@ +use dirs::home_dir; +use std::path::PathBuf; + +pub fn config_path() -> PathBuf { + let mut config_path = home_dir().unwrap(); + config_path.push(".config"); + config_path.push("fftviz"); + config_path.push("config.yaml"); + config_path +} + +pub fn config_exists() -> bool { + let cfg_path = config_path(); + cfg_path.exists() +} diff --git a/src/main.rs b/src/main.rs index fa46360..237921d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,9 +3,11 @@ mod args; mod fft; mod systems; +mod config; use args::*; use fft::*; +use config::*; use systems::get_keyboard_input::*; use systems::egui::*; use systems::startup::*; From 662ffe4ac7fb66b50eed0030ad87c8c3946b34f0 Mon Sep 17 00:00:00 2001 From: gursi26 Date: Wed, 13 Mar 2024 13:37:03 -0400 Subject: [PATCH 2/5] finished config parsing and added save button to egui --- src/args.rs | 110 ++++++++++++++++------------------- src/config.rs | 138 +++++++++++++++++++++++++++++++++++++++++++- src/main.rs | 3 +- src/systems/egui.rs | 12 +++- 4 files changed, 200 insertions(+), 63 deletions(-) diff --git a/src/args.rs b/src/args.rs index 1a47d3a..95778e5 100644 --- a/src/args.rs +++ b/src/args.rs @@ -10,100 +10,99 @@ pub struct CLIArgs { #[arg()] file_path: String, - /// Temporal resolution for FFT calculation (rendering always occurs at 60 fps with interpolation) - #[arg(long = "fft-fps", default_value_t = 12)] - fft_fps: u32, - /// Smoothing factor for spatial interpolation between bars - #[clap(long = "smoothness", default_value_t = 1)] - smoothness: u32, + #[clap(long = "smoothness", default_value = None)] + pub smoothness: Option, /// Number of individual frequencies detected by the FFT - #[arg(long = "freq-resolution", default_value_t = 90)] - freq_resolution: u32, + #[arg(long = "freq-resolution", default_value = None)] + pub freq_resolution: Option, /// Maximum frequency detected by FFT - #[arg(long = "min-freq", default_value_t = 0.0)] - min_freq: f32, + #[arg(long = "min-freq", default_value = None)] + pub min_freq: Option, /// Minimum frequency detected by FFT - #[arg(long = "max-freq", default_value_t = 5000.0)] - max_freq: f32, + #[arg(long = "max-freq", default_value = None)] + pub max_freq: Option, /// Volume - #[arg(long = "volume", default_value_t = 0.5)] - volume: f32, + #[arg(long = "volume", default_value = None)] + pub volume: Option, /// Window width - #[arg(long = "width", default_value_t = 1000.0)] - window_width: f32, + #[arg(long = "width", default_value = None)] + pub window_width: Option, /// Window height - #[arg(long = "height", default_value_t = 700.0)] - window_height: f32, + #[arg(long = "height", default_value = None)] + pub window_height: Option, /// Border size for each bar - #[arg(long = "border-size", default_value_t = 1)] - border_size: u32, + #[arg(long = "border-size", default_value = None)] + pub border_size: Option, /// Border color for each bar (in hex) - #[arg(long = "border-color", default_value_t = String::from("000000"))] - border_color: String, + #[arg(long = "border-color", default_value = None)] + pub border_color: Option, /// Color for each bar (in hex) - #[arg(long = "bar-color", default_value_t = String::from("FF0000"))] - bar_color: String, + #[arg(long = "bar-color", default_value = None)] + pub bar_color: Option, /// Use if you want track name to be printed #[arg(long = "track-name", action = ArgAction::SetTrue)] - track_name: bool, + pub track_name: Option, /// Use if you want the gui to be open when launched #[arg(long = "display-gui", action = ArgAction::SetTrue)] - display_gui: bool, + pub display_gui: Option, /// Color for currently playing text (in hex) - #[arg(long = "text-color", default_value_t = String::from("FFFFFF"))] - text_color: String, + #[arg(long = "text-color", default_value = None)] + pub text_color: Option, /// Font size of currently playing label - #[arg(long = "font-size", default_value_t = 25)] - font_size: u32, + #[arg(long = "font-size", default_value = None)] + pub font_size: Option, // Background color (in hex) - #[arg(long = "background-color", default_value_t = String::from("000000"))] - background_color: String, + #[arg(long = "background-color", default_value = None)] + pub background_color: Option, } -pub fn cli_args_to_fft_args(cli_args: CLIArgs) -> FFTArgs { +pub fn cli_args_to_fft_args(mut cli_args: CLIArgs) -> FFTArgs { if !Path::new(&cli_args.file_path).is_file() { println!("File \"{}\" not found!", cli_args.file_path); std::process::exit(1); } - bar_smoothness_constraint(cli_args.smoothness); - fft_fps_constraint(cli_args.fft_fps); - freq_resolution_constraint(cli_args.freq_resolution); + // Merges cli args with args in config.yaml. + // Precendence: Cli args > config.yaml args > default values + merge_config_with_cli_args(&mut cli_args); + + bar_smoothness_constraint(cli_args.smoothness.unwrap()); + freq_resolution_constraint(cli_args.freq_resolution.unwrap()); FFTArgs { file_path: Path::new(&cli_args.file_path).to_path_buf(), - border_size: cli_args.border_size as i32, - border_color: Color::hex(cli_args.border_color).unwrap(), - bar_color: Color::hex(cli_args.bar_color).unwrap(), - track_name: cli_args.track_name, - text_color: Color::hex(cli_args.text_color).unwrap(), - font_size: cli_args.font_size as i32, - background_color: Color::hex(cli_args.background_color).unwrap(), - smoothness: cli_args.smoothness, - fft_fps: cli_args.fft_fps, - freq_resolution: cli_args.freq_resolution, - window_height: cli_args.window_height, - window_width: cli_args.window_width, - min_freq: cli_args.min_freq, - max_freq: cli_args.max_freq, - display_gui: cli_args.display_gui, - volume: cli_args.volume, + border_size: cli_args.border_size.unwrap(), + border_color: Color::hex(cli_args.border_color.unwrap()).unwrap(), + bar_color: Color::hex(cli_args.bar_color.unwrap()).unwrap(), + track_name: cli_args.track_name.unwrap(), + text_color: Color::hex(cli_args.text_color.unwrap()).unwrap(), + font_size: cli_args.font_size.unwrap(), + background_color: Color::hex(cli_args.background_color.unwrap()).unwrap(), + smoothness: cli_args.smoothness.unwrap(), + freq_resolution: cli_args.freq_resolution.unwrap(), + window_height: cli_args.window_height.unwrap(), + window_width: cli_args.window_width.unwrap(), + min_freq: cli_args.min_freq.unwrap(), + max_freq: cli_args.max_freq.unwrap(), + display_gui: cli_args.display_gui.unwrap(), + volume: cli_args.volume.unwrap(), paused: false, + fft_fps: FFT_FPS } } @@ -118,13 +117,6 @@ pub fn bar_smoothness_constraint(v: u32) { } } -pub fn fft_fps_constraint(v: u32) { - if v < 6 || v > 60 || RENDERING_FPS % v != 0 { - println!("fft-fps must be between 6 and 60 inclusive and divide RENDERING_FPS = {}.", RENDERING_FPS); - std::process::exit(1); - } -} - fn freq_resolution_constraint(v: u32) { if v < 10 || v > 300 { println!("freq-resolution must be between 10 and 300 inclusive."); diff --git a/src/config.rs b/src/config.rs index 079968a..6b32623 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,52 @@ use dirs::home_dir; -use std::path::PathBuf; +use std::{io::{stdout, Write}, path::PathBuf}; +use serde::{Deserialize, Serialize}; +use serde_yaml::{self}; +use std::fs::{create_dir, create_dir_all, File, OpenOptions}; +use bevy::prelude::Color; + +use crate::{CLIArgs, FFTArgs}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct ConfigFFTArgs { + pub border_size: Option, + pub border_color: Option, + pub bar_color: Option, + pub display_track_name: Option, + pub text_color: Option, + pub font_size: Option, + pub background_color: Option, + pub smoothness: Option, + pub freq_resolution: Option, + pub window_width: Option, + pub window_height: Option, + pub min_freq: Option, + pub max_freq: Option, + pub display_gui: Option, + pub volume: Option, +} + +impl Default for ConfigFFTArgs { + fn default() -> Self { + ConfigFFTArgs { + border_size: Some(1), + border_color: Some(String::from("000000")), + bar_color: Some(String::from("FF0000")), + display_track_name: Some(false), + text_color: Some(String::from("FFFFFF")), + font_size: Some(25), + background_color: Some(String::from("000000")), + smoothness: Some(1), + freq_resolution: Some(90), + window_width: Some(1000.0), + window_height: Some(700.0), + min_freq: Some(0.0), + max_freq: Some(5000.0), + display_gui: Some(false), + volume: Some(0.5), + } + } +} pub fn config_path() -> PathBuf { let mut config_path = home_dir().unwrap(); @@ -13,3 +60,92 @@ pub fn config_exists() -> bool { let cfg_path = config_path(); cfg_path.exists() } + +pub fn read_config() -> ConfigFFTArgs { + let config_file = File::open(config_path()).expect("Could not find file lmao"); + let user_config_yaml = + serde_yaml::from_reader(config_file).expect("Could not read values lmao"); + user_config_yaml +} + +macro_rules! update_cli_arg { + ($cli_arg: expr, $config_arg: expr, $default_config_arg: expr) => { + if let None = *$cli_arg { + if let None = $config_arg { + *$cli_arg = $default_config_arg; + } else { + *$cli_arg = $config_arg; + } + } + }; +} + +macro_rules! overwrite_non_default_args { + ($user_config_arg: expr, $fft_arg: expr) => { + *$user_config_arg = Some($fft_arg); + }; +} + +pub fn convert_color_to_hex(c: &Color) -> String { + let c_vec = c.rgb_to_vec3(); + let (r, g, b) = ((c_vec.x * 255.0) as u32, (c_vec.y * 255.0) as u32, (c_vec.z * 255.0) as u32); + format!("{}{}{}", format!("{:02X}", r), format!("{:02X}", g), format!("{:02X}", b)) +} + +pub fn write_fftargs_to_config(args: &FFTArgs) { + let mut default_args = ConfigFFTArgs::default(); + overwrite_non_default_args!(&mut default_args.background_color, convert_color_to_hex(&args.background_color)); + overwrite_non_default_args!(&mut default_args.border_color, convert_color_to_hex(&args.border_color)); + overwrite_non_default_args!(&mut default_args.bar_color, convert_color_to_hex(&args.bar_color)); + overwrite_non_default_args!(&mut default_args.text_color, convert_color_to_hex(&args.text_color)); + overwrite_non_default_args!(&mut default_args.border_size, args.border_size); + overwrite_non_default_args!(&mut default_args.display_track_name, args.track_name); + overwrite_non_default_args!(&mut default_args.font_size, args.font_size); + overwrite_non_default_args!(&mut default_args.smoothness, args.smoothness); + overwrite_non_default_args!(&mut default_args.freq_resolution, args.freq_resolution); + overwrite_non_default_args!(&mut default_args.window_width, args.window_width); + overwrite_non_default_args!(&mut default_args.window_height, args.window_height); + overwrite_non_default_args!(&mut default_args.min_freq, args.min_freq); + overwrite_non_default_args!(&mut default_args.max_freq, args.max_freq); + overwrite_non_default_args!(&mut default_args.volume, args.volume); + + let cfg_path = config_path(); + create_dir_all(&cfg_path); + + let mut config_file = OpenOptions::new() + .write(true) + .create(true) + .open(cfg_path) + .expect("Could not open file."); + serde_yaml::to_writer(config_file, &default_args).unwrap(); +} + +pub fn merge_config_with_cli_args(args: &mut CLIArgs) { + if !config_exists() { + return; + } + + let user_config_yaml = read_config(); + let default_user_config = ConfigFFTArgs::default(); + + if let Some(x) = user_config_yaml.display_track_name { + args.track_name = Some(x); + } + if let Some(x) = user_config_yaml.display_gui { + args.display_gui = Some(x); + } + + update_cli_arg!(&mut args.background_color, user_config_yaml.background_color, default_user_config.background_color); + update_cli_arg!(&mut args.bar_color, user_config_yaml.bar_color, default_user_config.bar_color); + update_cli_arg!(&mut args.border_color, user_config_yaml.border_color, default_user_config.border_color); + update_cli_arg!(&mut args.border_size, user_config_yaml.border_size, default_user_config.border_size); + update_cli_arg!(&mut args.font_size, user_config_yaml.font_size, default_user_config.font_size); + update_cli_arg!(&mut args.freq_resolution, user_config_yaml.freq_resolution, default_user_config.freq_resolution); + update_cli_arg!(&mut args.max_freq, user_config_yaml.max_freq, default_user_config.max_freq); + update_cli_arg!(&mut args.min_freq, user_config_yaml.min_freq, default_user_config.min_freq); + update_cli_arg!(&mut args.smoothness, user_config_yaml.smoothness, default_user_config.smoothness); + update_cli_arg!(&mut args.text_color, user_config_yaml.text_color, default_user_config.text_color); + update_cli_arg!(&mut args.volume, user_config_yaml.volume, default_user_config.volume); + update_cli_arg!(&mut args.window_width, user_config_yaml.window_width, default_user_config.window_width); + update_cli_arg!(&mut args.window_height, user_config_yaml.window_height, default_user_config.window_height); +} diff --git a/src/main.rs b/src/main.rs index 237921d..ae27870 100644 --- a/src/main.rs +++ b/src/main.rs @@ -43,6 +43,7 @@ const RESCALING_THRESHOLDS: &[f32] = &[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0 const INTENSITY_RESCALING: &[f32] = &[0.4, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.6, 0.5]; const FREQ_RESCALING: &[f32] = &[0.9, 1.2, 1.2, 1.2, 1.0]; const AVERAGING_WINDOW: u32 = 1; +const FFT_FPS: u32 = 12; const MIN_BAR_HEIGHT: f32 = 0.001; const MAX_BAR_HEIGHT: f32 = 0.45; @@ -57,7 +58,6 @@ struct FFTArgs { text_color: Color, font_size: i32, background_color: Color, - fft_fps: u32, smoothness: u32, freq_resolution: u32, window_width: f32, @@ -67,6 +67,7 @@ struct FFTArgs { display_gui: bool, volume: f32, paused: bool, + fft_fps: u32, } #[derive(Resource)] diff --git a/src/systems/egui.rs b/src/systems/egui.rs index f589461..0dffdf9 100644 --- a/src/systems/egui.rs +++ b/src/systems/egui.rs @@ -1,4 +1,4 @@ -use crate::{AppState, FFTArgs}; +use crate::{write_fftargs_to_config, AppState, FFTArgs}; use bevy::render::mesh::VertexAttributeValues; use bevy_egui::egui::{Align2, Color32, Stroke}; use bevy::sprite::Anchor; @@ -28,7 +28,6 @@ pub fn ui_example_system( let window_handle = egui::Window::new("") .fixed_size(egui::Vec2 { x: 100.0, y: 100.0 }) .anchor(Align2::RIGHT_TOP, egui::Vec2::new(-10.0, 10.0)) - // .fixed_pos(egui::Pos2 { x: 10.0, y: 10.0 }) .collapsible(false); window_handle.show(contexts.ctx_mut(), |ui| { @@ -63,6 +62,15 @@ pub fn ui_example_system( ui.label("Border size: "); ui.add(egui::Slider::new(&mut args.border_size, 0..=10).text("value")); }); + + ui.allocate_space(egui::Vec2::new(1.0, 10.0)); + ui.horizontal(|ui| { + if ui.button("Save settings").clicked() { + write_fftargs_to_config(&args) + } + if ui.button("Reset").clicked() { + } + }); }); } } From d904f6691036fd6992ef1dcd72e382a99f38a0a6 Mon Sep 17 00:00:00 2001 From: gursi26 Date: Wed, 13 Mar 2024 16:43:25 -0400 Subject: [PATCH 3/5] added save, reset and reset to default buttons, fixed config.yaml write bug --- src/args.rs | 8 ++-- src/config.rs | 63 ++++++++++++++++++++++++++----- src/main.rs | 4 +- src/systems/egui.rs | 8 +++- src/systems/get_keyboard_input.rs | 12 +++--- 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/src/args.rs b/src/args.rs index 95778e5..0551089 100644 --- a/src/args.rs +++ b/src/args.rs @@ -28,7 +28,7 @@ pub struct CLIArgs { /// Volume #[arg(long = "volume", default_value = None)] - pub volume: Option, + pub volume: Option, /// Window width #[arg(long = "width", default_value = None)] @@ -71,7 +71,7 @@ pub struct CLIArgs { pub background_color: Option, } -pub fn cli_args_to_fft_args(mut cli_args: CLIArgs) -> FFTArgs { +pub fn cli_args_to_fft_args(mut cli_args: CLIArgs, use_default: bool) -> FFTArgs { if !Path::new(&cli_args.file_path).is_file() { println!("File \"{}\" not found!", cli_args.file_path); std::process::exit(1); @@ -79,7 +79,7 @@ pub fn cli_args_to_fft_args(mut cli_args: CLIArgs) -> FFTArgs { // Merges cli args with args in config.yaml. // Precendence: Cli args > config.yaml args > default values - merge_config_with_cli_args(&mut cli_args); + merge_config_with_cli_args(&mut cli_args, use_default); bar_smoothness_constraint(cli_args.smoothness.unwrap()); freq_resolution_constraint(cli_args.freq_resolution.unwrap()); @@ -107,7 +107,7 @@ pub fn cli_args_to_fft_args(mut cli_args: CLIArgs) -> FFTArgs { } pub fn parse_cli_args() -> FFTArgs { - cli_args_to_fft_args(args::CLIArgs::parse()) + cli_args_to_fft_args(args::CLIArgs::parse(), false) } // Value constraints pub fn bar_smoothness_constraint(v: u32) { diff --git a/src/config.rs b/src/config.rs index 6b32623..5a809a6 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,8 +1,9 @@ use dirs::home_dir; -use std::{io::{stdout, Write}, path::PathBuf}; +use std::{io::{stdout, Read, Write}, path::PathBuf}; use serde::{Deserialize, Serialize}; use serde_yaml::{self}; -use std::fs::{create_dir, create_dir_all, File, OpenOptions}; +use std::fs::{read_to_string, create_dir, create_dir_all, File, OpenOptions}; +use std::io::BufWriter; use bevy::prelude::Color; use crate::{CLIArgs, FFTArgs}; @@ -23,7 +24,7 @@ pub struct ConfigFFTArgs { pub min_freq: Option, pub max_freq: Option, pub display_gui: Option, - pub volume: Option, + pub volume: Option, } impl Default for ConfigFFTArgs { @@ -43,7 +44,7 @@ impl Default for ConfigFFTArgs { min_freq: Some(0.0), max_freq: Some(5000.0), display_gui: Some(false), - volume: Some(0.5), + volume: Some(50), } } } @@ -110,23 +111,67 @@ pub fn write_fftargs_to_config(args: &FFTArgs) { overwrite_non_default_args!(&mut default_args.volume, args.volume); let cfg_path = config_path(); - create_dir_all(&cfg_path); + create_dir_all(cfg_path.as_path().parent().unwrap()); let mut config_file = OpenOptions::new() .write(true) .create(true) - .open(cfg_path) + .open(&cfg_path) .expect("Could not open file."); serde_yaml::to_writer(config_file, &default_args).unwrap(); + + let mut cfg_yaml: Vec = read_to_string(&cfg_path) + .unwrap() // panic on possible file-reading errors + .lines() // split the string into an iterator of string slices + .map(String::from) // make each slice into a string + .collect(); // gather them together into a vector + + cfg_yaml.retain(|x| x.contains(":")); + + let f = File::open(&cfg_path).expect("Unable to create file"); + let mut f = BufWriter::new(f); + f.write_all(cfg_yaml.join("\n").as_bytes()).expect("Unable to write data"); +} + +pub fn reset_config_file() { + let default_user_config = ConfigFFTArgs::default(); + + let cfg_path = config_path(); + create_dir_all(cfg_path.as_path().parent().unwrap()); + + let mut config_file = OpenOptions::new() + .write(true) + .create(true) + .open(cfg_path) + .expect("Could not open file."); + serde_yaml::to_writer(config_file, &default_user_config).unwrap(); } -pub fn merge_config_with_cli_args(args: &mut CLIArgs) { +pub fn merge_config_with_cli_args(args: &mut CLIArgs, use_default: bool) { + let default_user_config = ConfigFFTArgs::default(); if !config_exists() { + update_cli_arg!(&mut args.background_color, None::, default_user_config.background_color); + update_cli_arg!(&mut args.bar_color, None::, default_user_config.bar_color); + update_cli_arg!(&mut args.border_color, None::, default_user_config.border_color); + update_cli_arg!(&mut args.border_size, None::, default_user_config.border_size); + update_cli_arg!(&mut args.font_size, None::, default_user_config.font_size); + update_cli_arg!(&mut args.freq_resolution, None::, default_user_config.freq_resolution); + update_cli_arg!(&mut args.max_freq, None::, default_user_config.max_freq); + update_cli_arg!(&mut args.min_freq, None::, default_user_config.min_freq); + update_cli_arg!(&mut args.smoothness, None::, default_user_config.smoothness); + update_cli_arg!(&mut args.text_color, None::, default_user_config.text_color); + update_cli_arg!(&mut args.volume, None::, default_user_config.volume); + update_cli_arg!(&mut args.window_width, None::, default_user_config.window_width); + update_cli_arg!(&mut args.window_height, None::, default_user_config.window_height); return; } - let user_config_yaml = read_config(); - let default_user_config = ConfigFFTArgs::default(); + let user_config_yaml: ConfigFFTArgs; + if use_default { + user_config_yaml = ConfigFFTArgs::default(); + } else { + user_config_yaml = read_config(); + } if let Some(x) = user_config_yaml.display_track_name { args.track_name = Some(x); diff --git a/src/main.rs b/src/main.rs index ae27870..84d0f65 100644 --- a/src/main.rs +++ b/src/main.rs @@ -65,7 +65,7 @@ struct FFTArgs { min_freq: f32, max_freq: f32, display_gui: bool, - volume: f32, + volume: u32, paused: bool, fft_fps: u32, } @@ -173,7 +173,7 @@ fn main() { let source = Decoder::new(file).unwrap(); let (_stream, stream_handle) = OutputStream::try_default().unwrap(); let sink = rodio::Sink::try_new(&stream_handle).unwrap(); - sink.set_volume(volume); + sink.set_volume(volume as f32 / 100.0); sink.append(source); app.insert_resource(AppState { diff --git a/src/systems/egui.rs b/src/systems/egui.rs index 0dffdf9..f3534e2 100644 --- a/src/systems/egui.rs +++ b/src/systems/egui.rs @@ -1,4 +1,4 @@ -use crate::{write_fftargs_to_config, AppState, FFTArgs}; +use crate::{cli_args_to_fft_args, parse_cli_args, reset_config_file, write_fftargs_to_config, AppState, FFTArgs}; use bevy::render::mesh::VertexAttributeValues; use bevy_egui::egui::{Align2, Color32, Stroke}; use bevy::sprite::Anchor; @@ -65,10 +65,14 @@ pub fn ui_example_system( ui.allocate_space(egui::Vec2::new(1.0, 10.0)); ui.horizontal(|ui| { - if ui.button("Save settings").clicked() { + if ui.button("Save").clicked() { write_fftargs_to_config(&args) } if ui.button("Reset").clicked() { + *args = parse_cli_args(); + } + if ui.button("Reset to default").clicked() { + *args = cli_args_to_fft_args(crate::args::CLIArgs::parse(), true); } }); }); diff --git a/src/systems/get_keyboard_input.rs b/src/systems/get_keyboard_input.rs index d73cc8c..02b49c4 100644 --- a/src/systems/get_keyboard_input.rs +++ b/src/systems/get_keyboard_input.rs @@ -39,13 +39,13 @@ pub fn get_keyboard_input( } } if keyboard_input.just_pressed(KeyCode::ArrowUp) { - args.volume += 0.1; - args.volume = args.volume.min(1.0); - app_state.sink.set_volume(args.volume); + args.volume += 5; + args.volume = args.volume.min(100); + app_state.sink.set_volume(args.volume as f32 / 100.0); } if keyboard_input.just_pressed(KeyCode::ArrowDown) { - args.volume -= 0.1; - args.volume = args.volume.max(0.0); - app_state.sink.set_volume(args.volume); + args.volume -= 5; + args.volume = args.volume.max(0); + app_state.sink.set_volume(args.volume as f32 / 100.0); } } From bc45c99bafa2b8edc239a45f3f422da6f45aadae Mon Sep 17 00:00:00 2001 From: gursi26 Date: Wed, 13 Mar 2024 17:15:36 -0400 Subject: [PATCH 4/5] bug fixes, completed config.yaml --- Cargo.toml | 1 + src/config.rs | 6 ++++-- src/main.rs | 5 +++++ src/systems/egui.rs | 20 ++++++++++++++++++-- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 78e91a0..79df888 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ serde = { version = "1.0.197", features = ["derive"] } dirs = "5.0.1" serde_yaml = "0.9.32" spectrum-analyzer = "1.5.0" +stopwatch = "0.0.7" # [profile.release] # lto = true diff --git a/src/config.rs b/src/config.rs index 5a809a6..daf4798 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,5 +1,5 @@ use dirs::home_dir; -use std::{io::{stdout, Read, Write}, path::PathBuf}; +use std::{fs::remove_file, io::{stdout, Read, Write}, path::PathBuf}; use serde::{Deserialize, Serialize}; use serde_yaml::{self}; use std::fs::{read_to_string, create_dir, create_dir_all, File, OpenOptions}; @@ -128,7 +128,9 @@ pub fn write_fftargs_to_config(args: &FFTArgs) { cfg_yaml.retain(|x| x.contains(":")); - let f = File::open(&cfg_path).expect("Unable to create file"); + remove_file(&cfg_path); + + let f = File::create(&cfg_path).expect("Unable to create file"); let mut f = BufWriter::new(f); f.write_all(cfg_yaml.join("\n").as_bytes()).expect("Unable to write data"); } diff --git a/src/main.rs b/src/main.rs index 84d0f65..8fc37bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,6 +22,7 @@ use bevy::{ prelude::*, sprite::{MaterialMesh2dBundle, Mesh2dHandle}, }; +use stopwatch::{Stopwatch}; use bevy_egui::{egui, EguiContexts, EguiPlugin}; use clap::{ArgAction, Parser}; use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator}; @@ -78,6 +79,8 @@ struct AppState { despawn_handles: Vec, total_frame_counter: usize, fft_frame_counter: usize, + stopwatch: Stopwatch, + display_str: String, } @@ -183,6 +186,8 @@ fn main() { despawn_handles: Vec::new(), fft_frame_counter: 0, total_frame_counter: 0, + stopwatch: Stopwatch::new(), + display_str: String::new(), }); app.run(); diff --git a/src/systems/egui.rs b/src/systems/egui.rs index f3534e2..cb07eb0 100644 --- a/src/systems/egui.rs +++ b/src/systems/egui.rs @@ -1,4 +1,4 @@ -use crate::{cli_args_to_fft_args, parse_cli_args, reset_config_file, write_fftargs_to_config, AppState, FFTArgs}; +use crate::{cli_args_to_fft_args, config_path, parse_cli_args, reset_config_file, write_fftargs_to_config, AppState, FFTArgs}; use bevy::render::mesh::VertexAttributeValues; use bevy_egui::egui::{Align2, Color32, Stroke}; use bevy::sprite::Anchor; @@ -66,15 +66,31 @@ pub fn ui_example_system( ui.allocate_space(egui::Vec2::new(1.0, 10.0)); ui.horizontal(|ui| { if ui.button("Save").clicked() { - write_fftargs_to_config(&args) + write_fftargs_to_config(&args); + app_state.display_str = format!("Saved to {:?}", config_path()); + app_state.stopwatch.start(); } if ui.button("Reset").clicked() { *args = parse_cli_args(); + app_state.display_str = String::from("Reset to saved settings."); + app_state.stopwatch.start(); + args.display_gui = true; } if ui.button("Reset to default").clicked() { *args = cli_args_to_fft_args(crate::args::CLIArgs::parse(), true); + app_state.display_str = String::from("Reset to default settings."); + app_state.stopwatch.start(); + args.display_gui = true; } }); + + if app_state.stopwatch.is_running() { + ui.label(&app_state.display_str); + } + if app_state.stopwatch.elapsed().as_secs() > 3 { + app_state.stopwatch.stop(); + app_state.stopwatch.reset(); + } }); } } From d22febcbc429506a224e50d8872e4d8b037727da Mon Sep 17 00:00:00 2001 From: gursi26 Date: Wed, 13 Mar 2024 17:27:06 -0400 Subject: [PATCH 5/5] update cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 79df888..de50b5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fftviz" -version = "0.2.2" +version = "0.3.0" edition = "2021" authors = ["Gursimar Singh "] license = "MIT"