From 75c9880d1a7bb7e54996743989374a45d5a26e49 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sat, 5 Nov 2016 15:56:24 +0200 Subject: Reordered passing in channels --- src/audio.rs | 41 ++++++----------------------------------- src/gui.rs | 41 ++++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 48 deletions(-) diff --git a/src/audio.rs b/src/audio.rs index c989c49..c038080 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -34,13 +34,8 @@ fn get_device_list_returns_devices() { assert!(devices.len() > 0); } - -pub struct OpenRecordingChannel { - pub receiver: Receiver>, - pub stream: pa::Stream> -} - -pub fn start_listening(pa: &pa::PortAudio, device_index: u32) -> Result { +pub fn start_listening(pa: &pa::PortAudio, device_index: u32, + sender: Sender>) -> Result>, pa::Error> { let device_info = try!(pa.device_info(pa::DeviceIndex(device_index))); let latency = device_info.default_low_input_latency; @@ -54,22 +49,16 @@ pub fn start_listening(pa: &pa::PortAudio, device_index: u32) -> Result, |max, next| - if max.is_none() || max.clone().unwrap().intensity < next.intensity { Some(next.clone()) } else { max } - ).unwrap().max_freq; - println!("{}Hz", max_frequency.floor()); - } -*/ diff --git a/src/gui.rs b/src/gui.rs index 444f21b..42e062d 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -3,8 +3,11 @@ use gtk::prelude::*; use std::cell::RefCell; use portaudio as pa; use std::rc::Rc; +use std::sync::Arc; use std::io; use std::io::Write; +use std::thread; +use std::sync::mpsc::*; const GUI_XML: &'static str = r#" @@ -20,43 +23,55 @@ const GUI_XML: &'static str = r#" struct ApplicationState { pa: pa::PortAudio, - channel: Option<::audio::OpenRecordingChannel> + pa_stream: Option>> } pub fn start_gui() -> Result<(), String> { let pa = try!(::audio::init().map_err(|e| e.to_string())); let microphones = try!(::audio::get_device_list(&pa).map_err(|e| e.to_string())); - + + let (mic_sender, mic_receiver) = channel(); let state = Rc::new(RefCell::new(ApplicationState { pa: pa, - channel: None + pa_stream: None })); try!(gtk::init().map_err(|_| "Failed to initialize GTK.")); let gtk_builder = try!(create_window(microphones)); - let dropdown: gtk::ComboBoxText = try!( - gtk_builder.get_object("dropdown") - .ok_or("GUI does not contain an object with id 'dropdown'") - ); { let state_for_dropdown = state.clone(); + + let dropdown: gtk::ComboBoxText = try!( + gtk_builder.get_object("dropdown").ok_or("GUI does not contain an object with id 'dropdown'") + ); dropdown.connect_changed(move |dropdown: >k::ComboBoxText| { - match state_for_dropdown.borrow_mut().channel { - Some(ref mut channel) => {channel.stream.stop().ok();}, + match state_for_dropdown.borrow_mut().pa_stream { + Some(ref mut stream) => {stream.stop().ok();}, _ => {} } - let selected_mic = dropdown.get_active_id().and_then(|id| id.parse().ok()).expect("Dropdown did not change to a valid value"); - let channel = ::audio::start_listening(&state_for_dropdown.borrow().pa, selected_mic).ok(); - if channel.is_none() { + let stream = ::audio::start_listening(&state_for_dropdown.borrow().pa, selected_mic, mic_sender.clone()).ok(); + if stream.is_none() { writeln!(io::stderr(), "Failed to open audio channel").ok(); } - state_for_dropdown.borrow_mut().channel = channel; + state_for_dropdown.borrow_mut().pa_stream = stream; }); } + let async_thread = thread::spawn(move || { + for samples in mic_receiver { + let frequency_domain = ::transforms::fft(samples, 44100.0); + + let max_frequency = frequency_domain.iter() + .fold(None as Option<::transforms::FrequencyBucket>, |max, next| + if max.is_none() || max.clone().unwrap().intensity < next.intensity { Some(next.clone()) } else { max } + ).unwrap().max_freq; + println!("{}Hz", max_frequency.floor()); + } + }); + gtk::main(); Ok(()) } -- cgit v1.2.3