다중 영역 개요

자동차에는 플랫폼과 상호작용하면서 별개의 미디어를 사용하려는 동시 사용자에 맞춘 새로운 사용 사례가 있기 마련입니다. 예를 들어 운전자는 앞좌석에서 음악을 재생하고 뒷좌석의 승객은 후면 디스플레이에서 YouTube 동영상을 시청할 수 있습니다. 다중 영역 오디오에서 이 작업이 가능한 이유는 서로 다른 오디오 소스를 차량의 다른 영역을 통해 동시에 재생할 수 있기 때문입니다.

Android 10의 다중 영역 오디오에서는 OEM이 오디오를 별도의 영역에 구성할 수 있습니다. 각 영역은 차량 내에서 자체 볼륨 그룹과 컨텍스트를 위한 라우팅 구성 및 포커스 관리 기능을 가진 기기 모음입니다. 이 방식으로 기본 앞좌석을 하나의 오디오 영역으로 구성하면서 후면 디스플레이의 헤드폰 잭을 두 번째 영역으로 구성할 수 있습니다.

영역은 car_audio_configuration.xml의 일부로 정의됩니다. 그러면 CarAudioService가 구성을 읽어오고 연결된 영역을 토대로 오디오 스트림을 라우팅하도록 AudioService를 지원합니다. 각 영역은 계속해서 컨텍스트 및 애플리케이션 uid를 기준으로 라우팅 규칙을 정의합니다. 플레이어가 생성되면 CarAudioService는 플레이어가 연결된 영역을 확인한 다음 사용 방식에 따라 AudioFlinger가 오디오를 라우팅해야 하는 기기를 결정합니다.

또한 각 오디오 영역의 포커스는 개별적으로 관리됩니다. 이를 통해 서로 다른 영역에 있는 애플리케이션이 서로 간섭하지 않으며 개별적으로 오디오를 생성할 수 있고, 이와 동시에 애플리케이션이 영역 내 포커스의 변화를 계속해서 따를 수 있습니다. CarAudioService 내 CarZonesAudioFocus가 각 영역의 포커스 관리를 담당합니다.

다중 영역 오디오 구성

그림 1. 다중 영역 오디오 구성

다중 영역 구성

Android 10에서는 car_audio_configuration.xmlcar_volumes_groups.xmlIAudioControl.getBusForContext를 대체합니다. 새 구성 파일에 영역 목록이 정의되어 있습니다. 각 영역에는 연결된 기기가 있는 하나 이상의 볼륨 그룹이 있으며 각 기기에는 해당 영역 내에서 라우팅해야 하는 컨텍스트가 있습니다. 모든 컨텍스트는 각 영역 내에 표시되어야 합니다.

공급업체 파티션에 있는 audio_policy는 보드의 오디오 하드웨어 구성을 나타냅니다. car_audio_configuration.xml에 참조된 모든 기기는 audio_policy_configuration.xml 내에 정의됩니다.

다중 영역 지원 사용 설정

다중 영역 오디오가 있는 경우 audioUseDynamicRouting 플래그를 true로 설정해야 합니다.

<resources>
    <bool name="audioUseDynamicRouting">true</bool>
</resources>

false인 경우 CarAudioService는 car_volumes_groups.xmlIAudioControl.getBusForContext를 사용하도록 다시 설정됩니다. HAL 레이어에는 필요한 변경이 없지만 car_audio_configuration.xml 파일을 통해 기기와 컨텍스트 간의 관계가 정의되므로 Android 10에는 IAudioControl.getBusForContext가 지원 중단되었습니다.

기본 영역

기본 영역은 기본적으로 모든 오디오가 라우트되는 공간입니다. 기본 영역은 하나만 있을 수 있으며 구성에서 isPrimary="true" 속성으로 표시됩니다. 기본 영역이 지정되지 않으면 시스템은 기본적으로 목록의 첫 번째 영역을 추천합니다.

샘플 구성

