스트리밍 사운드 웨이브
Voice Activity Detection (VAD)에 대해서는 이 페이지를 참조하세요.
스트리밍 사운드 웨이브는 재생 중에도 오디오 데이터를 동적으로 추가할 수 있는 유형의 임포트된 사운드 웨이브입니다. 되감기와 같은 임포트된 사운드 웨이브와 동일한 기능을 제공하며 SoundCue 등에서 사용할 수 있습니다.
스트리밍 사운드 웨이브 생성
먼저 스트리밍 사운드 웨이브를 생성해야 합니다. 조기 파괴를 방지하기 위해 강한 참조로 취급해야 합니다(예: Blueprints에서 별도 의 변수에 할당하거나 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
}));
오디오 데이터 추가
기존 버퍼의 끝에 오디오 데이터를 추가하려면 동적으로 오디오 데이터를 추가하는 적절한 함수를 사용하세요. 재생은 이러한 추가 작업의 큐(queue) 순서를 따릅니다.
- 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
함수를 사용합니다.
참고: 예시를 성공적으로 실행하려면 .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);
}
오디오 상태 채우기 시
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 데이터 처리를 참조하세요.