feat: ✨ new protocol and server implementation
This commit is contained in:
parent
d6e5389743
commit
51c29f7921
11 changed files with 445 additions and 198 deletions
|
@ -5,10 +5,9 @@ edition = "2024"
|
|||
|
||||
[dependencies]
|
||||
protocol = { path = "../protocol" }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
s2n-quic = { workspace = true }
|
||||
cpal = "0.15.3"
|
||||
iced = { features = ["tokio"], git = "https://github.com/iced-rs/iced", rev = "d39022432c778a8cda455f40b9c12245db86ce45" }
|
||||
fixed-resample = "0.8.0"
|
||||
|
|
|
@ -3,7 +3,7 @@ pub mod stream;
|
|||
pub mod voice;
|
||||
|
||||
const MICROPHONE_BUFFER_LENGHT: usize = 1024 * 4;
|
||||
const SPEAKER_BUFFER_LENGHT: usize = 1024 * 16 * 4;
|
||||
const SPEAKER_BUFFER_LENGHT: usize = 1024 * 16 * 16;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ClientConfig {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{net::SocketAddr, path::Path, sync::Arc};
|
||||
|
||||
use protocol::Error;
|
||||
use protocol::{Error, NETWORK_BUFFER_LENGTH, Signal, SignalType, SignedAudioDatum};
|
||||
use s2n_quic::{
|
||||
Client,
|
||||
client::Connect,
|
||||
|
@ -16,8 +16,8 @@ use crate::ClientConfig;
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct ConnectReturn {
|
||||
send_audio_task: JoinHandle<()>,
|
||||
receive_audio_task: JoinHandle<()>,
|
||||
send_signals_task: JoinHandle<()>,
|
||||
receive_signals_task: JoinHandle<()>,
|
||||
}
|
||||
|
||||
pub async fn connect(
|
||||
|
@ -58,13 +58,15 @@ pub async fn connect(
|
|||
.map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?;
|
||||
|
||||
let (receive_stream, send_stream) = stream.split();
|
||||
let ready_signal = broadcast::channel(3);
|
||||
|
||||
let receive_audio_task = tokio::spawn(receive_audio_data(receive_stream, speaker_sender));
|
||||
let send_audio_task = tokio::spawn(send_audio_data(send_stream, microphone_receiver));
|
||||
let send_signals_task = tokio::spawn(send_signals(send_stream, microphone_receiver));
|
||||
let speaker_clone = speaker_sender.clone();
|
||||
let receive_signals_task = tokio::spawn(receive_signals(receive_stream, speaker_sender));
|
||||
|
||||
Ok(ConnectReturn {
|
||||
send_audio_task,
|
||||
receive_audio_task,
|
||||
send_signals_task,
|
||||
receive_signals_task,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -81,49 +83,57 @@ pub async fn disconnect_watcher(
|
|||
|
||||
println!("Going to Disconnect");
|
||||
|
||||
connect_return.send_audio_task.abort();
|
||||
connect_return.receive_audio_task.abort();
|
||||
connect_return.send_signals_task.abort();
|
||||
connect_return.receive_signals_task.abort();
|
||||
|
||||
println!("Disconnected");
|
||||
}
|
||||
|
||||
async fn send_audio_data(
|
||||
async fn send_signals(
|
||||
mut send_stream: SendStream,
|
||||
old_microphone_receiver: broadcast::Receiver<f32>,
|
||||
mut microphone_receiver: broadcast::Receiver<f32>,
|
||||
) {
|
||||
let mut microphone_receiver = old_microphone_receiver.resubscribe();
|
||||
drop(old_microphone_receiver);
|
||||
loop {
|
||||
match microphone_receiver.recv().await {
|
||||
Ok(microphone_data) => {
|
||||
if let Err(err_val) = send_stream.write_f32(microphone_data).await {
|
||||
eprintln!("Error: Send Microphone Data | Remote | {}", err_val);
|
||||
todo!("GUI Status: Disconnect");
|
||||
// break;
|
||||
Ok(audio_datum) => {
|
||||
if let Err(err_val) = send_stream.write_f32(audio_datum).await {
|
||||
eprintln!("Error: Send Audio Datum | Remote | {}", err_val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Err(err_val) => {
|
||||
eprintln!("Error: Receive from Microphone | Local | {}", err_val);
|
||||
match err_val {
|
||||
broadcast::error::RecvError::Closed => break,
|
||||
broadcast::error::RecvError::Lagged(_) => {
|
||||
microphone_receiver = microphone_receiver.resubscribe()
|
||||
}
|
||||
}
|
||||
eprintln!("Error: Receive Audio Datum | Local | {}", err_val);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
async fn receive_audio_data(
|
||||
|
||||
async fn receive_signals(
|
||||
mut receive_stream: ReceiveStream,
|
||||
speaker_sender: Arc<broadcast::Sender<f32>>,
|
||||
speaker_sender: Arc<broadcast::Sender<SignedAudioDatum>>,
|
||||
) {
|
||||
let mut network_buffer = [0; NETWORK_BUFFER_LENGTH];
|
||||
loop {
|
||||
match receive_stream.read_f32().await {
|
||||
Ok(received_data) => {
|
||||
// todo: error only happens if there is no receiver, think about it
|
||||
let _ = speaker_sender.send(received_data);
|
||||
}
|
||||
match receive_stream.read_exact(&mut network_buffer).await {
|
||||
Ok(_) => match Signal::unpack_signal(&network_buffer) {
|
||||
Ok(received_signal) => match received_signal.signal_type {
|
||||
SignalType::AudioDatum => match received_signal.unpack_audio() {
|
||||
Ok(signed_audio_datum) => {
|
||||
let _ = speaker_sender.send(signed_audio_datum);
|
||||
}
|
||||
Err(err_val) => {
|
||||
eprintln!("Error: Unpack Audio | {}", err_val);
|
||||
println!("Warning: Illegal Operation");
|
||||
return;
|
||||
}
|
||||
},
|
||||
SignalType::SpeakerLeft => todo!(),
|
||||
},
|
||||
Err(err_val) => {
|
||||
eprintln!("Error: Unpack Signal | {}", err_val);
|
||||
}
|
||||
},
|
||||
Err(err_val) => {
|
||||
eprintln!("Error: Receive Audio Data | Remote | {}", err_val);
|
||||
todo!("GUI Status Disconnect");
|
||||
|
|
|
@ -72,25 +72,22 @@ pub async fn play(
|
|||
|
||||
let output = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
|
||||
for sample in data {
|
||||
if play_receiver.len() > 0 {
|
||||
match play_receiver.blocking_recv() {
|
||||
Ok(received_sample) => *sample = received_sample,
|
||||
Err(err_val) => match err_val {
|
||||
broadcast::error::RecvError::Closed => {
|
||||
eprintln!("Error: Speaker Receive | Local Channel | Channel Closed");
|
||||
return;
|
||||
}
|
||||
broadcast::error::RecvError::Lagged(lag_amount) => {
|
||||
eprintln!(
|
||||
"Error: Speaker Receive | Local Channel | Lagging by -> {}",
|
||||
lag_amount
|
||||
);
|
||||
play_receiver = play_receiver.resubscribe();
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
*sample = 0.0
|
||||
match play_receiver.try_recv() {
|
||||
Ok(received_sample) => *sample = received_sample,
|
||||
Err(err_val) => match err_val {
|
||||
broadcast::error::TryRecvError::Empty => *sample = 0.0,
|
||||
broadcast::error::TryRecvError::Closed => {
|
||||
eprintln!("Error: Speaker Receive | Local Channel | Channel Closed");
|
||||
return;
|
||||
}
|
||||
broadcast::error::TryRecvError::Lagged(lag_amount) => {
|
||||
eprintln!(
|
||||
"Error: Speaker Receive | Local Channel | Lagging by -> {}",
|
||||
lag_amount
|
||||
);
|
||||
play_receiver = play_receiver.resubscribe();
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue