Quản lý khối lượng

AAOS có quản lý âm lượng riêng trong CarAudioService . Nó sử dụng các âm lượng cố định với mong muốn rằng các âm lượng sẽ được áp dụng dưới mức HAL bằng bộ khuếch đại phần cứng thay vì bằng phần mềm. Nó cũng sắp xếp các thiết bị đầu ra thành các nhóm âm lượng để áp dụng cùng mức tăng cho tất cả các thiết bị được liên kết với nhóm âm lượng.

Sử dụng khối lượng cố định

Việc triển khai AAOS sẽ kiểm soát âm lượng bằng bộ khuếch đại phần cứng thay vì bộ trộn phần mềm. Để tránh tác dụng phụ, hãy đặt cờ config_useFixedVolume thành true (lớp phủ nếu cần):

<resources>
    <!-- Car uses hardware amplifier for volume. -->
    <bool name="config_useFixedVolume">true</bool>
</resources>

Khi cờ config_useFixedVolume không được đặt (hoặc được đặt thành false), các ứng dụng có thể gọi AudioManager.setStreamVolume() và thay đổi âm lượng theo loại luồng trong bộ trộn phần mềm. Điều này có thể là điều không mong muốn do tác động tiềm ẩn đối với các ứng dụng khác và thực tế là sự suy giảm âm lượng trong bộ trộn phần mềm dẫn đến ít bit có ý nghĩa hơn trong tín hiệu khi nhận được ở bộ khuếch đại phần cứng.

Nhóm âm lượng

Nhóm âm lượng quản lý âm lượng cho một tập hợp thiết bị trong vùng âm thanh. Đối với mỗi nhóm âm lượng, âm lượng có thể được điều khiển độc lập và mức tăng thu được được định cấu hình trên các thiết bị liên quan để áp dụng cho bộ khuếch đại của xe. Cài đặt âm lượng được duy trì cho người dùng và được tải khi người dùng đăng nhập.

Xác định nhóm khối lượng

CarAudioService sử dụng các nhóm âm lượng được xác định trong car_audio_configuration.xml :

<audioZoneConfiguration version="2.0">
    <zones>
        <zone name="primary zone" isPrimary="true">
            <volumeGroups>
                <group>
                    <device address="bus0_media_out">
                        <context context="music"/>
                    </device>
                </group>
                <group>
                    <device address="bus1_navigation_out">
                        <context context="navigation"/>
                    </device>
                    <device address="bus2_voice_command_out">
                        <context context="voice_command"/>
                    </device>
                </group>
                ...
            </volumeGroups>
        </zone>
     </zones>
</audioZoneConfiguration>

Ví dụ triển khai car_audio_configuration.xml .

Mỗi nhóm âm lượng phải chứa một hoặc nhiều thiết bị đầu ra có địa chỉ liên quan. Các địa chỉ này phải tương ứng với các thiết bị đầu ra được xác định trong audio_policy_configuration.xml .

Định cấu hình mức tăng nhóm âm lượng

Mỗi nhóm âm lượng có các giá trị khuếch đại tối thiểu, tối đa và mặc định cũng như kích thước bước. Chúng được xác định dựa trên các giá trị được định cấu hình trong audio_policy_configuration.xml cho các thiết bị được liên kết với nhóm âm lượng.

<devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus0_media_out">
  <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  <gains>
    <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
      minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  </gains>
</devicePort>

Trong quá trình khởi tạo, nhóm âm lượng sẽ kiểm tra giá trị khuếch đại của các thiết bị được liên kết và định cấu hình nhóm như sau:

  • Cỡ bước chân. Phải giống nhau đối với tất cả các thiết bị được điều khiển bởi nhóm âm lượng
  • Đạt được tối thiểu. Mức tăng tối thiểu nhỏ nhất trong số các thiết bị trong nhóm
  • Đạt được tối đa. Mức tăng tối đa cao nhất trong số các thiết bị trong nhóm
  • Mức tăng mặc định. Mức tăng mặc định cao nhất trong số các thiết bị trong nhóm

