From fb1eaf75a08eb8ac84802400f181992bcbc64dee Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Thu, 23 Oct 2025 13:26:30 +0200 Subject: [PATCH 1/6] fmt --- RustApp/.cargo/config.toml | 2 +- RustApp/src/audio/denoise_rnnoise.rs | 2 +- RustApp/src/ui/view.rs | 12 +++++++----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/RustApp/.cargo/config.toml b/RustApp/.cargo/config.toml index 34effef2..2ecdb8a8 100644 --- a/RustApp/.cargo/config.toml +++ b/RustApp/.cargo/config.toml @@ -1,5 +1,5 @@ [env] -RUST_LOG = "warn,android_mic=info" +RUST_LOG = "error,android_mic=info" ANDROID_MIC_COMMIT = "undefined" # ANDROID_MIC_FORMAT = "flatpak" # RUST_LOG = "info" diff --git a/RustApp/src/audio/denoise_rnnoise.rs b/RustApp/src/audio/denoise_rnnoise.rs index 13488476..932f2ca6 100644 --- a/RustApp/src/audio/denoise_rnnoise.rs +++ b/RustApp/src/audio/denoise_rnnoise.rs @@ -28,7 +28,7 @@ pub fn denoise_f32_stream(data: &[Vec]) -> anyhow::Result>> { // Convert f32 to i16 range let data_i16: Vec> = data .iter() - .map(|channel| channel.iter().map(|&x| (x * i16::MAX as f32)).collect()) + .map(|channel| channel.iter().map(|&x| x * i16::MAX as f32).collect()) .collect(); // Append new data into the cache diff --git a/RustApp/src/ui/view.rs b/RustApp/src/ui/view.rs index 26f55a79..462e8809 100644 --- a/RustApp/src/ui/view.rs +++ b/RustApp/src/ui/view.rs @@ -424,7 +424,10 @@ pub fn settings_window(app: &AppState) -> Element<'_, ConfigMsg> { ) })), ) - .push(button::text(fl!("reset_denoise_settings")).on_press(ConfigMsg::ResetDenoiseSettings)) + .push( + button::text(fl!("reset_denoise_settings")) + .on_press(ConfigMsg::ResetDenoiseSettings), + ) .push( settings::section() .title(fl!("title_app")) @@ -460,10 +463,9 @@ pub fn settings_window(app: &AppState) -> Element<'_, ConfigMsg> { ConfigMsg::Theme, )), ) - .add( - widget::settings::item::builder(fl!("about")) - .control(button::text(fl!("about_open")).on_press(ConfigMsg::ToggleAboutWindow)), - ), + .add(widget::settings::item::builder(fl!("about")).control( + button::text(fl!("about_open")).on_press(ConfigMsg::ToggleAboutWindow), + )), ), ) .into() From 34abe49dad5580b9a4adf72a7df661fa747da69b Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Thu, 23 Oct 2025 13:41:29 +0200 Subject: [PATCH 2/6] fix: select local ip by default in adapteur network when no ip in config --- RustApp/src/config.rs | 5 +++++ RustApp/src/ui/app.rs | 19 +++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/RustApp/src/config.rs b/RustApp/src/config.rs index cce855be..eee796f5 100644 --- a/RustApp/src/config.rs +++ b/RustApp/src/config.rs @@ -2,6 +2,7 @@ use std::{fmt::Display, net::IpAddr}; use clap::Parser; use light_enum::Values; +use local_ip_address::local_ip; use serde::{Deserialize, Serialize}; use crate::fl; @@ -89,6 +90,10 @@ impl Config { self.speex_dereverb_enabled = false; self.speex_dereverb_level = 0.5; } + + pub fn ip_or_default(&self) -> Option { + self.ip.or(local_ip().ok()) + } } #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Values)] diff --git a/RustApp/src/ui/app.rs b/RustApp/src/ui/app.rs index 47b5c256..5529dc81 100644 --- a/RustApp/src/ui/app.rs +++ b/RustApp/src/ui/app.rs @@ -7,7 +7,7 @@ use cpal::{ Device, Host, traits::{DeviceTrait, HostTrait}, }; -use local_ip_address::{list_afinet_netifas, local_ip}; +use local_ip_address::list_afinet_netifas; use notify_rust::Notification; use rtrb::RingBuffer; use tokio::sync::mpsc::Sender; @@ -202,11 +202,22 @@ impl AppState { let connect_options = match config.connection_mode { ConnectionMode::Tcp => { - let ip = config.ip.unwrap_or(local_ip().unwrap()); + let Some(ip) = config.ip_or_default() else { + let e = "no address ip found"; + + error!("failed to start audio stream: {e}"); + return self.add_log(&e.to_string()); + }; + ConnectOption::Tcp { ip } } ConnectionMode::Udp => { - let ip = config.ip.unwrap_or(local_ip().unwrap()); + let Some(ip) = config.ip_or_default() else { + let e = "no address ip found"; + + error!("failed to start audio stream: {e}"); + return self.add_log(&e.to_string()); + }; ConnectOption::Udp { ip } } #[cfg(feature = "adb")] @@ -308,7 +319,7 @@ impl Application for AppState { ip: *ip, }) .collect::>(); - let network_adapter = match &flags.config.data().ip { + let network_adapter = match &flags.config.data().ip_or_default() { Some(ip) => match network_adapters.iter().find(|adapter| adapter.ip == *ip) { Some(adapter) => Some(adapter.clone()), None => { From 861e7525628fe31f81b332d6a117c3518daaad7e Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Thu, 23 Oct 2025 16:08:15 +0200 Subject: [PATCH 3/6] start_minimized option --- RustApp/i18n/en/android_mic.ftl | 1 + RustApp/src/config.rs | 4 +++- RustApp/src/ui/app.rs | 19 +++++++++++++++---- RustApp/src/ui/message.rs | 1 + RustApp/src/ui/view.rs | 7 +++++++ 5 files changed, 27 insertions(+), 5 deletions(-) diff --git a/RustApp/i18n/en/android_mic.ftl b/RustApp/i18n/en/android_mic.ftl index 59b7dff2..56546399 100644 --- a/RustApp/i18n/en/android_mic.ftl +++ b/RustApp/i18n/en/android_mic.ftl @@ -47,6 +47,7 @@ reset_denoise_settings = Reset Denoise Settings title_app = App start_at_login = Start at login +start_minimized = Start minimized auto_connect = Auto connect theme = Theme amplify = Amplify diff --git a/RustApp/src/config.rs b/RustApp/src/config.rs index eee796f5..86f2d564 100644 --- a/RustApp/src/config.rs +++ b/RustApp/src/config.rs @@ -20,6 +20,7 @@ pub struct Config { // device that could be disconnected sometime. pub device_name: Option, pub start_at_login: bool, + pub start_minimized: bool, pub auto_connect: bool, pub denoise: bool, pub denoise_kind: DenoiseKind, @@ -75,7 +76,8 @@ impl Default for Config { speex_agc_enabled: false, speex_agc_target: 8000, // range: [8000, 65535] speex_dereverb_enabled: false, - speex_dereverb_level: 0.5, // range: [0.0, 1.0] + speex_dereverb_level: 0.5, + start_minimized: false, } } } diff --git a/RustApp/src/ui/app.rs b/RustApp/src/ui/app.rs index 5529dc81..a51a7884 100644 --- a/RustApp/src/ui/app.rs +++ b/RustApp/src/ui/app.rs @@ -352,9 +352,15 @@ impl Application for AppState { let mut commands = Vec::new(); - let (new_id, command) = cosmic::iced::window::open(settings); + let main_window = if flags.config.data().start_minimized { + None + } else { + let (new_id, command) = cosmic::iced::window::open(settings); - commands.push(command.map(|_| cosmic::action::Action::None)); + commands.push(command.map(|_| cosmic::action::Action::None)); + + Some(CustomWindow { window_id: new_id }) + }; let mut app = Self { core, @@ -368,7 +374,7 @@ impl Application for AppState { connection_state: ConnectionState::Default, network_adapters, network_adapter, - main_window: Some(CustomWindow { window_id: new_id }), + main_window, settings_window: None, about_window: None, logs: Vec::new(), @@ -393,7 +399,9 @@ impl Application for AppState { info!("config path: {}", flags.config_path); info!("log path: {}", flags.log_path); - commands.push(app.set_window_title(fl!("main_window_title"), new_id)); + if let Some(main_window) = &app.main_window { + commands.push(app.set_window_title(fl!("main_window_title"), main_window.window_id)); + } (app, Task::batch(commands)) } @@ -661,6 +669,9 @@ impl Application for AppState { .update(|c| c.speex_dereverb_level = speex_dereverb_level); return self.update_audio_stream(); } + ConfigMsg::StartMinimized(start_minimized) => { + self.config.update(|s| s.start_minimized = start_minimized); + } }, AppMsg::HideWindow => { let mut effects = Vec::new(); diff --git a/RustApp/src/ui/message.rs b/RustApp/src/ui/message.rs index c0b1030d..136ff038 100644 --- a/RustApp/src/ui/message.rs +++ b/RustApp/src/ui/message.rs @@ -34,6 +34,7 @@ pub enum ConfigMsg { UseRecommendedFormat, ResetDenoiseSettings, StartAtLogin(bool), + StartMinimized(bool), AutoConnect(bool), DeNoise(bool), DeNoiseKind(DenoiseKind), diff --git a/RustApp/src/ui/view.rs b/RustApp/src/ui/view.rs index 462e8809..20db9558 100644 --- a/RustApp/src/ui/view.rs +++ b/RustApp/src/ui/view.rs @@ -445,6 +445,13 @@ pub fn settings_window(app: &AppState) -> Element<'_, ConfigMsg> { } else { None }) + .add( + row() + .align_y(Vertical::Center) + .push(text(fl!("start_minimized"))) + .push(horizontal_space()) + .push(toggler(config.start_minimized).on_toggle(ConfigMsg::StartMinimized)), + ) .add( row() .align_y(Vertical::Center) From 521db36a9983987069ddf11e4a617c0652615809 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Thu, 23 Oct 2025 16:40:25 +0200 Subject: [PATCH 4/6] less notification when using start_minimized and udp --- RustApp/src/streamer/adb_streamer.rs | 6 ++++- RustApp/src/streamer/streamer_runner.rs | 2 ++ RustApp/src/streamer/tcp_streamer.rs | 7 +++++- RustApp/src/streamer/udp_streamer.rs | 6 ++++- RustApp/src/streamer/usb_streamer.rs | 3 ++- RustApp/src/ui/app.rs | 29 ++++++++++++++----------- RustApp/src/ui/tray.rs | 7 ++---- RustApp/src/ui/view.rs | 5 ++++- 8 files changed, 42 insertions(+), 23 deletions(-) diff --git a/RustApp/src/streamer/adb_streamer.rs b/RustApp/src/streamer/adb_streamer.rs index e6167081..a89c07c7 100644 --- a/RustApp/src/streamer/adb_streamer.rs +++ b/RustApp/src/streamer/adb_streamer.rs @@ -1,7 +1,10 @@ use anyhow::Result; use tokio::process::Command; -use crate::streamer::{StreamerMsg, tcp_streamer}; +use crate::{ + config::ConnectionMode, + streamer::{StreamerMsg, tcp_streamer}, +}; use super::{ AudioStream, ConnectError, StreamerTrait, @@ -108,6 +111,7 @@ impl StreamerTrait for AdbStreamer { TcpStreamerState::Streaming { .. } => StreamerMsg::Connected { ip: None, port: None, + mode: ConnectionMode::Adb, }, } } diff --git a/RustApp/src/streamer/streamer_runner.rs b/RustApp/src/streamer/streamer_runner.rs index ecfe11f9..a4ffa5e9 100644 --- a/RustApp/src/streamer/streamer_runner.rs +++ b/RustApp/src/streamer/streamer_runner.rs @@ -12,6 +12,7 @@ use std::net::IpAddr; use tokio::sync::mpsc::{self, Sender}; use crate::audio::AudioProcessParams; +use crate::config::ConnectionMode; use crate::streamer::{StreamerTrait, WriteError}; use super::{AudioStream, ConnectError, DummyStreamer, Streamer, tcp_streamer, udp_streamer}; @@ -82,6 +83,7 @@ pub enum StreamerMsg { Connected { ip: Option, port: Option, + mode: ConnectionMode, }, Ready(Sender), } diff --git a/RustApp/src/streamer/tcp_streamer.rs b/RustApp/src/streamer/tcp_streamer.rs index d6d6e0a8..f8c9d77c 100644 --- a/RustApp/src/streamer/tcp_streamer.rs +++ b/RustApp/src/streamer/tcp_streamer.rs @@ -5,7 +5,10 @@ use prost::Message; use tokio::net::{TcpListener, TcpStream}; use tokio_util::codec::{Framed, LengthDelimitedCodec}; -use crate::streamer::{DEFAULT_PC_PORT, MAX_PORT, StreamerMsg, WriteError}; +use crate::{ + config::ConnectionMode, + streamer::{DEFAULT_PC_PORT, MAX_PORT, StreamerMsg, WriteError}, +}; use super::{AudioPacketMessage, AudioStream, ConnectError, StreamerTrait}; @@ -76,6 +79,7 @@ impl StreamerTrait for TcpStreamer { TcpStreamerState::Streaming { .. } => StreamerMsg::Connected { ip: Some(self.ip), port: Some(self.port), + mode: ConnectionMode::Tcp, }, } } @@ -100,6 +104,7 @@ impl StreamerTrait for TcpStreamer { Ok(Some(StreamerMsg::Connected { ip: Some(self.ip), port: Some(self.port), + mode: ConnectionMode::Tcp, })) } TcpStreamerState::Streaming { diff --git a/RustApp/src/streamer/udp_streamer.rs b/RustApp/src/streamer/udp_streamer.rs index 945c8f58..2e25f226 100644 --- a/RustApp/src/streamer/udp_streamer.rs +++ b/RustApp/src/streamer/udp_streamer.rs @@ -5,7 +5,10 @@ use prost::Message; use tokio::net::UdpSocket; use tokio_util::{codec::LengthDelimitedCodec, udp::UdpFramed}; -use crate::streamer::{AudioPacketMessage, DEFAULT_PC_PORT, MAX_PORT, WriteError}; +use crate::{ + config::ConnectionMode, + streamer::{AudioPacketMessage, DEFAULT_PC_PORT, MAX_PORT, WriteError}, +}; use super::{AudioPacketMessageOrdered, AudioStream, ConnectError, StreamerMsg, StreamerTrait}; @@ -62,6 +65,7 @@ impl StreamerTrait for UdpStreamer { StreamerMsg::Connected { ip: Some(self.ip), port: Some(self.port), + mode: ConnectionMode::Udp, } } diff --git a/RustApp/src/streamer/usb_streamer.rs b/RustApp/src/streamer/usb_streamer.rs index ba035d9e..36a06962 100644 --- a/RustApp/src/streamer/usb_streamer.rs +++ b/RustApp/src/streamer/usb_streamer.rs @@ -12,7 +12,7 @@ use super::{ frame::UsbStream, }, }; -use crate::streamer::WriteError; +use crate::{config::ConnectionMode, streamer::WriteError}; use super::{AudioPacketMessage, ConnectError, StreamerMsg, StreamerTrait}; @@ -185,6 +185,7 @@ impl StreamerTrait for UsbStreamer { UsbStreamerState::Streaming => StreamerMsg::Connected { ip: None, port: None, + mode: ConnectionMode::Usb, }, } } diff --git a/RustApp/src/ui/app.rs b/RustApp/src/ui/app.rs index a51a7884..7c44f53e 100644 --- a/RustApp/src/ui/app.rs +++ b/RustApp/src/ui/app.rs @@ -206,7 +206,7 @@ impl AppState { let e = "no address ip found"; error!("failed to start audio stream: {e}"); - return self.add_log(&e.to_string()); + return self.add_log(e); }; ConnectOption::Tcp { ip } @@ -216,7 +216,7 @@ impl AppState { let e = "no address ip found"; error!("failed to start audio stream: {e}"); - return self.add_log(&e.to_string()); + return self.add_log(e); }; ConnectOption::Udp { ip } } @@ -466,7 +466,7 @@ impl Application for AppState { return self.add_log(format!("Listening on `{ip}:{port}`").as_str()); } } - StreamerMsg::Connected { ip, port } => { + StreamerMsg::Connected { ip, port, mode } => { if let Some(system_tray) = self.system_tray.as_mut() { system_tray.update_menu_state(false, &fl!("state_connected")); } @@ -477,15 +477,18 @@ impl Application for AppState { ip.unwrap_or(IpAddr::V4(Ipv4Addr::UNSPECIFIED)), port.unwrap_or_default() ); - // show notification when app is minimized - let _ = Notification::new() - .summary("AndroidMic") - .body(format!("Connected on {address}").as_str()) - .auto_icon() - .show() - .map_err(|e| { - error!("failed to show notification: {e}"); - }); + + if mode != ConnectionMode::Udp { + // show notification when app is minimized + let _ = Notification::new() + .summary("AndroidMic") + .body(format!("Connected on {address}").as_str()) + .auto_icon() + .show() + .map_err(|e| { + error!("failed to show notification: {e}"); + }); + } } self.connection_state = ConnectionState::Connected; @@ -701,7 +704,7 @@ impl Application for AppState { self.about_window = None; } - if !self.has_shown_minimize_notification { + if !self.config.data().start_minimized && !self.has_shown_minimize_notification { let _ = Notification::new() .summary("AndroidMic") .body(&fl!("minimized_to_tray")) diff --git a/RustApp/src/ui/tray.rs b/RustApp/src/ui/tray.rs index a75f8e2b..857eda83 100644 --- a/RustApp/src/ui/tray.rs +++ b/RustApp/src/ui/tray.rs @@ -77,11 +77,8 @@ impl SystemTray { })); let tray_sender = sender.clone(); - TrayIconEvent::set_event_handler(Some(move |event: TrayIconEvent| match event { - TrayIconEvent::DoubleClick { .. } => { - let _ = tray_sender.send(SystemTrayMsg::Show); - } - _ => {} + TrayIconEvent::set_event_handler(Some(move |event: TrayIconEvent| if let TrayIconEvent::DoubleClick { .. } = event { + let _ = tray_sender.send(SystemTrayMsg::Show); })); Ok(( diff --git a/RustApp/src/ui/view.rs b/RustApp/src/ui/view.rs index 20db9558..6a085e28 100644 --- a/RustApp/src/ui/view.rs +++ b/RustApp/src/ui/view.rs @@ -450,7 +450,10 @@ pub fn settings_window(app: &AppState) -> Element<'_, ConfigMsg> { .align_y(Vertical::Center) .push(text(fl!("start_minimized"))) .push(horizontal_space()) - .push(toggler(config.start_minimized).on_toggle(ConfigMsg::StartMinimized)), + .push( + toggler(config.start_minimized) + .on_toggle(ConfigMsg::StartMinimized), + ), ) .add( row() From 47fe89d42d1090842f18880c87fefeca1b265a84 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Thu, 23 Oct 2025 16:43:48 +0200 Subject: [PATCH 5/6] doc --- RustApp/src/config.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/RustApp/src/config.rs b/RustApp/src/config.rs index 86f2d564..36ce03db 100644 --- a/RustApp/src/config.rs +++ b/RustApp/src/config.rs @@ -24,12 +24,16 @@ pub struct Config { pub auto_connect: bool, pub denoise: bool, pub denoise_kind: DenoiseKind, + /// range: [-100, 0] pub speex_noise_suppress: i32, pub speex_vad_enabled: bool, + /// range: [0, 100] pub speex_vad_threshold: u32, pub speex_agc_enabled: bool, + /// range: [8000, 65535] pub speex_agc_target: u32, pub speex_dereverb_enabled: bool, + /// range: [0.0, 1.0] pub speex_dereverb_level: f32, pub theme: AppTheme, pub amplify: bool, @@ -70,11 +74,11 @@ impl Default for Config { theme: Default::default(), amplify: false, amplify_value: 2.0, - speex_noise_suppress: -30, // range: [-100, 0] + speex_noise_suppress: -30, speex_vad_enabled: false, - speex_vad_threshold: 80, // range: [0, 100] + speex_vad_threshold: 80, speex_agc_enabled: false, - speex_agc_target: 8000, // range: [8000, 65535] + speex_agc_target: 8000, speex_dereverb_enabled: false, speex_dereverb_level: 0.5, start_minimized: false, From 4d14d4a459bc1cefdce4fe7719f0a7fc6fa8de60 Mon Sep 17 00:00:00 2001 From: wiiznokes <78230769+wiiznokes@users.noreply.github.com> Date: Thu, 23 Oct 2025 22:09:02 +0200 Subject: [PATCH 6/6] opti: don't send audio wave data when ui not visible --- RustApp/src/audio/process.rs | 33 +++++++----- RustApp/src/streamer/mod.rs | 14 ++++- RustApp/src/streamer/streamer_runner.rs | 19 +++++-- RustApp/src/streamer/tcp_streamer.rs | 36 +++++-------- RustApp/src/streamer/udp_streamer.rs | 23 ++++----- RustApp/src/streamer/usb_streamer.rs | 22 ++++---- RustApp/src/ui/app.rs | 69 +++++++++++-------------- RustApp/src/ui/tray.rs | 6 ++- 8 files changed, 113 insertions(+), 109 deletions(-) diff --git a/RustApp/src/audio/process.rs b/RustApp/src/audio/process.rs index 75a195f9..a4cdb7a2 100644 --- a/RustApp/src/audio/process.rs +++ b/RustApp/src/audio/process.rs @@ -15,7 +15,10 @@ impl AudioStream { /// This function converts an audio stream from packet into producer /// apply any necessary conversions based on the audio format /// and returns mono channel f32 vector for audio wave display - pub fn process_audio_packet(&mut self, packet: AudioPacketMessage) -> anyhow::Result> { + pub fn process_audio_packet( + &mut self, + packet: AudioPacketMessage, + ) -> anyhow::Result>> { match self.audio_params.target_format.audio_format { AudioFormat::I16 => self.process_audio_packet_internal::(packet), AudioFormat::I24 => self.process_audio_packet_internal::(packet), @@ -32,7 +35,7 @@ impl AudioStream { fn process_audio_packet_internal( &mut self, packet: AudioPacketMessage, - ) -> anyhow::Result> + ) -> anyhow::Result>> where F: cpal::SizedSample + AudioBytes + std::fmt::Debug + 'static, { @@ -130,18 +133,22 @@ impl AudioStream { } } - // prepare mono channel buffer to return - let buffer_mono = if config.target_format.channel_count.to_number() == 1 { - buffer[0].clone() - } else { - // if not mono, average the channels - let mut mono_buffer: Vec = Vec::with_capacity(buffer[0].len()); - for i in 0..buffer[0].len() { - let sample: f32 = buffer.iter().map(|ch| ch[i]).sum::() - / config.target_format.channel_count.to_number() as f32; - mono_buffer.push(sample); + let buffer_mono = if self.is_window_visible { + // prepare mono channel buffer to return + if config.target_format.channel_count.to_number() == 1 { + Some(buffer[0].clone()) + } else { + // if not mono, average the channels + let mut mono_buffer: Vec = Vec::with_capacity(buffer[0].len()); + for i in 0..buffer[0].len() { + let sample: f32 = buffer.iter().map(|ch| ch[i]).sum::() + / config.target_format.channel_count.to_number() as f32; + mono_buffer.push(sample); + } + Some(mono_buffer) } - mono_buffer + } else { + None }; Ok(buffer_mono) diff --git a/RustApp/src/streamer/mod.rs b/RustApp/src/streamer/mod.rs index e3685fb2..68d217b1 100644 --- a/RustApp/src/streamer/mod.rs +++ b/RustApp/src/streamer/mod.rs @@ -36,11 +36,20 @@ const MAX_PORT: u16 = 60000; pub struct AudioStream { pub buff: Producer, pub audio_params: AudioProcessParams, + pub is_window_visible: bool, } impl AudioStream { - pub fn new(buff: Producer, audio_params: AudioProcessParams) -> Self { - Self { buff, audio_params } + pub fn new( + buff: Producer, + audio_params: AudioProcessParams, + is_window_visible: bool, + ) -> Self { + Self { + buff, + audio_params, + is_window_visible, + } } } @@ -48,6 +57,7 @@ impl Debug for AudioStream { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("AudioStream") .field("audio_params", &self.audio_params) + .field("is_window_visible", &self.is_window_visible) .finish() } } diff --git a/RustApp/src/streamer/streamer_runner.rs b/RustApp/src/streamer/streamer_runner.rs index a4ffa5e9..e666f111 100644 --- a/RustApp/src/streamer/streamer_runner.rs +++ b/RustApp/src/streamer/streamer_runner.rs @@ -37,10 +37,12 @@ pub enum StreamerCommand { connect_options: ConnectOption, buff: Producer, audio_params: AudioProcessParams, + is_window_visible: bool, }, ReconfigureStream { buff: Producer, audio_params: AudioProcessParams, + is_window_visible: bool, }, Stop, } @@ -52,17 +54,21 @@ impl Debug for StreamerCommand { connect_options, buff: _, audio_params, + is_window_visible, } => f .debug_struct("Connect") .field("connect_options", connect_options) .field("audio_params", audio_params) + .field("is_window_visible", is_window_visible) .finish(), Self::ReconfigureStream { buff: _, audio_params, + is_window_visible, } => f .debug_struct("ReconfigureStream") .field("audio_params", audio_params) + .field("is_window_visible", is_window_visible) .finish(), Self::Stop => write!(f, "Stop"), } @@ -130,8 +136,10 @@ pub fn sub() -> impl Stream { connect_options, buff, audio_params, + is_window_visible, } => { - let stream_config = AudioStream::new(buff, audio_params); + let stream_config = + AudioStream::new(buff, audio_params, is_window_visible); let new_streamer: Result = match connect_options { ConnectOption::Tcp { ip } => { @@ -169,8 +177,13 @@ pub fn sub() -> impl Stream { } } } - StreamerCommand::ReconfigureStream { buff, audio_params } => { - let stream_config = AudioStream::new(buff, audio_params); + StreamerCommand::ReconfigureStream { + buff, + audio_params, + is_window_visible, + } => { + let stream_config = + AudioStream::new(buff, audio_params, is_window_visible); streamer.reconfigure_stream(stream_config); } diff --git a/RustApp/src/streamer/tcp_streamer.rs b/RustApp/src/streamer/tcp_streamer.rs index f8c9d77c..b8b068b4 100644 --- a/RustApp/src/streamer/tcp_streamer.rs +++ b/RustApp/src/streamer/tcp_streamer.rs @@ -112,34 +112,26 @@ impl StreamerTrait for TcpStreamer { disconnect_loop_detecter: _, } => { match framed.next().await { - Some(Ok(frame)) => { - let mut res = None; - - match AudioPacketMessage::decode(frame) { - Ok(packet) => { - let buffer_size = packet.buffer.len(); - let sample_rate = packet.sample_rate; - - if let Ok(buffer) = self.stream_config.process_audio_packet(packet) - { - // compute the audio wave from the buffer - res = Some(StreamerMsg::UpdateAudioWave { + Some(Ok(frame)) => match AudioPacketMessage::decode(frame) { + Ok(packet) => { + let buffer_size = packet.buffer.len(); + let sample_rate = packet.sample_rate; + + match self.stream_config.process_audio_packet(packet) { + Ok(Some(buffer)) => { + debug!("received {} bytes", buffer_size); + Ok(Some(StreamerMsg::UpdateAudioWave { data: AudioPacketMessage::to_wave_data( &buffer, sample_rate, ), - }); - - debug!("received {} bytes", buffer_size); - }; - } - Err(e) => { - return Err(ConnectError::WriteError(WriteError::Deserializer(e))); + })) + } + _ => Ok(None), } } - - Ok(res) - } + Err(e) => Err(ConnectError::WriteError(WriteError::Deserializer(e))), + }, Some(Err(e)) => { match e.kind() { diff --git a/RustApp/src/streamer/udp_streamer.rs b/RustApp/src/streamer/udp_streamer.rs index 2e25f226..b30a33fa 100644 --- a/RustApp/src/streamer/udp_streamer.rs +++ b/RustApp/src/streamer/udp_streamer.rs @@ -72,8 +72,6 @@ impl StreamerTrait for UdpStreamer { async fn next(&mut self) -> Result, ConnectError> { match self.framed.next().await { Some(Ok((frame, addr))) => { - let mut res = None; - match AudioPacketMessageOrdered::decode(frame) { Ok(packet) => { if packet.sequence_number < self.tracked_sequence { @@ -89,21 +87,18 @@ impl StreamerTrait for UdpStreamer { let buffer_size = packet.buffer.len(); let sample_rate = packet.sample_rate; - if let Ok(buffer) = self.stream_config.process_audio_packet(packet) { - // compute the audio wave from the buffer - res = Some(StreamerMsg::UpdateAudioWave { - data: AudioPacketMessage::to_wave_data(&buffer, sample_rate), - }); - - debug!("From {:?}, received {} bytes", addr, buffer_size); + match self.stream_config.process_audio_packet(packet) { + Ok(Some(buffer)) => { + debug!("From {:?}, received {} bytes", addr, buffer_size); + Ok(Some(StreamerMsg::UpdateAudioWave { + data: AudioPacketMessage::to_wave_data(&buffer, sample_rate), + })) + } + _ => Ok(None), } } - Err(e) => { - return Err(ConnectError::WriteError(WriteError::Deserializer(e))); - } + Err(e) => Err(ConnectError::WriteError(WriteError::Deserializer(e))), } - - Ok(res) } Some(Err(e)) => { diff --git a/RustApp/src/streamer/usb_streamer.rs b/RustApp/src/streamer/usb_streamer.rs index 36a06962..a88f29e7 100644 --- a/RustApp/src/streamer/usb_streamer.rs +++ b/RustApp/src/streamer/usb_streamer.rs @@ -195,27 +195,23 @@ impl StreamerTrait for UsbStreamer { Some(Ok(frame)) => { self.state = UsbStreamerState::Streaming; - let mut res = None; match AudioPacketMessage::decode(frame) { Ok(packet) => { let buffer_size = packet.buffer.len(); let sample_rate = packet.sample_rate; - if let Ok(buffer) = self.stream_config.process_audio_packet(packet) { - // compute the audio wave from the buffer - res = Some(StreamerMsg::UpdateAudioWave { - data: AudioPacketMessage::to_wave_data(&buffer, sample_rate), - }); - - debug!("received {} bytes", buffer_size); + match self.stream_config.process_audio_packet(packet) { + Ok(Some(buffer)) => { + debug!("received {} bytes", buffer_size); + Ok(Some(StreamerMsg::UpdateAudioWave { + data: AudioPacketMessage::to_wave_data(&buffer, sample_rate), + })) + } + _ => Ok(None), } } - Err(e) => { - return Err(ConnectError::WriteError(WriteError::Deserializer(e))); - } + Err(e) => Err(ConnectError::WriteError(WriteError::Deserializer(e))), } - - Ok(res) } Some(Err(e)) => { panic!("{}", e); diff --git a/RustApp/src/ui/app.rs b/RustApp/src/ui/app.rs index 7c44f53e..ce88254c 100644 --- a/RustApp/src/ui/app.rs +++ b/RustApp/src/ui/app.rs @@ -160,6 +160,7 @@ impl AppState { self.send_command(StreamerCommand::ReconfigureStream { buff: producer, audio_params: AudioProcessParams::new(audio_config, config), + is_window_visible: self.main_window.is_some(), }); Task::none() @@ -232,6 +233,7 @@ impl AppState { connect_options, buff: producer, audio_params: AudioProcessParams::new(audio_config, config), + is_window_visible: self.main_window.is_some(), }); Task::none() @@ -249,6 +251,26 @@ impl AppState { Task::none() } + + fn open_main_window(&mut self) -> Task { + let mut commands = Vec::new(); + let settings = window::Settings { + size: Size::new(800.0, 600.0), + position: window::Position::Centered, + icon: window_icon!("icon"), + ..Default::default() + }; + + let (window_id, command) = cosmic::iced::window::open(settings); + + commands.push(command.map(|_| cosmic::action::Action::None)); + + commands.push(self.set_window_title(fl!("main_window_title"), window_id)); + + self.main_window = Some(CustomWindow { window_id }); + + Task::batch(commands) + } } pub struct Flags { @@ -342,26 +364,8 @@ impl Application for AppState { } }; - // configure window settings - let settings = window::Settings { - size: Size::new(800.0, 600.0), - position: window::Position::Centered, - icon: window_icon!("icon"), - ..Default::default() - }; - let mut commands = Vec::new(); - let main_window = if flags.config.data().start_minimized { - None - } else { - let (new_id, command) = cosmic::iced::window::open(settings); - - commands.push(command.map(|_| cosmic::action::Action::None)); - - Some(CustomWindow { window_id: new_id }) - }; - let mut app = Self { core, audio_stream: None, @@ -374,7 +378,7 @@ impl Application for AppState { connection_state: ConnectionState::Default, network_adapters, network_adapter, - main_window, + main_window: None, settings_window: None, about_window: None, logs: Vec::new(), @@ -399,8 +403,8 @@ impl Application for AppState { info!("config path: {}", flags.config_path); info!("log path: {}", flags.log_path); - if let Some(main_window) = &app.main_window { - commands.push(app.set_window_title(fl!("main_window_title"), main_window.window_id)); + if !app.config.data().start_minimized { + commands.push(app.open_main_window()); } (app, Task::batch(commands)) @@ -716,6 +720,8 @@ impl Application for AppState { self.has_shown_minimize_notification = true; } + effects.push(self.update_audio_stream()); + return cosmic::iced_runtime::Task::batch(effects); } AppMsg::Menu(menu_msg) => match menu_msg { @@ -746,26 +752,9 @@ impl Application for AppState { )), ); } else { - let settings = window::Settings { - size: Size::new(800.0, 600.0), - position: window::Position::Centered, - icon: window_icon!("icon"), - ..Default::default() - }; + let command = self.open_main_window(); - let (new_id, command) = cosmic::iced::window::open(settings); - self.main_window = Some(CustomWindow { window_id: new_id }); - let set_window_title = - self.set_window_title(fl!("main_window_title"), new_id); - - return command - .map(|_| cosmic::action::Action::None) - .chain(set_window_title) - .chain(cosmic::iced_runtime::task::effect( - cosmic::iced::runtime::Action::Window(window::Action::GainFocus( - new_id, - )), - )); + return Task::batch(vec![command, self.update_audio_stream()]); } } SystemTrayMsg::Exit => { diff --git a/RustApp/src/ui/tray.rs b/RustApp/src/ui/tray.rs index 857eda83..37163008 100644 --- a/RustApp/src/ui/tray.rs +++ b/RustApp/src/ui/tray.rs @@ -77,8 +77,10 @@ impl SystemTray { })); let tray_sender = sender.clone(); - TrayIconEvent::set_event_handler(Some(move |event: TrayIconEvent| if let TrayIconEvent::DoubleClick { .. } = event { - let _ = tray_sender.send(SystemTrayMsg::Show); + TrayIconEvent::set_event_handler(Some(move |event: TrayIconEvent| { + if let TrayIconEvent::DoubleClick { .. } = event { + let _ = tray_sender.send(SystemTrayMsg::Show); + } })); Ok((