Compare commits

...

1 commit

Author SHA1 Message Date
6ed2c01c05
refactor comments 2025-01-27 12:44:50 +01:00
4 changed files with 59 additions and 27 deletions

View file

@ -41,10 +41,11 @@ impl Listener for NetworkListener {
fn listen(port: u16) -> Result<()> { fn listen(port: u16) -> Result<()> {
// Create the bind address string // Create the bind address string
let bind_addr = format!("0.0.0.0:{}", port); let bind_addr = format!("0.0.0.0:{}", port);
// Attempt to bind the UDP socket to the address // Attempt to bind the UDP socket to the address
let socket = UdpSocket::bind(bind_addr); let socket = UdpSocket::bind(bind_addr);
let socket = match socket { let socket = match socket {
Ok(s) => s, // If successful, use the socket Ok(s) => s,
Err(e) => { Err(e) => {
// If there's an error, return a BindError // If there's an error, return a BindError
return Err(BindError { return Err(BindError {
@ -60,14 +61,19 @@ impl Listener for NetworkListener {
loop { loop {
// Buffer to store incoming data // Buffer to store incoming data
let mut data = [0; 1_048_576]; let mut data = [0; 1_048_576];
// Receive data from the socket // Receive data from the socket
let (amt, src) = socket.recv_from(&mut data).expect("Didn't receive data"); let (amt, src) = socket.recv_from(&mut data).expect("Didn't receive data");
// Print the amount of data received and the source address // Print the amount of data received and the source address
println!("Received {} bytes from {}", amt, src); println!("Received {} bytes from {}", amt, src);
// Slice the buffer to the actual amount of data received // Slice the buffer to the actual amount of data received
let data = &mut data[..amt]; let data = &mut data[..amt];
// Deserialize the data into a Message // Deserialize the data into a Message
let msg = bincode::deserialize::<Message>(data).expect("Failed to deserialize"); let msg = bincode::deserialize::<Message>(data).expect("Failed to deserialize");
// Handle the deserialized message // Handle the deserialized message
NetworkListener::handle_message(msg); NetworkListener::handle_message(msg);
} }

View file

@ -20,8 +20,10 @@ pub struct NetworkDispatcher;
impl NetworkDispatcher { impl NetworkDispatcher {
// Load a sound file and return a Decoder // Load a sound file and return a Decoder
fn load_sound(path: String) -> Decoder<BufReader<File>> { fn load_sound(path: String) -> Decoder<BufReader<File>> {
let file = BufReader::new(File::open(path).unwrap()); // Open the file // Open the file
Decoder::new(file).unwrap() // Decode the file let file = BufReader::new(File::open(path).unwrap());
// Decode the file
Decoder::new(file).unwrap()
} }
} }
@ -39,23 +41,28 @@ impl Dispatcher for NetworkDispatcher {
let channels = source.channels(); let channels = source.channels();
let sample_rate = source.sample_rate(); let sample_rate = source.sample_rate();
let duration = source.total_duration().unwrap(); let duration = source.total_duration().unwrap();
let chunk_len = Duration::from_millis(200); // Length of each chunk to send // Length of each chunk to send
let chunk_len = Duration::from_millis(200);
let mut offset = Duration::from_secs(0); // Initial offset // Initial offset
let mut offset = Duration::from_secs(0);
// Iterate over each address // Iterate over each address
for addr in addrs { for addr in addrs {
// Skip empty addresses
if addr.is_empty() { if addr.is_empty() {
continue; // Skip empty addresses continue;
} }
let source = source.clone(); // Clone the source for each thread // Clone the source for each thread
let source = source.clone();
// Spawn a new thread for each address // Spawn a new thread for each address
thread::spawn(move || { thread::spawn(move || {
// Bind to a local UDP socket // Bind to a local UDP socket
let sock = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind"); let sock = UdpSocket::bind("0.0.0.0:0").expect("Failed to bind");
sock.connect(addr.clone()).expect("Failed to connect"); // Connect to the address // Connect to the address
sock.connect(addr.clone()).expect("Failed to connect");
// Loop until the entire duration is covered // Loop until the entire duration is covered
while offset < duration { while offset < duration {
@ -66,11 +73,13 @@ impl Dispatcher for NetworkDispatcher {
.take_duration(chunk_len) .take_duration(chunk_len)
.collect::<Vec<i16>>(); .collect::<Vec<i16>>();
offset += chunk_len; // Update the offset // Update the offset
offset += chunk_len;
// Create a PlaySound message // Create a PlaySound message
let msg = Message::PlaySound(PlaySound { let msg = Message::PlaySound(PlaySound {
timestamp: (now + offset).as_micros(), // Timestamp for synchronization // Timestamp for synchronization
timestamp: (now + offset).as_micros(),
channels: channels, channels: channels,
sample_rate: sample_rate, sample_rate: sample_rate,
sound_data: sound_data, sound_data: sound_data,

View file

@ -1,4 +1,5 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // Hide console window on Windows in release mode #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
// Hide console window on Windows in release mode
// Import necessary modules and crates // Import necessary modules and crates
use client_handler::{Listener, NetworkListener}; use client_handler::{Listener, NetworkListener};
@ -18,7 +19,8 @@ mod ui_app;
fn main() -> eframe::Result { fn main() -> eframe::Result {
// Define options for the eframe application // Define options for the eframe application
let options = eframe::NativeOptions { let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default().with_inner_size([700.0, 400.0]), // Set initial window size // Set initial window size
viewport: egui::ViewportBuilder::default().with_inner_size([700.0, 400.0]),
..Default::default() ..Default::default()
}; };
@ -29,13 +31,15 @@ fn main() -> eframe::Result {
match result { match result {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
eprintln!("Failed to bind: {}", e.message); // Print error message if binding fails // Print error message if binding fails
eprintln!("Failed to bind: {}", e.message);
// Try with port 3001 if port 3000 fails // Try with port 3001 if port 3000 fails
let result = NetworkListener::listen(3001); let result = NetworkListener::listen(3001);
match result { match result {
Ok(_) => {} Ok(_) => {}
Err(e) => { Err(e) => {
eprintln!("Failed to bind again: {}", e.message); // Print error message if binding fails again // Print error message if binding fails again
eprintln!("Failed to bind again: {}", e.message);
} }
} }
} }
@ -44,13 +48,17 @@ fn main() -> eframe::Result {
// Run the eframe application // Run the eframe application
eframe::run_native( eframe::run_native(
"My egui App", // Application title // Application title
options, // Application options "My egui App",
// Application options
options,
Box::new(|cc| { Box::new(|cc| {
// This gives us image support: // This gives us image support:
egui_extras::install_image_loaders(&cc.egui_ctx); // Install image loaders for egui context // Install image loaders for egui context
egui_extras::install_image_loaders(&cc.egui_ctx);
Ok(Box::<UIApp>::default()) // Initialize the UI application // Initialize the UI application
Ok(Box::<UIApp>::default())
}), }),
) )
} }

View file

@ -1,16 +1,25 @@
use serde::{Deserialize, Serialize}; // Importing necessary traits from serde for serialization and deserialization use serde::{Deserialize, Serialize};
// Importing necessary traits from serde for serialization and deserialization
// Define an enum called Message which can hold different types of messages // Define an enum called Message which can hold different types of messages
#[derive(Serialize, Deserialize, Debug)] // Automatically generate code for serialization, deserialization, and debugging #[derive(Serialize, Deserialize, Debug)]
// Automatically generate code for serialization, deserialization, and debugging
pub enum Message { pub enum Message {
PlaySound(PlaySound), // A variant of the Message enum that holds a PlaySound struct PlaySound(PlaySound),
// A variant of the Message enum that holds a PlaySound struct
} }
// Define a struct called PlaySound which represents a sound to be played // Define a struct called PlaySound which represents a sound to be played
#[derive(Serialize, Deserialize, Debug)] // Automatically generate code for serialization, deserialization, and debugging #[derive(Serialize, Deserialize, Debug)]
// Automatically generate code for serialization, deserialization, and debugging
pub struct PlaySound { pub struct PlaySound {
pub timestamp: u128, // The timestamp when the sound should be played pub timestamp: u128,
pub channels: u16, // The number of audio channels (e.g., 2 for stereo) // The timestamp when the sound should be played
pub sample_rate: u32, // The sample rate of the audio (e.g., 44100 for 44.1 kHz) pub channels: u16,
pub sound_data: Vec<i16>, // The actual sound data as a vector of 16-bit integers // The number of audio channels (e.g., 2 for stereo)
pub sample_rate: u32,
// The sample rate of the audio (e.g., 44100 for 44.1 kHz)
pub sound_data: Vec<i16>,
// The actual sound data as a vector of 16-bit integers
} }