lock-free-vumeter/src/main.rs

118 lines
3.0 KiB
Rust

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<T>(&mut self, buffer: cpal::InputBuffer<T>) 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();
}