diff options
author | Justin Worthe <justin.worthe@gmail.com> | 2016-11-01 20:27:06 +0200 |
---|---|---|
committer | Justin Worthe <justin.worthe@gmail.com> | 2016-11-01 20:27:06 +0200 |
commit | 420ad331332bce98f871f1c4ca2c0bea51688767 (patch) | |
tree | 8fd78664a5d319797ce2c372228f06bd81649fa9 /src | |
parent | 494e89fd10511e1830ac76d0c0309f097a185774 (diff) |
Closed and opened audio channels
Diffstat (limited to 'src')
-rw-r--r-- | src/audio.rs | 21 | ||||
-rw-r--r-- | src/gui.rs | 39 |
2 files changed, 36 insertions, 24 deletions
diff --git a/src/audio.rs b/src/audio.rs index 8f23bed..c989c49 100644 --- a/src/audio.rs +++ b/src/audio.rs @@ -2,8 +2,6 @@ extern crate portaudio; use portaudio as pa; use std::sync::mpsc::*; -use std::io; -use std::io::Write; const SAMPLE_RATE: f64 = 44100.0; const FRAMES: usize = 512; @@ -37,23 +35,12 @@ fn get_device_list_returns_devices() { } -pub struct OpenRecordingChannel<'a> { - receiver: Receiver<Vec<f32>>, - stream: pa::Stream<'a, pa::NonBlocking, pa::Input<f32>> +pub struct OpenRecordingChannel { + pub receiver: Receiver<Vec<f32>>, + pub stream: pa::Stream<pa::NonBlocking, pa::Input<f32>> } -impl<'a> Drop for OpenRecordingChannel<'a> { - fn drop(&mut self) { - //if stream doesn't close cleanly, don't end the world. It's probably fine. - match self.stream.stop() { - Result::Err(err) => {writeln!(io::stderr(), "Failed to close audio stream. {}", err).ok();}, - _ => {} - } - } -} - -pub fn start_listening<'a>(pa: &'a pa::PortAudio, device_index: u32) -> Result<OpenRecordingChannel<'a>, pa::Error> { - //let pa = try!(pa::PortAudio::new()); +pub fn start_listening(pa: &pa::PortAudio, device_index: u32) -> Result<OpenRecordingChannel, pa::Error> { let device_info = try!(pa.device_info(pa::DeviceIndex(device_index))); let latency = device_info.default_low_input_latency; @@ -1,6 +1,10 @@ use gtk; use gtk::prelude::*; -use std::cell::Cell; +use std::cell::RefCell; +use portaudio as pa; +use std::rc::Rc; +use std::io; +use std::io::Write; const GUI_XML: &'static str = r#" <interface> @@ -14,23 +18,44 @@ const GUI_XML: &'static str = r#" </interface> "#; +struct ApplicationState { + pa: pa::PortAudio, + channel: Option<::audio::OpenRecordingChannel> +} + 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 selected_mic: Cell<Option<u32>> = Cell::new(None); + + let state = Rc::new(RefCell::new(ApplicationState { + pa: pa, + channel: 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'") ); - dropdown.connect_changed(move |dropdown: >k::ComboBoxText| { - selected_mic.set(dropdown.get_active_id().and_then(|id| id.parse().ok())); - println!("{}", selected_mic.get().unwrap()); - }); + { + let state_for_dropdown = state.clone(); + dropdown.connect_changed(move |dropdown: >k::ComboBoxText| { + match state_for_dropdown.borrow_mut().channel { + Some(ref mut channel) => {channel.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() { + writeln!(io::stderr(), "Failed to open audio channel").ok(); + } + state_for_dropdown.borrow_mut().channel = channel; + }); + } gtk::main(); Ok(()) |