extern crate cpal; extern crate gtk; use std::thread; use std::iter::Iterator; use cpal::{EventLoop, StreamData, UnknownTypeInputBuffer, Sample}; use gtk::prelude::*; use gtk::{Button, Window, WindowType}; pub struct Gui { window: gtk::Window } impl Gui { pub fn new() -> Self { let window = Window::new(WindowType::Toplevel); window.set_title("Hello GTK"); window.set_default_size(350, 70); let button = Button::new_with_label("Click me now"); window.add(&button); window.show_all(); window.connect_delete_event(|_, _| { println!("Bye"); gtk::main_quit(); Inhibit(false) }); button.connect_clicked(|_| { println!("Clicked!"); }); Self { window: window } } } struct AudioEngine { event_loop: EventLoop, max_value: i16, } impl AudioEngine { pub fn new() -> Self { AudioEngine { event_loop: EventLoop::new(), max_value: 0 } } pub fn init(&mut self) -> Result<(), String> { let device = cpal::default_input_device() .ok_or("Could not find a default input device")?; let mut supported_formats_range = device.supported_input_formats() .map_err(|_| "Could not get supported input formats")?; let format = supported_formats_range .next() .ok_or("Could not get supported formats range")? .with_max_sample_rate(); let stream_id = self.event_loop.build_input_stream(&device, &format) .map_err(|_| "Could not build input stream")?; self.event_loop.play_stream(stream_id); Ok(()) } pub fn run(&mut self) { self.event_loop.run(|_stream_id, stream_data| { match stream_data { StreamData::Input { buffer: UnknownTypeInputBuffer::I16(buffer) } => self.process_audio(buffer), StreamData::Input { buffer: UnknownTypeInputBuffer::U16(buffer) } => self.process_audio(buffer), StreamData::Input { buffer: UnknownTypeInputBuffer::F32(buffer) } => self.process_audio(buffer), _ => unreachable!() } }); } fn process_audio(&mut self, buffer: cpal::InputBuffer) where T: cpal::Sample { let max = buffer .iter() .map(Sample::to_i16) .max() .unwrap_or(0) .abs(); if max > self.max_value { println!("new max: {}", max); self.max_value = max; } } } fn main() { // Audio: thread::spawn(move || { let mut audio_engine = AudioEngine::new(); audio_engine.init().unwrap_or_else(|err| { panic!("Could not start audio engine: {}", err); }); audio_engine.run(); }); // GUI if gtk::init().is_err() { panic!("Failed to initialize GTK."); } let _gui = Gui::new(); gtk::main(); }