summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2017-07-05 20:25:48 +0200
committerJustin Worthe <justin@worthe-it.co.za>2017-07-05 20:25:48 +0200
commit4048c4f9bfeea1827ed004ae9d1961bd0a78a1bb (patch)
treebaae31b5f5afaaadeb177fc53c9319476bd4aa4d /src
parent85ac457388422c3a3f0ed8155ca6506276e3efd1 (diff)
Started listening on default microphone on startup
Diffstat (limited to 'src')
-rw-r--r--src/audio.rs12
-rw-r--r--src/gui.rs46
2 files changed, 37 insertions, 21 deletions
diff --git a/src/audio.rs b/src/audio.rs
index 9a5ea0e..c7cea54 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -24,6 +24,11 @@ pub fn get_device_list(pa: &pa::PortAudio) -> Result<Vec<(u32, String)>, pa::Err
Ok(list)
}
+pub fn get_default_device(pa: &pa::PortAudio) -> Result<u32, pa::Error> {
+ let pa::DeviceIndex(default_input_index) = pa.default_input_device()?;
+ Ok(default_input_index)
+}
+
#[test]
#[ignore]
fn get_device_list_returns_devices() {
@@ -35,8 +40,13 @@ fn get_device_list_returns_devices() {
assert!(devices.len() > 0);
}
+pub fn start_listening_default(pa: &pa::PortAudio, sender: Sender<Vec<f64>>) -> Result<pa::Stream<pa::NonBlocking, pa::Input<f32>>, pa::Error> {
+ let default = get_default_device(&pa)?;
+ start_listening(&pa, default, sender)
+}
+
pub fn start_listening(pa: &pa::PortAudio, device_index: u32,
- sender: Sender<Vec<f64>>) -> Result<pa::Stream<pa::NonBlocking, pa::Input<f32>>, pa::Error> {
+ sender: Sender<Vec<f64>>) -> Result<pa::Stream<pa::NonBlocking, pa::Input<f32>>, 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 3dd5719..53e9a51 100644
--- a/src/gui.rs
+++ b/src/gui.rs
@@ -39,13 +39,14 @@ struct CrossThreadState {
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 default_microphone = try!(::audio::get_default_device(&pa).map_err(|e| e.to_string()));
+
try!(gtk::init().map_err(|_| "Failed to initialize GTK."));
let state = Rc::new(RefCell::new(ApplicationState {
pa: pa,
pa_stream: None,
- ui: create_window(microphones)
+ ui: create_window(microphones, default_microphone)
}));
let cross_thread_state = Arc::new(RwLock::new(CrossThreadState {
@@ -72,7 +73,7 @@ pub fn start_gui() -> Result<(), String> {
Ok(())
}
-fn create_window(microphones: Vec<(u32, String)>) -> RustyUi {
+fn create_window(microphones: Vec<(u32, String)>, default_microphone: u32) -> RustyUi {
let window = gtk::Window::new(gtk::WindowType::Toplevel);
window.set_title("Rusty Microphone");
window.connect_delete_event(|_, _| {
@@ -87,7 +88,7 @@ fn create_window(microphones: Vec<(u32, String)>) -> RustyUi {
vbox.add(&hbox);
let dropdown = gtk::ComboBoxText::new();
dropdown.set_hexpand(true);
- set_dropdown_items(&dropdown, microphones);
+ set_dropdown_items(&dropdown, microphones, default_microphone);
hbox.add(&dropdown);
let oscilloscope_toggle_button = gtk::Button::new_with_label("Osc");
@@ -129,32 +130,37 @@ fn create_window(microphones: Vec<(u32, String)>) -> RustyUi {
}
}
-fn set_dropdown_items(dropdown: &gtk::ComboBoxText, microphones: Vec<(u32, String)>) {
+fn set_dropdown_items(dropdown: &gtk::ComboBoxText, microphones: Vec<(u32, String)>, default_mic: u32) {
for (index, name) in microphones {
dropdown.append(Some(format!("{}", index).as_ref()), name.as_ref());
}
+ dropdown.set_active_id(Some(format!("{}", default_mic).as_ref()));
}
fn connect_dropdown_choose_microphone(mic_sender: Sender<Vec<f64>>, state: Rc<RefCell<ApplicationState>>) {
- let outer_state = state.clone();
- let ref dropdown = outer_state.borrow().ui.dropdown;
+ let dropdown = state.borrow().ui.dropdown.clone();
+ start_listening_current_dropdown_value(&dropdown, mic_sender.clone(), state.clone());
dropdown.connect_changed(move |dropdown: &gtk::ComboBoxText| {
- match state.borrow_mut().pa_stream {
- Some(ref mut stream) => {stream.stop().ok();},
- _ => {}
- }
- let selected_mic = match dropdown.get_active_id().and_then(|id| id.parse().ok()) {
- Some(mic) => mic,
- None => {return;}
- };
- let stream = ::audio::start_listening(&state.borrow().pa, selected_mic, mic_sender.clone()).ok();
- if stream.is_none() {
- writeln!(io::stderr(), "Failed to open audio channel").ok();
- }
- state.borrow_mut().pa_stream = stream;
+ start_listening_current_dropdown_value(&dropdown, mic_sender.clone(), state.clone())
});
}
+fn start_listening_current_dropdown_value(dropdown: &gtk::ComboBoxText, mic_sender: Sender<Vec<f64>>, state: Rc<RefCell<ApplicationState>>) {
+ match state.borrow_mut().pa_stream {
+ Some(ref mut stream) => {stream.stop().ok();},
+ _ => {}
+ }
+ let selected_mic = match dropdown.get_active_id().and_then(|id| id.parse().ok()) {
+ Some(mic) => mic,
+ None => {return;}
+ };
+ let stream = ::audio::start_listening(&state.borrow().pa, selected_mic, mic_sender).ok();
+ if stream.is_none() {
+ writeln!(io::stderr(), "Failed to open audio channel").ok();
+ }
+ state.borrow_mut().pa_stream = stream;
+}
+
fn start_processing_audio(mic_receiver: Receiver<Vec<f64>>, cross_thread_state: Arc<RwLock<CrossThreadState>>) {
thread::spawn(move || {
loop {