MetaSounds 아키텍처
UE5의 차세대 DSP 그래프 기반 오디오 시스템의 내부 구조를 깊이 이해합니다
MetaSounds란?
Sound Cue를 대체하는 차세대 절차적 오디오 시스템
MetaSounds는 UE5에서 도입된 차세대 오디오 시스템으로, 각 MetaSound가 자체적인 DSP(Digital Signal Processing) 렌더링 엔진으로 동작합니다. Sound Cue가 런타임에 해석되는 파라미터 그래프였다면, MetaSounds는 컴파일된 DSP 그래프로서 샘플 수준의 정밀도와 실시간 합성 능력을 제공합니다.
MetaSounds의 각 인스턴스는 독립적인 오디오 렌더링 엔진입니다. 서로 다른 샘플레이트, 버퍼 크기, 채널 구성으로 렌더링할 수 있으며, 메인 Audio Mixer와 비동기적으로 병렬 처리됩니다.
MetaSounds vs Sound Cue - 근본적 차이
Sound Cue (레거시)
- 파라미터 그래프 -- Wave 재생 흐름 제어
- 런타임에 인터프리터가 평가
- 프레임 단위 타이밍 정밀도
- 합성 불가 (Wave 재생만)
- Audio Thread에서 순차 처리
MetaSounds (차세대)
- DSP 렌더링 그래프 -- 신호 처리 파이프라인
- 컴파일된 최적화 C++ 오브젝트로 실행
- 샘플 단위(sample-accurate) 정밀도
- 오실레이터, FM/AM 합성, 필터 지원
- 각 인스턴스가 독립적으로 병렬 렌더링
에셋 타입 체계
MetaSound Source, Patch, Preset의 역할과 관계
MetaSounds는 세 가지 에셋 타입으로 구성됩니다. 각각의 역할을 이해하면 재사용 가능한 모듈형 오디오 시스템을 구축할 수 있습니다.
| 에셋 타입 | 클래스 | 역할 | 독립 재생 |
|---|---|---|---|
| MetaSound Source | UMetaSoundSource | 완전한 오디오 소스. Audio Component에서 재생 가능 | O |
| MetaSound Patch | UMetaSoundPatch | 재사용 가능한 DSP 모듈. 다른 MetaSound에서 참조 | X |
| MetaSound Preset | UMetaSoundSource/Patch | 기존 Source/Patch의 파라미터만 변경한 변형 | 부모에 따름 |
에셋 관계도
내부에서 참조 ↓
파라미터 변형 ↓
MetaSound Patch는 "함수"처럼 사용합니다. 예를 들어, "랜덤 피치 변조기"를 Patch로 만들면, 발자국, 무기, 충격음 등 여러 MetaSound Source에서 동일한 로직을 재사용할 수 있습니다. DRY(Don't Repeat Yourself) 원칙을 오디오에 적용하는 것입니다.
DSP 그래프 실행 모델
MetaSounds의 내부 렌더링 파이프라인과 데이터 흐름
MetaSounds DSP 그래프는 컴파일 시 최적화된 정적 C++ 오브젝트로 변환됩니다. 노드 간 데이터는 참조로 전달되며(복사 없음), 이는 Sound Cue 대비 현저히 높은 성능을 제공합니다.
데이터 타입
| 데이터 타입 | 전달 레이트 | 설명 | 와이어 색상 |
|---|---|---|---|
| Audio | 매 샘플 (Sample Rate) | 오디오 신호. 오실레이터, 필터 입출력 | 파란색 |
| Float | 매 블록 (Block Rate) | 제어 파라미터. 볼륨, 피치, 주파수 등 | 연두색 |
| Int32 | 매 블록 | 정수 파라미터. 카운터, 인덱스 | 주황색 |
| Bool | 매 블록 | 조건 분기 | 노란색 |
| Trigger | 이벤트 기반 | 실행 흐름 제어 (Play, On Finished 등) | 분홍색 |
| Time | 매 블록 | 시간 값 (초 단위) | 보라색 |
블록 vs 샘플 레이트
Audio Rate: 매 샘플마다 값이 변함 (48kHz = 초당 48,000번). 오디오 신호 자체를 다룰 때 사용.
Block Rate: 버퍼 단위로 값이 변함 (1024 samples/block = 초당 ~47번). 파라미터 제어에 적합하며 CPU 부하가 낮음.
예: "볼륨을 서서히 변경"은 Block Rate(Float)로 충분하지만, "오실레이터 주파수 변조(FM)"는 Audio Rate가 필요합니다.
// MetaSound C++ Node API로 커스텀 노드 정의
#include "MetasoundNodeInterface.h"
#include "MetasoundExecutableOperator.h"
namespace Metasound
{
class FMyGainNode : public TExecutableOperator<FMyGainNode>
{
public:
// 입력 정의
static const FVertexInterface& GetVertexInterface()
{
static const FVertexInterface Interface(
FInputVertexInterface(
TInputDataVertex<FAudioBuffer>("Audio In", {}),
TInputDataVertex<float>("Gain", {}, 1.0f)
),
FOutputVertexInterface(
TOutputDataVertex<FAudioBuffer>("Audio Out", {})
)
);
return Interface;
}
// 매 오디오 블록마다 실행되는 핵심 함수
void Execute()
{
const FAudioBuffer& InBuffer = *InputAudio;
FAudioBuffer& OutBuffer = *OutputAudio;
float GainValue = *GainInput;
// 샘플 단위 처리
for (int32 i = 0; i < InBuffer.Num(); ++i)
{
OutBuffer[i] = InBuffer[i] * GainValue;
}
}
};
}
런타임 파라미터 인터페이스
게임플레이에서 MetaSounds 파라미터를 실시간 제어하기
MetaSounds의 Input 노드를 통해 외부(Blueprint/C++)에서 파라미터를 실시간으로 제어할 수 있습니다. 이는 Sound Cue의 파라미터 시스템보다 훨씬 유연하고 강력합니다.
파라미터 설정 흐름
// Audio Component를 통해 MetaSound 파라미터 설정
void AVehicle::UpdateAudioParameters()
{
if (EngineAudioComp)
{
// Float 파라미터 설정 (속도에 따른 피치)
EngineAudioComp->SetFloatParameter(
FName("Speed"), CurrentSpeed);
// Int 파라미터 설정 (기어 단수)
EngineAudioComp->SetIntParameter(
FName("GearIndex"), CurrentGear);
// Bool 파라미터 설정 (터보 활성화)
EngineAudioComp->SetBoolParameter(
FName("bTurboActive"), bTurboEnabled);
// Trigger 파라미터 (기어 변속 이벤트)
EngineAudioComp->SetTriggerParameter(
FName("OnGearShift"));
// Wave 파라미터 (동적 사운드 교체)
EngineAudioComp->SetWaveParameter(
FName("EngineLoop"), NewEngineSound);
}
}
MetaSound Input 파라미터 이름은 SetFloatParameter 등의 함수에서 FName으로 정확히 일치해야 합니다. 오타가 있으면 무시되므로, 프로젝트 전체에서 파라미터 이름을 상수로 관리하는 것을 권장합니다.
핵심 요약
- MetaSounds는 각 인스턴스가 독립적인 DSP 렌더링 엔진으로 동작하는 차세대 오디오 시스템이다
- 에셋은 Source(재생 가능), Patch(재사용 모듈), Preset(파라미터 변형) 세 가지 타입이 있다
- DSP 그래프는 컴파일된 C++ 오브젝트로 변환되어 참조 기반 데이터 전달로 고성능을 제공한다
- Audio Rate(매 샘플)와 Block Rate(매 블록)의 차이를 이해하고 적절히 사용해야 한다
- C++ Node API로 커스텀 노드를 생성하여 MetaSounds를 확장할 수 있다
- SetFloatParameter 등으로 Blueprint/C++에서 실시간 파라미터 제어가 가능하다
도전 과제
배운 내용을 직접 실습해보세요
MetaSound Source 에셋을 새로 생성하고, Wave Player 노드로 Sound Wave를 재생하는 기본 그래프를 구성하세요. Output 노드에 연결하여 사운드가 정상 재생되는지 확인하고, MetaSound와 Sound Cue의 에디터 UI 차이를 비교하세요.
MetaSound 에디터에서 Float, Bool, Trigger 타입의 Input을 추가하고, 블루프린트에서 UAudioComponent::SetFloatParameter()로 실시간 제어하세요. 입력값에 따라 피치가 변하는 엔진 사운드를 구현하세요.
동일한 사운드 로직(Random + Modulator + Attenuation)을 Sound Cue와 MetaSound로 각각 구현하고, 100개 동시 재생 시 stat Audio에서 CPU 사용량과 메모리 차이를 비교 분석하세요.