From 420ad331332bce98f871f1c4ca2c0bea51688767 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Tue, 1 Nov 2016 20:27:06 +0200 Subject: Closed and opened audio channels --- src/audio.rs | 21 ++++----------------- src/gui.rs | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 36 insertions(+), 24 deletions(-) (limited to 'src') 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>, - stream: pa::Stream<'a, pa::NonBlocking, pa::Input> +pub struct OpenRecordingChannel { + pub receiver: Receiver>, + pub stream: pa::Stream> } -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, pa::Error> { - //let pa = try!(pa::PortAudio::new()); +pub fn start_listening(pa: &pa::PortAudio, device_index: u32) -> Result { let device_info = try!(pa.device_info(pa::DeviceIndex(device_index))); let latency = device_info.default_low_input_latency; diff --git a/src/gui.rs b/src/gui.rs index c48c45d..444f21b 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -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#" @@ -14,23 +18,44 @@ const GUI_XML: &'static str = r#" "#; +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> = 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(()) -- cgit v1.2.3