Version: Unity 6.0 (6000.0)
언어 : 한국어
SDK에 포함된 네이티브 오디오 플러그인 예시
오디오 플레이리스트 무작위화

오디오 스페이셜라이저 SDK

오디오 스페이셜라이저 SDK는 애플리케이션이 오디오 소스에서 주변 공간으로 오디오를 전달하는 방식을 변경하는 컨트롤을 제공합니다. 이는 네이티브 오디오 플러그인 SDK의 확장 기능입니다.

오디오 소스의 빌트인 패닝은 간단한 형태의 공간화입니다. 소스를 가져와서 오디오 리스너와 오디오 소스 간의 거리와 각도에 따라 왼쪽 및 오른쪽 귀 기여도의 게인을 조절합니다. 이는 수평면에서 플레이어에게 간단한 방향 신호를 제공합니다.

Unity 오디오 스페이셜라이저 SDK 및 예제 구현

Unity는 오디오 공간화 작업을 위한 유연성과 지원을 제공하기 위해 네이티브 오디오 플러그인 SDK의 확장 기능으로 오픈 인터페이스인 오디오 스페이셜라이저 SDK를 제공합니다. Unity의 표준 패너를 더 고급 패너로 교체하고 계산에 필요한 소스와 리스너에 대한 중요한 메타데이터에 액세스할 수 있습니다.

네이티브 스페이셜라이저 오디오 플러그인의 예시는 Unity 네이티브 오디오 플러그인 SDK를 참조하십시오. 이 플러그인은 직접 HRTF(헤드 관련 전송 함수)만 지원하며 예시 용도로만 사용됩니다.

플러그인에 포함된 간단한 리버브를 사용하여 스페이셜라이저 플러그인에서 리버브 플러그인으로 오디오 데이터를 라우팅할 수 있습니다. HRTF 필터링은 KEMAR 데이터 세트의 수정된 버전을 기반으로 합니다. KEMAR 데이터 세트에 대한 자세한 내용은 MIT Media Lab의 기술 자료 및 측정 파일을 참조하십시오.

인간 피험자로부터 얻은 데이터 세트를 살펴보려면 IRCAM 데이터 세트를 참조하십시오.

Unity 오디오 스페이셜라이저 초기화

Unity는 오디오 소스가 오디오 데이터를 디코딩한 직후에 공간화 효과를 적용합니다. 이렇게 하면 각 소스에 별도의 효과 인스턴스가 있는 오디오 데이터 스트림이 생성됩니다. Unity는 해당 효과 인스턴스와 함께 해당 소스의 오디오만 처리합니다.

플러그인이 스페이셜라이저로 작동하도록 활성화하려면 효과에 대한 설명 비트 필드에 플래그를 설정해야 합니다.

definition.flags |= UnityAudioEffectDefinitionFlags_IsSpatializer;

UnityAudioEffectDefinitionFlags_IsSpatializer 플래그를 설정하면 Unity는 플러그인 스캔 단계에서 플러그인을 스페이셜라이저로 인식합니다. Unity는 플러그인의 인스턴스를 생성할 때 UnityAudioEffectState 구조의 spatializerdata 멤버에 대한 UnityAudioSpatializerData 구조를 할당합니다.

프로젝트에서 스페이셜라이저를 사용하려면 프로젝트 설정(메뉴: Edit > Project Settings > Audio)에서 선택합니다.

스페이셜라이저 플러그인 선택기
스페이셜라이저 플러그인 선택기

그런 다음 스페이셜라이저 플러그인으로 사용하려는 오디오 소스용 인스펙터 창에서 Spatialize를 활성화합니다.

오디오 소스의 스페이셜라이저 체크박스
오디오 소스의 스페이셜라이저 체크박스

AudioSource.spatialize 프로퍼티를 사용하여 C# 스크립트를 통해 오디오 소스용 스페이셜라이저도 활성화할 수 있습니다.

소리가 많은 애플리케이션에서 근처에 있는 소리에만 스페이셜라이저를 활성화하고 먼 소리에는 기존의 패닝을 사용하여 스페이셜라이저 효과에 대한 혼합 스레드에 CPU 로드를 줄이고자 할 수도 있습니다.

Unity가 공간 데이터를 스페이셜라이저가 아닌 오디오 믹서 플러그인에 전달하게 하려면 설명 비트 필드에 있는 다음의 플래그를 사용할 수 있습니다.

definition.flags |= UnityAudioEffectDefinitionFlags_NeedsSpatializerData;

플러그인이 UnityAudioEffectDefinitionFlags_NeedsSpatializerData 플래그로 초기화되면 플러그인은 UnityAudioSpatializerData 구조를 수신하지만, listenermatrix 필드만 유효합니다. UnityAudioSpatializerData에 대한 자세한 내용은 스페이셜라이저 효과 메타데이터 섹션을 참조하십시오.

