From 5b3a11a733dbae4f8437b5e2eff537971e7f3767 Mon Sep 17 00:00:00 2001 From: "j.foucher" Date: Wed, 1 Jul 2026 14:31:02 +0200 Subject: [PATCH] ConvAgent: agent audio multicast back to Reliable (fix Opus crackle/gaps) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sending Opus over Unreliable multicast caused missing words and crackling: Opus is a stateful inter-frame codec, so a dropped or reordered packet desyncs the decoder and corrupts all following frames until the stream resets. Unreliable was originally adopted only to stop a reliable-buffer overflow — but that overflow came from 32-152KB raw-PCM RPCs (pre-Opus). With Opus + sub-chunking each RPC is ~2KB (2-3 partial bunches) at ~1.25 RPC/s, so the 512-bunch reliable buffer stays in single digits and cannot overflow. Reliable restores ordered, lossless delivery. - MulticastReceiveAgentAudio: Unreliable -> Reliable. - Keep the 40-frame (0.8s, ~2KB) sub-chunking — it is what keeps packets small enough for Reliable to be safe. - Harden the raw-PCM fallback (only reached if Opus init fails): hard-cap one message at 320KB and drop the tail so it can never overflow the reliable buffer, and warn on every fallback (config bug: [Voice]). Co-Authored-By: Claude Opus 4.8 --- .../PS_AI_ConvAgent_ElevenLabsComponent.cpp | 37 ++++++++++++------- .../PS_AI_ConvAgent_ElevenLabsComponent.h | 16 +++++--- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_ElevenLabsComponent.cpp b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_ElevenLabsComponent.cpp index ab04703..a8b5590 100644 --- a/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_ElevenLabsComponent.cpp +++ b/Unreal/PS_AI_Agent/Plugins/PS_AI_ConvAgent/Source/PS_AI_ConvAgent/Private/PS_AI_ConvAgent_ElevenLabsComponent.cpp @@ -1278,24 +1278,33 @@ void UPS_AI_ConvAgent_ElevenLabsComponent::HandleAudioReceived(const TArray