Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI #2

Merged
merged 5 commits into from Mar 8, 2024
Merged

UI #2

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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);
}
}