오디오 정책 구성

Android 10 출시에는 오디오 정책 관리자의 중요한 리팩터링이 포함되어 복잡한 자동차 사용 사례를 더 유연하게 지원할 수 있습니다.

  • OEM별 라우팅 전략
  • 동일한 볼륨 곡선을 사용하는 기존 스트림 유형 그룹을 맞춤설정할 수 있는 볼륨 그룹
  • 하드 코딩되는 대신 오디오 정책 엔진에 의해 선언되는 라우팅 전략
  • 오디오 정책 엔진에서 관리하는 볼륨 곡선 및 그룹
  • 일반 코드와 구성 가능한 코드 간의 향후 분할에 대비하고 더 풍부한 오디오 기기 관리 기능을 제공하는 내부 리팩터링. 예를 들어 정책 규칙에서 유형에 국한되지 않고 모든 기기 속성을 사용합니다.

Android 7.0에는 오디오 토폴로지를 설명하기 위한 오디오 정책 구성 파일 형식(XML)이 도입되었습니다.

이전 Android 출시에서는 device/<company>/<device>/audio/audio_policy.conf를 사용하여 제품의 오디오 기기를 선언해야 했습니다(device/samsung/tuna/audio/audio_policy.conf에서 Galaxy Nexus 오디오 하드웨어에 관한 이 파일의 예시 확인 가능). 그러나 CONF는 단순하고 배타적이어서 텔레비전 및 자동차와 같은 카테고리의 복잡한 토폴로지를 설명하기에는 너무 제한적인 형식입니다.

Android 7.0에서는 audio_policy.conf를 지원 중단하고 사람이 더 쉽게 읽을 수 있고, 광범위한 편집 및 파싱 도구를 제공하며, 복잡한 오디오 토폴로지를 유연하게 설명할 수 있는 XML 파일 형식을 사용하여 오디오 토폴로지를 정의하는 지원을 추가했습니다. Android 7.0에서는 구성 파일의 XML 형식을 선택하는 데 USE_XML_AUDIO_POLICY_CONF 빌드 플래그를 사용합니다.

XML 형식의 이점

XML 파일은 CONF 파일에서처럼 출력 및 입력 스트림 프로필의 개수와 유형, 재생 및 캡처에 사용할 수 있는 기기, 오디오 속성을 정의할 수 있습니다. 또한 XML 형식은 다음과 같은 향상된 기능을 제공합니다.

  • Android 10에서는 둘 이상의 활성 녹음 앱을 동시에 사용할 수 있습니다.
    • 녹음을 시작하더라도 동시 실행으로 인해 거부되는 상황이 발생하지 않습니다.
    • registerAudioRecordingCallback(AudioManager.AudioRecordingCallback cb) 콜백은 캡처 경로 변경을 클라이언트에 알립니다.
  • 다음 상황에서는 클라이언트가 무음 오디오 샘플을 가져옵니다.
    • 개인 정보 보호에 민감한 사용 사례(예: VOICE_COMMUNICATION)가 활성 상태입니다.
    • 클라이언트에 포그라운드 서비스 또는 포그라운드 UI가 없습니다.
    • 특수 역할은 정책에 의해 다음과 같이 인식됩니다.
      • 접근성 서비스: 개인 정보 보호에 민감한 사용 사례가 활성 상태인 경우에도 녹음할 수 있습니다.
      • 어시스턴트: UI가 맨 위에 있으면 개인 정보 보호에 민감한 사용 사례로 고려합니다.
  • 오디오 프로필은 HDMI 단순 오디오 설명어와 비슷한 구조로, 각 오디오 형식에 다양한 샘플링 레이트/채널 마스크 집합을 사용할 수 있습니다.
  • 기기와 스트림 간의 가능한 모든 연결에 관한 명시적인 정의가 있습니다. 이전에는 암시적 규칙으로 동일한 HAL 모듈에 연결된 모든 기기를 연결하여 오디오 정책이 오디오 패치 API에서 요청한 연결을 제어하지 못하도록 할 수 있었습니다. XML 형식에서 토폴로지 설명은 연결 제한을 정의합니다.
  • include를 지원하여 표준 A2DP, USB 또는 경로 변경 제출 정의의 반복을 방지합니다.
  • 볼륨 곡선을 맞춤설정할 수 있습니다. 이전에는 볼륨 테이블이 하드 코딩되었습니다. XML 형식에서 볼륨 테이블이 설명되며 맟춤설정될 수 있습니다.

frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml의 템플릿은 사용 중인 이러한 다수의 기능을 보여 줍니다.

파일 형식 및 위치

새 오디오 정책 구성 파일은 audio_policy_configuration.xml이며 /system/etc에 있습니다. 다음 예는 Android 12와 Android 12 미만 버전의 XML 파일 형식으로 된 간단한 오디오 정책 구성을 보여줍니다.

최상위 수준 구조에는 각 오디오 HAL 하드웨어 모듈에 상응하는 모듈이 포함되어 있으며, 각 모듈에는 믹스 포트, 기기 포트, 경로의 목록이 있습니다.

  • 믹스 포트는 재생 및 캡처를 위해 오디오 HAL에서 열 수 있는 스트림의 가능한 구성 프로필을 설명합니다.
  • 기기 포트는 기기 유형(및 관련된 경우 선택적으로 주소 및 오디오 속성)에 연결할 수 있는 기기를 설명합니다.
  • 경로는 믹스 포트 설명어에서 분리되어 기기 간 경로 또는 스트림에서 기기까지 경로를 설명할 수 있습니다.

볼륨 테이블은 UI 색인에서 dB 단위의 볼륨으로 변환하는 데 사용되는 곡선을 정의하는 간단한 점 목록입니다. 별도의 include 파일이 기본 곡선을 제공하지만, 특정 사용 사례 및 기기 카테고리의 각 곡선을 덮어쓸 수 있습니다.

파일 포함

XML Inclusion(XInclude) 메서드를 사용하여 다른 XML 파일에 있는 오디오 정책 구성 정보를 포함할 수 있습니다. 포함된 모든 파일은 위에 설명된 구조를 따라야 하며 다음과 같은 제한사항이 적용됩니다.

  • 파일에는 최상위 수준 요소만 포함될 수 있습니다.
  • 파일에는 XInclude 요소가 포함될 수 없습니다.

include를 사용하면 AOSP(Android 오픈소스 프로젝트) 오디오 HAL 모듈 구성 정보를 모든 오디오 정책 구성 파일에 복사하지 않아도 됩니다(이 방식은 오류가 발생하기 쉬움). 표준 오디오 정책 구성 XML 파일은 다음 오디오 HAL에 제공됩니다.

  • A2DP: a2dp_audio_policy_configuration.xml
  • 하위 믹스 경로 변경: rsubmix_audio_policy_configuration.xml
  • USB: usb_audio_policy_configuration.xml

오디오 정책 코드 조직

AudioPolicyManager.cpp는 여러 모듈로 분할되어 유지 및 구성이 용이합니다. frameworks/av/services/audiopolicy의 조직에는 다음 모듈이 포함됩니다.

모듈 설명
/managerdefault 모든 앱에 공통된 일반 인터페이스 및 동작 구현을 포함합니다. 엔진 기능 및 추상화된 일반적인 개념에서 AudioPolicyManager.cpp와 유사합니다.
/common 기본 클래스를 정의합니다(예: 입출력 오디오 스트림 프로필, 오디오 기기 설명어, 오디오 패치, 오디오 포트의 데이터 구조). 이는 이전에 AudioPolicyManager.cpp 내부에서 정의되었습니다.
/engine

특정 사용 사례에 사용해야 할 기기와 볼륨을 정의하는 규칙을 구현합니다. 이는 지정된 재생 또는 캡처 사용 사례에 적합한 기기를 가져오거나, 연결된 기기 또는 라우팅 결정을 변경할 수 있는 외부 상태(강제 사용 호출 상태)를 설정하는 것과 같이 일반적인 부분으로 표준 인터페이스를 구현합니다.

구성 가능기본의 두 가지 버전으로 제공됩니다. 버전 선택 방법에 관한 자세한 내용은 매개변수 프레임워크를 사용하는 구성을 참고하세요.

/engineconfigurable 매개변수 프레임워크에 의존하는 정책 엔진 구현입니다(아래 참조). 구성은 매개변수 프레임워크 및 정책이 XML 파일에서 정의되는 위치를 기반으로 합니다.
/enginedefault 이전 Android 오디오 정책 관리자 구현을 기반으로 하는 정책 엔진 구현입니다. 이는 기본값이며 Nexus 및 AOSP 구현에 상응하는 하드 코딩 규칙을 포함합니다.
/service 나머지 프레임워크에 대한 인터페이스를 사용하는 바인더 인터페이스, 스레딩, 잠금 구현을 포함합니다.

