Định tuyến âm thanh

Trong Android 10, car_audio_configuration.xml thay thế car_volumes_groups.xmlIAudioControl.getBusForContext . Trong tệp cấu hình mới, danh sách các vùng được xác định. Mỗi vùng có một hoặc nhiều nhóm âm lượng với các thiết bị được liên kết của chúng và mỗi thiết bị có các bối cảnh cần được định tuyến trong vùng đó. Điều bắt buộc là tất cả các bối cảnh phải được thể hiện trong mỗi vùng.

Định cấu hình định tuyến âm thanh

Các tệp chính sách âm thanh, thường nằm trong phân vùng của nhà cung cấp, thể hiện cấu hình phần cứng âm thanh của bo mạch. Tất cả các thiết bị được tham chiếu trong car_audio_configuration.xml phải được xác định trong audio_policy_configuration.xml .

Kích hoạt định tuyến AAOS

Để sử dụng định tuyến dựa trên AAOS, bạn phải đặt cờ audioUseDynamicRouting thành true :

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

Khi false , định tuyến và phần lớn CarAudioService sẽ bị tắt và hệ điều hành sẽ quay trở lại hoạt động mặc định của AudioService .

Vùng chính

Theo mặc định, tất cả âm thanh sẽ được chuyển đến vùng chính. Chỉ có thể có một vùng chính, được biểu thị trong cấu hình bằng thuộc tính isPrimary="true" .

Cấu hình mẫu

Ví dụ: một chiếc xe có thể có hai khu vực - khu vực chính và hệ thống giải trí cho hàng ghế sau. Cùng với đó, một car_audio_configuration.xml có thể sẽ được xác định như sau:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true">
           <volumeGroups>
               <group>
                   <device address="bus0_media_out">
                       <context context="music"/>
                       <context context="announcement"/>
                   </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"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                   </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>
       </zone>
        <zone name="rear seat zone" audioZoneId="1">
           <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"/>
                       <context context="emergency"/>
                       <context context="safety"/>
                       <context context="vehicle_status"/>
                       <context context="announcement"/>
                   </device>
               </group>
           </volumeGroups>
    </zones>
</audioZoneConfiguration>

Ở đây, vùng chính đã phân tách bối cảnh cho các thiết bị khác nhau. Điều này cho phép HAL áp dụng các hiệu ứng xử lý hậu kỳ khác nhau và trộn trên mỗi đầu ra của thiết bị bằng phần cứng của xe. Các thiết bị đã được sắp xếp thành bốn nhóm âm lượng: phương tiện, điều hướng, cuộc gọi và báo thức. Nếu hệ thống được định cấu hình để useFixedVolume thì mức âm lượng cho từng nhóm sẽ được chuyển vào HAL để áp dụng cho đầu ra của các thiết bị này.

Đối với vùng thứ cấp, đầu ra dự kiến ​​sẽ thông qua một thiết bị đầu ra duy nhất. Trong ví dụ này, tất cả các cách sử dụng đều được chuyển đến một thiết bị và nhóm âm lượng để giữ cho mọi thứ đơn giản.

Cấu hình âm thanh khu vực có người ở

Trong Android 11 car_audio_configuration.xml đã được mở rộng hơn nữa để giới thiệu hai trường mới là audioZoneIdoccupantZoneId . Đầu tiên, audioZoneId có thể được sử dụng để kiểm soát việc quản lý vùng tốt hơn. Mặt khác, occupantZoneId có thể được sử dụng để định cấu hình định tuyến dựa trên ID người dùng.

Để sử dụng các trường mới này, cần có V2 của car_audio_configuration.xml . Xem lại cấu hình âm thanh ở trên nhưng sử dụng trường mới để ánh xạ id vùng người ở và id vùng âm thanh, cấu hình mới không có định nghĩa nhóm âm lượng có thể được thiết lập dưới dạng:

<audioZoneConfiguration version="2.0">
       <zone name="primary zone" isPrimary="true" occupantZoneId="0">
         ...
       </zone>
       <zone name="rear seat zone" audioZoneId="1" occupantZoneId="1">
         ...
       </zone>
    </zones>
</audioZoneConfiguration>

Cấu hình ở trên xác định ánh xạ giữa vùng chính với vùng có người ở 0 và audioZoneId 1 với occupantZoneId 1. Nói chung, mọi ánh xạ giữa vùng có người ở và vùng âm thanh đều có thể được định cấu hình nhưng ánh xạ phải là một-một. Dưới đây là các quy tắc xác định hai trường mới:

  • audioZoneId cho vùng chính luôn bằng 0
  • Số audioZoneIdoccupantZoneId không thể lặp lại
  • audioZoneIdoccupantZoneId chỉ có thể có ánh xạ 1-1

