added sliders to dynamically select waveform resolution but also widgets refresh rate

This commit is contained in:
ao kami 2025-07-14 21:09:46 +02:00
parent 8cdd6b06e2
commit a1b69e13bd
2 changed files with 52 additions and 13 deletions

View file

@ -1,3 +1,5 @@
use iced::Element;
mod pw; mod pw;
mod waveform; mod waveform;
@ -23,23 +25,26 @@ struct Rgba {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
enum Message { enum Message {
Waveform(waveform::Message),
RateUpdated(f64),
Tick, Tick,
} }
impl RumbleWrecker { impl RumbleWrecker {
fn new() -> Self { fn new() -> Self {
// Spawn default output monitor capture via pipewire
let (tx_left, rx_left) = std::sync::mpsc::channel::<Vec<f32>>(); let (tx_left, rx_left) = std::sync::mpsc::channel::<Vec<f32>>();
let (tx_right, rx_right) = std::sync::mpsc::channel::<Vec<f32>>(); let (tx_right, rx_right) = std::sync::mpsc::channel::<Vec<f32>>();
std::thread::spawn(move || { std::thread::spawn(move || {
let _pw_res = crate::pw::init_pw(tx_left, tx_right); let _pw_res = crate::pw::init_pw(tx_left, tx_right);
}); });
// Init widgets with image size
let w = 1024u32; let w = 1024u32;
let h = 256u32; let h = 256u32;
Self { Self {
refresh_rate: 40, refresh_rate: 32,
stream_left: rx_left, stream_left: rx_left,
stream_right: rx_right, stream_right: rx_right,
waveform: waveform::Waveform::new(w, h), waveform: waveform::Waveform::new(w, h),
@ -48,6 +53,14 @@ impl RumbleWrecker {
fn update(&mut self, message: Message) { fn update(&mut self, message: Message) {
match 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 => { Message::Tick => {
let mut left_samples = Vec::<f32>::new(); let mut left_samples = Vec::<f32>::new();
let mut right_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() { 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> { 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> { fn subscription(&self) -> iced::Subscription<Message> {

View file

@ -1,12 +1,19 @@
use crate::Rgba; use crate::Rgba;
pub struct Waveform { pub struct Waveform {
resolution: f32,
rgba: Rgba, rgba: Rgba,
} }
#[derive(Debug, Clone, Copy)]
pub enum Message {
ResolutionChanged(f32),
}
impl Waveform { impl Waveform {
pub fn new(width: u32, height: u32) -> Self { pub fn new(width: u32, height: u32) -> Self {
Self { Self {
resolution: 0.5,
rgba: Rgba { rgba: Rgba {
width: width, width: width,
height: height, 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 (left_samples, right_samples) = samples;
let mut last_rows = ((self.rgba.height/2) as usize, (self.rgba.height/2) as usize); 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; 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_left_row = (self.rgba.height as usize, 0usize);
let mut previous_right_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<'_, Message> {
pub fn view(&self) -> iced::Element<'_, crate::Message> {
let img_handle = iced::widget::image::Handle::from_rgba( let img_handle = iced::widget::image::Handle::from_rgba(
self.rgba.width, self.rgba.width,
self.rgba.height, self.rgba.height,
self.rgba.pixels.clone() 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()
} }
} }