Streaming Sound Wave
ストリーミングサウンドウェーブは、再生中であっても動的にオーディオデータを追加できる、インポートされたサウンドウェーブの一種です。巻き戻しなどの機能はインポートされたサウンドウェーブと同じで、SoundCueなどで使用できます。
音声活動検出 (VAD) については、このページ を参照してください。
ストリーミングサウンドウェーブの作成
まず、ストリーミングサウンドウェーブを作成する必要があります。早期に破棄されないように、強参照として扱う必要があることに注意してください(例えば、Blueprintでは別の変数に割り当てる、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);
加速または歪んだオーディオ再生の回避
サウンドウェーブの再生中にオーディオデータをストリーミングすると、特定のシナリオでオーディオ再生が加速したり歪んだりする場合があります。この問題は通常、以下の状況で発生します:
- サウンドウェーブの再生が現在のバッファの終端付近/終端にある
- 新しいオーディオデータがストリーミングサウンドウェーブに継続的にキューイングされている
- 再生が受信データストリームに追いついてしまう
オーディオデータの投入はいつでも問題なく停止できます。ただし、リアルタイムオーディオストリーミングなどの継続的なストリーミングが必要なシナリオでは、オーディオデータストリーミングの信頼性に応じて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 関数を使用しています。
注記: この例を正常に実行するには、** .Build.cs** ファイルの PublicDependencyModuleNames または PrivateDependencyModuleNames に RuntimeAudioImporter モジュールを追加し、プロジェクトの .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 Data Handlingを参照してください。