#[macro_use]
extern crate std;
use audio_visualizer::spectrum::staticc::plotters_png_file::spectrum_static_plotters_png_visualize;
use audio_visualizer::test_support::TEST_OUT_DIR;
use minimp3::{Decoder as Mp3Decoder, Error as Mp3Error, Frame as Mp3Frame};
use spectrum_analyzer::windows::{blackman_harris_4term, hamming_window, hann_window};
use spectrum_analyzer::{
samples_fft_to_spectrum, FrequencyLimit, SpectrumTotalScaleFunctionFactory,
};
use std::fs::File;
use std::time::Instant;
fn main() {
println!("bass drum example:");
example__bass_drum_sample();
println!("============================");
println!("clap beat example:");
example__clap_beat_sample();
println!("============================");
println!("high hat example:");
example__high_hat_sample();
}
#[allow(non_snake_case)]
fn example__bass_drum_sample() {
let samples = read_mp3("test/samples/bass_drum_with_high-hat_at_end-sample.mp3");
to_spectrum_and_plot(
&samples[0..16384],
"example__mp3-samples__bass_drum__spectrum",
FrequencyLimit::Max(5000.0),
)
}
#[allow(non_snake_case)]
fn example__clap_beat_sample() {
let samples = read_mp3("test/samples/clap-beat-sample.mp3");
to_spectrum_and_plot(
&samples[0..16384],
"example__mp3-samples__clap_beat__spectrum",
FrequencyLimit::Max(5000.0),
)
}
#[allow(non_snake_case)]
fn example__high_hat_sample() {
let samples = read_mp3("test/samples/high-hat-sample.mp3");
to_spectrum_and_plot(
&samples[0..4096],
"example__mp3-samples__high-hat__spectrum",
FrequencyLimit::All,
)
}
fn to_spectrum_and_plot(samples: &[f32], filename: &str, frequency_limit: FrequencyLimit) {
let no_window = &samples[..];
let now = Instant::now();
let hann_window = hann_window(&no_window);
println!(
"[Measurement]: Hann-Window with {} samples took: {}µs",
samples.len(),
now.elapsed().as_micros()
);
let now = Instant::now();
let hamming_window = hamming_window(&no_window);
println!(
"[Measurement]: Hamming-Window with {} samples took: {}µs",
samples.len(),
now.elapsed().as_micros()
);
let blackman_harris_4term_window = blackman_harris_4term(&no_window);
println!(
"[Measurement]: Blackmann-Harris-4-term-Window with {} samples took: {}µs",
samples.len(),
now.elapsed().as_micros()
);
let blackman_harris_7term_window = blackman_harris_4term(&no_window);
println!(
"[Measurement]: Blackmann-Harris-7-term-Window with {} samples took: {}µs",
samples.len(),
now.elapsed().as_micros()
);
let now = Instant::now();
let spectrum_no_window = samples_fft_to_spectrum(
&no_window,
44100,
frequency_limit,
None,
Some(get_scale_to_one_fn_factory()),
);
println!(
"[Measurement]: FFT to Spectrum with no window with {} samples took: {}µs",
samples.len(),
now.elapsed().as_micros()
);
let now = Instant::now();
let spectrum_hamming_window = samples_fft_to_spectrum(
&hamming_window,
44100,
frequency_limit,
None,
Some(get_scale_to_one_fn_factory()),
);
println!(
"[Measurement]: FFT to Spectrum with Hamming window with {} samples took: {}µs",
samples.len(),
now.elapsed().as_micros()
);
let now = Instant::now();
let spectrum_hann_window = samples_fft_to_spectrum(
&hann_window,
44100,
frequency_limit,
None,
Some(get_scale_to_one_fn_factory()),
);
println!(
"[Measurement]: FFT to Spectrum with Hann window with {} samples took: {}µs",
samples.len(),
now.elapsed().as_micros()
);
let now = Instant::now();
let spectrum_blackman_harris_4term_window = samples_fft_to_spectrum(
&blackman_harris_4term_window,
44100,
frequency_limit,
None,
Some(get_scale_to_one_fn_factory()),
);
println!("[Measurement]: FFT to Spectrum with Blackmann Harris 4-term window with {} samples took: {}µs", samples.len(), now.elapsed().as_micros());
let now = Instant::now();
let spectrum_blackman_harris_7term_window = samples_fft_to_spectrum(
&blackman_harris_7term_window,
44100,
frequency_limit,
None,
Some(get_scale_to_one_fn_factory()),
);
println!("[Measurement]: FFT to Spectrum with Blackmann Harris 7-term window with {} samples took: {}µs", samples.len(), now.elapsed().as_micros());
spectrum_static_plotters_png_visualize(
&spectrum_no_window.to_map(None),
TEST_OUT_DIR,
&format!("{}--no-window.png", filename),
false,
);
spectrum_static_plotters_png_visualize(
&spectrum_hamming_window.to_map(None),
TEST_OUT_DIR,
&format!("{}--hamming-window.png", filename),
false,
);
spectrum_static_plotters_png_visualize(
&spectrum_hann_window.to_map(None),
TEST_OUT_DIR,
&format!("{}--hann-window.png", filename),
false,
);
spectrum_static_plotters_png_visualize(
&spectrum_blackman_harris_4term_window.to_map(None),
TEST_OUT_DIR,
&format!("{}--blackman-harris-4-term-window.png", filename),
false,
);
spectrum_static_plotters_png_visualize(
&spectrum_blackman_harris_7term_window.to_map(None),
TEST_OUT_DIR,
&format!("{}--blackman-harris-7-term-window.png", filename),
false,
);
}
fn get_scale_to_one_fn_factory() -> SpectrumTotalScaleFunctionFactory {
Box::new(move |_min: f32, max: f32, _average: f32, _median: f32| Box::new(move |x| x / max))
}
fn read_mp3(file: &str) -> Vec<f32> {
let samples = read_mp3_to_mono(file);
let samples = samples.into_iter().map(|x| x as f32).collect::<Vec<f32>>();
samples
}
fn read_mp3_to_mono(file: &str) -> Vec<i16> {
let mut decoder = Mp3Decoder::new(File::open(file).unwrap());
let mut lrlr_mp3_samples = vec![];
loop {
match decoder.next_frame() {
Ok(Mp3Frame {
data: samples_of_frame,
..
}) => {
for sample in samples_of_frame {
lrlr_mp3_samples.push(sample);
}
}
Err(Mp3Error::Eof) => break,
Err(e) => panic!("{:?}", e),
}
}
lrlr_mp3_samples
}