diff --git a/Cargo.lock b/Cargo.lock index 495c183..649a047 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,6 +106,7 @@ dependencies = [ "env_logger", "log", "rustfft", + "textplots", ] [[package]] @@ -165,6 +166,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "bytemuck" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3" + [[package]] name = "bytes" version = "1.9.0" @@ -247,6 +254,16 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "colored" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" +dependencies = [ + "lazy_static", + "windows-sys 0.59.0", +] + [[package]] name = "combine" version = "4.6.7" @@ -313,6 +330,16 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c87e182de0887fd5361989c677c4e8f5000cd9491d6d563161a8f3a5519fc7f" +[[package]] +name = "drawille" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64e461c3f1e69d99372620640b3fd5f0309eeda2e26e4af69f6760c0e1df845" +dependencies = [ + "colored", + "fnv", +] + [[package]] name = "either" version = "1.13.0" @@ -358,6 +385,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "gimli" version = "0.28.1" @@ -768,6 +801,15 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rgb" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" +dependencies = [ + "bytemuck", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -836,6 +878,16 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "textplots" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f59b64803118dbff62f92842b3154a2c802dfd8e18660132bbcbfb141c637ae3" +dependencies = [ + "drawille", + "rgb", +] + [[package]] name = "thiserror" version = "1.0.69" diff --git a/Cargo.toml b/Cargo.toml index 174a5cd..f3caad9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,5 @@ color-eyre = "0.6" cpal = { version = "0.15", features = ["jack"] } rustfft = "6.2" + +textplots = "0.8" diff --git a/src/main.rs b/src/main.rs index 1f3a5b6..6ccc695 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use std::{thread::sleep, time::Duration}; +use std::{sync::mpsc, thread::sleep, time::Duration}; use color_eyre::eyre::bail; use cpal::{ @@ -6,7 +6,11 @@ use cpal::{ BufferSize, HostId, SupportedBufferSize, }; use log::{debug, error, info, trace}; -use rustfft::{num_complex::Complex, FftPlanner}; +use rustfft::{ + num_complex::{Complex, ComplexFloat}, + FftPlanner, +}; +use textplots::{Chart, Plot, Shape}; fn main() -> color_eyre::Result<()> { env_logger::init(); @@ -44,6 +48,7 @@ fn main() -> color_eyre::Result<()> { let fft = planner.plan_fft_forward(buffer_size as usize); let mut fft_data = vec![Complex::new(0.0, 0.0); buffer_size as usize]; let mut fft_scratch = vec![Complex::new(0.0, 0.0); buffer_size as usize]; + let (sender, receiver) = mpsc::channel(); let stream = device.build_input_stream( &config, @@ -51,7 +56,15 @@ fn main() -> color_eyre::Result<()> { for i in 0..data.len() { fft_data[i] = Complex::new(data[i], 0.0); } - fft.process_with_scratch(&mut fft_data[..], &mut fft_scratch[..]); + let mut fft_output = vec![Complex::new(0.0, 0.0); data.len()]; + fft.process_outofplace_with_scratch( + &mut fft_data[..], + &mut fft_output[..], + &mut fft_scratch[..], + ); + if let Err(e) = sender.send(fft_output) { + error!("Unable to send fft output: {e}"); + } }, |err| { error!("input stream error: {err}"); @@ -62,6 +75,14 @@ fn main() -> color_eyre::Result<()> { stream.play()?; loop { - sleep(Duration::from_secs(1)); + let data = receiver.recv()?; + let plot_data: Vec<_> = data + .into_iter() + .enumerate() + .map(|(i, datum)| ((i as f32).log10(), datum.abs() / 1024.0.sqrt())) + .collect(); + Chart::new_with_y_range(200, 50, 0.0, 1024.0.log10(), 0.0, 2.0) + .lineplot(&Shape::Bars(&plot_data[..])) + .display(); } }