매개변수 프레임워크를 사용하는 구성

오디오 정책 코드는 구성 파일에서 완전히 정의된 오디오 정책을 지원하는 동시에 이해하고 유지하기 쉽게 구성되어 있습니다. 조직 및 오디오 정책 설계는 매개변수 처리를 위한 플러그인 기반 및 규칙 기반 프레임워크인 Intel의 매개변수 프레임워크를 기반으로 합니다.

구성 가능한 오디오 정책을 사용하면 공급업체 OEM은 다음과 같은 작업을 처리할 수 있습니다.

  • XML에서 시스템의 구조와 매개변수를 설명합니다.
  • 설명된 매개변수에 액세스하기 위해 백엔드(플러그인)를 C++로 작성하거나 재사용합니다.
  • 특정 매개변수가 특정 값을 가져야하는 조건/규칙을 XML 또는 도메인별 언어로 정의합니다.

AOSP에는 Frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml에서 매개변수 프레임워크를 사용하는 오디오 정책 구성 파일의 예시가 포함됩니다. 자세한 내용은 매개변수 프레임워크에 관한 Intel 문서를 참조하세요.

Android 10 이하에서는 빌드 옵션 USE_CONFIGURABLE_AUDIO_POLICY를 사용하여 구성 가능한 오디오 정책이 선택됩니다. Android 11 이상에서 오디오 정책 엔진 버전은 audio_policy_configuration.xml 파일에서 선택됩니다. 구성 가능한 오디오 정책 엔진을 선택하려면 다음 예와 같이 globalConfiguration 요소의 engine_library 속성 값을 configurable로 설정합니다.

<audioPolicyConfiguration>
    <globalConfiguration engine_library="configurable" />
...
</audioPolicyConfiguration>

오디오 정책 라우팅 API

Android 6.0에서는 오디오 패치/오디오 포트 인프라를 기반으로 하는 공개 Enumeration 및 Selection API를 도입했으며, 개발자가 연결된 오디오 레코드 또는 트랙을 위한 특정 기기 출력 및 입력의 환경설정을 지정할 수 있습니다.

Android 7.0에서는 Enumeration 및 Selection API가 CTS 테스트의 검증을 거쳤으며, 네이티브 C/C++(OpenSL ES) 오디오 스트림 라우팅을 포함하도록 확장됩니다. 네이티브 스트림의 라우팅은 AudioTrackAudioRecord 클래스에 관련된 명시적인 라우팅 메서드를 대체하고, 결합하고, 지원 중단하는 AudioRouting 인터페이스가 추가되어 자바에서 계속 처리됩니다.

Enumeration 및 Selection API에 관한 자세한 내용은 Android 구성 인터페이스OpenSLES_AndroidConfiguration.h를 참조하세요. 오디오 라우팅에 관한 자세한 내용은 AudioRouting을 참조하세요.

다중 채널 지원

하드웨어 및 드라이버가 HDMI를 통해 다중 채널 오디오를 지원하는 경우 오디오 스트림을 오디오 하드웨어로 직접 출력할 수 있습니다. 이는 AudioFlinger 믹서를 우회하므로 두 채널로 다운믹스되지 않습니다. 오디오 HAL은 출력 스트림 프로필이 다중 채널 오디오 기능을 지원하는지 여부를 노출해야 합니다. HAL이 기능을 노출하는 경우 기본 정책 관리자는 HDMI를 통한 다중 채널 재생을 허용합니다. 구현 세부정보는 device/samsung/tuna/audio/audio_hw.c를 참조하세요.

제품에 다중 채널 오디오 출력이 포함되도록 지정하려면 제품의 다중 채널 출력을 설명하도록 오디오 정책 구성 파일을 수정합니다. frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml의 다음 예시는 동적 채널 마스크를 보여 줍니다. 즉, 연결 후 오디오 정책 관리자가 HDMI 싱크에서 지원하는 채널 마스크를 쿼리합니다.

AUDIO_CHANNEL_OUT_5POINT1과 같은 정적 채널 마스크를 지정할 수도 있습니다. AudioFlinger의 믹서는 다중 채널 오디오를 지원하지 않는 오디오 기기로 콘텐츠를 전송할 때 자동으로 스테레오로 다운믹스합니다.

미디어 코덱

하드웨어 및 드라이버에서 지원하는 오디오 코덱이 제품에 맞게 올바르게 선언되도록 합니다. 자세한 내용은 프레임워크에 코덱 노출을 참조하세요.