Định tuyến thông qua UID ứng dụng

Một loạt API ẩn đã được giới thiệu cho CarAudioManager trong phiên bản 10 để cho phép các ứng dụng truy vấn và đặt vùng âm thanh cũng như tiêu điểm.

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

Các API ở trên cho phép ứng dụng của bên thứ nhất quản lý định tuyến âm thanh dựa trên UID của ứng dụng. Do đó, cả ID vùng âm thanh và UID của ứng dụng cũng cần thiết. Với thông tin đó, bạn có thể đặt định tuyến âm thanh bằng cách sử dụng API CarAudioManager#setZoneIdForUid .

Thay đổi vùng cho một ứng dụng

Theo mặc định, tất cả các tuyến âm thanh đến vùng chính. Để cập nhật ứng dụng được định tuyến đến một vùng khác, hãy sử dụng CarAudioManager#setZoneIdForUid :

// Find zone to play
int zoneId = ...

// Find application's uid
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");
}

N Lưu ý: Luồng và tiêu điểm không thể chuyển đổi vùng một cách linh hoạt. Do đó, phải dừng phát lại và yêu cầu lại tiêu điểm để thay đổi vùng.

Định tuyến bằng ID người dùng

Mặc dù định tuyến dựa trên UID của ứng dụng cho phép kiểm soát tốt việc định tuyến âm thanh của từng ứng dụng nhưng nó cũng yêu cầu định tuyến âm thanh cho từng ứng dụng phải được xác định trước khi ứng dụng thực sự yêu cầu tập trung âm thanh và phát âm thanh. Để giảm thiểu vấn đề này và tạo điều kiện thuận lợi hơn nữa cho các ứng dụng của bên thứ ba phát âm thanh mà không cần sửa đổi, CarAudioService sử dụng vùng người ngồi trong ô tô và ánh xạ vùng âm thanh để xác định định tuyến dựa trên id người dùng. Bằng cách này, khi người dùng đăng nhập vào khu vực có người ở, dịch vụ âm thanh ô tô sẽ được thông báo. Với tín hiệu này, việc định tuyến và quản lý tiêu điểm âm thanh sẽ được cấu hình tự động cho tất cả các vùng âm thanh.

Định tuyến dựa trên UID của ứng dụng vẫn có thể được sử dụng nhưng phải được thực hiện độc lập với định tuyến id người dùng. Điều này có nghĩa là nếu xác định ánh xạ vùng người ở với vùng âm thanh ô tô thì định tuyến dựa trên UID sẽ bị tắt và việc cố gắng gọi CarAudioManager#setZoneidForUid sẽ báo lỗi.

Mặc dù việc định tuyến âm thanh và quản lý tiêu điểm đã được đơn giản hóa bằng tính năng quản lý khu vực dành cho người sử dụng, người dùng vẫn phải được chỉ định vào khu vực dành cho người sử dụng. Điều này có thể được thực hiện bằng cách sử dụng CarOccupantZoneManager#assignProfileUserToOccupantZone . API này yêu cầu quyền để quản lý người dùng. Kỳ vọng hiện tại là các OEM quản lý việc phân bổ vùng người dùng cho người sử dụng thông qua một số loại giao diện người dùng hệ thống. Sau khi hoàn tất việc khởi chạy ứng dụng, định tuyến âm thanh, quản lý tiêu điểm, tất cả sẽ được cấu hình tự động cho người dùng.

Định tuyến với setPreferredDevice

Cùng với những thay đổi trên, Android 11 còn có API mới để truy vấn các thiết bị đầu ra được liên kết với từng vùng, CarAudioManager#getOutputDeviceForUsage(intzoneId, int use).

API có thể được sử dụng để truy vấn thiết bị đầu ra cho một vùng cụ thể và cách sử dụng thuộc tính âm thanh. Bằng cách này, các ứng dụng của bên thứ nhất có thể định tuyến âm thanh đến các vùng khác nhau bằng cách sử dụng API setPreferredDevice của trình phát. API getOutputDeviceForUsage yêu cầu PERMISSION_CAR_CONTROL_AUDIO_SETTINGS và là API hệ thống. Dưới đây là ví dụ về cách tìm thiết bị đa phương tiện cho một vùng cụ thể và định tuyến đến thiết bị đó bằng API setPreferredDevice .

audioZoneId = ... ;
mediaDeviceInfo = mCarAudioManager
            .getOutputDeviceForUsage(audioZoneId, AudioAttributes.USAGE_MEDIA);
…
mPlayer.setPreferredDevice(mediaDeviceInfo);