串流音波
串流音波是一種支援動態添加音訊資料的匯入音波類型,即使在播放期間也能使用。它提供與匯入音波相同的功能,例如倒帶,並可用於 SoundCue 等。
關於語音活動偵測 (VAD),請參閱此頁面。
建立串流音波
首先,您應該建立一個串流音波。請注意,您應將其視為強引用,以防止過早銷毀(例如,在 Blueprint 中將其指派給單獨的變數,或在 C++ 中使用 UPROPERTY())。
- Blueprint
- C++

UStreamingSoundWave* StreamingSoundWave = UStreamingSoundWave::CreateStreamingSoundWave();
播放音波
接著你可以播放該音波。不過,現在不一定要這麼做,你可以稍後再開始播放音波。

預先分配音訊資料
選擇性地,你可以預先分配音訊資料(位元組),以避免每次附加新的音訊資料時重新分配整個 PCM 緩衝區。
- 藍圖
- 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
}));
追加音頻數據
若要將音頻數據添加到現有緩衝區的末尾,請使用適當的函數來動態追加音頻數據。播放將遵循這些追加操作的隊列順序。
- 藍圖
- 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 之後,也需增加額外的延遲,以建立更大的緩衝區後再開始播放。
- 藍圖
- 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 類似,但不會廣播已填充的音訊資料。當您想要追蹤音訊資料何時被填充,而不傳遞填充音訊資料的陣列時,這會很有用,因為可以提升效能。
- 藍圖
- 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 資料處理。