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

finished freq_rescaling #7

Merged
merged 1 commit into from Mar 10, 2024
Merged
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
23 changes: 5 additions & 18 deletions src/args.rs
Expand Up @@ -15,8 +15,8 @@ pub struct CLIArgs {
fft_fps: u32,

/// Smoothing factor for spatial interpolation between bars
#[clap(long = "bar-smoothness", default_value_t = 1)]
bar_smoothness: u32,
#[clap(long = "smoothness", default_value_t = 1)]
smoothness: u32,

/// Number of individual frequencies detected by the FFT
#[arg(long = "freq-resolution", default_value_t = 90)]
Expand All @@ -30,10 +30,6 @@ pub struct CLIArgs {
#[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.0)]
window_width: f32,
Expand Down Expand Up @@ -81,10 +77,9 @@ pub fn cli_args_to_fft_args(cli_args: CLIArgs) -> FFTArgs {
std::process::exit(1);
}

bar_smoothness_constraint(cli_args.bar_smoothness);
bar_smoothness_constraint(cli_args.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(),
Expand All @@ -95,12 +90,11 @@ pub fn cli_args_to_fft_args(cli_args: CLIArgs) -> FFTArgs {
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,
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,
averaging_window: cli_args.averaging_window,
min_freq: cli_args.min_freq,
max_freq: cli_args.max_freq,
display_gui: cli_args.display_gui
Expand All @@ -113,7 +107,7 @@ pub fn parse_cli_args() -> FFTArgs {
// Value constraints
pub fn bar_smoothness_constraint(v: u32) {
if v > 3 {
println!("bar-smoothness must be between 0 and 3 inclusive.");
println!("smoothness must be between 0 and 3 inclusive.");
std::process::exit(1);
}
}
Expand All @@ -131,10 +125,3 @@ fn freq_resolution_constraint(v: u32) {
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);
}
}
17 changes: 15 additions & 2 deletions src/fft.rs
Expand Up @@ -40,7 +40,6 @@ pub fn space_interpolate(v: &mut Vec<f32>, num_new_frames: u32) {
}
}

#[allow(dead_code)]
pub fn smooth_fft(mut fft: FFT, alpha: u32) -> FFT {
let mut new_fft = Vec::new();
for i in (alpha as usize)..(fft.num_frames - alpha as usize) {
Expand All @@ -58,7 +57,7 @@ pub fn smooth_fft(mut fft: FFT, alpha: u32) -> FFT {
fft
}

pub fn normalize_fft(mut fft: FFT, bounds: &[f32], scaling_factor: &[f32]) -> FFT {
pub fn intensity_normalize_fft(mut fft: FFT, bounds: &[f32], scaling_factor: &[f32]) -> FFT {
let min_max_scale = fft.max - fft.min;
let rescale = |mut x: Vec<f32>| -> Vec<f32> {
for i in x.iter_mut() {
Expand All @@ -76,6 +75,20 @@ pub fn normalize_fft(mut fft: FFT, bounds: &[f32], scaling_factor: &[f32]) -> FF
fft
}

pub fn frequency_normalize_fft(mut fft: FFT, scaling_factor: &[f32]) -> FFT {
let n_freq_buckets = scaling_factor.len();
let n_bars = fft.fft[0].len();
let bars_per_bucket = n_bars / n_freq_buckets;
let rescale = |mut x: Vec<f32>| -> Vec<f32> {
for (i, v) in x.iter_mut().enumerate() {
*v *= scaling_factor[(i / bars_per_bucket).min(n_freq_buckets - 1)];
}
x
};
fft.fft = fft.fft.into_par_iter().map(|x| rescale(x)).collect();
fft
}

#[allow(dead_code)]
pub fn write_fft_to_binary_file(filepath: &PathBuf, fft: &FFT) -> io::Result<()> {
let mut file = File::create(filepath)?;
Expand Down
17 changes: 10 additions & 7 deletions src/main.rs
Expand Up @@ -30,15 +30,17 @@ use std::io::BufReader;
use std::path::PathBuf;
use std::time::Duration;

// TODO : Add to brew, and whatever linux/windows uses
// TODO : Add to other package managers
// TODO : Add yaml config file for changing default settings
// TODO : Add a button to gui to write current state to config file
// TODO : Add a button to gui to reset to default

// Constants
const RENDERING_FPS: u32 = 60;
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] = &[0.4, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.6, 0.5];
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 MIN_BAR_HEIGHT: f32 = 0.001;
const MAX_BAR_HEIGHT: f32 = 0.45;
Expand All @@ -54,11 +56,10 @@ struct FFTArgs {
font_size: i32,
background_color: Color,
fft_fps: u32,
bar_smoothness: u32,
smoothness: u32,
freq_resolution: u32,
window_width: f32,
window_height: f32,
averaging_window: u32,
min_freq: f32,
max_freq: f32,
display_gui: bool,
Expand All @@ -84,11 +85,13 @@ fn compute_and_preprocess_fft(fp: &PathBuf, args: &FFTArgs) -> Vec<Vec<f32>> {
args.max_freq,
);

fft = smooth_fft(fft, args.averaging_window);
fft = normalize_fft(fft, RESCALING_THRESHOLDS, RESCALING_FACTOR);
fft = smooth_fft(fft, AVERAGING_WINDOW);
fft = intensity_normalize_fft(fft, RESCALING_THRESHOLDS, INTENSITY_RESCALING);
fft = frequency_normalize_fft(fft, FREQ_RESCALING);

let mut fft_vec = fft.fft;

// Reverses bar order and prepends
for c in fft_vec.iter_mut() {
let mut reversed = c.clone();
reversed.reverse();
Expand All @@ -98,7 +101,7 @@ fn compute_and_preprocess_fft(fp: &PathBuf, args: &FFTArgs) -> Vec<Vec<f32>> {

fft_vec
.par_iter_mut()
.for_each(|x| space_interpolate(x, args.bar_smoothness));
.for_each(|x| space_interpolate(x, args.smoothness));

fft_vec
}
Expand Down