diff --git a/src/analyzer.rs b/src/analyzer.rs index 3771a21..ff961ef 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -203,6 +203,9 @@ impl FftAnalyzer { let mut lock = self.last_analysis.lock().unwrap(); *lock = result; } + fn progress(&self) -> f32 { + self.audio_buf.lock().unwrap().read_since_last_update as f32 / self.fft_length as f32 + } } impl Analyzer for FftAnalyzer { diff --git a/src/main.rs b/src/main.rs index 75e4b59..cf01d6b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ use egui::Color32; use egui_plot::{Legend, Line, Plot}; use std::mem::swap; +use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::sync::{Arc, Mutex}; use std::thread::{self, JoinHandle}; @@ -90,6 +91,7 @@ struct MyApp { fft_thread: JoinHandle<()>, fft_close_channel: Sender<()>, fft_length: usize, + fft_progress: Arc, audio_device: cpal::Device, audio_config: cpal::StreamConfig, @@ -118,6 +120,11 @@ impl eframe::App for MyApp { }); self.sample_rate_box(ui); self.fft_length_box(ui); + + ui.separator(); + ui.with_layout(egui::Layout::bottom_up(egui::Align::Center), |ui| { + self.fft_progress(ui) + }); }); egui::CentralPanel::default().show(ctx, |ui| { ui_plot(ui, self.last_result.clone()); @@ -163,6 +170,14 @@ impl MyApp { self.set_fft_length(FFT_LENGTHS[self.ui_selections.fft_length]); } } + fn fft_progress(&mut self, ui: &mut egui::Ui) { + let percent = self.fft_progress.load(Ordering::Relaxed) as f32 / self.fft_length as f32; + let fft_progress = egui::ProgressBar::new(percent); + ui.add(fft_progress); + if percent >= 1.0 { + self.fft_progress.store(0, Ordering::Relaxed); + } + } fn new(cc: &eframe::CreationContext) -> Self { let host = cpal::default_host(); println!("Audio host: {}", host.id().name()); @@ -223,6 +238,7 @@ impl MyApp { }) .unwrap(), fft_length: FFT_LENGTHS[DEFAULT_FFT_LENGTH], + fft_progress: Arc::new(AtomicUsize::new(0)), fft_close_channel: fft_close_channel.0, ui_selections: MyAppUiSelections { audio_device: device_names @@ -295,12 +311,15 @@ impl MyApp { ); let new_channel = self.sample_channel.clone(); + let fft_progress_ref = self.fft_progress.clone(); self.audio_stream = Some( self.audio_device .build_input_stream( &self.audio_config, - move |data, _| handle_audio_frame(data, new_channel.clone()), + move |data, _| { + handle_audio_frame(data, new_channel.clone(), fft_progress_ref.clone()) + }, move |err| panic!("{:?}", err), Some(std::time::Duration::from_secs(1)), ) @@ -405,10 +424,18 @@ fn fft_thread_impl( } } -fn handle_audio_frame(data: &[SampleType], chan: Sender>) { +fn handle_audio_frame( + data: &[SampleType], + chan: Sender>, + fft_progress: Arc, +) { // Copy and send to processor thread // FIXME: Fails at fft lengths > 16384. Are we too slow collecting data? - chan.send(data.to_vec()).unwrap_or_default() + chan.send(data.to_vec()).unwrap_or_default(); + fft_progress.store( + fft_progress.load(Ordering::Relaxed) + data.len(), + Ordering::Relaxed, + ); } fn main() {