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 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> {

View file

@ -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()
}
}