Unity가 스페이셜라이저 플러그인을 대신하여 거리 감쇠를 적용하지 않게 하려면 다음의 플래그를 사용하십시오.

definition.flags |= UnityAudioEffectDefinitionFlags_AppliesDistanceAttenuation;

UnityAudioEffectDefinitionFlags_AppliesDistanceAttenuation 플래그는 Unity에 스페이셜라이저가 거리 감쇠 적용을 처리한다는 것을 나타냅니다. 거리 감쇠에 대한 자세한 내용은 감쇠 곡선 및 가청도 섹션을 참조하십시오.

스페이셜라이저 효과 메타데이터

사운드 혼합에서 실행되는 다른 Unity 오디오 효과와 달리 Unity는 오디오 소스가 오디오 데이터를 디코딩한 직후에 스페이셜라이저를 적용합니다. 스페이셜라이저 효과의 각 인스턴스에는 주로 오디오 소스에 대한 데이터와 연결된 자체적인 UnityAudioSpatializerData 인스턴스가 있습니다.

struct UnityAudioSpatializerData
{
    float listenermatrix[16];   // Matrix that transforms sourcepos into the local space of the listener
    float sourcematrix[16];     // Transform matrix of the Audio Source
    float spatialblend;         // Distance-controlled spatial blend
    float reverbzonemix;        // Reverb zone mix level parameter (and curve) on 
                                // the Audio Source
    float spread;               // Spread parameter of the Audio Source (0..360 degrees)
    float stereopan;            // Stereo panning parameter of the Audio Source (-1: fully left, 1: fully right)
                                // The spatializer plugin may override the distance attenuation to
                                // influence the voice prioritization (leave this callback as NULL 
                                // to use the built-in Audio Source attenuation curve)
    UnityAudioEffect_DistanceAttenuationCallback distanceattenuationcallback;
    float minDistance;          // The minimum distance of the Audio Source. 
                                // This value may be useful for determining when to apply near-field effects. 
    float maxDistance;          // The maximum distance of the Audio Source, or the 
                                // distance where the audio becomes inaudible to the listener. 
    
};

구조에는 인스펙터에서 Audio Source 컴포넌트의 Spatial Blend, Reverb Zone Mix, Spread, Stereo Pan, Minimum Distance, Maximum Distance 프로퍼티에 해당하는 필드가 있습니다.

UnityAudioSpatializerData 구조에는 오디오 리스너와 오디오 소스에 대한 전체 4x4 트랜스폼 매트릭스가 포함되어 있습니다. 두 매트릭스를 곱하여 상대적인 방향 벡터를 얻을 수 있도록 리스너 매트릭스가 반전됩니다. 리스너 매트릭스는 항상 정규 직교이므로 역 매트릭스를 빠르게 계산할 수 있습니다.

Unity의 오디오 시스템은 원시 소스 사운드를 스테레오 신호로만 제공합니다. 소스가 모노 또는 멀티 채널인 경우에도 신호는 스테레오이며, Unity는 필요에 따라 업믹싱 또는 다운믹싱을 사용합니다.

매트릭스 규칙

sourcematrix 필드에는 오디오 소스의 변환 매트릭스 사본이 포함되어 있습니다. 회전되지 않은 게임 오브젝트의 기본 오디오 소스의 경우 매트릭스는 위치가 요소 12, 13, 14에 인코딩되는 이동 매트릭스입니다.

listenermatrix 필드에는 AudioListener의 트랜스폼 매트릭스의 인버스가 포함되어 있습니다.

아래와 같이 AudioListener에서 오디오 소스로 방향 벡터를 결정할 수 있으며 여기서 L은 listenermatrix이고 S는 sourcematrix입니다.

float dir_x = L[0] * S[12] + L[4] * S[13] + L[ 8] * S[14] + L[12];
float dir_y = L[1] * S[12] + L[5] * S[13] + L[ 9] * S[14] + L[13];
float dir_z = L[2] * S[12] + L[6] * S[13] + L[10] * S[14] + L[14];

(L[12], L[13], L[14])의 위치는 카메라 매트릭스에 대해 Unity의 인스펙터 창에 표시되는 음수 값입니다. 카메라도 회전했다면 회전 효과도 먼저 실행 취소해야 합니다. 변환-회전 매트릭스를 반전하려면 왼쪽 상단의 3x3 회전 매트릭스를 L로 전치하고 아래와 같이 위치를 계산합니다.

