added sliders to dynamically select waveform resolution but also widgets refresh rate
This commit is contained in:
parent
8cdd6b06e2
commit
a1b69e13bd
2 changed files with 52 additions and 13 deletions
33
src/main.rs
33
src/main.rs
|
@ -1,3 +1,5 @@
|
|||
use iced::Element;
|
||||
|
||||
mod pw;
|
||||
mod waveform;
|
||||
|
||||
|
@ -23,23 +25,26 @@ struct Rgba {
|
|||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Message {
|
||||
Waveform(waveform::Message),
|
||||
RateUpdated(f64),
|
||||
Tick,
|
||||
}
|
||||
|
||||
impl RumbleWrecker {
|
||||
fn new() -> Self {
|
||||
// Spawn default output monitor capture via pipewire
|
||||
let (tx_left, rx_left) = std::sync::mpsc::channel::<Vec<f32>>();
|
||||
let (tx_right, rx_right) = std::sync::mpsc::channel::<Vec<f32>>();
|
||||
|
||||
std::thread::spawn(move || {
|
||||
let _pw_res = crate::pw::init_pw(tx_left, tx_right);
|
||||
});
|
||||
|
||||
// Init widgets with image size
|
||||
let w = 1024u32;
|
||||
let h = 256u32;
|
||||
|
||||
Self {
|
||||
refresh_rate: 40,
|
||||
refresh_rate: 32,
|
||||
stream_left: rx_left,
|
||||
stream_right: rx_right,
|
||||
waveform: waveform::Waveform::new(w, h),
|
||||
|
@ -48,6 +53,14 @@ impl RumbleWrecker {
|
|||
|
||||
fn update(&mut self, message: Message) {
|
||||
match message {
|
||||
Message::Waveform(msg) => {
|
||||
self.waveform.update(msg);
|
||||
}
|
||||
|
||||
Message::RateUpdated(new_refresh_rate) => {
|
||||
self.refresh_rate = (new_refresh_rate as u64).clamp(1, 200);
|
||||
},
|
||||
|
||||
Message::Tick => {
|
||||
let mut left_samples = Vec::<f32>::new();
|
||||
let mut right_samples = Vec::<f32>::new();
|
||||
|
@ -59,18 +72,26 @@ impl RumbleWrecker {
|
|||
}
|
||||
|
||||
if !left_samples.is_empty() && !right_samples.is_empty() {
|
||||
self.waveform.update((&left_samples, &right_samples), 0.5);
|
||||
self.waveform.tick((&left_samples, &right_samples));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&self) -> iced::Element<'_, Message> {
|
||||
let waveform = self.waveform.view();
|
||||
let waveform : iced::Element<'_, Message> = self.waveform.view().map(Message::Waveform);
|
||||
|
||||
// refresh rate slider
|
||||
let rate_label = iced::widget::text("Refresh rate:");
|
||||
let rate_value = iced::widget::text(format!("{:3}ms", &self.refresh_rate));
|
||||
let rate_slider: Element<'_, Message> = iced::widget::slider(1f64..=200f64, self.refresh_rate as f64, Message::RateUpdated).into();
|
||||
let rate_row = iced::widget::Row::new()
|
||||
.align_y(iced::Alignment::Center)
|
||||
.spacing(12)
|
||||
.push(rate_label)
|
||||
.push(rate_value)
|
||||
.push(rate_slider);
|
||||
|
||||
iced::widget::Column::new().push(waveform).into()
|
||||
iced::widget::Column::new().push(waveform).push(rate_row).into()
|
||||
}
|
||||
|
||||
fn subscription(&self) -> iced::Subscription<Message> {
|
||||
|
|
|
@ -1,12 +1,19 @@
|
|||
use crate::Rgba;
|
||||
|
||||
pub struct Waveform {
|
||||
resolution: f32,
|
||||
rgba: Rgba,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum Message {
|
||||
ResolutionChanged(f32),
|
||||
}
|
||||
|
||||
impl Waveform {
|
||||
pub fn new(width: u32, height: u32) -> Self {
|
||||
Self {
|
||||
resolution: 0.5,
|
||||
rgba: Rgba {
|
||||
width: width,
|
||||
height: height,
|
||||
|
@ -15,14 +22,22 @@ impl Waveform {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn update(&mut self, samples: (&Vec<f32>, &Vec<f32>), resolution: f32 ) {
|
||||
pub fn update(&mut self, waveform_message: Message) {
|
||||
match waveform_message {
|
||||
Message::ResolutionChanged(new_resolution) => {
|
||||
self.resolution = new_resolution.clamp(0.01, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn tick(&mut self, samples: (&Vec<f32>, &Vec<f32>)) {
|
||||
let (left_samples, right_samples) = samples;
|
||||
let mut last_rows = ((self.rgba.height/2) as usize, (self.rgba.height/2) as usize);
|
||||
|
||||
let span = (self.rgba.width as f32 * resolution) as usize;
|
||||
let span = (self.rgba.width as f32 * self.resolution) as usize;
|
||||
let moved_start = self.rgba.width as usize - span;
|
||||
|
||||
if resolution < 1.0 {
|
||||
if self.resolution < 1.0 {
|
||||
let mut previous_left_row = (self.rgba.height as usize, 0usize);
|
||||
let mut previous_right_row = (self.rgba.height as usize, 0usize);
|
||||
|
||||
|
@ -96,15 +111,18 @@ impl Waveform {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
pub fn view(&self) -> iced::Element<'_, crate::Message> {
|
||||
pub fn view(&self) -> iced::Element<'_, Message> {
|
||||
let img_handle = iced::widget::image::Handle::from_rgba(
|
||||
self.rgba.width,
|
||||
self.rgba.height,
|
||||
self.rgba.pixels.clone()
|
||||
);
|
||||
iced::widget::center_x(iced::widget::image(img_handle)).into()
|
||||
let img: iced::Element<'_, Message> = iced::widget::image(img_handle).into();
|
||||
// let centered_img = iced::widget::center_x(img);
|
||||
let resolution_slider = iced::widget::Slider::new(0.05..=1.0, self.resolution, Message::ResolutionChanged).step(0.05);
|
||||
// let resolution_slider = iced::widget::slider(0.05..=1.0, self.resolution, Message::ResolutionChanged);
|
||||
|
||||
iced::widget::Column::new().push(img).push(resolution_slider).into()
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue