Skip to content

Commit

Permalink
Merge pull request #2 from gursi26/ui
Browse files Browse the repository at this point in the history
UI
  • Loading branch information
gursi26 committed Mar 8, 2024
2 parents ba47584 + de09e53 commit 9850c46
Show file tree
Hide file tree
Showing 11 changed files with 709 additions and 313 deletions.
10 changes: 9 additions & 1 deletion Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "fftviz"
version = "0.1.7"
version = "0.2.0"
edition = "2021"
authors = ["Gursimar Singh <gursi26.dev@gmail.com>"]
license = "MIT"
Expand All @@ -13,10 +13,18 @@ categories = ["command-line-utilities"]

[dependencies]
bevy = "0.13.0"
bevy_egui = "0.25.0"
bincode = "1.3.3"
clap = { version = "4.5.0", features = ["derive"] }
microfft = "0.5.1"
rayon = "1.9.0"
rodio = "0.17.3"
serde = { version = "1.0.197", features = ["derive"] }
spectrum-analyzer = "1.5.0"

# [profile.release]
# lto = true
# opt-level = 3
# codegen-units = 1
# incremental = false

30 changes: 26 additions & 4 deletions README.md
Expand Up @@ -18,25 +18,47 @@ cargo install fftviz
fftviz "path/to/audio/file.mp3"
```

- Use the `-h` flag for configuration options
- Keybinds:
- `q` to quit
- `e` for config gui

- Run with `-h` flag for configuration options
```
fftviz -h
A quick FFT visualizer for audio files
A lightweight, customizable FFT visualizer for audio files.
Usage: fftviz [OPTIONS] <FILE_PATH>
Arguments:
<FILE_PATH> File path to Audio file
Options:
--fft-fps <FFT_FPS>
Temporal resolution for FFT calculation (rendering always occurs at 60 fps with interpolation) [default: 12]
--bar-smoothness <BAR_SMOOTHNESS>
Smoothing factor for spatial interpolation between bars [default: 1]
--freq-resolution <FREQ_RESOLUTION>
Number of individual frequencies detected by the FFT [default: 90]
--min-freq <MIN_FREQ>
Maximum frequency detected by FFT [default: 0]
--max-freq <MAX_FREQ>
Minimum frequency detected by FFT [default: 5000]
--averaging-window <AVERAGING_WINDOW>
Size of averaging window (larger = less movement) [default: 1]
--width <WINDOW_WIDTH>
Window width [default: 1000]
--height <WINDOW_HEIGHT>
Window height [default: 700]
--border-size <BORDER_SIZE>
Border size for each bar [default: 1]
--border-color <BORDER_COLOR>
Border color for each bar (in hex) [default: 000000]
--bar-color <BAR_COLOR>
Color for each bar (in hex) [default: FF0000]
--disable-title
Whether to disable printing
--track-name
Use if you want track name to be printed
--display-gui
Use if you want the gui to be open when launched
--text-color <TEXT_COLOR>
Color for currently playing text (in hex) [default: FFFFFF]
--font-size <FONT_SIZE>
Expand Down
140 changes: 140 additions & 0 deletions src/args.rs
@@ -0,0 +1,140 @@
use std::path::Path;
use bevy::prelude::*;
use crate::*;
use clap::{ArgAction, Parser};

#[derive(Debug, Parser)]
#[clap(author, version, about)]
pub struct CLIArgs {
/// File path to Audio file
#[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 = "bar-smoothness", default_value_t = 1)]
bar_smoothness: u32,

/// Number of individual frequencies detected by the FFT
#[arg(long = "freq-resolution", default_value_t = 90)]
freq_resolution: u32,

/// Maximum frequency detected by FFT
#[arg(long = "min-freq", default_value_t = 0.0)]
min_freq: f32,

/// Minimum frequency detected by FFT
#[arg(long = "max-freq", default_value_t = 5000.0)]
max_freq: f32,

/// Size of averaging window (larger = less movement)
#[arg(long = "averaging-window", default_value_t = 1)]
averaging_window: u32,

/// Window width
#[arg(long = "width", default_value_t = 1000)]
window_width: i32,

/// Window height
#[arg(long = "height", default_value_t = 700)]
window_height: i32,

/// Border size for each bar
#[arg(long = "border-size", default_value_t = 1)]
border_size: u32,

/// Border color for each bar (in hex)
#[arg(long = "border-color", default_value_t = String::from("000000"))]
border_color: String,

/// Color for each bar (in hex)
#[arg(long = "bar-color", default_value_t = String::from("FF0000"))]
bar_color: String,

/// Use if you want track name to be printed
#[arg(long = "track-name", action = ArgAction::SetTrue)]
track_name: bool,

/// Use if you want the gui to be open when launched
#[arg(long = "display-gui", action = ArgAction::SetTrue)]
display_gui: bool,

/// Color for currently playing text (in hex)
#[arg(long = "text-color", default_value_t = String::from("FFFFFF"))]
text_color: String,

/// Font size of currently playing label
#[arg(long = "font-size", default_value_t = 25)]
font_size: u32,

// Background color (in hex)
#[arg(long = "background-color", default_value_t = String::from("000000"))]
background_color: String,
}

pub fn cli_args_to_fft_args(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.bar_smoothness);
fft_fps_constraint(cli_args.fft_fps);
freq_resolution_constraint(cli_args.freq_resolution);
averaging_window_constraint(cli_args.averaging_window);

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(),
bar_smoothness: cli_args.bar_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,
averaging_window: cli_args.averaging_window,
min_freq: cli_args.min_freq,
max_freq: cli_args.max_freq,
display_gui: cli_args.display_gui
}
}

pub fn parse_cli_args() -> FFTArgs {
cli_args_to_fft_args(args::CLIArgs::parse())
}
// Value constraints
pub fn bar_smoothness_constraint(v: u32) {
if v > 3 {
println!("bar-smoothness must be between 0 and 3 inclusive.");
std::process::exit(1);
}
}

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.");
std::process::exit(1);
}
}

fn averaging_window_constraint(v: u32) {
if v < 1 || v > 5 {
println!("averaging-window must be between 1 and 5 inclusive.");
std::process::exit(1);
}
}

0 comments on commit 9850c46

Please sign in to comment.