Âm thanh ô tô

Android Automotive OS (AAOS) được xây dựng dựa trên hệ thống âm thanh cốt lõi của Android để hỗ trợ các trường hợp sử dụng vận hành như hệ thống thông tin giải trí trên xe. AAOS chịu trách nhiệm về âm thanh thông tin giải trí (nghĩa là phương tiện, điều hướng và liên lạc) nhưng không chịu trách nhiệm trực tiếp về chuông và cảnh báo có yêu cầu nghiêm ngặt về tính khả dụng và thời gian. Mặc dù AAOS cung cấp các tín hiệu và cơ chế giúp xe quản lý âm thanh nhưng cuối cùng, xe sẽ quyết định xem nên phát những âm thanh nào cho người lái và hành khách, đảm bảo rằng các âm thanh quan trọng về an toàn và âm thanh quy định được nghe đúng cách mà không cần gián đoạn.

Vì Android quản lý trải nghiệm đa phương tiện của xe nên các nguồn phương tiện bên ngoài như bộ thu sóng radio phải được đại diện bởi các ứng dụng có thể xử lý tiêu điểm âm thanh và các sự kiện quan trọng về phương tiện cho nguồn.

Android 11 bao gồm những thay đổi sau đây đối với việc hỗ trợ âm thanh liên quan đến ô tô:

Âm thanh và luồng Android

Hệ thống âm thanh ô tô xử lý các âm thanh và luồng sau:

Sơ đồ kiến ​​trúc lấy luồng làm trung tâm

Hình 1. Sơ đồ kiến ​​trúc lấy luồng làm trung tâm

Android quản lý âm thanh phát ra từ các ứng dụng Android, kiểm soát các ứng dụng đó và định tuyến âm thanh của chúng đến các thiết bị đầu ra tại HAL dựa trên loại âm thanh:

  • Các luồng logic , được gọi là nguồn trong danh pháp âm thanh cốt lõi, được gắn thẻ Thuộc tính âm thanh .
  • Luồng vật lý , được gọi là thiết bị trong danh pháp âm thanh cốt lõi, không có thông tin ngữ cảnh sau khi trộn.

Để đảm bảo độ tin cậy, âm thanh bên ngoài (đến từ các nguồn độc lập như chuông cảnh báo thắt dây an toàn) được quản lý bên ngoài Android, bên dưới HAL hoặc thậm chí trong phần cứng riêng biệt. Người triển khai hệ thống phải cung cấp một bộ trộn chấp nhận một hoặc nhiều luồng âm thanh đầu vào từ Android, sau đó kết hợp các luồng đó theo cách phù hợp với các nguồn âm thanh bên ngoài mà xe yêu cầu.

Việc triển khai HAL và bộ trộn bên ngoài chịu trách nhiệm đảm bảo nghe thấy các âm thanh bên ngoài quan trọng về mặt an toàn cũng như trộn trong các luồng do Android cung cấp và định tuyến chúng đến các loa phù hợp.

Âm thanh Android

Ứng dụng có thể có một hoặc nhiều trình phát tương tác thông qua API Android tiêu chuẩn (ví dụ: AudioManager để kiểm soát tiêu điểm hoặc MediaPlayer để phát trực tuyến) để phát ra một hoặc nhiều luồng dữ liệu âm thanh hợp lý. Dữ liệu này có thể là kênh đơn hoặc âm thanh vòm 7.1, nhưng được định tuyến và xử lý dưới dạng một nguồn duy nhất. Luồng ứng dụng được liên kết với AudioAttribution để đưa ra gợi ý cho hệ thống về cách thể hiện âm thanh.

Các luồng logic được gửi qua AudioService và được định tuyến đến một (và chỉ một) luồng đầu ra vật lý có sẵn, mỗi luồng là đầu ra của bộ trộn trong AudioFlinger. Sau khi các thuộc tính âm thanh đã được trộn vào luồng vật lý, chúng sẽ không còn khả dụng nữa.

