init
This commit is contained in:
87
src-tauri/src/domain/audio_client.rs
Normal file
87
src-tauri/src/domain/audio_client.rs
Normal file
@@ -0,0 +1,87 @@
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::AtomicU32;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::oneshot;
|
||||
use bytes::{Bytes};
|
||||
use crate::core::opus::{AudioOpus, AudioOpusDecoder};
|
||||
use crate::utils::ringbuf::{RingBufReader, RingBufWriter, RingBuffer};
|
||||
use crate::utils::shared_store::SharedArcMap;
|
||||
|
||||
struct AudioClient {
|
||||
uuid: uuid::Uuid,
|
||||
decode_sender: mpsc::Sender<DecodeRequest>,
|
||||
buffer_reader: RingBufReader<Vec<i16>>,
|
||||
buffer_writer: RingBufWriter<Vec<i16>>
|
||||
}
|
||||
|
||||
struct DecodeRequest {
|
||||
data: Bytes,
|
||||
sequence: u16,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct AudioClientManager {
|
||||
audio_clients: SharedArcMap<uuid::Uuid, AudioClient>,
|
||||
}
|
||||
|
||||
impl AudioClient {
|
||||
pub fn new() -> Self {
|
||||
let (writer, reader) = RingBuffer::<Vec<i16>>::new(1024).split();
|
||||
|
||||
let (decode_sender, mut decode_reader) = mpsc::channel::<DecodeRequest>(100);
|
||||
let decode_handle = tokio::spawn(async move {
|
||||
let mut decoder = AudioOpus::new(44800, 1, "voip")
|
||||
.create_decoder().unwrap();
|
||||
let mut last_sequence: u16 = 0;
|
||||
while let Some(request) = decode_reader.recv().await {
|
||||
// si la séquence est "trop vieille" on la drop. (voir plus tard pour un système de ratrapage si c'est possible)
|
||||
if last_sequence < request.sequence {
|
||||
// todo : si le décodage est trop long, voir pour le mettre dans un thread
|
||||
// avec let result = tokio::task::spawn_blocking({
|
||||
// let data = request.data.clone();
|
||||
// move || decoder.decode(&data)
|
||||
// }).await.unwrap();
|
||||
let start = std::time::Instant::now();
|
||||
let result = decoder.decode(&request.data);
|
||||
if start.elapsed() > Duration::from_millis(1) {
|
||||
println!("⚠️ Frame drop possible: {:?}", start.elapsed());
|
||||
}
|
||||
match result {
|
||||
Ok(audio_frame) => {
|
||||
// Pousser la frame complète dans le buffer
|
||||
writer.push(audio_frame);
|
||||
},
|
||||
Err(e) => {
|
||||
eprintln!("Erreur de décodage audio : {}", e);
|
||||
}
|
||||
}
|
||||
last_sequence = request.sequence;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Self {
|
||||
uuid: uuid::Uuid::new_v4(),
|
||||
decode_sender,
|
||||
buffer_reader: reader,
|
||||
buffer_writer: writer,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn write_audio(&self, sequence: u16, data: Bytes) {
|
||||
let _ = self.decode_sender.send(DecodeRequest {
|
||||
data,
|
||||
sequence
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl AudioClientManager {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
audio_clients: SharedArcMap::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user