Do cách định cấu hình các giá trị này, nên có thể đặt mức tăng của nhóm âm lượng nằm ngoài phạm vi được hỗ trợ cho thiết bị được liên kết với nhóm âm lượng. Trong trường hợp này, đối với thiết bị đó, mức tăng sẽ được đặt thành giá trị mức tăng tối thiểu hoặc tối đa của thiết bị dựa trên việc giá trị của nhóm âm lượng nằm dưới hay trên phạm vi.

Mã định danh nhóm khối lượng

Các nhóm khối lượng được xác định trong thời gian chạy theo thứ tự định nghĩa của chúng trong tệp XML. ID nằm trong khoảng từ 0 đến N-1 trong vùng âm thanh, trong đó N là số nhóm âm lượng trong vùng đó. Bằng cách này, ID nhóm tập không phải là duy nhất giữa các vùng. Những giá trị nhận dạng này được sử dụng cho các API CarAudioManager được liên kết với các nhóm âm lượng. Bất kỳ API nào nhận groupId mà không có zoneId sẽ mặc định là vùng âm thanh chính.

Quản lý âm lượng đa vùng

Mỗi vùng âm thanh dự kiến ​​sẽ có một hoặc nhiều nhóm âm lượng và mỗi nhóm âm lượng chỉ được liên kết với một vùng âm thanh duy nhất. Mối quan hệ này được xác định là một phần của car_audio_configuration.xml . Xem ví dụ được cung cấp trong Xác định nhóm âm lượng ở trên.

Mức âm lượng hiện tại cho từng vùng được duy trì cho người dùng được liên kết với vùng đó. Các cài đặt này dành riêng cho vùng, nghĩa là nếu người dùng đăng nhập trên màn hình được liên kết với vùng chính, sau đó đăng nhập vào vùng được liên kết với vùng âm thanh phụ, thì mức âm lượng được tải và duy trì cho vùng đầu tiên sẽ khác với những thứ dành cho khu vực thứ cấp.

Xử lý các sự kiện phím âm lượng

Android xác định một số mã khóa để điều khiển âm lượng, bao gồm KEYCODE_VOLUME_UP , KEYCODE_VOLUME_DOWNKEYCODE_VOLUME_MUTE . Theo mặc định, Android định tuyến các sự kiện phím âm lượng tới các ứng dụng. Việc triển khai ô tô phải buộc các sự kiện quan trọng này tới CarAudioService , sau đó có thể gọi setGroupVolume hoặc setMasterMute nếu thích hợp.

Để buộc hành vi này, hãy đặt cờ config_handleVolumeKeysInWindowManager thành true :

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

Các sự kiện phím âm lượng hiện không có cách nào để phân biệt chúng dành cho vùng nào và do đó được cho là tất cả đều được liên kết với vùng âm thanh chính. Khi nhận được sự kiện phím âm lượng, CarAudioService sẽ xác định nhóm âm lượng nào cần điều chỉnh bằng cách tìm nạp ngữ cảnh âm thanh cho trình phát đang hoạt động, sau đó điều chỉnh nhóm âm lượng chứa thiết bị đầu ra được liên kết với ngữ cảnh âm thanh có mức ưu tiên cao nhất. Mức độ ưu tiên được xác định dựa trên thứ tự cố định được xác định trong CarVolume.AUDIO_CONTEXT_VOLUME_PRIORITY .

Làm mờ dần và cân bằng

Cả hai phiên bản AudioControl HAL đều bao gồm các API để cài đặt độ mờ và độ cân bằng trong xe. Có các API hệ thống tương ứng cho CarAudioManager chuyển các giá trị xuống AudioControl HAL. Các API này yêu cầu android.car.permission.CAR_CONTROL_AUDIO_VOLUME .

Các API AudioControl là:

  • setBalanceTowardRight(float value) . Chuyển âm lượng loa về phía bên phải (+) hoặc bên trái (-) của ô tô. 0,0 được căn giữa, +1.0 hoàn toàn bên phải, -1.0 hoàn toàn bên trái và giá trị nằm ngoài phạm vi -1 đến 1 là lỗi.
  • setFadeTowardFront(float value) - Chuyển âm lượng loa về phía trước (+) hoặc phía sau (-) của ô tô. 0,0 ở giữa, +1,0 ở phía trước hoàn toàn, -1,0 ở phía sau hoàn toàn và giá trị nằm ngoài phạm vi -1 đến 1 là lỗi.