float listenerpos_x = -(L[0] * L[12] + L[ 1] * L[13] + L[ 2] * L[14]);
float listenerpos_y = -(L[4] * L[12] + L[ 5] * L[13] + L[ 6] * L[14]);
float listenerpos_z = -(L[8] * L[12] + L[ 9] * L[13] + L[10] * L[14]);

오디오 스페이셜라이저 플러그인 코드의 예시는 Plugin_Spatializer.cpp 파일의 215번째 줄을 참조하십시오.

감쇠 곡선 및 가청도

Unity 오디오 스페이셜라이저 초기화 섹션에 명시된 대로 UnityAudioEffectDefinitionFlags_AppliesDistanceAttenuation 플래그를 지정하지 않으면 Unity 오디오 시스템은 계속 거리 감쇠를 제어합니다. Unity는 공간화 단계에 진입하기 전에 사운드에 거리 감쇠를 적용하고, 오디오 시스템이 소스의 대략적인 가청도를 알 수 있도록 합니다. 오디오 시스템은 사용자가 정의한 Max Real Voices 한계치를 충족하도록 중요도를 기반으로 동적 가상 사운드의 근사 가청도를 사용합니다.

Unity는 실제 신호 레벨 측정에서 가청도 정보를 얻지 않고 거리 조절 감쇠 곡선, Volume 프로퍼티, 믹서에 의해 적용되는 감쇠에서 읽는 값의 조합을 사용합니다.

감쇠 곡선을 직접 오버라이드하거나 오디오 소스 곡선으로 계산된 값을 수정에 사용할 수 있습니다. 값을 오버라이드하거나 수정하려면 아래와 같이 UnityAudioSpatializerData 구조에서 콜백을 사용합니다.

typedef UNITY_AUDIODSP_RESULT (UNITY_AUDIODSP_CALLBACK* UnityAudioEffect_DistanceAttenuationCallback)(
    UnityAudioEffectState* state,
    float distanceIn,
    float attenuationIn,
    float* attenuationOut);

또한 아래에 표시된 것과 같이 간단한 커스텀 로그 커브를 사용할 수 있습니다.

UNITY_AUDIODSP_RESULT UNITY_AUDIODSP_CALLBACK SimpleLogAttenuation(
    UnityAudioEffectState* state,
    float distanceIn,
    float attenuationIn,
    float* attenuationOut)
{
    const float rollOffScale = 1.0f; // Similar to the one in the Audio Project Settings
    *attenuationOut = 1.0f / max(1.0f, rollOffScale * distanceIn);
    return UNITY_AUDIODSP_OK;
}

Unity API에서 C# 스크립트 사용

오디오 소스에는 스페이셜라이저 효과에서 파라미터를 설정하고 가져올 수 있는 두 가지 메서드(SetSpatializerFloat, GetSpatializerFloat)가 있습니다. 이러한 메서드는 일반 네이티브 오디오 플러그인 인터페이스의 SetFloatParameterGetFloatParameter 메서드와 유사하게 작동합니다. 그러나 SetSpatializerFloatGetSpatializerFloat는 설정하거나 읽어야 하는 파라미터에 인덱스를 가져오고, SetFloatParameterGetFloatParameter는 이름으로 파라미터를 나타냅니다.

부울 프로퍼티 AudioSource.spatializer는 Unity의 인스펙터 창에서 오디오 소스의 Spatialize 옵션에 연결됩니다. 프로퍼티는 오디오 프로젝트 설정에서 선택한 플러그인에 따라 Unity가 스페이셜라이저 효과를 인스턴스화하고 할당 해제하는 방식을 제어합니다.

프로젝트의 메모리나 다른 리소스와 관련하여 스페이셜라이저 효과의 인스턴스화에 리소스 소모가 심할 경우 사용해야 할 때마다 Unity가 스페이셜라이저의 새로운 인스턴스를 생성할 필요가 없도록 프리셋 ’풀’에서 공간화 효과를 할당하는 것이 효과적일 수 있습니다. Unity 플러그인 인터페이스 바인딩을 매우 가볍게하고 오디오 효과를 동적으로 할당하면 프로젝트 내에서 프레임이 감소하거나 기타 성능 문제가 발생하는 것을 피할 수 있습니다.

플러그인 예제의 알려진 한계

빠른 컨볼루션 알고리즘으로 인해 고속 이동은 일부 지퍼 아티팩트를 발생하며 오버랩 세이브 컨볼루션이나 크로스 페이딩 버퍼를 사용하여 제거할 수 있습니다.

이 코드는 또한 리스너가 플레이어 캐릭터에 직접 부착되어 있든 카메라가 다른 위치에 있든 리스너의 머리가 기울어지는 것을 지원하지 않습니다.

SDK에 포함된 네이티브 오디오 플러그인 예시
오디오 플레이리스트 무작위화