summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Worthe <justin.worthe@gmail.com>2016-11-01 20:27:06 +0200
committerJustin Worthe <justin.worthe@gmail.com>2016-11-01 20:27:06 +0200
commit420ad331332bce98f871f1c4ca2c0bea51688767 (patch)
tree8fd78664a5d319797ce2c372228f06bd81649fa9 /src
parent494e89fd10511e1830ac76d0c0309f097a185774 (diff)
Closed and opened audio channels
Diffstat (limited to 'src')
-rw-r--r--src/audio.rs21
-rw-r--r--src/gui.rs39
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;
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#"
<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: &gtk::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: &gtk::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(())