Skip to content

Commit

Permalink
added background color flag, smaller screen dimensions and update readme
Browse files Browse the repository at this point in the history
  • Loading branch information
gursi26 committed Mar 4, 2024
1 parent b6a7db0 commit db03eb2
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 42 deletions.
70 changes: 70 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,73 @@ Cargo.lock
# Added by cargo

/target
# Created by https://www.toptal.com/developers/gitignore/api/rust,rust-analyzer,macos,osx
# Edit at https://www.toptal.com/developers/gitignore?templates=rust,rust-analyzer,macos,osx

### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon


# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### macOS Patch ###
# iCloud generated files
*.icloud

### OSX ###
# General

# Icon must end with two \r

# Thumbnails

# Files that might appear in the root of a volume

# Directories potentially created on remote AFP share

### Rust ###
# Generated by Cargo
# will have compiled files and executables
debug/
target/

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

# MSVC Windows builds of rustc generate these, which store debugging information
*.pdb

### rust-analyzer ###
# Can be generated by other build systems other than cargo (ex: bazelbuild/rust_rules)
rust-project.json


# End of https://www.toptal.com/developers/gitignore/api/rust,rust-analyzer,macos,osx

5 changes: 1 addition & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "fftviz"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
authors = ["Gursimar Singh <gursi26.dev@gmail.com>"]
license = "MIT"
Expand All @@ -11,9 +11,6 @@ repository = "https://github.com/gursi26/fftviz"
keywords = ["cli"]
categories = ["command-line-utilities"]


# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bincode = "1.3.3"
clap = { version = "4.5.0", features = ["derive"] }
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
# fft-visualizer
A lightweight FFT visualizer for audio files.
# fftviz
A lightweight FFT visualizer for audio files. Built with Rust + Raylib.

![demo image](assets/demo.png)
Binary file added assets/demo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 2 additions & 13 deletions src/fft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@ pub fn normalize_fft(mut fft: FFT, bounds: &[f32], scaling_factor: &[f32]) -> FF
fft
}

#[allow(dead_code)]
pub fn write_fft_to_binary_file(filepath: &PathBuf, fft: &FFT) -> io::Result<()> {
let mut file = File::create(filepath)?;
let encoded_data = serialize(fft).map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
file.write_all(&encoded_data)?;
Ok(())
}

#[allow(dead_code)]
pub fn read_fft_from_binary_file(filepath: &PathBuf) -> io::Result<FFT> {
let mut file = File::open(filepath)?;
let mut buffer = Vec::new();
Expand Down Expand Up @@ -141,16 +143,3 @@ pub fn compute_fft(audio_path: &PathBuf) -> FFT {
}
}

pub fn compute_and_cache_fft(audio_path: &PathBuf) -> FFT {
let file_name = audio_path.file_stem().unwrap().to_str().unwrap();
let mut cache_path = audio_path.parent().unwrap().to_path_buf();
cache_path.push(format!(".{}.fft", file_name));

if cache_path.is_file() && !FORCE_CACHE_REFRESH {
let fft = read_fft_from_binary_file(&cache_path).unwrap();
return fft;
}
let fft = compute_fft(audio_path);
write_fft_to_binary_file(&cache_path, &fft).unwrap();
fft
}
40 changes: 18 additions & 22 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use std::path::PathBuf;

// Constants
const RENDERING_FPS: u32 = 60;
const SCREEN_WIDTH: i32 = 1780;
const SCREEN_HEIGHT: i32 = 1000;
const SCREEN_WIDTH: i32 = 1000;
const SCREEN_HEIGHT: i32 = 700;

const FREQUENCY_RESOLUTION: u32 = 100;
const FFT_FPS: u32 = 12;
Expand All @@ -27,8 +27,6 @@ const FFT_WINDOW: i32 =
const BAR_INTERPOLATION_FACTOR: u32 = 2;
const RESCALING_THRESHOLDS: &[f32] = &[0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9];
const RESCALING_FACTOR: &[f32] = &[2.0, 1.7, 1.3, 1.2, 1.1, 1.0, 0.9, 0.8, 0.7];
const CACHE_FFT: bool = false;
const FORCE_CACHE_REFRESH: bool = false;


#[derive(Debug, Parser)]
Expand All @@ -42,35 +40,40 @@ struct CLIArgs {
#[arg(long = "border-size", default_value_t = 1)]
border_size: u32,

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

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

/// Set to false to disable printing currently playing song title
#[arg(long = "print-text", action = ArgAction::SetFalse)]
print_text: bool,
/// Whether to disable printing
#[arg(long = "disable-title", action = ArgAction::SetTrue)]
disable_title: bool,

/// Text of currently playing label
/// 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,
}

struct FFTArgs {
file_path: String,
border_size: i32,
border_color: Color,
bar_color: Color,
print_text: bool,
disable_title: bool,
text_color: Color,
font_size: i32,
background_color: Color
}

fn main() {
Expand All @@ -83,14 +86,7 @@ fn main() {
cache_path.push(format!(".{}.fft", file_name));

println!("Computing FFT...");
let mut fft;
if CACHE_FFT {
fft = compute_and_cache_fft(&p);
} else if cache_path.is_file() {
fft = read_fft_from_binary_file(&cache_path).unwrap();
} else {
fft = compute_fft(&p);
}
let mut fft = compute_fft(&p);

fft = normalize_fft(fft, RESCALING_THRESHOLDS, RESCALING_FACTOR);
let mut fft_vec = fft.fft;
Expand All @@ -105,7 +101,7 @@ fn main() {
let mut fft = fft_vec.into_iter().peekable();
let mut i = 0;

let (mut rl, thread) = raylib::init().title("fft-visualizer").build();
let (mut rl, thread) = raylib::init().title("fftviz").build();
rl.set_target_fps(RENDERING_FPS);
rl.set_window_size(SCREEN_WIDTH, SCREEN_HEIGHT);

Expand All @@ -119,7 +115,7 @@ fn main() {

while !rl.window_should_close() && fft.peek().is_some() && !rl.is_key_down(KeyboardKey::KEY_Q) {
let mut d = rl.begin_drawing(&thread);
d.clear_background(Color::BLACK);
d.clear_background(args.background_color);

if i as u32 % num_frame_gen == 0 {
fft_chunk = fft.next().unwrap();
Expand Down Expand Up @@ -157,7 +153,7 @@ fn main() {
);
}

if args.print_text {
if !args.disable_title {
d.draw_text(
&format!("Playing: {:?}", p.file_stem().unwrap().to_str().unwrap())[..],
10,
Expand Down
3 changes: 2 additions & 1 deletion src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ pub fn cli_args_to_fft_args(cli_args: CLIArgs) -> FFTArgs {
border_size: cli_args.border_size as i32,
border_color: Color::from_hex(&cli_args.border_color[..]).unwrap(),
bar_color: Color::from_hex(&cli_args.bar_color[..]).unwrap(),
print_text: cli_args.print_text,
disable_title: cli_args.disable_title,
text_color: Color::from_hex(&cli_args.text_color[..]).unwrap(),
font_size: cli_args.font_size as i32,
background_color: Color::from_hex(&cli_args.background_color[..]).unwrap()
}
}

0 comments on commit db03eb2

Please sign in to comment.