summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-16 15:29:57 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-16 15:29:57 +0100
commita11245c39d1551dc1e209c950d84c63931b604a5 (patch)
tree5f49e8205659881221e8e495b1d9f9ae9477e9bc /client
parent44220f3ff1015c056730c8ee4c95cb55a0759abc (diff)
downloadweareserver-a11245c39d1551dc1e209c950d84c63931b604a5.tar
weareserver-a11245c39d1551dc1e209c950d84c63931b604a5.tar.bz2
weareserver-a11245c39d1551dc1e209c950d84c63931b604a5.tar.zst
fix audio ringbuf and improve vad
Diffstat (limited to 'client')
-rw-r--r--client/src/audio.rs32
-rw-r--r--client/src/state.rs23
2 files changed, 36 insertions, 19 deletions
diff --git a/client/src/audio.rs b/client/src/audio.rs
index f93466d..d90898a 100644
--- a/client/src/audio.rs
+++ b/client/src/audio.rs
@@ -56,7 +56,7 @@ impl Audio {
inconf.buffer_size = cpal::BufferSize::Fixed(480);
let mut outconf = outdev.default_input_config()?.config();
- outconf.channels = 1;
+ outconf.channels = 2;
outconf.sample_rate = cpal::SampleRate(48_000);
outconf.buffer_size = cpal::BufferSize::Fixed(480);
@@ -101,6 +101,7 @@ impl Audio {
}
}
+#[derive(Debug)]
pub struct APlayPacket {
pos: Vec3,
channel: u128,
@@ -156,10 +157,11 @@ impl AEncoder {
let (tx, end_tx) = self.trigger.update(energy);
if tx {
let size = self.encoder.encode_float(&denoise, &mut out)?;
+ debug!("encoded size={size}");
let _ = self.sender.try_send(out[..size].to_vec());
}
if end_tx {
- // TODO send end frame
+ let _ = self.sender.try_send(vec![]);
}
}
Ok(())
@@ -168,14 +170,14 @@ impl AEncoder {
impl VadTrigger {
pub fn update(&mut self, energy: f32) -> (bool, bool) {
- debug!("E={energy:.02}");
let now = Instant::now();
- if energy > 1. {
+ let thres = if self.transmitting { 0.1 } else { 1. };
+ if energy > thres {
self.last_sig = now;
}
let last_sig_elapsed = (now - self.last_sig).as_secs_f32();
let prev_transmitting = self.transmitting;
- self.transmitting = last_sig_elapsed < 0.5;
+ self.transmitting = last_sig_elapsed < 0.2;
match (prev_transmitting, self.transmitting) {
(false, true) => info!("start transmit"),
@@ -188,6 +190,8 @@ impl VadTrigger {
}
const BUFFER_SIZE: usize = 48_000;
+const JITTER_COMP: usize = 48_00 * 2;
+
pub struct ADecoder {
decoder: Decoder,
receiver: Receiver<APlayPacket>,
@@ -210,8 +214,12 @@ impl ADecoder {
))
}
pub fn data(&mut self, samples: &mut [f32]) -> Result<()> {
- while self.buffer.len() < samples.len() {
- if let Ok(p) = self.receiver.try_recv() {
+ for p in self.receiver.try_iter() {
+ if p.data.is_empty() {
+ if self.channels.remove(&p.channel).is_some() {
+ info!("channel {} ended", p.channel % 1_000_000)
+ }
+ } else {
let mut output = [0f32; AE_FRAME_SIZE];
let size = self.decoder.decode_float(
Some(p.data.as_slice()),
@@ -219,17 +227,19 @@ impl ADecoder {
false,
)?;
- let channel_cursor = self.channels.entry(p.channel).or_insert(self.playback);
+ let channel_cursor = self.channels.entry(p.channel).or_insert_with(|| {
+ info!("channel {} started", p.channel % 1_000_000);
+ (self.playback + JITTER_COMP) % BUFFER_SIZE
+ });
let free_space = *channel_cursor - self.playback;
for i in 0..size.min(free_space) {
// TODO positional audio
let _ = p.pos;
- self.buffer[*channel_cursor] = [output[i], output[i]];
+ self.buffer[*channel_cursor][0] += output[i];
+ self.buffer[*channel_cursor][1] += output[i];
*channel_cursor += 1;
*channel_cursor %= BUFFER_SIZE
}
- } else {
- break;
}
}
for x in samples.array_chunks_mut::<2>() {
diff --git a/client/src/state.rs b/client/src/state.rs
index e59691a..560c8bd 100644
--- a/client/src/state.rs
+++ b/client/src/state.rs
@@ -41,6 +41,7 @@ pub struct State<'a> {
pub prefab_index_res_loaded: Option<Resource<PrefabIndex>>,
pub prefab_index_res: Option<Resource<PrefabIndex>>,
pub avatar_ob: Option<Object>,
+ pub last_position_tx: Instant,
}
pub struct InputState {
@@ -73,6 +74,7 @@ impl<'a> State<'a> {
prefab_index_res_loaded: None,
avatar_ob: None,
prefab_index: PrefabIndex::default().into(),
+ last_position_tx: Instant::now(),
})
}
pub fn draw(&mut self) {
@@ -146,9 +148,11 @@ impl<'a> State<'a> {
match &p {
Packet::PrefabIndex(res) => self.prefab_index_res = Some(res.to_owned()),
Packet::Sound(ob, data) => {
- if let Some(obdata) = self.tree.objects.get(ob) {
- self.audio
- .incoming_packet(ob.0, obdata.pos.into(), data.0.clone())
+ if Some(ob) != self.avatar_ob.as_ref() {
+ if let Some(obdata) = self.tree.objects.get(ob) {
+ self.audio
+ .incoming_packet(ob.0, obdata.pos.into(), data.0.clone())
+ }
}
}
_ => (),
@@ -169,11 +173,14 @@ impl<'a> State<'a> {
}
if let Some(ob) = self.avatar_ob {
- self.network.packet_send.send(Packet::Position(
- ob,
- self.camera.position().into(),
- self.camera.rotation().into(),
- ))?;
+ if self.last_position_tx.elapsed().as_secs_f32() > 0.1 {
+ self.network.packet_send.send(Packet::Position(
+ ob,
+ self.camera.position().into(),
+ self.camera.rotation().into(),
+ ))?;
+ self.last_position_tx = Instant::now();
+ }
while let Some(p) = self.audio.pop_output() {
self.network.packet_send.send(Packet::Sound(ob, Data(p)))?;
}