118 lines
3.0 KiB
Rust
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();
|
|
}
|