Mỗi luồng vật lý sau đó được gửi tới Audio HAL để hiển thị trên phần cứng. Trong các ứng dụng ô tô, phần cứng kết xuất có thể là codec cục bộ (tương tự như thiết bị di động) hoặc bộ xử lý từ xa trên mạng vật lý của xe. Dù bằng cách nào, nhiệm vụ của việc triển khai Audio HAL là cung cấp dữ liệu mẫu thực tế và khiến dữ liệu đó trở nên có thể nghe được.

Luồng bên ngoài

Các luồng âm thanh không được định tuyến qua Android (vì lý do chứng nhận hoặc thời gian) có thể được gửi trực tiếp đến bộ trộn bên ngoài. Kể từ Android 11, HAL hiện có thể yêu cầu lấy nét cho những âm thanh bên ngoài này để thông báo cho Android để Android có thể thực hiện các hành động thích hợp như tạm dừng phương tiện hoặc ngăn người khác lấy nét.

Nếu các luồng bên ngoài là các nguồn phương tiện sẽ tương tác với môi trường âm thanh mà Android đang tạo ra (ví dụ: dừng phát lại MP3 khi bộ dò bên ngoài được bật), thì các luồng bên ngoài đó phải được thể hiện bằng ứng dụng Android. Ứng dụng như vậy sẽ yêu cầu tập trung âm thanh thay mặt cho nguồn phương tiện thay vì HAL và sẽ phản hồi các thông báo tập trung bằng cách bắt đầu/dừng nguồn bên ngoài nếu cần để phù hợp với chính sách tập trung của Android. Ứng dụng này cũng chịu trách nhiệm xử lý các sự kiện quan trọng của phương tiện như phát/tạm dừng. Một cơ chế được đề xuất để kiểm soát các thiết bị bên ngoài như vậy là HwAudioSource .

Các thiết bị đầu ra

Ở cấp độ Âm thanh HAL, loại thiết bị AUDIO_DEVICE_OUT_BUS cung cấp thiết bị đầu ra chung để sử dụng trong hệ thống âm thanh trên xe. Thiết bị bus hỗ trợ các cổng có thể định địa chỉ (trong đó mỗi cổng là điểm cuối của luồng vật lý) và dự kiến ​​sẽ là loại thiết bị đầu ra được hỗ trợ duy nhất trên xe.

Việc triển khai hệ thống có thể sử dụng một cổng bus cho tất cả âm thanh Android, trong trường hợp đó, Android kết hợp mọi thứ lại với nhau và phân phối dưới dạng một luồng. Ngoài ra, HAL có thể cung cấp một cổng bus cho mỗi CarAudioContext để cho phép phân phối đồng thời bất kỳ loại âm thanh nào. Điều này giúp việc triển khai HAL có thể trộn và loại bỏ các âm thanh khác nhau theo ý muốn.

Việc gán ngữ cảnh âm thanh cho thiết bị đầu ra được thực hiện thông qua car_audio_configuration.xml .

Đầu vào micrô

Khi thu âm thanh, Audio HAL nhận được lệnh gọi openInputStream bao gồm đối số AudioSource cho biết cách xử lý đầu vào micrô.

Nguồn VOICE_RECOGNITION (cụ thể là Trợ lý Google) yêu cầu luồng micrô âm thanh nổi có hiệu ứng khử tiếng vang (nếu có) nhưng không áp dụng quy trình xử lý nào khác cho luồng đó. Beamforming dự kiến ​​sẽ được thực hiện bởi Trợ lý.

Đầu vào micrô đa kênh

Để thu âm thanh từ thiết bị có nhiều hơn hai kênh (âm thanh nổi), hãy sử dụng mặt nạ chỉ mục kênh thay vì mặt nạ chỉ mục vị trí (chẳng hạn như CHANNEL_IN_LEFT ). Ví dụ:

