소개
Scalable Hardware Audio Processing Engine(SHAPE)은 오디오 재생 및 조작에 가장 일반적으로 사용되는 여러 빌딩 블록을 위한 하드웨어 가속을 제공합니다. 타이틀은 Audio Control Processor(ACP)가 관리하는 SHAPE 처리 블록의 구성과 순서를 완전히 제어합니다. ACP는 하드웨어 구성요소입니다. 타이틀은 입력에서 출력까지 하나 이상의 SHAPE 구성요소를 연결하기 위해 정의된 경로를 생성합니다. 이러한 경로를 플로우그래프 라고 합니다. 생성된 각 플로우그래프는 ACP가 처리할 일련의 명령으로 제출됩니다. 이 항목에서는 가장 자주 마주치게 될 런타임 시나리오를 성공적으로 구현하는 플로우그래프를 만들고 제출하는 모범 사례와, 성능을 극대화하기 위해 피해야 할 구성에 대해 논의합니다. 이 항목에서는 다음을 다룹니다:SHAPE 구성요소 및 기능
명령 큐 는 플로우그래프가 하드웨어에 제출될 때 ACP에 의해 자동으로 관리되고 채워집니다. 다음 표는 구성요소 및 인스턴싱 기능의 통합 목록입니다.
다음 표는 구성요소 및 믹스 버퍼 라우팅 규칙의 통합 목록입니다.
| SHAPE 구성요소| 인스턴스당 입력 믹스 버퍼| 인스턴스당 출력 믹스 버퍼|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| XMA| 해당 없음. 메모리에서 읽습니다.| 해당 없음. 메모리로 디코드하며 일반적으로 SRC가 소비합니다.|
| SRC| 0; 메모리에서 읽습니다.| 모노는 1, 스테레오는 2.|
| FLT/VOL| 1.| 1.|
| EQ/CMP| 1 (또는 사이드체인 구성의 경우 2).| 1.|
| MB| 해당 없음. 믹스 버퍼는 다른 믹스 버퍼에서 직접 읽을 수 없습니다.| 해당 없음. 믹스 버퍼는 다른 믹스 버퍼에 직접 쓸 수 없습니다.|
| DMA| 1; 전송당 최대 32 오디오 프레임.| 1; 전송당 최대 32 오디오 프레임.|
SHAPE의 빌딩 블록에 대한 자세한 내용은 관련 Xfest 강연 The Sound of XBOX One (Conference Material > Xfest 2012) 및 백서 The Sound of the Future (Developer Education Materials > All NDA Whitepapers)를 참고하십시오.
플로우그래프 사용 시나리오에 대한 참고사항
많은 타이틀에서는 플로우그래프를 직접 구현하지 않을 수도 있습니다. XAudio2는 SHAPE 구성요소를 암묵적으로 구현하며, 오디오 미들웨어는 하드웨어 플로우그래프를 타이틀 개발자로부터 추상화할 수 있습니다. 하지만 플로우그래프를 구성하면 XBOX One 콘솔의 오디오 가속 기능을 직접 활용할 수 있습니다. 구체적으로는 자체 오디오 렌더링 솔루션을 개발 및 구현하거나, XAudio2 또는 미들웨어가 지원하지 않는 사용자 지정 구성이 있는 경우에 그렇습니다. 개발하는 모든 타이틀에서, 이 항목의 뒷부분에서 논의되는 SHAPE의 기능을 이해하고 잠재적 플로우그래프 토폴로지를 미리 계획하는 것에서 가치를 찾을 수 있습니다.비효율적인 시나리오 및 병리적 사례
다음 섹션에서는 성능 문제를 유발할 수 있는 일반적인 시나리오를 설명합니다. 또한 이러한 문제를 피하기 위한 권장사항을 제공합니다.잘못 구성된 플로우그래프
불가능한 신호 흐름을 구성하거나 출력에서 실현되지 않는 데이터를 만드는 플로우그래프를 생성할 수 있습니다. 다음은 플로우그래프 생성 시 발생하는 가장 일반적인 오류입니다.- 생성되거나 할당되지 않은 SHAPE 객체에 대한 참조
- 잘못된 명령 또는 매개변수
- 믹스 버퍼 입/출력 참조 카운트 정확성
- 기존 믹스 버퍼 가상 ID의 재할당
- SHAPE 구성요소 간 믹스 버퍼 연결 누락
- 스테레오 콘텐츠를 렌더링할 때 두 믹스 버퍼로 라우팅할 수 있는 SRC 블록을 제외하고, SHAPE 구성요소의 출력으로 여러 믹스 버퍼를 사용하는 것
- 믹스 버퍼의 순환 참조 믹스 버퍼는 모든 입력이 제공되고 출력이 소비될 때까지 사용할 수 없습니다. 믹스 버퍼에 순환 참조가 있으면, 믹스 버퍼는 사실상 무한한 입력을 가지게 되어 절대 사용 가능해지지 않으며 그래프가 hang됩니다.
- 고아 믹스 버퍼 출력이 없는 믹스 버퍼는 마지막 입력이 처리되는 즉시 사용 가능해집니다. 오디오 장치(예: 스피커 또는 헤드셋)로 렌더링하기 위한 믹스 버퍼는 DMA 출력 블록으로 종료되어야 합니다. 그러면 믹스 버퍼가 최종 믹싱을 위해 메인 메모리에 제공됩니다.
명령 순서
ACP는 각 SHAPE 구성요소에 대한 명령 큐를 자동으로 채웁니다. 큐를 채울 때, ACP는 구성요소의 항목이 비어질 때까지 특정 구성요소에 대한 이후 명령을 건너뜁니다. 일반적으로 명령을 건너뛰는 것은 무시할 만한 성능 페널티에 해당합니다. 그러나 명령 순서에 따라 타이틀은 SHAPE 구성요소의 최적이 아닌 순서를 생성할 수 있습니다. 이는 채워지지 않은 상태의 하나 이상의 큐가 다른 큐를 기다리게 만듭니다. 이러한 대기는 프레임당 사용 가능한 인스턴스 수를 줄입니다. 그림 1은 명령 순서가 성능에 어떻게 영향을 미칠 수 있는지 보여줍니다. 모범 사례로서, 플로우그래프에 표시된 것처럼 왼쪽에서 오른쪽이 아닌 위에서 아래로 FLT/VOL 명령을 발행하십시오. 그러면 더 많은 보이스가 완료될 수 있습니다. 이 방식은 플로우그래프 하단에 표시된 EQ/CMP가 병렬로 처리되도록 합니다. 그림 1. EQ/CMP가 병렬로 처리되어 성능을 향상시킬 수 있도록 왼쪽에서 오른쪽이 아닌 위에서 아래로 FLT/VOL 명령을 발행하는 방법을 보여주는 플로우그래프. 특정 유형의 명령 간에 플로우그래프를 정렬하는 모범 사례로는 서브믹스 단계까지 또는 재사용된 SHAPE 구성요소까지 보이스의 처리 경로를 통한 깊이(depth)를 우선하십시오. 그런 다음 공통 처리 순서를 공유하는 보이스에 대해 너비(breadth)를 우선하십시오. 그림 1은 최적(그리고 일반적)인 접근 방식이 가장 왼쪽 열의 FLT/VOL에 대한 FLT/VOL 명령을 먼저 만들고, 그런 다음 상단 스테레오 보이스의 두 채널에 대한 나머지 FLT/VOL 명령을 회전시키는 것임을 보여줍니다.믹스 버퍼 인스턴스 할당
믹스 버퍼는 기록되는 동안 잠깁니다. 모든 입력이 믹스에 기여할 때까지 출력을 읽을 수 없습니다. 구현 관점에서, 믹스 버퍼는 이를 관리하기 위해numIn과 numOut 필드를 사용합니다. 따라서 동시에 128개 이상의 물리 믹스 버퍼가 필요한 시나리오를 구성할 수 있습니다.
SHAPE는 믹스 버퍼를 가상화하므로, 폴리포니가 높은 경우에도 이 시나리오는 일반적으로 문제가 되지 않습니다. 하지만 많은 수의 믹스 버퍼가 동시에 액세스되어야 하는 플로우그래프를 구성할 수 있습니다. 특히 여러 보이스 중에서 서브믹싱 또는 마스터링하는 믹스 버퍼는 마지막 보이스가 그 안에 믹싱되고 믹스 버퍼의 마지막 출력이 이후 SHAPE 블록에 의해 소비될 때까지 잠깁니다.
일반적인 시나리오에서 - 모든 SHAPE 보이스가 믹싱되는 단일 7.1 마스터링 보이스에서 - 128 보이스 중 8개가 프레임 내내 잠깁니다. 플로우그래프 종속성 체인이 있는 광범위한 다채널 서브믹싱이 있다면 추가 믹스 버퍼가 프레임의 상당 부분 동안 잠길 수 있으며(가상 믹스 버퍼의 용량 감소), 예를 들어 4인 플레이어 타이틀에 대해 메인 스피커와 플레이어별 7.1 헤드셋 믹스를 모두 만든다면 40개의 동시 믹스 버퍼를 소비할 수 있는 추가 마스터링 보이스가 생성됩니다.
일반적으로 128개 이상의 동시 물리 믹스 버퍼가 필요한 사례는 병리적입니다. 그러나 전체 프레임 동안 불필요하게 잠긴 믹스 버퍼는 타이틀이 잠재적 처리량을 달성할 수 있는 능력을 감소시킵니다. 그림 2는 특정 시간에 사용 가능한 믹스 버퍼 수를 줄일 수 있는 불필요한 서브믹싱을 나타냅니다.
명령 순서(그림 2)에 따라, 5개의 별도 7.1 마스터링 믹스 버퍼는 거의 전체 프레임 동안 잠길 수 있으며 이는 128개 물리 믹스 버퍼 중 40개에 해당합니다. 이 경로에는 한 번에 다른 2개의 믹스 버퍼만 사용해야 하지만 - 즉 FLT/VOL 또는 EQ/CMP에 대한 쌍으로 된 입력과 출력 - 스피커로 가는 모든 믹스 버퍼를 먼저 처리하는 것을 고려하십시오. 그런 다음 그 믹스 버퍼를 해제하고 헤드셋 1, 2 등을 처리할 수 있습니다.
그림 2. 잘못된 명령 순서로 인한 할당된 믹스 버퍼 인스턴스의 불필요한 서브믹싱 및 잠금을 보여주는 플로우그래프.
SHAPE 구성요소 선택 및 밸런싱 (FLT/VOL 대 EQ/CMP)
동일한 SHAPE 구성요소를 순서대로 반복해서 사용하면 최대 처리량에 도달할 수 있는 능력을 감소시킬 수 있습니다. 반면, 다른 구성요소를 번갈아 사용함으로써 각 SHAPE 블록이 의미 있는 병렬 처리를 수행하도록 할 수 있습니다. 그림 3은 일반적인 예시를 보여줍니다: FLT/VOL은 모두 병렬로 처리될 수 없습니다. 성능이 저하될 수 있습니다. 그림 3. 모든 FLT/VOL을 병렬로 처리하려는 시도를 보여주는 플로우그래프. 두 번째 FLT/VOL 세트는 첫 번째 세트가 완료될 때까지 기다려야 하며, 그 동안 다른 SHAPE 블록은 사용되지 않을 수 있습니다. 어느 세트가 필터링에만 독점적으로 사용된다면 EQ/CMP가 한 세트에 더 나은 선택일 수 있습니다. 특히 동일한 구성으로 된 플로우그래프(그림 4)에 더 많은 보이스가 있는 경우에 그렇습니다. 그러면 첫 번째 세트가 EQ/CMP 블록을 처리하는 동안 이들이 FLT/VOL을 시작할 수 있습니다. 그림 4는 이상적인 SHAPE 기능에 더 가까운 성능을 보여줍니다. 이 플로우그래프는 필터링에만 사용되는 것으로 추정되는 하나의 FLT/VOL 세트(그림 3 참고)를 EQ/CMP로 대체하여 두 SHAPE 구성요소의 병렬 처리를 가능하게 합니다. 그림 4. FLT/VOL 및 EQ/CMP를 병렬로 처리하려는 시도를 보여주는 플로우그래프. SHAPE 구성요소의 밸런싱은 다양한 구성요소의 최대 인스턴싱을 고려할 때도 관련이 있습니다. 프레임 내에서 발생할 수 있는 2560개의 FLT/VOL 구성요소는 FLT/VOL 하드웨어가 512개의 EQ/CMP 블록으로 가능한 것보다 약 5배 더 많은 계산을 실행할 수 있게 합니다. 단일 FLT/VOL과 직렬로 EQ/CMP 블록을 실행하면, EQ/CMP와 결합된 여러 FLT/VOL 구성요소를 실행하는 것보다 성능이 낮아지는데, 이는 전자의 처리가 후자의 소비에 의해 게이트되기 때문입니다.지나치게 많거나 빈번한 저가치 DMA 왕복
DMA는 SHAPE 버스에 대해 사용 가능한 읽기/쓰기 대역폭에 의해 제한됩니다. 사용 가능한 대역폭을 모두 소비하면 - 이 시나리오는 일반적으로 병리적이지만 - DMA 블록이 stall되고 처리량이 감소합니다. 앞서 논의한 바와 같이, DMA 입력 블록 이후에 발생하는 모든 처리는 DMA가 완료될 때까지 기다려야 합니다. 따라서 플로우그래프의 대부분이 차단된 상태로 DMA가 완료되기를 기다린 다음에야 플로우그래프가 처리를 시작할 수 있는 플로우그래프를 만들 수 있습니다. 또한 DMA 왕복이 오디오 스트림에 제공하는 가치와 관련하여 이를 평가해야 합니다. 지연이 최소한으로 추가되는 것(오디오 프레임의 2.667ms 크기의 배수로 DMA를 통해 액세스되는 프레임 수의 관점에서 제어할 수 있음)은 대부분의 오디오 재생 시나리오에서 문제가 되지 않을 수 있습니다. 이는 DMA 오른쪽의 블록이 이전 프레임의 오디오 데이터를 처리하기 때문입니다. 특히, 최종 믹스도 오디오 엔드포인트에 표시하기 위해 DMA로 메모리에 다시 보낼 계획이라면, 최종 믹스를 수행하기 위해 SHAPE로 DMA를 다시 보내는 것은 불필요할 수 있습니다. 그림 5는 잠재적으로 낮은 가치의 예를 보여줍니다. CPU/GPU 처리를 위해 DMA를 통해 메모리로 전송된 보이스가 SHAPE로 다시 가져와지고, 마스터링 믹스로 7.1 패닝됩니다. 그런 다음 보이스는 DMA를 통해 메모리로 다시 전송됩니다. 그림 5는 FLT/VOL 블록의 보이스에 필터링이 적용되지 않는다고 가정하며, 7.1 마스터링 믹스 버퍼로 추가 보이스가 라우팅됨을 전제로 합니다. 그림 5. 불필요한 FLT/VOL 구성요소와 불필요한 DMA 왕복이 있는 잠재적 저가치 라우팅을 보여주는 플로우그래프. 그림 6은 그림 5의 의도를 잠재적으로 더 최적으로 라우팅한 것을 보여줍니다. 보이스는 CPU/GPU 처리를 위해 DMA를 통해 메모리로 전송됩니다. 그런 다음 보이스는 7.1 패닝될 수 있고 추가 DMA, 추가 오디오 프레임 지연, 또는 7개의 FLT/VOL 구성요소 사용의 오버헤드 없이 CPU 자체에서 나머지 7.1 믹스와 결합될 수 있습니다. 그림 6. 추가 DMA 왕복이나 불필요한 FLT/VOL 구성요소 없이 더 최적의 라우팅을 보여주는 플로우그래프. 프로세스에서 DMA를 제거할 때 너무 많이 제거하지 않도록 하십시오. 다음과 같은 경우 왕복 DMA를 사용하는 것이 정당화될 수 있습니다:- 특정 보이스에 대해 상당한 양의 추가 SHAPE 처리를 수행하려는 경우.
- 믹스 버퍼가 제공하는 하드웨어 미터링 및 클리핑 감지를 활용하려는 경우.
SHAPE 플로우그래프 계획 및 검토
구현 전 연습으로, 프레임 내에서 예상되는 보이스 사용의 플로우그래프를 사운드 효과 및 음악의 동시 스트림 수와 같은 관점에서 분류 및 정량화된 보이스와 함께 시각적으로 표현하십시오. 이 정보를 시각적으로 캡처하면 앞서 논의한 성능 위험 중 일부를 피하는 방법을 이해하는 데 도움이 될 수 있습니다. 다음은 이러한 플로우그래프에서 도출할 수 있는 주요 지표 중 일부입니다.-
동시 및 전체 프레임 내 각 SHAPE 구성요소의 최대 수:
- 이 플로우그래프가 이론적 최고치보다 충분히 낮은지 확인하십시오.
- 구성요소의 저사용 및 과사용에 유의하십시오. 필요에 따라 구성요소의 밸런스를 재조정하십시오.
- 플로우그래프 대부분에서 너무 많은 믹스 버퍼가 잠긴 상태로 있어야 한다면 믹스 버퍼 사용을 재구성하는 것을 고려하십시오.
-
SHAPE를 통한 3D 포지셔닝 구현 계획:
- 모든 보이스가 7.1 패닝될 것인가, 아니면 가장 가까운 2개 또는 n 개의 스피커 간에 패닝될 것인가?
- 모든 7.1 패닝을 SHAPE에서 수행해야 하는가, 아니면 이미 DMA를 통해 CPU로 전송된 보이스는 CPU 자체에서 패닝하는 것이 가장 좋은가?
- 메모리와의 DMA 전환 수 및 이러한 전환의 비대칭 여부. 예를 들어, 일부 보이스는 다른 보이스보다 SHAPE에 더 많이 쓰이고 나오는데, 이는 추가적인 지연이 있을 가능성이 있음을 의미합니다.
영구적 대 비영구적 플로우그래프
플로우그래프를 영구적 또는 비영구적으로 처리되도록 제출할 수 있습니다. 영구적 플로우그래프는 처리한 후 상주 상태로 남아 있으며, 읽기 및 쓰기 포인터가 진행되고 다른 컨텍스트 정보가 업데이트된 후 다음 프레임에서 처리를 반복합니다. 다음 시나리오 중 하나에 대해 영구적 플로우그래프를 사용하십시오.- 매우 복잡한 플로우그래프: 각 프레임을 재조립하는 데 상당한 양의 CPU 처리가 필요한 플로우그래프
- 매우 정적인 플로우그래프: 오랜 기간 동안 동일한 보이스 수와 구성을 유지하는 플로우그래프
- 보이스 토폴로지가 자주 변경됩니다.
- 타이틀의 오디오 소프트웨어 엔진의 처리 케이던스가 SHAPE 하드웨어에서 분리되어 있습니다. 즉, 2.667ms의 배수가 아닙니다.
- 실시간보다 빠른 시나리오에서 오디오 처리를 실행하려고 합니다. 즉, 가능해질 때마다 소비되도록 그래프를 제출할 때입니다.
SHAPE 이슈 디버깅
플로우그래프를 개발할 때, 문제 디버깅에 도움이 되는 메시지에 등록하는 것을 권장합니다. 특히 IAcpHal::Connect 메서드의NumMessages 매개변수를 사용하십시오.
메시징 시스템은 잘못된 플로우그래프(ACP_FLOWGRAPH_TERMINATED_REASON_INVALID_GRAPH 등), 차단된 명령, 하드웨어 프레임 크기인 2.667ms가 허용하는 것보다 더 많은 처리를 수행하려는 시도로 인해 발생한 프레임 아웃과 같은 다양한 문제에 대한 풍부한 피드백을 제공합니다.
이 방식은 디버깅에 도움이 됩니다. 그러나 타이틀을 출시하기 전에 다음을 수행하도록 하십시오:
- 런타임 시나리오에서 모든 오류 표시 메시지를 제거합니다.
- 각 제출된 플로우그래프에 대해
ACP_MESSAGE_TYPE_FLOWGRAPH_COMPLETED메시지(ACP_MESSAGE_TYPE 열거형 참고)를 검사하여 플로우그래프 처리가 일관되게 성공하는지 확인합니다.
놓친 메시지
ACP 메시지를 사용하여 엔진 상태를 구동하는 경우 그리고 많은 수의 메시지를 처리하는 경우, 개발 중에ACP_MESSAGE::droppedMessageCount를 검사해야 합니다. 0이 아닌 값은 메시지 큐가 가득 차서 메시지를 버려야 했음을 나타냅니다. 이 값이 발생하면 큐를 더 빠르게 서비스하고 더 크게 만드는 것을 고려하십시오.
프레임 아웃
개발 중에는 과잉 예산, 최적이 아닌 플로우그래프 및 기타 이유로 인해 오디오 프레임(2.667ms)의 끝이 도래하기 전에 플로우그래프가 완료되지 않을 수 있습니다. 이 미완성 플로우그래프는 영구적 플로우그래프에 대해ACP_FLOWGRAPH_TERMINATED_TIME_EXCEEDED 메시지를 발생시킵니다. 그것들은 불완전한 상태가 됩니다. 반면, 비영구적 플로우그래프는 이러한 방식으로 제약을 받지 않으며 프레임을 넘나들며 완료될 때까지 실행됩니다.
차단된 명령
SRC 및 DMA 명령은 다음 표에 나타난 여러 시나리오에서 차단됨(ACP_MESSAGE_TYPE_SRC_BLOCKED 및 ACP_MESSAGE_TYPE_DMA_BLOCKED, ACP_MESSAGE_TYPE 열거형 참고)으로 보고될 수 있습니다.
명령이 차단된 것으로 확인되면 - 이는 항목이 처리를 위해 SHAPE 큐에 추가되기 전과 런타임에 모두 발생할 수 있음 - 명령이 그래프에서 축출됩니다. 이는 오디오 드롭으로 이어질 수 있습니다. 개발 중에는 플로우그래프 처리 개선의 첫 번째 지점으로 차단된 명령을 사용하십시오. 출시 전에 타이틀은 명령 차단도 방지해야 합니다.
오디오 버퍼가 충분히 크고 버퍼 크기와 관련된 정기적인 간격으로 데이터가 스트리밍되도록 하여 DMA 명령의 차단을 방지할 수 있습니다. 예를 들어 한 번에 4개의 하드웨어 프레임을 스트리밍하는 경우, 하드웨어가 타이틀의 읽기 포인터보다 앞서 쓸 수 있도록 해당 프레임의 배수 - 적어도 8에서 더블 버퍼링 - 가 버퍼에 있도록 하십시오. 대신, 다음 플로우그래프를 제출하기 전에 소비하고 DMA 읽기 포인터를 업데이트한 다음 플로우그래프를 제출하여 버퍼 비우기를 강제할 수 있습니다.
SRC 명령에는 다음 세 가지 모드가 있습니다(ShapeSrcContext.h에 상세히 설명됨).
-
SHAPE_SRC_COMMAND_TYPE_START플로우그래프의 거의 모든 SRC 명령에 사용하십시오. 정상적으로 처리하고 현재 플로우그래프에 이어 더 많은 오디오 데이터가 있을 것으로 예상하십시오. -
SHAPE_SRC_COMMAND_TYPE_STOP_IMMEDIATE소스 XMA 또는 PCM 데이터 처리를 즉시 중지하는 데 사용하십시오. SRC는 이 프레임에 대해 0으로 채워진 버퍼를 출력합니다. -
SHAPE_SRC_COMMAND_TYPE_STOP_END보이스의 마지막 패킷을 나타내는 데 사용하십시오.STOP_END나STOP_IMMEDIATE로 제출되지 않으면 SRC 명령이 완료되지 않습니다. 이는 활성 플로우그래프를 stall시킵니다. 영구적 플로우그래프는 오디오 프레임 끝에서 종료되고, 비영구적 플로우그래프는 절대 완료되지 않습니다.
