Add FFT progress bar
This commit is contained in:
		| @@ -203,6 +203,9 @@ impl FftAnalyzer { | |||||||
|         let mut lock = self.last_analysis.lock().unwrap(); |         let mut lock = self.last_analysis.lock().unwrap(); | ||||||
|         *lock = result; |         *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 { | impl Analyzer for FftAnalyzer { | ||||||
|   | |||||||
							
								
								
									
										33
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								src/main.rs
									
									
									
									
									
								
							| @@ -6,6 +6,7 @@ use egui::Color32; | |||||||
| use egui_plot::{Legend, Line, Plot}; | use egui_plot::{Legend, Line, Plot}; | ||||||
|  |  | ||||||
| use std::mem::swap; | use std::mem::swap; | ||||||
|  | use std::sync::atomic::{AtomicUsize, Ordering}; | ||||||
| use std::sync::mpsc::{channel, Receiver, Sender}; | use std::sync::mpsc::{channel, Receiver, Sender}; | ||||||
| use std::sync::{Arc, Mutex}; | use std::sync::{Arc, Mutex}; | ||||||
| use std::thread::{self, JoinHandle}; | use std::thread::{self, JoinHandle}; | ||||||
| @@ -90,6 +91,7 @@ struct MyApp { | |||||||
|     fft_thread: JoinHandle<()>, |     fft_thread: JoinHandle<()>, | ||||||
|     fft_close_channel: Sender<()>, |     fft_close_channel: Sender<()>, | ||||||
|     fft_length: usize, |     fft_length: usize, | ||||||
|  |     fft_progress: Arc<AtomicUsize>, | ||||||
|  |  | ||||||
|     audio_device: cpal::Device, |     audio_device: cpal::Device, | ||||||
|     audio_config: cpal::StreamConfig, |     audio_config: cpal::StreamConfig, | ||||||
| @@ -118,6 +120,11 @@ impl eframe::App for MyApp { | |||||||
|                 }); |                 }); | ||||||
|             self.sample_rate_box(ui); |             self.sample_rate_box(ui); | ||||||
|             self.fft_length_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| { |         egui::CentralPanel::default().show(ctx, |ui| { | ||||||
|             ui_plot(ui, self.last_result.clone()); |             ui_plot(ui, self.last_result.clone()); | ||||||
| @@ -163,6 +170,14 @@ impl MyApp { | |||||||
|             self.set_fft_length(FFT_LENGTHS[self.ui_selections.fft_length]); |             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 { |     fn new(cc: &eframe::CreationContext) -> Self { | ||||||
|         let host = cpal::default_host(); |         let host = cpal::default_host(); | ||||||
|         println!("Audio host: {}", host.id().name()); |         println!("Audio host: {}", host.id().name()); | ||||||
| @@ -223,6 +238,7 @@ impl MyApp { | |||||||
|                 }) |                 }) | ||||||
|                 .unwrap(), |                 .unwrap(), | ||||||
|             fft_length: FFT_LENGTHS[DEFAULT_FFT_LENGTH], |             fft_length: FFT_LENGTHS[DEFAULT_FFT_LENGTH], | ||||||
|  |             fft_progress: Arc::new(AtomicUsize::new(0)), | ||||||
|             fft_close_channel: fft_close_channel.0, |             fft_close_channel: fft_close_channel.0, | ||||||
|             ui_selections: MyAppUiSelections { |             ui_selections: MyAppUiSelections { | ||||||
|                 audio_device: device_names |                 audio_device: device_names | ||||||
| @@ -295,12 +311,15 @@ impl MyApp { | |||||||
|         ); |         ); | ||||||
|  |  | ||||||
|         let new_channel = self.sample_channel.clone(); |         let new_channel = self.sample_channel.clone(); | ||||||
|  |         let fft_progress_ref = self.fft_progress.clone(); | ||||||
|  |  | ||||||
|         self.audio_stream = Some( |         self.audio_stream = Some( | ||||||
|             self.audio_device |             self.audio_device | ||||||
|                 .build_input_stream( |                 .build_input_stream( | ||||||
|                     &self.audio_config, |                     &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), |                     move |err| panic!("{:?}", err), | ||||||
|                     Some(std::time::Duration::from_secs(1)), |                     Some(std::time::Duration::from_secs(1)), | ||||||
|                 ) |                 ) | ||||||
| @@ -405,10 +424,18 @@ fn fft_thread_impl( | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| fn handle_audio_frame(data: &[SampleType], chan: Sender<Vec<SampleType>>) { | fn handle_audio_frame( | ||||||
|  |     data: &[SampleType], | ||||||
|  |     chan: Sender<Vec<SampleType>>, | ||||||
|  |     fft_progress: Arc<AtomicUsize>, | ||||||
|  | ) { | ||||||
|     // Copy and send to processor thread |     // Copy and send to processor thread | ||||||
|     // FIXME: Fails at fft lengths > 16384. Are we too slow collecting data? |     // 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() { | fn main() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user