final AudioFormat audioFormat = new AudioFormat.Builder()
    .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
    .setSampleRate(44100)
    .setChannelIndexMask(0xf /* 4 channels, 0..3 */)
    .build();
final AudioRecord audioRecord = new AudioRecord.Builder()
    .setAudioFormat(audioFormat)
    .build();
audioRecord.setPreferredDevice(someAudioDeviceInfo);

Khi cả setChannelMasksetChannelIndexMask đều được đặt, AudioRecord chỉ sử dụng giá trị do setChannelMask đặt (tối đa hai kênh).

Chụp đồng thời

Kể từ Android 10, khung Android hỗ trợ thu thập dữ liệu đầu vào đồng thời nhưng có những hạn chế để bảo vệ quyền riêng tư của người dùng. Là một phần của những hạn chế này, các nguồn ảo như AUDIO_SOURCE_FM_TUNER sẽ bị bỏ qua và do đó được phép ghi đồng thời cùng với đầu vào thông thường (chẳng hạn như micrô). HwAudioSources cũng không được coi là một phần của các hạn chế thu âm đồng thời.

Các ứng dụng được thiết kế để hoạt động với các thiết bị AUDIO_DEVICE_IN_BUS hoặc với các thiết bị AUDIO_DEVICE_IN_FM_TUNER phụ phải dựa vào việc xác định rõ ràng các thiết bị đó và sử dụng AudioRecord.setPreferredDevice() để bỏ qua logic chọn nguồn mặc định của Android.

Cách sử dụng âm thanh

AAOS chủ yếu sử dụng AudioAttributes.AttributeUsages để định tuyến, điều chỉnh âm lượng và quản lý tiêu điểm. Cách sử dụng là sự thể hiện "lý do" luồng được phát. Do đó, tất cả các luồng và yêu cầu tập trung vào âm thanh phải chỉ định cách sử dụng cho việc phát lại âm thanh của chúng. Khi không được đặt cụ thể khi xây dựng đối tượng AudioAttribution, việc sử dụng sẽ được mặc định là USAGE_UNKNOWN . Mặc dù điều này hiện được xử lý giống như USAGE_MEDIA nhưng không nên dựa vào hành vi này để phát lại phương tiện.

Cách sử dụng hệ thống

Trong Android 11, cách sử dụng hệ thống đã được giới thiệu. Các cách sử dụng này hoạt động tương tự như các cách sử dụng đã thiết lập trước đó, ngoại trừ việc chúng yêu cầu sử dụng API hệ thống cũng như android.permission.MODIFY_AUDIO_ROUTING . Các cách sử dụng hệ thống mới là:

  • USAGE_EMERGENCY
  • USAGE_SAFETY
  • USAGE_VEHICLE_STATUS
  • USAGE_ANNOUNCEMENT

Để xây dựng AudioAttributes với cách sử dụng hệ thống, hãy sử dụng AudioAttributes.Builder#setSystemUsage thay vì setUsage . Việc gọi phương thức này với cách sử dụng không thuộc hệ thống sẽ dẫn đến IllegalArgumentException bị ném ra. Ngoài ra, nếu cả mức sử dụng và mức sử dụng hệ thống đã được đặt trên trình tạo, nó sẽ đưa ra IllegalArgumentException khi xây dựng.

Để kiểm tra mức sử dụng nào được liên kết với phiên bản AudioAttributes , hãy gọi AudioAttributes#getSystemUsage . Điều này trả về việc sử dụng hoặc việc sử dụng hệ thống được liên kết.

Bối cảnh âm thanh

Để đơn giản hóa việc định cấu hình âm thanh AAOS, các cách sử dụng tương tự đã được nhóm thành CarAudioContext . Các ngữ cảnh âm thanh này được sử dụng trong toàn bộ CarAudioService để xác định định tuyến, nhóm âm lượng và quản lý tiêu điểm âm thanh.