OEM có quyền quyết định cách áp dụng những giá trị này và cách chúng hiển thị với người dùng. Chúng có thể được áp dụng nghiêm ngặt cho phương tiện truyền thông hoặc trên diện rộng cho tất cả âm thanh của Android.

Android 11 cũng giới thiệu hỗ trợ áp dụng hiệu ứng âm thanh cho các thiết bị đầu ra. Với điều này, bạn có thể quản lý độ mờ và cân bằng thông qua hiệu ứng âm thanh trên thiết bị đầu ra thích hợp thay vì thông qua các API này.

Giảm âm thanh

Giảm âm thanh xảy ra khi phương tiện giảm mức tăng của một luồng để có thể nghe rõ hơn một luồng khác đang phát cùng lúc. Trong AAOS, việc giảm âm thanh được giao cho HAL thực hiện vì có thể có nhiều âm thanh bên ngoài Android mà hệ điều hành không kiểm soát được. Trong Android 11, thông tin chính có sẵn để HAL đưa ra quyết định tránh né là liệu cả hai thiết bị đầu ra đều có luồng hoạt động hay không.

Khi nào nên vịt

Mặc dù mỗi OEM có quyền quyết định cách HAL của họ xử lý việc giảm tải, nhưng có một số nguyên tắc chung mà chúng tôi khuyến nghị. Nhiều luồng phát trong Android thường xảy ra nhất khi hai ứng dụng/dịch vụ đồng thời giữ tiêu điểm âm thanh. Với ý nghĩ đó, hãy xem Ma trận tương tác để tìm hiểu khi nào Android có thể cấp tiêu điểm đồng thời và do đó, khi nào hai luồng khác nhau có thể phát đồng thời.

Hãy nhớ rằng mọi luồng được Android kết hợp với nhau sẽ được thực hiện trước khi áp dụng bất kỳ khoản lợi nhuận nào. Do đó, bất kỳ luồng nào cần được giảm bớt khi phát đồng thời với một luồng khác phải được định tuyến đến các thiết bị đầu ra riêng biệt để HAL có thể áp dụng giảm bớt trước khi trộn chúng lại với nhau.

Hành vi vịt được đề xuất

Sau đây là những tương tác đồng thời tiềm năng mà chúng tôi khuyên bạn nên áp dụng cách né tránh:

  • EMERGENCY . Giảm bớt hoặc tắt tiếng mọi thứ ngoại trừ SAFETY để đảm bảo người lái xe nghe thấy âm thanh
  • SAFETY . Tránh mọi thứ trừ EMERGENCY để đảm bảo tài xế nghe được âm thanh
  • NAVIGATION . Tránh mọi thứ ngoại trừ SAFETYEMERGENCY
  • CALL . Tránh mọi thứ ngoại trừ SAFETY , EMERGENCYNAVIGATION
  • VOICE . Vịt CALL_RING
  • Tùy thuộc vào OEM để xác định tầm quan trọng của VEHICLE_SOUNDS đang hoạt động và liệu họ có nên giảm bớt các âm thanh khác để đảm bảo người lái xe nghe thấy chúng hay không.
  • MUSICANNOUNCEMENT nên được tránh xa mọi thứ. Ngoại lệ chính cho điều này là các âm tương tác cảm ứng hiện được phát dưới dạng SYSTEM_SOUND

Những cân nhắc khác khi thả vịt

Một số ứng dụng/dịch vụ như điều hướng hoặc trợ lý có thể sử dụng nhiều người chơi để hoàn thành hành động của họ. Các OEM nên tránh giảm âm lượng quá mạnh dựa trên thời điểm dữ liệu truyền phát ngừng truyền qua các thiết bị đầu ra này để đảm bảo người dùng không tạm thời đưa phương tiện trở lại mức âm lượng tối đa trước khi giảm âm lượng xuống khi lần phát lại tiếp theo từ ứng dụng điều hướng hoặc ứng dụng trợ lý bắt đầu.

