111 lines
3.7 KiB
Rust
111 lines
3.7 KiB
Rust
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;
|
|
|
|
pub struct AudioClient {
|
|
uuid: uuid::Uuid,
|
|
decode_sender: mpsc::Sender<DecodeRequest>,
|
|
buffer_reader: RingBufReader<i16>,
|
|
buffer_writer: RingBufWriter<i16>
|
|
}
|
|
|
|
struct DecodeRequest {
|
|
data: Bytes,
|
|
sequence: u16,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct AudioClientManager {
|
|
audio_clients: SharedArcMap<uuid::Uuid, AudioClient>,
|
|
}
|
|
|
|
impl AudioClient {
|
|
pub fn new() -> Self {
|
|
let (writer, reader) = RingBuffer::<i16>::new(4096).split();
|
|
|
|
let (decode_sender, mut decode_reader) = mpsc::channel::<DecodeRequest>(100);
|
|
let writer_clone = writer.clone();
|
|
let decode_handle = tokio::spawn(async move {
|
|
let mut decoder = AudioOpus::new(48000, 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 rattrapage 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_clone.push_slice_overwrite(&audio_frame);
|
|
println!("writed 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 fn write_audio(&self, sequence: u16, data: Bytes) {
|
|
let _ = self.decode_sender.try_send(DecodeRequest {
|
|
data,
|
|
sequence
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
impl AudioClientManager {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
audio_clients: SharedArcMap::new()
|
|
}
|
|
}
|
|
|
|
pub fn audio_client_exists(&self, uuid: uuid::Uuid) -> bool {
|
|
self.audio_clients.contains_key(&uuid)
|
|
}
|
|
|
|
pub fn get_audio_client(&self, uuid: uuid::Uuid) -> Option<Arc<AudioClient>> {
|
|
self.audio_clients.get(&uuid)
|
|
}
|
|
|
|
pub fn add_audio_client(&self, uuid: uuid::Uuid, audio_client: AudioClient) {
|
|
self.audio_clients.insert(uuid, audio_client);
|
|
}
|
|
|
|
pub fn remove_audio_client(&self, uuid: uuid::Uuid) {
|
|
self.audio_clients.remove(&uuid);
|
|
}
|
|
|
|
pub fn write_audio_to_client(&self, uuid: uuid::Uuid, sequence: u16, data: Bytes) {
|
|
let _ = self.audio_clients.get(&uuid).unwrap().write_audio(sequence, data);
|
|
}
|
|
}
|