Ngữ cảnh âm thanh trong Android 11 là:

XeÂm ThanhBối Cảnh Công dụng thuộc tính liên quan
MUSIC UNKNOWN, GAME, MEDIA
NAVIGATION ASSISTANCE_NAVIGATION_GUIDANCE
VOICE_COMMAND ASSISTANT, ASSISTANCE_ACCESSIBILITY
CALL_RING NOTIFICATION_RINGTONE
CALL VOICE_COMMUNICATION, VOICE_COMMUNICATION_SIGNALING
ALARM ALARM
NOTIFICATION NOTIFICATION, NOTIFICATION_*
SYSTEM_SOUND ASSISTANCE_SONIFICATION
EMERGENCY EMERGENCY
SAFETY SAFETY
VEHICLE_STATUS VEHICLE_STATUS
ANNOUNCEMENT ANNOUNCEMENT

Ánh xạ giữa bối cảnh âm thanh và cách sử dụng. Các hàng được đánh dấu dành cho cách sử dụng hệ thống mới.

Âm thanh đa vùng

Ô tô xuất hiện một loạt trường hợp sử dụng mới xoay quanh việc người dùng đồng thời tương tác với nền tảng và tìm cách sử dụng phương tiện riêng biệt. Ví dụ: người lái xe có thể phát nhạc trong cabin trong khi hành khách ngồi ở ghế sau đang xem video YouTube trên màn hình phía sau. Âm thanh đa vùng cho phép thực hiện điều này bằng cách cho phép các nguồn âm thanh khác nhau phát đồng thời qua các khu vực khác nhau của xe.

Âm thanh đa vùng bắt đầu từ Android 10 cho phép các OEM định cấu hình âm thanh thành các vùng riêng biệt. Mỗi vùng là một tập hợp các thiết bị trong xe với các nhóm âm lượng riêng, cấu hình định tuyến cho các ngữ cảnh và quản lý tiêu điểm. Theo cách này, cabin chính có thể được cấu hình thành một vùng âm thanh, trong khi giắc cắm tai nghe của màn hình phía sau được cấu hình thành vùng thứ hai.

Các vùng được xác định là một phần của car_audio_configuration.xml . Sau đó, CarAudioService đọc cấu hình và giúp AudioService định tuyến các luồng âm thanh dựa trên vùng liên kết của chúng. Mỗi vùng vẫn xác định các quy tắc định tuyến dựa trên ngữ cảnh và uid ứng dụng. Khi trình phát được tạo, CarAudioService sẽ xác định vùng mà trình phát được liên kết và sau đó dựa trên mức sử dụng, AudioFlinger sẽ định tuyến âm thanh tới thiết bị nào.

Tiêu điểm cũng được duy trì độc lập cho từng vùng âm thanh. Điều này cho phép các ứng dụng ở các vùng khác nhau tạo ra âm thanh một cách độc lập mà không gây nhiễu lẫn nhau trong khi các ứng dụng vẫn tôn trọng những thay đổi về tiêu điểm trong vùng của chúng. CarZonesAudioFocus trong CarAudioService chịu trách nhiệm quản lý tiêu điểm cho từng vùng.

Định cấu hình âm thanh đa vùng

Hình 2. Cấu hình âm thanh đa vùng

Âm thanh HAL

Việc triển khai âm thanh ô tô dựa trên Android Audio HAL tiêu chuẩn, bao gồm:

  • IDevice.hal . Tạo luồng đầu vào và đầu ra, xử lý âm lượng chính và tắt tiếng, đồng thời sử dụng:
    • createAudioPatch . Để tạo các bản vá bên ngoài-bên ngoài giữa các thiết bị.
    • IDevice.setAudioPortConfig() để cung cấp âm lượng cho mỗi luồng vật lý.
  • IStream.hal . Cùng với các biến thể đầu vào và đầu ra, quản lý việc truyền các mẫu âm thanh đến và đi từ phần cứng.

