Streaming Sound Wave
流式音波是一种支持动态添加音频数据的导入音波类型,即使在播放过程中也能添加。它提供与导入音波相同的功能,例如倒带,并可用于SoundCues等。
关于语音活动检测 (VAD),请参阅此页面。
创建流式音波
首先,您应该创建一个流式音波。请注意,您应将其视为强引用以防止过早销毁(例如,在蓝图中将其分配给单独的变量,或在C++中使用 UPROPERTY())。
- Blueprint
- C++

UStreamingSoundWave* StreamingSoundWave = UStreamingSoundWave::CreateStreamingSoundWave();
播放声音波形
然后你就可以播放那个声音波形了。不过,现在没有必要这样做,你可以稍后再开始播放声音波形。

预分配音频数据
可选地,你可以预分配音频数据(字节),以避免每次追加新音频数据时重新分配整个PCM缓冲区。
- Blueprint
- C++

// Assuming StreamingSoundWave is a UE reference to a UStreamingSoundWave object (or its derived type, such as UCapturableSoundWave)
StreamingSoundWave->PreAllocateAudioData(12582912, FOnPreAllocateAudioDataResultNative::CreateWeakLambda(this, [StreamingSoundWave](bool bSucceeded)
{
// Handle the result
}));
追加音频数据
要向现有缓冲区的末尾添加音频数据,请使用相应的函数来动态追加音频数据。播放将遵循这些追加操作的队列顺序。
- Blueprint
- C++

// Assuming StreamingSoundWave is a UE reference to a UStreamingSoundWave object (or its derived type, such as UCapturableSoundWave)
// Example of appending encoded audio data
TArray<uint8> AudioData = ...; // Fill with audio data
StreamingSoundWave->AppendAudioDataFromEncoded(AudioData, ERuntimeAudioFormat::Auto);
// Or, if you have raw audio data
TArray<uint8> RawAudioData = ...; // Fill with raw audio data
StreamingSoundWave->AppendAudioDataFromRAW(RawAudioData, ERuntimeRAWAudioFormat::Float32, 44100, 2);
避免加速或失真的音频播放
在播放声音波形时同时流式传输音频数据,您可能会在特定场景下遇到音频播放加速或失真的问题。此问题通常在以下情况发生:
- 声音波形播放接近/到达当前缓冲区的末尾
- 新的音频数据正被持续排队到流式声音波形中
- 播放进度赶上了传入的数据流
您可以随时停止填充音频数据而不会出现问题。但是,对于需要连续流式传输的场景(例如实时音频流),根据您的音频数据流可靠性,有两种方法:
对于可靠、一致的流式传输: 使用 OnPopulateAudioState 委托在收到第一个数据块后立即开始播放。
对于不可靠的流式传输(网络问题、间歇性数据): 即使在 OnPopulateAudioState 被触发后,也添加额外的延迟,以便在开始播放前建立更大的缓冲区。
- Blueprint
- C++

// Approach 1: For reliable streaming - start immediately after first chunk
bool bHasStartedPlayback = false;
StreamingSoundWave->OnPopulateAudioStateNative.AddWeakLambda(this, [this, &bHasStartedPlayback]()
{
if (!bHasStartedPlayback)
{
UGameplayStatics::PlaySound2D(GetWorld(), StreamingSoundWave);
bHasStartedPlayback = true;
}
});
// Approach 2: For unreliable streaming - add delay after first chunk
bool bHasStartedPlayback = false;
StreamingSoundWave->OnPopulateAudioStateNative.AddWeakLambda(this, [this, &bHasStartedPlayback]()
{
if (!bHasStartedPlayback)
{
// Add delay to build up buffer for unreliable streaming
GetWorld()->GetTimerManager().SetTimer(PlaybackDelayTimer, [this]()
{
UGameplayStatics::PlaySound2D(GetWorld(), StreamingSoundWave);
}, 0.5f, false); // Half-second delay
bHasStartedPlayback = true;
}
});
注意: 您可以随时停止填充音频数据,而不会导致播放问题。具体方法取决于您的音频数据流可靠性——对于稳定的流使用即时播放,或为不可靠的流(例如,网络连接问题)添加额外的缓冲延迟。
示例用法
最后,您的实现可能如下所示:
- Blueprint
- C++

这是一个向流式音频波追加音频数据的基本代码示例。
该示例使用了位于 EXAMPLEMODULE 模块中 UAppendAudioClassExample 类内的 AppendAudioExample 函数。
注意:要成功运行此示例,请确保将 RuntimeAudioImporter 模块添加到 .Build.cs 文件中的 PublicDependencyModuleNames 或 PrivateDependencyModuleNames,同时也添加到您项目的 .uproject 文件中。
#pragma once
#include "CoreMinimal.h"
#include "UObject/Object.h"
#include "AppendAudioClassExample.generated.h"
UCLASS(BlueprintType)
class EXAMPLEMODULE_API UAppendAudioClassExample : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable)
void AppendAudioExample();
private:
// Please pay attention to making the StreamingSoundWave a hard reference, such as using UPROPERTY(), to prevent it from being prematurely garbage collected
UPROPERTY()
class UStreamingSoundWave* StreamingSoundWave;
};
#include "AppendAudioClassExample.h"
#include "Sound/StreamingSoundWave.h"
void UAppendAudioClassExample::AppendAudioExample()
{
// Create a streaming sound wave
StreamingSoundWave = UStreamingSoundWave::CreateStreamingSoundWave();
// Append audio data
TArray<uint8> StreamedAudioDataToAdd = ...; // Fill with audio data
StreamingSoundWave->AppendAudioDataFromEncoded(StreamedAudioDataToAdd, ERuntimeAudioFormat::Auto);
// Play the sound wave
UGameplayStatics::PlaySound2D(GetWorld(), StreamingSoundWave);
}
On Populate Audio State
OnPopulateAudioState 委托的功能与 OnPopulateAudioData 类似,但不会广播已填充的音频数据。当您希望跟踪音频数据何时被填充,但又不想传递已填充音频数据的数组时,这非常有用,可以提高性能。
- Blueprint
- C++

// Assuming StreamingSoundWave is a UE reference to a UStreamingSoundWave object (or its derived type, such as UCapturableSoundWave)
StreamingSoundWave->OnPopulateAudioStateNative.AddWeakLambda(this, [this]()
{
// Handle the result
});
处理 PCM 数据
如需在播放期间实时访问 PCM 数据,请参阅 PCM 数据处理。