流音波
语音活动检测 (VAD),请参阅此页面。
流音波是一种支持动态添加音频数据的导入音波类型,即使在播放过程中也是如此。它提供与导入音波相同的功能,例如回放,并可用于 SoundCues 等。
创建流音波
首先,您应该创建一个流音波。请注意,应将其视为强引用以防止过早销毁(例如,通过在蓝图中将其分配给单独的变量,或在 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);
避免加速音频播放
通常,当您需要流式传输音频数据并同时播放时,您应该在播放前稍作延迟,以避免由于缓冲区填充过快导致的音频加速。通常建议延迟大约半秒。
示例用法
最终,您的实现可能如下所示:
- Blueprint
- C++
这是一个将音频数据附加到流音波的基本代码示例。
该示例使用位于EXAMPLEMODULE
模块中UAppendAudioClassExample
类的AppendAudioExample
函数。
注意:要成功运行示例,请确保在 .Build.cs 文件中的 PublicDependencyModuleNames
或 PrivateDependencyModuleNames
中添加 RuntimeAudioImporter
模块,以及在项目的 .uproject 文件中添加该模块。
Header file (.h)
#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;
};
Source file (.cpp)
#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);
}
关于 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数据处理。