앞에서 정의된 사용 사례 예의 경우 차량에는 2개의 영역(기본 영역과 뒷좌석 시트 엔터테인먼트 시스템)이 필요합니다. 이 점을 고려하면 가능한 car_audio_configuration.xml은 다음과 같이 정의됩니다.

<audioZoneConfiguration version="1.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                   </device>
                   <device address="bus3_call_ring_out">
                       <context context="call_ring"/>
                   </device>
                   <device address="bus6_notification_out">
                       <context context="notification"/>
                   </device>
                   <device address="bus7_system_sound_out">
                       <context context="system_sound"/>
                   </device>
               </group>
               <group>
                   <device address="bus1_navigation_out">
                       <context context="navigation"/>
                   </device>
                   <device address="bus2_voice_command_out">
                       <context context="voice_command"/>
                   </device>
               </group>
               <group>
                   <device address="bus4_call_out">
                       <context context="call"/>
                   </device>
               </group>
               <group>
                   <device address="bus5_alarm_out">
                       <context context="alarm"/>
                   </device>
               </group>
           </volumeGroups>
           <displays>
                <display port="0"/>
           </displays>
       </zone>
        <zone name="rear seat zone">
           <volumeGroups>
               <group>
                   <device address="bus100_rear_seat">
                       <context context="music"/>
                       <context context="navigation"/>
                       <context context="voice_command"/>
                       <context context="call_ring"/>
                       <context context="call"/>
                       <context context="alarm"/>
                       <context context="notification"/>
                       <context context="system_sound"/>
                   </device>
               </group>
           </volumeGroups>
           <displays>
               <display port="1"/>
           </displays>
    </zones>
</audioZoneConfiguration>

여기서 기본 영역은 컨텍스트를 개별 기기로 분리했습니다. 이렇게 하면 HAL이 차량의 하드웨어를 사용하여 서로 다른 후처리 효과와 믹싱을 각 기기 출력에 적용할 수 있습니다. 기기는 미디어, 내비게이션, 통화, 알람의 4가지 볼륨 그룹으로 정렬되었습니다. 시스템이 useFixedVolume으로 구성된 경우 각 그룹의 볼륨 수준이 HAL로 전달되어 그러한 기기의 출력에 적용됩니다.

보조 영역에서 예상 출력은 단일 헤드폰 잭을 통해 이루어집니다. 이 예에서는 작동이 단순하도록 모든 사용이 단일 기기 및 볼륨 그룹으로 라우팅됩니다.

각 영역에는 디스플레이 목록을 선택적으로 포함할 수 있습니다(각 디스플레이에는 물리적 디스플레이 포트가 연결되어 있음). 따라서 일부 애플리케이션은 타겟팅하려는 특정 디스플레이에 연결된 영역을 쿼리할 수 있습니다(아래 참고).

숨겨진 새 API(OEM 및 시스템 애플리케이션만 해당)

Android 10에는 앱이 오디오 영역과 포커스를 쿼리하고 설정할 수 있도록 일련의 숨겨진 API가 CarAudioManager에 도입되었습니다.

int[] getAudioZoneIds();
int getZoneIdForUid(int uid);
boolean setZoneIdForUid(int zoneId, int uid);
boolean clearZoneIdForUid(int uid);
int getZoneIdForDisplay(Display display);

앱의 영역 변경

기본적으로 모든 오디오는 기본 영역으로 라우팅됩니다. 애플리케이션을 다른 영역으로 라우팅하도록 업데이트하려면 setZoneIdForUid를 사용합니다.

int zoneIdForDisplayId =
mCarAudioManager.getZoneIdForDisplay(selectedDisplay);

Int uid = mContext.getPackageManager() .getApplicationInfo(mContext.getPackageName(), 0) .uid;
if (mCarAudioManager.setZoneIdForUid(zoneId, info.uid)) { Log.d(TAG, "Zone successfully updated"); } else { Log.d(TAG, "Failed to change zone"); }

참고: 스트림은 영역을 동적으로 전환할 수 없습니다. 따라서 영역을 변경하려면 재생을 중지해야 합니다.