Android 4.1 버전에서는 지연 시간이 낮은 오디오 출력 경로를 위한 내부 프레임워크 변경사항이 도입되었습니다. 전에는 최소의 공용 클라이언트 API 또는 HAL API 변경사항이 있었습니다. 이 문서에서는 점차적으로 계속적인 진화를 거듭한 초기 설계에 대해 설명합니다. 이 설계를 제대로 이해하면 기기 OEM 및 SoC 공급업체에서 특정 기기 및 칩셋에 대해 올바르게 설계를 구현하는 데 도움이 될 수 있습니다. 이 문서는 애플리케이션 개발자를 대상으로 하지 않습니다.
트랙 생성
클라이언트는 AudioTrack C++ 구성자의 audio_output_flags_t
또는 AudioTrack::set()
에서 비트 AUDIO_OUTPUT_FLAG_FAST
를 선택적으로 설정할 수 있습니다. 현재 이렇게 설정된 유일한 클라이언트는 다음과 같습니다.
- OpenSL ES 또는 AAudio 기반의 Android 네이티브 오디오
- android.media.SoundPool
- android.media.ToneGenerator
AudioTrack C++ 구현은 AUDIO_OUTPUT_FLAG_FAST
를 검토하며, 클라이언트 수준에서 선택적으로 요청을 거부할 수 있습니다. 요청을 전달하기로 결정한 경우에는 IAudioTrack
팩토리 메서드 IAudioFlinger::createTrack()
의 매개변수인 track_flags_t
의 TRACK_FAST
비트를 사용합니다.
AudioFlinger 오디오 서버에서 TRACK_FAST
요청을 검토하며, 서버 수준에서 선택적으로 요청을 거부할 수 있습니다. 또한 공유된 메모리 제어 블록의 비트 CBLK_FAST
를 통해 요청이 수락되었는지 클라이언트에 알립니다.
결정에 영향을 미치는 요인은 다음과 같습니다.
- 이 출력의 빠른 믹서 스레드 존재 여부(아래 참조)
- 트랙 표본화율
- 이 트랙의 콜백 핸들러 실행을 위한 클라이언트 스레드 존재 여부
- 트랙 버퍼 크기
- 가용한 패스트 트랙 슬롯(아래 참조)
클라리언트 요청이 수락된 경우 이를 '패스트 트랙'이라고 부르며, 수락되지 않은 경우에는 '일반 트랙'이라고 부릅니다.
믹서 스레드
AudioFlinger는 일반 믹서 스레드 생성 시점에 빠른 믹서 스레드도 함께 생성할지 결정합니다. 일반 믹서와 빠른 믹서 모두 특정 트랙과 연결되지 않으며, 오히려 트랙 집합과 연결됩니다. 항상 일반 믹서 스레드가 있습니다. 빠른 믹서는 일반 믹서 스레드에 종속되며(존재하는 경우), 일반 믹서 스레드의 제어 하에서 작동합니다.
빠른 믹서
기능
빠른 믹서 스레드는 다음과 같은 기능을 제공합니다.
- 일반 믹서의 하위 믹스와 최대 7개의 클라이언트 패스트 트랙을 믹싱
- 트랙별 감쇠
생략된 기능:
- 트랙별 표본화율 변환
- 트랙별 효과
- 믹스별 효과
기간
패스트 믹서는 주기적으로 실행되며, 스케줄링 안정성이 필요한 경우에는 2~3밀리초 또는 5밀리초보다 약간 높은 기간이 권장됩니다. 이 수치는 온전한 버퍼 파이프라인을 고려했을 때 총 지연 시간이 대략 10ms이도록 선택됩니다. 더 작은 값도 가능하지만 전력 소비가 증가할 수 있으며 CPU 스케줄링 예측성에 따라 문제가 발생할 확률도 있습니다. 최대 20ms의 더 큰 값도 가능하지만 총 지연 시간이 저하될 수 있으므로 피하는 것이 좋습니다.
일정 예약
패스트 믹서는 격상된 SCHED_FIFO
우선순위에서 실행됩니다. 아주 약간의 CPU 시간이 필요할 수는 있지만 자주 실행되어야 하며 스케줄링 잡음이 낮아야 합니다.
잡음은 주기 시간의 편차를 나타내며, 실제 주기 시간과 예상 주기 시간 간의 차이입니다.
너무 늦게 실행하면 언더런으로 인한 문제로 이어질 수 있습니다. 너무 일찍 실행하면 트랙이 데이터를 제공하기 전에 패스트 트랙을 중단함으로 인한 문제로 이어질 수 있습니다.
차단
HAL write()
외에는 패스트 믹서 스레드가 아무 것도 차단하지 않는 것이 좋습니다. 패스트 믹서 내에서 다른 차단이 발생할 경우 버그로 간주됩니다. 특히 mutexes는 피하는 것이 좋습니다.
대신 비차단 알고리즘(잠김 방지 알고리즘)이 사용됩니다.
이 주제에 대한 자세한 내용은 우선순위 역전 회피를 참조하세요.
다른 구성요소에 대한 관계
패스트 믹서는 클라이언트와 직접적으로 상호작용하는 경우가 거의 없습니다. 특히 바인더 수준의 작업은 확인하지 않지만 클라이언트의 공유된 메모리 제어 블록에는 액세스합니다.
패스트 믹서는 상태 대기열을 통해 일반 믹서에서 명령어를 수신합니다.
트랙 데이터를 가져오는 경우 외에는 클라이언트와의 상호작용이 일반 믹서를 통해 이루어집니다.
패스트 믹서의 기본 싱크는 오디오 HAL입니다.
일반 믹서
기능
모든 기능이 사용 설정됨:
- 최대 32개 트랙
- 트랙별 감쇠
- 트랙별 표본화율 변환
- 효과 처리
기간
기간은 >= 20ms인 패스트 믹서 기간의 첫 번째 중적분으로 계산됩니다.
스케줄링
일반 믹서는 격상된 SCHED_OTHER
우선순위에서 실행됩니다.
차단
일반 믹서는 차단이 허용되지만 다양한 mutexes와 하위 믹스 작성을 위한 차단 파이프에서 차단하는 경우가 많습니다.
다른 구성요소에 대한 관계
일반 믹서는 바인더 스레드, 오디오 정책 관리자, 패스트 믹서 스레드 및 클라이언트 트랙을 비롯한 외부 환경과 광범위하게 상호작용합니다.
일반 믹서의 싱크는 패스트 믹서의 트랙 0에 대한 차단 파이프입니다.
플래그
AUDIO_OUTPUT_FLAG_FAST
비트는 힌트입니다. 요청이 이행된다는 보장은 없습니다.
AUDIO_OUTPUT_FLAG_FAST
는 클라이언트 수준 개념입니다. 서버에는 표시되지 않습니다.
TRACK_FAST
는 클라이언트 -> 서버 개념입니다.