From ff42fc5be41e10579b245f8d4ca924b5a4599568 Mon Sep 17 00:00:00 2001 From: mmhospedagem Date: Thu, 10 Sep 2026 11:55:30 -0300 Subject: [PATCH] fix(voip): increase live audio buffer headroom --- .changeset/soft-owls-buffer.md | 5 +++++ packages/voip/src/media/WaAudioEngine.ts | 4 ++-- packages/voip/src/media/__tests__/audio-engine.test.ts | 8 ++++---- 3 files changed, 11 insertions(+), 6 deletions(-) create mode 100644 .changeset/soft-owls-buffer.md diff --git a/.changeset/soft-owls-buffer.md b/.changeset/soft-owls-buffer.md new file mode 100644 index 00000000..a258f19f --- /dev/null +++ b/.changeset/soft-owls-buffer.md @@ -0,0 +1,5 @@ +--- +'@zapo-js/voip': patch +--- + +Increase the live audio buffer headroom to absorb upstream jitter without dropping recent speech. diff --git a/packages/voip/src/media/WaAudioEngine.ts b/packages/voip/src/media/WaAudioEngine.ts index 4904bef6..52d0dfcf 100644 --- a/packages/voip/src/media/WaAudioEngine.ts +++ b/packages/voip/src/media/WaAudioEngine.ts @@ -91,8 +91,8 @@ export class WaAudioEngine { this.extPreBufferSize = Math.floor(this.sampleRate * EXT_FEED_RESUME_FRACTION) this.extTargetBuffer = Math.floor(this.sampleRate * 0.06) - this.extHighWater = Math.floor(this.sampleRate * 0.2) - this.extMaxBuffer = Math.floor(this.sampleRate * 0.5) + this.extHighWater = Math.floor(this.sampleRate * 0.45) + this.extMaxBuffer = Math.floor(this.sampleRate * 0.75) } setAudioSender(sender: AudioSender): void { diff --git a/packages/voip/src/media/__tests__/audio-engine.test.ts b/packages/voip/src/media/__tests__/audio-engine.test.ts index 3b2ac6fc..229bedfa 100644 --- a/packages/voip/src/media/__tests__/audio-engine.test.ts +++ b/packages/voip/src/media/__tests__/audio-engine.test.ts @@ -63,8 +63,8 @@ test('feedExternalAudio caps the live buffer and drops oldest on overflow', () = for (let i = 0; i < 10; i++) { level = engine.feedExternalAudio(new Float32Array(2000)) } - assert.equal(level, 500) - assert.equal(engine.getLiveBufferMs(), 500) + assert.equal(level, 750) + assert.equal(engine.getLiveBufferMs(), 750) }) test('feedExternalAudio keeps only the tail of an oversized chunk', () => { @@ -72,8 +72,8 @@ test('feedExternalAudio keeps only the tail of an oversized chunk', () => { engine.setExternalMode(true) const level = engine.feedExternalAudio(new Float32Array(10_000)) - assert.equal(level, 500) - assert.equal(engine.getLiveBufferMs(), 500) + assert.equal(level, 625) + assert.equal(engine.getLiveBufferMs(), 625) }) test('feedExternalAudio is a no-op before external mode is enabled', () => {