diff --git a/.gitignore b/.gitignore index cacc1a2..804504f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ target/ .vscode/ dist/ certificates/ -audios/ +audio/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html diff --git a/streamer/src/gui.rs b/streamer/src/gui.rs index 59cb8f1..0fcf88d 100644 --- a/streamer/src/gui.rs +++ b/streamer/src/gui.rs @@ -1,5 +1,4 @@ use std::{ - cmp::max, fs::File, path::Path, process::exit, @@ -18,13 +17,9 @@ use crate::{ gui_components::{button_with_centered_text, text_centered}, gui_utils::{self, change_audio_volume, change_microphone_volume}, utils::get_config, - Config, BUFFER_LENGTH, + Config, AUDIO_BUFFER_SIZE, AUDIO_PATH, AUDIO_SCROLLABLE_BUTTON_SIZE, BUFFER_LENGTH, }; -const AUDIOS_PATH: &str = "audios"; - -const AUDIO_SCROLLABLE_BUTTON_SIZE: u16 = 35; - #[derive(Debug, Clone)] pub enum Player { Play, @@ -46,6 +41,7 @@ struct AudioMiscellaneous { playing_file_name: String, files: Option>, decoded_to_playing_sender: Option>, + should_decode_now_sender: Option>, } #[derive(Debug, Clone)] @@ -161,7 +157,8 @@ impl Streamer { selected_file_name: String::new(), playing_file_name: String::new(), files: None, - decoded_to_playing_sender: None, + decoded_to_playing_sender: Some(channel(AUDIO_BUFFER_SIZE).0), + should_decode_now_sender: Some(channel(1).0), }, gui_status: GUIStatus { are_we_connect: Condition::Passive, @@ -206,7 +203,8 @@ impl Streamer { selected_file_name: String::new(), playing_file_name: String::new(), files: None, - decoded_to_playing_sender: None, + decoded_to_playing_sender: Some(channel(AUDIO_BUFFER_SIZE).0), + should_decode_now_sender: Some(channel(1).0), }, gui_status: GUIStatus { are_we_connect: Condition::Passive, @@ -359,7 +357,7 @@ impl Streamer { self.gui_status.are_we_play_audio = Condition::Loading; let path = format!( "{}/{}", - AUDIOS_PATH, self.audio_miscellaneous.selected_file_name + AUDIO_PATH, self.audio_miscellaneous.selected_file_name ); match File::open(path) { Ok(file) => { @@ -372,21 +370,7 @@ impl Streamer { return Task::none(); } } - self.audio_miscellaneous.decoded_to_playing_sender = Some( - channel(max( - self.audio_miscellaneous - .file - .as_ref() - .unwrap() - .metadata() - .unwrap() - .len() as usize - * 10, - 1, - )) - .0, - ); - + self.audio_miscellaneous.should_decode_now_sender = Some(channel(1).0); let audio_stream_sender = self.data_channel.audio_stream_sender.clone(); let playing_to_base_sender = self.communication_channel.playing_to_base_sender.clone(); @@ -428,12 +412,17 @@ impl Streamer { .unwrap(); let audio_volume = self.gui_status.audio_volume.value.clone(); - + let should_decode_now_sender = self + .audio_miscellaneous + .should_decode_now_sender + .clone() + .unwrap(); let playing_command = Task::perform( async move { gui_utils::start_playing( audio_stream_sender, decoded_to_playing_sender_for_playing, + should_decode_now_sender, file, playing_to_base_sender, base_to_playing_receiver, @@ -525,7 +514,7 @@ impl Streamer { ) } Event::ChooseAudio(chosen_audio) => { - let path = format!("{}/{}", AUDIOS_PATH, chosen_audio); + let path = format!("{}/{}", AUDIO_PATH, chosen_audio); match File::open(path) { Ok(file) => { self.audio_miscellaneous.file = Some(file); @@ -566,21 +555,21 @@ impl Streamer { Event::IcedEvent(iced_event) => match iced_event { iced::Event::Keyboard(_) => Task::perform( async move { - let files = gui_utils::list_files(Path::new(AUDIOS_PATH)).await; + let files = gui_utils::list_files(Path::new(AUDIO_PATH)).await; Event::ListFiles(files) }, Message::Event, ), iced::Event::Mouse(_) => Task::perform( async move { - let files = gui_utils::list_files(Path::new(AUDIOS_PATH)).await; + let files = gui_utils::list_files(Path::new(AUDIO_PATH)).await; Event::ListFiles(files) }, Message::Event, ), iced::Event::Touch(_) => Task::perform( async move { - let files = gui_utils::list_files(Path::new(AUDIOS_PATH)).await; + let files = gui_utils::list_files(Path::new(AUDIO_PATH)).await; Event::ListFiles(files) }, Message::Event, @@ -591,7 +580,7 @@ impl Streamer { self.exit(); } async move { - let files = gui_utils::list_files(Path::new(AUDIOS_PATH)).await; + let files = gui_utils::list_files(Path::new(AUDIO_PATH)).await; Event::ListFiles(files) } }, @@ -872,7 +861,7 @@ impl Streamer { pub fn list_files() -> Task { Task::perform( async move { - let files = gui_utils::list_files(Path::new(AUDIOS_PATH)).await; + let files = gui_utils::list_files(Path::new(AUDIO_PATH)).await; Event::ListFiles(files) }, Message::Event, diff --git a/streamer/src/gui_utils.rs b/streamer/src/gui_utils.rs index 8006b79..cdfb281 100644 --- a/streamer/src/gui_utils.rs +++ b/streamer/src/gui_utils.rs @@ -172,6 +172,7 @@ pub async fn stop_recording( pub async fn start_playing( audio_stream_sender: Sender, decoded_to_playing_sender: Sender, + should_decode_now_sender: Sender, file: File, playing_to_base_sender: Sender, base_to_playing_receiver: Receiver, @@ -182,6 +183,7 @@ pub async fn start_playing( audio_stream_sender, file, decoded_to_playing_sender, + should_decode_now_sender, playing_to_base_sender, base_to_playing_receiver, audio_volume, diff --git a/streamer/src/lib.rs b/streamer/src/lib.rs index e13896a..d0f1319 100644 --- a/streamer/src/lib.rs +++ b/streamer/src/lib.rs @@ -7,6 +7,9 @@ pub mod streaming; pub mod utils; pub const BUFFER_LENGTH: usize = 1000000; +pub const AUDIO_PATH: &str = "audio"; +pub const AUDIO_BUFFER_SIZE: usize = 1048576; +pub const AUDIO_SCROLLABLE_BUTTON_SIZE: u16 = 35; #[derive(Debug, Clone)] pub struct Config { diff --git a/streamer/src/playing.rs b/streamer/src/playing.rs index 34028b7..c9769f8 100644 --- a/streamer/src/playing.rs +++ b/streamer/src/playing.rs @@ -27,6 +27,7 @@ pub async fn play( audio_stream_sender: Sender, file: File, decoded_to_playing_sender: Sender, + should_decode_now_sender: Sender, playing_to_base_sender: Sender, mut base_to_playing_receiver: Receiver, audio_volume: Arc>, @@ -39,16 +40,29 @@ pub async fn play( let output_device_sample_rate = output_device_config.sample_rate.0; let mut decoded_to_playing_receiver = decoded_to_playing_sender.subscribe(); + let should_decode_now_receiver = should_decode_now_sender.subscribe(); let audio_process_task = tokio::spawn(process_audio( output_device_sample_rate, file, decoded_to_playing_sender, + should_decode_now_receiver, )); while decoded_to_playing_receiver.is_empty() { tokio::time::sleep(Duration::from_millis(10)).await; } + let output_data_fn = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| { for sample in data { + if should_decode_now_sender.receiver_count() > 0 { + if should_decode_now_sender.len() == 0 { + if crate::AUDIO_BUFFER_SIZE / 2 > decoded_to_playing_receiver.len() { + if let Err(err_val) = should_decode_now_sender.send(true) { + eprintln!("Error: Decode Order | {}", err_val); + } + } + } + } + if decoded_to_playing_receiver.len() > 0 { let single = match decoded_to_playing_receiver.blocking_recv() { Ok(single) => single * *audio_volume.lock().unwrap(), @@ -165,7 +179,8 @@ fn resample_audio( async fn process_audio( output_device_sample_rate: u32, file: File, - decoded_to_playing_sender: tokio::sync::broadcast::Sender, + decoded_to_playing_sender: Sender, + mut should_decode_now_receiver: Receiver, ) { let media_source_stream = MediaSourceStream::new(Box::new(file), Default::default()); @@ -220,7 +235,6 @@ async fn process_audio( ), None => return, }; - let mut resampler = SincFixedIn::::new( output_device_sample_rate as f64 / audio_sample_rate as f64, 2.0, @@ -238,7 +252,7 @@ async fn process_audio( let _ = decoded_to_playing_sender.send(*single_right as f32); } - loop { + while let Ok(true) = should_decode_now_receiver.recv().await { let (mut audio_decoded_left, mut audio_decoded_right) = (vec![], vec![]); match decode_audio(&mut format, track_id, &mut decoder) { @@ -253,7 +267,6 @@ async fn process_audio( } None => break, }; - let (audio_resampled_left, audio_resampled_right) = resample_audio(audio_decoded_left, audio_decoded_right, &mut resampler);