Các loại thiết bị ô tô

Các loại thiết bị sau đây có liên quan đến nền tảng ô tô.

Loại thiết bị Sự miêu tả
AUDIO_DEVICE_OUT_BUS Đầu ra chính từ Android (đây là cách tất cả âm thanh từ Android được truyền tới xe). Được sử dụng làm địa chỉ để phân biệt các luồng cho từng ngữ cảnh.
AUDIO_DEVICE_OUT_TELEPHONY_TX Được sử dụng cho âm thanh được định tuyến tới đài phát thanh di động để truyền tải.
AUDIO_DEVICE_IN_BUS Được sử dụng cho đầu vào không được phân loại khác.
AUDIO_DEVICE_IN_FM_TUNER Chỉ được sử dụng cho đầu vào radio phát sóng.
AUDIO_DEVICE_IN_TV_TUNER Được sử dụng cho thiết bị TV nếu có.
AUDIO_DEVICE_IN_LINE Được sử dụng cho giắc đầu vào Aux.
AUDIO_DEVICE_IN_BLUETOOTH_A2DP Đã nhận được nhạc qua Bluetooth.
AUDIO_DEVICE_IN_TELEPHONY_RX Được sử dụng cho âm thanh nhận được từ sóng vô tuyến di động liên quan đến cuộc gọi điện thoại.

Cấu hình thiết bị âm thanh

Các thiết bị âm thanh hiển thị với Android phải được xác định trong /audio_policy_configuration.xml , bao gồm các thành phần sau:

  • tên mô-đun. Hỗ trợ "chính" (được sử dụng cho các trường hợp sử dụng ô tô), "A2DP", "remote_submix" và "USB". Tên mô-đun và trình điều khiển âm thanh tương ứng phải được biên dịch thành audio.primary.$(variant).so .
  • devicePorts. Chứa danh sách mô tả thiết bị cho tất cả các thiết bị đầu vào và đầu ra (bao gồm các thiết bị được gắn cố định và thiết bị di động) có thể được truy cập từ mô-đun này.
    • Đối với mỗi thiết bị đầu ra, bạn có thể xác định điều khiển khuếch đại bao gồm các giá trị tối thiểu/tối đa/mặc định/bước tính bằng milibel (1 millibel = 1/100 dB = 1/1000 bel).
    • Thuộc tính địa chỉ trên phiên bản devicePort có thể được sử dụng để tìm thiết bị, ngay cả khi có nhiều thiết bị có cùng loại thiết bị như AUDIO_DEVICE_OUT_BUS .
  • mixPorts. Chứa danh sách tất cả các luồng đầu ra và đầu vào được hiển thị bởi HAL âm thanh. Mỗi phiên bản mixPort có thể được coi là một luồng vật lý tới Android AudioService.
  • các tuyến đường. Xác định danh sách các kết nối có thể có giữa các thiết bị đầu vào và đầu ra hoặc giữa luồng và thiết bị.

Ví dụ sau xác định thiết bị đầu ra bus0_phone_out trong đó tất cả luồng âm thanh Android được trộn bởi mixer_bus0_phone_out. Tuyến đường đưa luồng đầu ra của mixer_bus0_phone_out tới thiết bị bus0_phone_out .

<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>bus0_phone_out</item>
<defaultOutputDevice>bus0_phone_out</defaultOutputDevice>
            <mixPorts>
                <mixPort name="mixport_bus0_phone_out"
                         role="source"
                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="bus0_phone_out"
                            role="sink"
                            type="AUDIO_DEVICE_OUT_BUS"
                            address="BUS00_PHONE">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400"
                                maxValueMB="4000"
                                defaultValueMB="0"
                                stepValueMB="100"/>
                    </gains>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="bus0_phone_out"
                       sources="mixport_bus0_phone_out"/>
            </routes>
        </module>
    </modules>
</audioPolicyConfiguration>