Android Automotive OS (AAOS) xây dựng dựa trên ngăn xếp âm thanh cốt lõi của Android để hỗ trợ các trường hợp sử dụng hoạt động 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í (chẳng hạn như nội dung đa phương tiện, chỉ đường và thông tin liên lạc) nhưng không trực tiếp chịu trách nhiệm về tiếng chuông và cảnh báo yêu cầu nghiêm ngặt về tính sẵn có và thời gian. Mặc dù AAOS cung cấp các tín hiệu và các cơ chế giúp xe quản lý âm thanh, nhưng cuối cùng thì việc đó là do xe để thực hiện cuộc gọi về những âm thanh sẽ được phát cho người lái xe và cho hành khách, đảm bảo âm thanh quan trọng về an toàn và âm thanh theo quy định đều được áp dụng phù hợp đã nghe thấy mà không bị gián đoạn.
Vì Android quản lý trải nghiệm nội dung nghe nhìn trên xe, các nguồn nội dung nghe nhìn bên ngoài chẳng hạn như bộ dò đài sẽ được biểu thị bằng các ứng dụng có thể xử lý âm thanh và sự kiện chính về nội dung nghe nhìn cho nguồn.
Android 11 có những thay đổi sau đây đối với âm thanh liên quan đến ô tô hỗ trợ:
- Tự động chọn vùng âm thanh dựa trên Mã nhận dạng người dùng được liên kết
- Cách sử dụng hệ thống mới để hỗ trợ âm thanh dành riêng cho ô tô
- Hỗ trợ quyền phát âm thanh HAL
- Quyền phát âm thanh bị trễ đối với các sự kiện phát trực tiếp không tạm thời
- Chế độ cài đặt cho người dùng để kiểm soát hoạt động tương tác giữa thao tác di chuyển và cuộc gọi
Âm thanh và luồng nội dung trên Android
Hệ thống âm thanh trên ô tô xử lý những âm thanh và luồng sau:
Hình 1. Sơ đồ cấu trúc tập trung vào luồng
Android quản lý âm thanh đến từ các ứng dụng Android, kiểm soát các ứng dụng đó và định tuyến âm thanh của họ đến thiết bị đầu ra tại HAL dựa trên loại âm thanh:
- Luồng logic, còn gọi là nguồn trong âm thanh cốt lõi đều được gắn thẻ Thuộc tính âm thanh.
- Luồng thực tế, còn gọi là thiết bị trong âm thanh chính không có thông tin ngữ cảnh sau khi kết hợp.
Để đảm bảo độ tin cậy, âm thanh bên ngoài (âm thanh độc lập chẳng hạn như chuông cảnh báo 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. Trình triển khai hệ thống phải cung cấp một trình kết hợp chấp nhận một hoặc nhiều luồng đầu vào âm thanh từ Android rồi 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à chiếc xe.
Việc triển khai HAL và bộ trộn bên ngoài chịu trách nhiệm đảm bảo Những âm thanh bên ngoài có tính an toàn cao sẽ được nghe thấy và để phối trong âm thanh do Android cung cấp và định tuyến chúng đến loa phù hợp.
Âm thanh trên Android
Ứng dụng có thể có một hoặc nhiều người chơi tương tác thông qua phiên bản Android tiêu chuẩn API (ví dụ: AudioManager để điều khiển 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 logic. Dữ liệu này có thể là đơn kênh đơn kênh hoặc âm thanh vòm 7.1 nhưng được định tuyến và xử lý như một nguồn duy nhất. Luồng ứng dụng được liên kết với AudioAttributes nhằm đư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à một) trong số các luồng đầu ra vật lý sẵn có, mỗi luồng là đầu ra của bộ trộn trong AudioFlinger. Sau khi đã trộn các thuộc tính âm thanh với luồng thực, chúng không còn khả dụng.
Sau đó, mỗi luồng vật lý sẽ được phân phối đến HAL âm thanh để kết xuất trên phần cứng. Trong ứng dụng dành cho ô tô, phần cứng kết xuất có thể là bộ mã hoá và giải mã cục bộ (tương tự như thiết bị di động) hoặc bộ xử lý từ xa trên màn hình chính của xe mạng. Dù bằng cách nào, nhiệm vụ của việc triển khai HAL âm thanh là cung cấp dữ liệu mẫu thực tế và làm cho dữ liệu đó có âm thanh.
Luồng bên ngoài
Các luồng âm thanh không được định tuyến qua Android (để chứng nhận hoặc về thời gian) có thể được gửi trực tiếp tới bộ trộn bên ngoài. Kể từ Android 11, HAL giờ có thể yêu cầu tiêu điểm cho những âm thanh bên ngoài này để thông báo cho Android để ứng dụng có thể thực hiện các hành động thích hợp như tạm dừng nội dung nghe nhìn hoặc ngăn để người khác không thể tập trung.
Nếu luồng bên ngoài là nguồn nội dung nghe nhìn sẽ tương tác với âm thanh môi trường mà Android đang tạo (ví dụ: dừng phát MP3 khi đã bật bộ điều chỉnh bên ngoài), thì những luồng bên ngoài đó sẽ được biểu thị bằng Ứng dụng Android. Một ứng dụng như vậy sẽ yêu cầu quyền phát âm thanh thay mặt cho nguồn nội dung đa phương tiện thay vì HAL và sẽ phản hồi thông báo lấy tiêu điểm bằng cách bắt đầu/dừng nguồn bên ngoài khi cần thiết để phù hợp với tiêu điểm Android . Ứng dụng này cũng chịu trách nhiệm xử lý các sự kiện chính đối với nội dung đa phương tiện như phát/tạm dừng. Một cơ chế được đề xuất để điều khiển các thiết bị bên ngoài đó là HwAudioSource.
Thiết bị đầu ra
Ở cấp độ HAL âm thanh, 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 của xe. Xe buýt
thiết bị hỗ trợ các cổng có thể định địa chỉ (trong đó mỗi cổng là điểm cuối cho một
luồng thực) và dự kiến sẽ là loại thiết bị đầu ra duy nhất được hỗ trợ trong
một chiếc xe.
Quá trình triển khai hệ thống có thể sử dụng một cổng bus cho tất cả âm thanh Android, trong
trong trường hợp này, Android kết hợp mọi thứ 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 HAL có thể
để trộn và giảm bớt các âm thanh theo ý muốn.
Việc chỉ định ngữ cảnh âm thanh cho các thiết bị đầu ra được thực hiện thông qua
car_audio_configuration.xml
.
Đầu vào micrô
Khi ghi âm, HAL âm thanh nhận được openInputStream
lệnh gọi bao gồm đối số AudioSource
cho biết cách
đầu vào micrô cần được xử lý.
Nguồn VOICE_RECOGNITION
(cụ thể là Trợ lý Google) mong đợi một luồng micrô âm thanh nổi
hiệu ứng loại bỏ tiếng vọng (nếu có) nhưng không có quy trình xử lý nào khác được áp dụng cho hiệu ứng này.
Trợ lý dự kiến sẽ thực hiện việc tạo tia sáng.
Đầu vào micrô đa kênh
Để ghi âm từ một thiết bị có nhiều 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ả setChannelMask
và setChannelIndexMask
được đặt, AudioRecord
chỉ sử dụng giá trị được đặt bởi
setChannelMask
(tối đa 2 kênh).
Chụp đồng thời
Kể từ Android 10, khung Android hỗ trợ việc lấy đồng thời
thông tin đầu vào, nhưng có các hạn chế nhằm bảo vệ quyền riêng tư của người dùng. Là một phần
các hạn chế này, các nguồn ảo như
AUDIO_SOURCE_FM_TUNER
bị bỏ qua và do đó được phép
được ghi đồng thời 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 hoạt động đồng thời
hạn chế chụp.
Các ứng dụng được thiết kế để hoạt động với AUDIO_DEVICE_IN_BUS
thiết bị hoặc với
thiết bị AUDIO_DEVICE_IN_FM_TUNER
phụ phải dựa vào nền tảng một cách rõ ràng
xác định các thiết bị đó và sử dụng AudioRecord.setPreferredDevice()
bỏ qua logic lựa chọn nguồn mặc định của Android.
Mức 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à
đại diện cho "lý do" luồng đang được phát. Do đó, tất cả các luồng
và yêu cầu quyền phát âm thanh phải chỉ định cách sử dụng cho tính năng phát âm thanh. Thời gian
không được thiết lập cụ thể khi tạo đối tượng AudioAttributes, việc sử dụng sẽ
mặc định là USAGE_UNKNOWN
. Mặc dù hiện tại chúng tôi xử lý
là USAGE_MEDIA
, nên bạn không nên dựa vào hành vi này cho nội dung nghe nhìn
video.
Mức sử dụng hệ thống
Android 11 đã ra mắt các cách sử dụng hệ thống. Các trường hợp sử dụng này hoạt động
tương tự như cách sử dụng đã thiết lập trước đây, ngoại trừ việc chúng yêu cầu API hệ thống
để sử dụng cũng như android.permission.MODIFY_AUDIO_ROUTING
. Gói thuê bao mới
cách sử dụng hệ thống là:
USAGE_EMERGENCY
USAGE_SAFETY
USAGE_VEHICLE_STATUS
USAGE_ANNOUNCEMENT
Để tạo AudioAttributes
bằng hoạt động sử dụng hệ thống, hãy sử dụng
AudioAttributes.Builder#setSystemUsage
thay vì setUsage
. Gọi phương thức này bằng một mức sử dụng ngoài hệ thống
sẽ dẫn đến việc gửi IllegalArgumentException
. Ngoài ra, nếu
cả việc sử dụng và sử dụng hệ thống đã được thiết lập trên một trình tạo, thì trình tạo này sẽ gửi một
IllegalArgumentException
khi tạo bản dựng.
Để kiểm tra xem mục đích sử dụng liên kết với AudioAttributes
hãy gọi AudioAttributes#getSystemUsage
.
Hàm này sẽ trả về mức sử dụng hệ thống hoặc mức sử dụng được liên kết.
Ngữ cảnh âm thanh
Để đơn giản hoá cấu hình của âm thanh AAOS, chúng tôi đã nhóm các trường hợp sử dụng tương tự nhau
vào CarAudioContext
. Những ngữ cảnh âm thanh này được sử dụng xuyên suốt
CarAudioService
để xác định chế độ định tuyến, nhóm âm lượng và quyền phát âm thanh
Google Cloud.
Bối cảnh âm thanh trong Android 11 là:
Bối cảnh âm thanh ô tô | Cách sử dụng thuộc tính được liên kết |
---|---|
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 |
Liên kết giữa bối cảnh âm thanh và cách sử dụng âm thanh. Các hàng được đánh dấu là dành cho người dùng mới mức sử dụng hệ thống.
Âm thanh nhiều vùng
Ô tô xuất hiện một loạt các trường hợp sử dụng mới liên quan đến 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 các phương tiện riêng biệt. Cho ví dụ: người lái xe có thể phát nhạc trong cabin khi hành khách ở ghế sau đang xem một video trên YouTube trên màn hình sau. Tính năng Âm thanh nhiều vùng sẽ bật bằng cách cho phép nhiều nguồn âm thanh phát đồng thời qua nhiều khu vực của chiếc xe.
Tính năng Âm thanh nhiều vùng kể từ Android 10 cho phép OEM định cấu hình âm thanh thành các vùng riêng biệt. Mỗi khu vực 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 ngữ cảnh và tiêu điểm Google Cloud. Bằng cách này, bạn có thể định cấu hình cabin chính là một âm thanh trong khi giắc cắm tai nghe trên màn hình sau được định cấu hình thành khu vực thứ hai.
Các vùng này đượ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 luồng âm thanh dựa trên vùng được liên kết. Mỗi vùng vẫn xác định
quy tắc định tuyến dựa trên ngữ cảnh và uid ứng dụng. Khi người chơi
đã tạo, CarAudioService
sẽ xác định người chơi ở vùng nào
liên kết với thiết bị nào, sau đó dựa vào việc sử dụng thiết bị nào mà AudioFlinger
sẽ định tuyến âm thanh đến.
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 khác nhau
để tạo âm thanh độc lập mà không cần
can thiệp vào nhau trong khi khiến các ứng dụng vẫn tuân theo các thay đổi trong
tập trung trong vùng của họ. CarZonesAudioFocus
ở trong
CarAudioService
chịu trách nhiệm quản lý tiêu điểm của mỗi
vùng.
Hình 2. Định cấu hình âm thanh nhiều vùng
Lớp trừu tượng phần cứng (HAL) cho âm thanh
Việc triển khai âm thanh trên ô tô dựa trên lớp trừu tượng phần cứng (HAL) cho âm thanh Android tiêu chuẩn, bao gồm:
IDevice.hal
. Tạo các 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 giữa các thiết bị.IDevice.setAudioPortConfig()
để cung cấp âm lượng cho mỗi luồng thực.
IStream.hal
. Cùng với các biến thể đầu vào và đầu ra, quản lý việc truyền trực tuyến mẫu âm thanh đến và đi từ phần cứng.
Các loại thiết bị trên ô tô
Những loại thiết bị sau đây phù hợp với nền tảng ô tô.
Loại thiết bị | Mô tả |
---|---|
AUDIO_DEVICE_OUT_BUS |
Đầu ra chính từ Android (đây là cách tất cả âm thanh từ Android giao đến xe). Được 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 |
Dùng cho âm thanh được định tuyến đến sóng vô tuyến di động để truyền. |
AUDIO_DEVICE_IN_BUS |
Dùng cho dữ liệu đầu vào không được phân loại theo cách khác. |
AUDIO_DEVICE_IN_FM_TUNER |
Chỉ dùng để phát sóng vô tuyến. |
AUDIO_DEVICE_IN_TV_TUNER |
Dùng cho thiết bị TV nếu có. |
AUDIO_DEVICE_IN_LINE |
Dùng cho giắc đầu vào AUX. |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
Đã nhận nhạc qua Bluetooth. |
AUDIO_DEVICE_IN_TELEPHONY_RX |
Dùng cho âm thanh nhận được từ hệ thống phát thanh di động liên kết với điện thoại . |
Định cấu hình thiết bị âm thanh
Thiết bị âm thanh mà 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" (dùng cho các trường hợp sử dụng trong ô tô),
"A2DP", "remote_submix" và "USB". Tên mô-đun và âm thanh tương ứng
trình điều khiển cần được biên dịch thành
audio.primary.$(variant).so
. - devicePorts. Chứa danh sách mã mô tả thiết bị cho tất cả đầu vào và đầu ra thiết bị (bao gồm cả thiết bị được gắn cố định và thiết bị có thể tháo rời) 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 bộ đ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).
- Bạn có thể sử dụng thuộc tính địa chỉ trên thực thể devicePort để tìm
thiết bị của bạn, ngay cả khi có nhiều thiết bị có cùng loại thiết bị với
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 lớp trừu tượng phần cứng (HAL) âm thanh. Mỗi thực thể MixPort có thể được coi là một luồng thực để Android AudioService.
- tuyến đường. Xác định danh sách các kết nối có thể có giữa đầu vào và đầu ra trên nhiều thiết bị hoặc giữa luồng và thiết bị.
Ví dụ sau đây xác định một thiết bị đầu ra bus0_phone_out trong đó tất cả
Các luồng âm thanh trên Android được trộn bằng Mixer_bus0_phone_out. Tuyến đường này sẽ lấy
luồng đầu ra mixer_bus0_phone_out
đến 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>