Fix compile errors in PS_AI_Agent_ElevenLabs plugin

- Remove WebSockets from .uplugin (it is a module, not a plugin)
- Add AudioCapture plugin dependency to .uplugin
- Fix FOnAudioCaptureFunction: use OpenAudioCaptureStream (not deprecated
  OpenDefaultCaptureStream) and correct callback signature (const void* per UE 5.3+)
- Cast void* to float* inside OnAudioGenerate for float sample processing
- Fix TArray::RemoveAt: use EAllowShrinking::No instead of deprecated bool overload

Plugin now compiles cleanly with no errors or warnings on UE 5.5 / Win64.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
j.foucher 2026-02-19 13:02:11 +01:00
parent b114ab063d
commit bb1a857e86
5 changed files with 15 additions and 16 deletions

View File

@ -21,10 +21,6 @@
{ {
"Name": "PS_AI_Agent_ElevenLabs", "Name": "PS_AI_Agent_ElevenLabs",
"Enabled": true "Enabled": true
},
{
"Name": "WebSockets",
"Enabled": true
} }
] ]
} }

View File

@ -28,7 +28,7 @@
], ],
"Plugins": [ "Plugins": [
{ {
"Name": "WebSockets", "Name": "AudioCapture",
"Enabled": true "Enabled": true
} }
] ]

View File

@ -262,7 +262,7 @@ void UElevenLabsConversationalAgentComponent::OnProceduralUnderflow(
const int32 BytesToPush = FMath::Min(AudioQueue.Num(), BytesRequired); const int32 BytesToPush = FMath::Min(AudioQueue.Num(), BytesRequired);
InProceduralWave->QueueAudio(AudioQueue.GetData(), BytesToPush); InProceduralWave->QueueAudio(AudioQueue.GetData(), BytesToPush);
AudioQueue.RemoveAt(0, BytesToPush, false); AudioQueue.RemoveAt(0, BytesToPush, EAllowShrinking::No);
} }
void UElevenLabsConversationalAgentComponent::EnqueueAgentAudio(const TArray<uint8>& PCMData) void UElevenLabsConversationalAgentComponent::EnqueueAgentAudio(const TArray<uint8>& PCMData)

View File

@ -37,15 +37,15 @@ void UElevenLabsMicrophoneCaptureComponent::StartCapture()
} }
// Open the default audio capture stream. // Open the default audio capture stream.
// FAudioCapture discovers the default device and its sample rate automatically. // FOnAudioCaptureFunction uses const void* per UE 5.3+ API (cast to float* inside).
Audio::FOnAudioCaptureFunction CaptureCallback = Audio::FOnAudioCaptureFunction CaptureCallback =
[this](const float* InAudio, int32 NumSamples, int32 InNumChannels, [this](const void* InAudio, int32 NumFrames, int32 InNumChannels,
int32 InSampleRate, double StreamTime, bool bOverflow) int32 InSampleRate, double StreamTime, bool bOverflow)
{ {
OnAudioGenerate(InAudio, NumSamples, InNumChannels, InSampleRate, StreamTime, bOverflow); OnAudioGenerate(InAudio, NumFrames, InNumChannels, InSampleRate, StreamTime, bOverflow);
}; };
if (!AudioCapture.OpenDefaultCaptureStream(DeviceParams, MoveTemp(CaptureCallback), 1024)) if (!AudioCapture.OpenAudioCaptureStream(DeviceParams, MoveTemp(CaptureCallback), 1024))
{ {
UE_LOG(LogElevenLabsMic, Error, TEXT("Failed to open default audio capture stream.")); UE_LOG(LogElevenLabsMic, Error, TEXT("Failed to open default audio capture stream."));
return; return;
@ -80,7 +80,7 @@ void UElevenLabsMicrophoneCaptureComponent::StopCapture()
// Audio callback (background thread) // Audio callback (background thread)
// ───────────────────────────────────────────────────────────────────────────── // ─────────────────────────────────────────────────────────────────────────────
void UElevenLabsMicrophoneCaptureComponent::OnAudioGenerate( void UElevenLabsMicrophoneCaptureComponent::OnAudioGenerate(
const float* InAudio, int32 NumSamples, const void* InAudio, int32 NumFrames,
int32 InNumChannels, int32 InSampleRate, int32 InNumChannels, int32 InSampleRate,
double StreamTime, bool bOverflow) double StreamTime, bool bOverflow)
{ {
@ -89,8 +89,11 @@ void UElevenLabsMicrophoneCaptureComponent::OnAudioGenerate(
UE_LOG(LogElevenLabsMic, Verbose, TEXT("Audio capture buffer overflow.")); UE_LOG(LogElevenLabsMic, Verbose, TEXT("Audio capture buffer overflow."));
} }
// Device sends float32 interleaved samples; cast from the void* API.
const float* FloatAudio = static_cast<const float*>(InAudio);
// Resample + downmix to 16000 Hz mono. // Resample + downmix to 16000 Hz mono.
TArray<float> Resampled = ResampleTo16000(InAudio, NumSamples, InNumChannels, InSampleRate); TArray<float> Resampled = ResampleTo16000(FloatAudio, NumFrames, InNumChannels, InSampleRate);
// Apply volume multiplier. // Apply volume multiplier.
if (!FMath::IsNearlyEqual(VolumeMultiplier, 1.0f)) if (!FMath::IsNearlyEqual(VolumeMultiplier, 1.0f))

View File

@ -55,12 +55,12 @@ public:
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
private: private:
/** Called by the audio capture callback on a background thread. */ /** Called by the audio capture callback on a background thread. Raw void* per UE 5.3+ API. */
void OnAudioGenerate(const float* InAudio, int32 NumSamples, void OnAudioGenerate(const void* InAudio, int32 NumFrames,
int32 InNumChannels, int32 InSampleRate, double StreamTime, bool bOverflow); int32 InNumChannels, int32 InSampleRate, double StreamTime, bool bOverflow);
/** Simple linear resample from InSampleRate to 16000 Hz. */ /** Simple linear resample from InSampleRate to 16000 Hz. Input is float32 frames. */
static TArray<float> ResampleTo16000(const float* InAudio, int32 NumSamples, static TArray<float> ResampleTo16000(const float* InAudio, int32 NumFrames,
int32 InChannels, int32 InSampleRate); int32 InChannels, int32 InSampleRate);
Audio::FAudioCapture AudioCapture; Audio::FAudioCapture AudioCapture;