summaryrefslogtreecommitdiff
path: root/client/src/audio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/audio.rs')
-rw-r--r--client/src/audio.rs32
1 files changed, 21 insertions, 11 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>() {