Đối với những chiếc xe có nhiều tầng âm thanh với khả năng cách âm đủ tốt, còn có tùy chọn định tuyến âm thanh đến các khu vực khác nhau trong xe thay vì giảm tốc độ. Ví dụ: hướng dẫn điều hướng có thể được chuyển đến loa tựa đầu của người lái trong khi nhạc vẫn tiếp tục phát khắp cabin ở mức âm lượng bình thường.

Âm thanh quan trọng về an toàn

Mặc dù Android 11 đã giới thiệu API tập trung âm thanh HAL nhưng HAL vẫn phụ thuộc vào việc đảm bảo các âm thanh quan trọng về an toàn được ưu tiên hơn các API khác. Ngay cả khi HAL giữ tiêu điểm âm thanh cho USAGE_EMERGENCY , điều đó không đảm bảo các ứng dụng và dịch vụ trong Android sẽ không phát âm thanh. HAL có trách nhiệm xác định luồng nào từ Android sẽ được trộn hoặc tắt tiếng khi phát ra các âm thanh quan trọng về an toàn.

Định cấu hình giao diện người dùng cài đặt âm lượng

AAOS tách giao diện người dùng cài đặt âm lượng khỏi cấu hình nhóm âm lượng (có thể được phủ lên như được mô tả trong Định cấu hình nhóm âm lượng). Sự tách biệt này đảm bảo rằng không cần thay đổi nếu cấu hình nhóm âm lượng thay đổi trong tương lai.

Trong giao diện người dùng Cài đặt ô tô, tệp packages/apps/Car/Settings/res/xml/car_volume_items.xml chứa các thành phần giao diện người dùng (tài nguyên tiêu đề và biểu tượng) được liên kết với từng AudioAttributes.USAGE được xác định. Tệp này cung cấp khả năng hiển thị hợp lý VolumeGroups được xác định bằng cách sử dụng các tài nguyên được liên kết với cách sử dụng được công nhận đầu tiên có trong mỗi Nhóm khối lượng.

Ví dụ: ví dụ sau định nghĩa một VolumeGroup bao gồm cả voice_communicationvoice_communication_signalling . Việc triển khai mặc định của giao diện người dùng cài đặt ô tô sẽ hiển thị VolumeGroup bằng cách sử dụng các tài nguyên được liên kết với voice_communication vì đây là tài nguyên đầu tiên trong tệp.

<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto">
    <item car:usage="voice_communication"
          car:title="@*android:string/volume_call"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="voice_communication_signalling"
          car:title="@*android:string/volume_call"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="media"
          car:title="@*android:string/volume_music"
          car:icon="@*android:drawable/ic_audio_media"/>
    <item car:usage="game"
          car:title="@*android:string/volume_music"
          car:icon="@*android:drawable/ic_audio_media"/>
    <item car:usage="alarm"
          car:title="@*android:string/volume_alarm"
          car:icon="@*android:drawable/ic_audio_alarm"/>
    <item car:usage="assistance_navigation_guidance"
          car:title="@string/navi_volume_title"
          car:icon="@drawable/ic_audio_navi"/>
    <item car:usage="notification_ringtone"
          car:title="@*android:string/volume_ringtone"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="assistant"
          car:title="@*android:string/volume_unknown"
          car:icon="@*android:drawable/ic_audio_vol"/>
    <item car:usage="notification"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_communication_request"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_communication_instant"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_communication_delayed"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_event"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="assistance_accessibility"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="assistance_sonification"
          car:title="@*android:string/volume_unknown"
          car:icon="@*android:drawable/ic_audio_vol"/>
    <item car:usage="unknown"
          car:title="@*android:string/volume_unknown"
          car:icon="@*android:drawable/ic_audio_vol"/>
</carVolumeItems>

Các thuộc tính và giá trị được sử dụng trong cấu hình trên được khai báo trong packages/apps/Car/Settings/res/values/attrs.xml . Giao diện người dùng cài đặt âm lượng sử dụng các API CarAudioManager dựa trên VolumeGroup sau:

  • getVolumeGroupCount() để biết nên rút ra bao nhiêu điều khiển.
  • getGroupMinVolume()getGroupMaxVolume() để nhận giới hạn dưới và giới hạn trên.
  • getGroupVolume() để lấy âm lượng hiện tại.
  • registerVolumeChangeObserver() để nhận thông báo về thay đổi âm lượng.