Version: 2021.2
네이티브 오디오 플러그인 SDK
오디오 프로파일러

오디오 스페이셜라이저 SDK

오디오 스페이셜라이저 SDK는 애플리케이션이 오디오 소스에서 주변 공간으로 오디오를 전달하는 방법을 변경하는 제어를 제공합니다. 이것은 네이티브 오디오 플러그인 SDK 확장자입니다.

오디오 소스의 빌트인 패닝은 간단한 형태의 공간화입니다. 이는 소스를 받아 오디오 리스너와 오디오 소스 사이의 거리와 각도에 따라 왼쪽과 오른쪽 귀에 주어지는 게인을 조절합니다. 이것은 수평면 위의 플레이어에게 소리의 방향에 대한 간단한 단서를 제공합니다.

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

오디오 스페이셜라이저 작업에 대한 유연성과 지원을 제공하기 위해 Unity는 네이티브 오디오 플러그인 SDK의 확장자로 개방형 인터페이스인 오디오 스페이셜라이저 SDK를 가지고 있습니다. Unity의 표준 패너를 더 우수한 패너로 바꿀 수 있고 계산에 필요한 소스와 청취자에 대한 중요한 메타데이터에 대한 액세스를 제공할 수 있습니다.

네이티브 스페이셜라이저 오디오 플러그인의 예제에 대해서는 Unity 네이티브 오디오 플러그인 SDK를 참조하십시오. 플러그인은 헤드 관련 전송 기술(HRTF)만 지원하며 예시용으로만 사용됩니다.

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

인간 피험자로부터 얻은 데이터 세트를 살펴보려면 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. 
    
};

구조에는 인스펙터 내의 오디오 소스 컴포넌트 프로퍼티에 해당하는 Spatial Blend, Reverb Zone Mix, Spread, Stereo Pan, Minimum DistanceMaximum Distance 필드가 포함되어 있습니다.

UnityAudioSpatializerData 구조에는 오디오 리스너와 오디오 소스를 위한 전체 4x4 트랜스폼 매트릭스가 포함되어 있습니다. 리스너 매트릭스는 상대 방향 벡터를 얻기 위해 두 매트릭스를 곱하도록 역행렬화됩니다. 리스너 매트릭스는 항상 직교 행렬이므로 역행렬을 빨리 계산할 수 있습니다.

Unity 오디오 시스템은 원시 소스 사운드를 스테레오 신호로만 제공합니다. 신호는 소스가 Mono나 다중 채널일 때도 스테레오이며 필요에 따라 업 믹싱이나 다운 믹싱을 사용합니다.

매트릭스 규칙

sourcematrix 필드에는 오디오 소스의 변환 매트릭스 복사본이 포함됩니다. 회전되지 않은 GameObject의 기본 오디오 소스의 경우 매트릭스는 포지션이 요소 12, 13, 14에 인코딩되는 이동 매트릭스입니다.

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

아래와 같이 AudioListener에서 오디오 소스로 방향 벡터를 결정할 수 있으며 여기서 L은 listermatrix이고 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 file의 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# 스크립트 사용

오디오 소스에는 스페이셜라이저 효과의 파라미터를 설정하고 가져오기 위해 사용할 수 있는 메서드는 SetSpatializerFloatGetSpatializerFloat 이렇게 2개가 있습니다. 이 메서드는 일반 네이티브 오디오 플러그인 인터페이스의 SetFloatParameter, GetFloatParameter 메서드와 비슷하게 작동합니다. 하지만 SetSpatializerFloatGetSpatializerFloat 메서드는 설정하거나 읽을 파라미터에 인덱싱하는 반면 SetFloatParameterGetFloatParameter 메서드는 이름을 사용하여 파라미터를 의미한다는 것입니다.

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

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

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

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

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

네이티브 오디오 플러그인 SDK
오디오 프로파일러