feat: ✨ remote mixer part 4
This commit is contained in:
parent
50917c09d5
commit
35ebb58698
6 changed files with 64 additions and 145 deletions
|
@ -8,7 +8,7 @@ use iced::{
|
||||||
Element, Task, Theme,
|
Element, Task, Theme,
|
||||||
widget::{button, column, row},
|
widget::{button, column, row},
|
||||||
};
|
};
|
||||||
use protocol::{BUFFER_LENGTH, Error};
|
use protocol::Error;
|
||||||
use tokio::{
|
use tokio::{
|
||||||
sync::{
|
sync::{
|
||||||
broadcast::{self},
|
broadcast::{self},
|
||||||
|
@ -17,7 +17,7 @@ use tokio::{
|
||||||
time::sleep,
|
time::sleep,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{ClientConfig, stream::connect, voice::record};
|
use crate::{ClientConfig, MICROPHONE_BUFFER_LENGHT, stream::connect, voice::record};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct Signal {
|
struct Signal {
|
||||||
|
@ -59,7 +59,7 @@ struct Channel {
|
||||||
impl Channel {
|
impl Channel {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
microphone: broadcast::channel(BUFFER_LENGTH).0.into(),
|
microphone: broadcast::channel(MICROPHONE_BUFFER_LENGHT / 4).0.into(),
|
||||||
// speaker: broadcast::channel(BUFFER_LENGTH),
|
// speaker: broadcast::channel(BUFFER_LENGTH),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,9 @@ pub mod gui;
|
||||||
pub mod stream;
|
pub mod stream;
|
||||||
pub mod voice;
|
pub mod voice;
|
||||||
|
|
||||||
|
const MICROPHONE_BUFFER_LENGHT: usize = 1024 * 16;
|
||||||
|
const SPEAKER_BUFFER_LENGHT: usize = 1024 * 16 * 4;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ClientConfig {
|
pub struct ClientConfig {
|
||||||
certificate_path: String,
|
certificate_path: String,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{net::SocketAddr, path::Path, sync::Arc};
|
use std::{net::SocketAddr, path::Path, sync::Arc};
|
||||||
|
|
||||||
use protocol::{BUFFER_LENGTH, Error};
|
use protocol::Error;
|
||||||
use s2n_quic::{
|
use s2n_quic::{
|
||||||
Client,
|
Client,
|
||||||
client::Connect,
|
client::Connect,
|
||||||
|
@ -11,7 +11,7 @@ use tokio::{
|
||||||
sync::{broadcast, oneshot},
|
sync::{broadcast, oneshot},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{ClientConfig, voice::play};
|
use crate::{ClientConfig, SPEAKER_BUFFER_LENGHT, voice::play};
|
||||||
|
|
||||||
pub async fn connect(
|
pub async fn connect(
|
||||||
connection_stop_signal_receiver: oneshot::Receiver<bool>,
|
connection_stop_signal_receiver: oneshot::Receiver<bool>,
|
||||||
|
@ -51,7 +51,7 @@ pub async fn connect(
|
||||||
.await
|
.await
|
||||||
.map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?;
|
.map_err(|err_val| Error::ConnectionSetup(err_val.to_string()))?;
|
||||||
let (receive_stream, send_stream) = stream.split();
|
let (receive_stream, send_stream) = stream.split();
|
||||||
let (speaker_sender, speaker_receiver) = broadcast::channel(BUFFER_LENGTH);
|
let (speaker_sender, speaker_receiver) = broadcast::channel(SPEAKER_BUFFER_LENGHT);
|
||||||
let (speaker_stop_signal_sender, speaker_stop_signal_receiver) = oneshot::channel();
|
let (speaker_stop_signal_sender, speaker_stop_signal_receiver) = oneshot::channel();
|
||||||
tokio::spawn(play(speaker_receiver, speaker_stop_signal_receiver));
|
tokio::spawn(play(speaker_receiver, speaker_stop_signal_receiver));
|
||||||
let receive_voice_data_task = tokio::spawn(receive_audio_data(receive_stream, speaker_sender));
|
let receive_voice_data_task = tokio::spawn(receive_audio_data(receive_stream, speaker_sender));
|
||||||
|
|
|
@ -11,6 +11,7 @@ pub async fn record(
|
||||||
let host = cpal::default_host();
|
let host = cpal::default_host();
|
||||||
let input_device = host.default_input_device().unwrap();
|
let input_device = host.default_input_device().unwrap();
|
||||||
let config = input_device.default_input_config().unwrap().into();
|
let config = input_device.default_input_config().unwrap().into();
|
||||||
|
println!("Recorder Stream Config = {:#?}", config);
|
||||||
|
|
||||||
let input = move |data: &[f32], _: &cpal::InputCallbackInfo| {
|
let input = move |data: &[f32], _: &cpal::InputCallbackInfo| {
|
||||||
for &sample in data {
|
for &sample in data {
|
||||||
|
@ -50,6 +51,7 @@ pub async fn play(
|
||||||
let host = cpal::default_host();
|
let host = cpal::default_host();
|
||||||
let output_device = host.default_output_device().unwrap();
|
let output_device = host.default_output_device().unwrap();
|
||||||
let config = output_device.default_output_config().unwrap().into();
|
let config = output_device.default_output_config().unwrap().into();
|
||||||
|
println!("Speaker Stream Config = {:#?}", config);
|
||||||
|
|
||||||
let output = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
|
let output = move |data: &mut [f32], _: &cpal::OutputCallbackInfo| {
|
||||||
for sample in data {
|
for sample in data {
|
||||||
|
|
|
@ -7,8 +7,6 @@ use std::{
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub const BUFFER_LENGTH: usize = 1024 * 16;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
ConnectionSetup(String),
|
ConnectionSetup(String),
|
||||||
|
|
|
@ -16,29 +16,56 @@ use tokio::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::ServerConfig;
|
use crate::ServerConfig;
|
||||||
const BUFFER_LENGTH: usize = protocol::BUFFER_LENGTH;
|
const BUFFER_LENGTH: usize = 1024 * 16 * 2;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct User {
|
struct User {
|
||||||
sender: broadcast::Sender<f32>,
|
audio_buffer: Arc<RwLock<VecDeque<f32>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl User {
|
impl User {
|
||||||
async fn new() -> broadcast::Sender<f32> {
|
async fn new() -> Arc<RwLock<VecDeque<f32>>> {
|
||||||
let (sender, _) = broadcast::channel(BUFFER_LENGTH);
|
let audio_buffer = Arc::new(RwLock::new(VecDeque::new()));
|
||||||
let new_user = Self {
|
let new_user = Self {
|
||||||
sender: sender.clone(),
|
audio_buffer: audio_buffer.clone(),
|
||||||
};
|
};
|
||||||
ONLINE_USERS.write().await.push(new_user);
|
ONLINE_USERS.write().await.push(new_user);
|
||||||
if let Err(err_val) = NEW_USER_NOTIFIER.send(sender.clone()) {
|
audio_buffer
|
||||||
eprintln!("Error: Send New User | Local | {}", err_val);
|
|
||||||
}
|
|
||||||
sender.clone()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static ONLINE_USERS: LazyLock<RwLock<Vec<User>>> = LazyLock::new(|| vec![].into());
|
static ONLINE_USERS: LazyLock<RwLock<Vec<User>>> = LazyLock::new(|| vec![].into());
|
||||||
static NEW_USER_NOTIFIER: LazyLock<broadcast::Sender<broadcast::Sender<f32>>> =
|
static GLOBAL_MIXER: LazyLock<broadcast::Sender<f32>> =
|
||||||
LazyLock::new(|| broadcast::channel(BUFFER_LENGTH).0);
|
LazyLock::new(|| broadcast::channel(BUFFER_LENGTH).0);
|
||||||
|
|
||||||
|
async fn global_mixer() {
|
||||||
|
let global_mixer_sender = GLOBAL_MIXER.clone();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
sleep(Duration::from_millis(100)).await;
|
||||||
|
let mut mixed_audio_buffer = VecDeque::new();
|
||||||
|
for online_user in ONLINE_USERS.read().await.iter() {
|
||||||
|
let mut inner_buffer = vec![];
|
||||||
|
while let Some(audio_data) = online_user.audio_buffer.write().await.pop_front() {
|
||||||
|
inner_buffer.push(audio_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i, audio_data) in inner_buffer.iter().enumerate() {
|
||||||
|
match mixed_audio_buffer.get(i) {
|
||||||
|
Some(original_value) => mixed_audio_buffer[i] = original_value + audio_data,
|
||||||
|
None => mixed_audio_buffer.push_back(*audio_data),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mixed_audio_buffer.truncate(mixed_audio_buffer.len() * 85 / 100);
|
||||||
|
while let Some(audio_data) = mixed_audio_buffer.pop_front() {
|
||||||
|
if let Err(err_val) = global_mixer_sender.send(audio_data) {
|
||||||
|
eprintln!("Error: Send Mixed Audio Data | Local | {}", err_val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn start(server_config: ServerConfig) {
|
pub async fn start(server_config: ServerConfig) {
|
||||||
let mut server = Server::builder()
|
let mut server = Server::builder()
|
||||||
.with_io(server_config.server_address.as_str())
|
.with_io(server_config.server_address.as_str())
|
||||||
|
@ -51,6 +78,8 @@ pub async fn start(server_config: ServerConfig) {
|
||||||
.start()
|
.start()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
tokio::spawn(global_mixer());
|
||||||
|
|
||||||
while let Some(connection) = server.accept().await {
|
while let Some(connection) = server.accept().await {
|
||||||
tokio::spawn(handle_client(connection));
|
tokio::spawn(handle_client(connection));
|
||||||
}
|
}
|
||||||
|
@ -74,152 +103,39 @@ async fn handle_client(mut connection: Connection) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let (receive_stream, send_stream) = stream.split();
|
let (receive_stream, send_stream) = stream.split();
|
||||||
|
|
||||||
let new_user_sender = User::new().await;
|
let user_audio_buffer = User::new().await;
|
||||||
|
|
||||||
tokio::spawn(receiver_audio_data(receive_stream, new_user_sender));
|
tokio::spawn(receiver_audio_data(receive_stream, user_audio_buffer));
|
||||||
tokio::spawn(send_audio_data(send_stream));
|
tokio::spawn(send_audio_data(send_stream));
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn mixer_with_buffer(
|
async fn send_audio_data(mut send_stream: SendStream) {
|
||||||
unmixed_audio_data: Arc<RwLock<VecDeque<Arc<RwLock<VecDeque<f32>>>>>>,
|
let mut global_mixer_receiver = GLOBAL_MIXER.subscribe();
|
||||||
) -> Vec<f32> {
|
|
||||||
let mut mixed_audio_buffer = vec![];
|
|
||||||
for audio_buffer in unmixed_audio_data.read().await.iter() {
|
|
||||||
let mut inner_audio_buffer = vec![];
|
|
||||||
|
|
||||||
while let Some(audio_data) = audio_buffer.write().await.pop_front() {
|
|
||||||
inner_audio_buffer.push(audio_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i, audio_data) in inner_audio_buffer.iter().enumerate() {
|
|
||||||
match mixed_audio_buffer.get(i) {
|
|
||||||
Some(current_audio_data) => mixed_audio_buffer[i] = current_audio_data + audio_data,
|
|
||||||
None => mixed_audio_buffer.push(*audio_data),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mixed_audio_buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
// async fn mixer_with_channel(
|
|
||||||
// unmixed_audio_data: Arc<RwLock<VecDeque<Arc<RwLock<VecDeque<f32>>>>>>,
|
|
||||||
// sender: broadcast::Sender<f32>,
|
|
||||||
// ) {
|
|
||||||
// loop {
|
|
||||||
// sleep(Duration::from_nanos(10)).await;
|
|
||||||
// let mut mixed_audio_buffer = vec![];
|
|
||||||
// for audio_buffer in unmixed_audio_data.read().await.iter() {
|
|
||||||
// let mut inner_audio_buffer = vec![];
|
|
||||||
//
|
|
||||||
// while let Some(audio_data) = audio_buffer.write().await.pop_front() {
|
|
||||||
// inner_audio_buffer.push(audio_data);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// for (i, audio_data) in inner_audio_buffer.iter().enumerate() {
|
|
||||||
// match mixed_audio_buffer.get(i) {
|
|
||||||
// Some(current_audio_data) => {
|
|
||||||
// mixed_audio_buffer[i] = current_audio_data + audio_data
|
|
||||||
// }
|
|
||||||
// None => mixed_audio_buffer.push(*audio_data),
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// for audio_data in mixed_audio_buffer {
|
|
||||||
// if let Err(err_val) = sender.send(audio_data) {
|
|
||||||
// eprintln!("Error: Send Mixed Audio | Local | {}", err_val);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
async fn new_user_handler(
|
|
||||||
mut receiver: broadcast::Receiver<f32>,
|
|
||||||
unmixed_audio_data: Arc<RwLock<VecDeque<Arc<RwLock<VecDeque<f32>>>>>>,
|
|
||||||
) {
|
|
||||||
let local_audio_buffer = Arc::new(RwLock::new(VecDeque::new()));
|
|
||||||
unmixed_audio_data
|
|
||||||
.write()
|
|
||||||
.await
|
|
||||||
.push_back(local_audio_buffer.clone());
|
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
match receiver.recv().await {
|
match global_mixer_receiver.recv().await {
|
||||||
Ok(received_audio_data) => {
|
Ok(received_audio_data) => {
|
||||||
local_audio_buffer
|
if let Err(err_val) = send_stream.write_f32(received_audio_data).await {
|
||||||
.write()
|
eprintln!("Error: Send Audio Data | Remote | {}", err_val);
|
||||||
.await
|
|
||||||
.push_back(received_audio_data);
|
|
||||||
}
|
|
||||||
Err(err_val) => {
|
|
||||||
eprintln!("Error: Receive Audio Data | Local | {}", err_val);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn send_audio_data(mut send_stream: SendStream) {
|
|
||||||
let unmixed_audio_data = Arc::new(RwLock::new(VecDeque::new()));
|
|
||||||
for online_user in ONLINE_USERS.read().await.iter() {
|
|
||||||
let receiver = online_user.sender.subscribe();
|
|
||||||
let unmixed_audio_data = unmixed_audio_data.clone();
|
|
||||||
tokio::spawn(new_user_handler(receiver, unmixed_audio_data));
|
|
||||||
}
|
|
||||||
let unmixed_audio_data_for_handling_new_user = unmixed_audio_data.clone();
|
|
||||||
tokio::spawn(async move {
|
|
||||||
loop {
|
|
||||||
match NEW_USER_NOTIFIER.subscribe().recv().await {
|
|
||||||
Ok(new_user_sender) => {
|
|
||||||
let receiver = new_user_sender.subscribe();
|
|
||||||
let unmixed_audio_data = unmixed_audio_data_for_handling_new_user.clone();
|
|
||||||
tokio::spawn(new_user_handler(receiver, unmixed_audio_data));
|
|
||||||
}
|
|
||||||
Err(err_val) => {
|
|
||||||
eprintln!("Error: Receive New User | Local | {}", err_val);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
Err(err_val) => {
|
||||||
});
|
eprintln!("Error: Receive Mixed Audio Data | Local | {}", err_val);
|
||||||
|
|
||||||
// let (mixer_sender, mut mixer_receiver) = broadcast::channel(BUFFER_LENGTH);
|
|
||||||
// tokio::spawn(mixer_with_channel(unmixed_audio_data, mixer_sender));
|
|
||||||
// loop {
|
|
||||||
// match mixer_receiver.recv().await {
|
|
||||||
// Ok(mixed_audio_data) => {
|
|
||||||
// if let Err(err_val) = send_stream.write_f32(mixed_audio_data).await {
|
|
||||||
// eprintln!("Error: Send Audio Data | Remote | {}", err_val);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Err(err_val) => {
|
|
||||||
// eprintln!("Error: Receive Mixed Audio Data | Local | {}", err_val);
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
loop {
|
|
||||||
sleep(Duration::from_millis(50)).await;
|
|
||||||
let mixed_audio_buffer = mixer_with_buffer(unmixed_audio_data.clone()).await;
|
|
||||||
for mixed_audio_data in mixed_audio_buffer {
|
|
||||||
if let Err(err_val) = send_stream.write_f32(mixed_audio_data).await {
|
|
||||||
eprintln!("Error: Send Audio Data | Remote | {}", err_val);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn receiver_audio_data(mut receive_stream: ReceiveStream, sender: broadcast::Sender<f32>) {
|
async fn receiver_audio_data(
|
||||||
|
mut receive_stream: ReceiveStream,
|
||||||
|
audio_buffer: Arc<RwLock<VecDeque<f32>>>,
|
||||||
|
) {
|
||||||
loop {
|
loop {
|
||||||
match receive_stream.read_f32().await {
|
match receive_stream.read_f32().await {
|
||||||
Ok(received_audio_data) => {
|
Ok(received_audio_data) => {
|
||||||
if let Err(err_val) = sender.send(received_audio_data) {
|
audio_buffer.write().await.push_back(received_audio_data);
|
||||||
eprintln!("Error: Send Audio Data | Local | {}", err_val);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(err_val) => {
|
Err(err_val) => {
|
||||||
eprintln!("Error: Receive Audio Data | Remote | {}", err_val);
|
eprintln!("Error: Receive Audio Data | Remote | {}", err_val);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue