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 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> {
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue