Android Automotive OS (AAOS) สร้างขึ้นจากสแต็กเสียงหลักของ Android เพื่อรองรับกรณีการใช้งานสำหรับระบบสาระบันเทิงในรถยนต์ AAOS มีหน้าที่รับผิดชอบต่อเสียงสาระบันเทิง (นั่นคือ สื่อ การนำทาง และการสื่อสาร) แต่จะไม่รับผิดชอบโดยตรงต่อเสียงกริ่งและคำเตือนที่มีข้อกำหนดด้านความพร้อมใช้งานและเวลาอย่างเข้มงวด แม้ว่า AAOS จะมีสัญญาณและกลไกที่ช่วยให้ยานพาหนะจัดการเสียงได้ แต่สุดท้ายแล้ว ยานพาหนะจะต้องตัดสินใจว่าควรเล่นเสียงใดให้ผู้ขับขี่และผู้โดยสารฟัง เพื่อให้มั่นใจว่าเสียงที่สำคัญต่อความปลอดภัยและเสียงตามข้อกำหนดจะได้ยินอย่างถูกต้องโดยไม่ขาดตอน
เนื่องจาก Android จัดการประสบการณ์การใช้งานสื่อของยานพาหนะ แหล่งที่มาของสื่อภายนอก เช่น เครื่องรับวิทยุ ควรแสดงโดยแอปที่จัดการโฟกัสเสียงและเหตุการณ์สำคัญเกี่ยวกับสื่อสำหรับแหล่งที่มาได้
Android 11 มีการเปลี่ยนแปลงต่อไปนี้เกี่ยวกับการรองรับเสียงที่เกี่ยวข้องกับยานยนต์
- การเลือกโซนเสียงอัตโนมัติตามรหัสผู้ใช้ที่เชื่อมโยง
- การใช้งานระบบแบบใหม่เพื่อรองรับเสียงเฉพาะยานยนต์
- การรองรับโฟกัสเสียง HAL
- โฟกัสเสียงที่ล่าช้าสำหรับสตรีมแบบถาวร
- การตั้งค่าผู้ใช้เพื่อควบคุมการโต้ตอบระหว่างการไปยังส่วนต่างๆ และการโทร
เสียงและสตรีมของ Android
ระบบเสียงยานยนต์จัดการเสียงและสตรีมต่อไปนี้
รูปที่ 1 แผนภาพสถาปัตยกรรมที่เน้นสตรีม
Android จะจัดการเสียงที่มาจากแอป Android, ควบคุมแอปเหล่านั้น และกำหนดเส้นทางเสียงไปยังอุปกรณ์เอาต์พุตที่ HAL โดยอิงตามประเภทเสียง ดังนี้
- สตรีมเชิงตรรกะหรือที่เรียกว่าแหล่งที่มาในคําศัพท์หลักของเสียงจะมีการติดแท็กแอตทริบิวต์เสียง
- สตรีมจริงหรือที่เรียกว่าอุปกรณ์ในคําศัพท์ของเสียงหลักจะไม่มีข้อมูลบริบทหลังจากมิกซ์
เสียงภายนอก (ที่มาจากแหล่งที่มาอิสระ เช่น เสียงกริ่งเตือนให้คาดเข็มขัดนิรภัย) ได้รับการจัดการนอก Android ที่อยู่ต่ำกว่า HAL หรือแม้แต่ในฮาร์ดแวร์แยกต่างหากเพื่อความเสถียร ผู้ติดตั้งระบบต้องจัดหามิกเซอร์ที่รับอินพุตเสียงอย่างน้อย 1 สตรีมจาก Android แล้วรวมสตรีมเหล่านั้นเข้ากับแหล่งเสียงภายนอกที่ยานพาหนะต้องการ
การใช้งาน HAL และมิกเซอร์ภายนอกมีหน้าที่รับผิดชอบในการตรวจสอบว่าได้ยินเสียงภายนอกที่สำคัญต่อความปลอดภัย รวมถึงผสมในสตรีมที่ Android มีให้และส่งไปยังลำโพงที่เหมาะสม
เสียงของ Android
แอปอาจมีโปรแกรมเล่นอย่างน้อย 1 รายการที่โต้ตอบผ่าน Android API มาตรฐาน (เช่น AudioManager สำหรับการควบคุมโฟกัสหรือ MediaPlayer สำหรับสตรีมมิง) เพื่อส่งสตรีมข้อมูลเสียงเชิงตรรกะอย่างน้อย 1 รายการ ข้อมูลนี้อาจเป็นโมโนแบบช่องเดียวหรือเซอร์ราวด์ 7.1 แต่ระบบจะกำหนดเส้นทางและถือว่าเป็นแหล่งที่มาเดียว สตรีมแอปจะเชื่อมโยงกับ AudioAttributes ที่บอกระบบเกี่ยวกับวิธีแสดงเสียง
ระบบจะส่งสตรีมเชิงตรรกะผ่าน AudioService และกำหนดเส้นทางไปยังสตรีมเอาต์พุตจริงที่มีอยู่ 1 (รายการเดียว) ซึ่งแต่ละรายการเป็นเอาต์พุตของมิกเซอร์ภายใน AudioFlinger หลังจากมิกซ์แอตทริบิวต์เสียงลงเป็นสตรีมจริงแล้ว แอตทริบิวต์ดังกล่าวจะใช้งานไม่ได้อีกต่อไป
จากนั้นระบบจะส่งสตรีมจริงแต่ละรายการไปยัง Audio HAL เพื่อแสดงผลบนฮาร์ดแวร์ ในแอปยานยนต์ ฮาร์ดแวร์การแสดงผลอาจเป็นตัวแปลงรหัสในเครื่อง (คล้ายกับอุปกรณ์เคลื่อนที่) หรือตัวประมวลผลระยะไกลในเครือข่ายจริงของยานพาหนะ ไม่ว่าจะด้วยวิธีใด การติดตั้งใช้งาน Audio HAL มีหน้าที่ส่งข้อมูลตัวอย่างจริงและทำให้เสียงดังขึ้น
สตรีมภายนอก
สตรีมเสียงที่ไม่ควรส่งผ่าน Android (เพื่อเหตุผลด้านเวลาหรือการรับรอง) อาจส่งไปยังมิกเซอร์ภายนอกโดยตรง ตั้งแต่ Android 11 เป็นต้นไป HAL สามารถขอโฟกัสสำหรับเสียงภายนอกเหล่านี้เพื่อแจ้งให้ Android ทราบได้ เพื่อให้ดำเนินการที่เหมาะสม เช่น หยุดสื่อชั่วคราวหรือป้องกันไม่ให้เสียงอื่นๆ ได้รับโฟกัส
หากสตรีมภายนอกเป็นแหล่งที่มาของสื่อที่ควรโต้ตอบกับสภาพแวดล้อมเสียงที่ Android สร้างขึ้น (เช่น หยุดการเล่น MP3 เมื่อเปิดเครื่องรับสัญญาณภายนอก) สตรีมภายนอกเหล่านั้นควรแสดงโดยแอป Android แอปดังกล่าวจะขอโฟกัสเสียงในนามของแหล่งที่มาของสื่อแทน HAL และจะตอบสนองต่อการแจ้งเตือนโฟกัสด้วยการเปิด/หยุดแหล่งที่มาภายนอกตามที่จำเป็นเพื่อให้สอดคล้องกับนโยบายโฟกัสของ Android แอปมีหน้าที่จัดการเหตุการณ์สําคัญของสื่อด้วย เช่น เล่น/หยุดชั่วคราว กลไกที่แนะนำในการควบคุมอุปกรณ์ภายนอกดังกล่าวคือ HwAudioSource
อุปกรณ์เอาต์พุต
ที่ระดับ Audio HAL ประเภทอุปกรณ์ AUDIO_DEVICE_OUT_BUS
จะมีอุปกรณ์เอาต์พุตทั่วไปสำหรับใช้ในระบบเสียงของยานพาหนะ อุปกรณ์บัสรองรับพอร์ตที่ระบุตำแหน่งได้ (โดยที่พอร์ตแต่ละพอร์ตเป็นปลายทางสําหรับสตรีมจริง) และคาดว่าจะเป็นอุปกรณ์เอาต์พุตประเภทเดียวที่รองรับในยานพาหนะ
การติดตั้งใช้งานระบบสามารถใช้พอร์ตบัส 1 พอร์ตสำหรับเสียงทั้งหมดของ Android ได้ ซึ่งในกรณีนี้ Android จะผสมเสียงทั้งหมดเข้าด้วยกันและส่งเป็น 1 สตรีม
หรือ HAL อาจจัดเตรียมพอร์ตบัส 1 พอร์ตสำหรับ CarAudioContext
แต่ละรายการเพื่อให้ส่งเสียงประเภทใดก็ได้พร้อมกัน วิธีนี้ช่วยให้การติดตั้งใช้งาน HAL สามารถผสมและลดเสียงต่างๆ ได้ตามต้องการ
การกำหนดบริบทเสียงให้กับอุปกรณ์เอาต์พุตทำได้ผ่าน car_audio_configuration.xml
อินพุตไมโครโฟน
เมื่อบันทึกเสียง HAL เสียงจะได้รับการเรียก openInputStream
ที่มีอาร์กิวเมนต์ AudioSource
ซึ่งระบุวิธีประมวลผลอินพุตไมโครโฟน
แหล่งที่มา VOICE_RECOGNITION
(โดยเฉพาะ Google Assistant) ต้องการสตรีมไมโครโฟนสเตอริโอที่มีเอฟเฟกต์การตัดเสียงสะท้อน (หากมี) แต่ไม่มีการประมวลผลอื่นๆ
คาดว่า Assistant จะเป็นผู้ดำเนินการจัดระเบียบสัญญาณ
อินพุตไมโครโฟนหลายช่อง
หากต้องการบันทึกเสียงจากอุปกรณ์ที่มีมากกว่า 2 ช่อง (สเตอริโอ) ให้ใช้มาสก์ดัชนีช่องแทนมาสก์ดัชนีตำแหน่ง (เช่น CHANNEL_IN_LEFT
) ตัวอย่างเช่น
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);
เมื่อตั้งค่าทั้ง setChannelMask
และ setChannelIndexMask
แล้ว AudioRecord
จะใช้เฉพาะค่าที่ setChannelMask
กำหนด (สูงสุด 2 ช่องทาง)
การจับภาพพร้อมกัน
ตั้งแต่ Android 10 เฟรมเวิร์ก Android รองรับการบันทึกอินพุตพร้อมกัน แต่มีข้อจํากัดเพื่อปกป้องความเป็นส่วนตัวของผู้ใช้ แหล่งที่มาเสมือน เช่น AUDIO_SOURCE_FM_TUNER
จะถูกละเว้นตามข้อจำกัดเหล่านี้ และระบบจึงอนุญาตให้บันทึกพร้อมกันกับอินพุตปกติ (เช่น ไมโครโฟน)
HwAudioSources
ยังไม่ถือว่าเป็นส่วนหนึ่งของข้อจำกัดการบันทึกพร้อมกัน
แอปที่ออกแบบมาให้ทำงานกับอุปกรณ์ AUDIO_DEVICE_IN_BUS
หรืออุปกรณ์ AUDIO_DEVICE_IN_FM_TUNER
รองต้องอาศัยการระบุอุปกรณ์เหล่านั้นอย่างชัดเจนและใช้ AudioRecord.setPreferredDevice()
เพื่อข้ามตรรกะการเลือกแหล่งที่มาเริ่มต้นของ Android
การใช้เสียง
AAOS จะใช้
AudioAttributes.AttributeUsages
เป็นหลักในการกำหนดเส้นทาง การปรับระดับเสียง และการจัดการโฟกัส การใช้งานแสดงถึง "เหตุผล" ที่เล่นสตรีม ดังนั้น สตรีมทั้งหมดและคำขอโฟกัสเสียงควรระบุการใช้งานสำหรับการเล่นเสียง หากไม่ได้ตั้งค่าไว้โดยเฉพาะเมื่อสร้างออบเจ็กต์ AudioAttributes ระบบจะใช้ค่าเริ่มต้นเป็น USAGE_UNKNOWN
แม้ว่าปัจจุบันระบบจะถือว่าค่านี้เหมือนกับ USAGE_MEDIA
แต่คุณไม่ควรใช้ลักษณะการทำงานนี้สำหรับการเล่นสื่อ
การใช้งานระบบ
ใน Android 11 มีการเปิดตัวการใช้งานระบบ การใช้งานเหล่านี้มีลักษณะการทำงานคล้ายกับการใช้งานที่สร้างขึ้นก่อนหน้านี้ ยกเว้นว่าต้องใช้ API ของระบบด้วยเช่นกัน รวมถึง android.permission.MODIFY_AUDIO_ROUTING
การใช้งานระบบใหม่มีดังนี้
USAGE_EMERGENCY
USAGE_SAFETY
USAGE_VEHICLE_STATUS
USAGE_ANNOUNCEMENT
หากต้องการสร้าง AudioAttributes
ที่มีการใช้งานระบบ ให้ใช้ AudioAttributes.Builder#setSystemUsage
แทน setUsage
การเรียกใช้เมธอดนี้ด้วยการใช้งานที่ไม่ใช่ระบบจะส่งผลให้ระบบแสดง IllegalArgumentException
นอกจากนี้ หากตั้งค่าทั้งการใช้งานระบบและการใช้งานในบิลเดอร์ ระบบจะแสดงIllegalArgumentException
เมื่อสร้าง
หากต้องการตรวจสอบการใช้งานที่เชื่อมโยงกับอินสแตนซ์ AudioAttributes
ให้เรียกใช้ AudioAttributes#getSystemUsage
ซึ่งจะแสดงการใช้งานหรือการใช้งานระบบที่เชื่อมโยง
บริบทเสียง
เราได้จัดกลุ่มการใช้งานที่คล้ายกันไว้ใน CarAudioContext
เพื่อลดความซับซ้อนในการกําหนดค่าเสียง AAOS บริบทเสียงเหล่านี้ใช้ใน CarAudioService
ตลอดเพื่อกำหนดการกำหนดเส้นทาง กลุ่มระดับเสียง และการจัดการโฟกัสเสียง
บริบทเสียงใน Android 11 มีดังนี้
CarAudioContext | AttributeUsages ที่เชื่อมโยง |
---|---|
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 |
การแมประหว่างบริบทและการใช้งานเสียง แถวที่ไฮไลต์มีไว้สำหรับการใช้งานระบบใหม่
เสียงแบบหลายโซน
ยานยนต์มีชุด Use Case ใหม่เกี่ยวกับผู้ใช้ที่โต้ตอบกับแพลตฟอร์มพร้อมกันและต้องการบริโภคสื่อแยกกัน เช่น คนขับสามารถเปิดเพลงในห้องโดยสารขณะที่ผู้โดยสารเบาะหลังกำลังดูวิดีโอ YouTube บนจอแสดงผลด้านหลัง เสียงหลายโซนช่วยให้การดำเนินการนี้เป็นไปได้ด้วยการอนุญาตให้แหล่งที่มาของเสียงต่างๆ เล่นพร้อมกันผ่านพื้นที่ต่างๆ ของยานพาหนะ
เสียงหลายโซนที่เริ่มตั้งแต่ Android 10 ช่วยให้ OEM กำหนดค่าเสียงเป็นโซนแยกกันได้ แต่ละโซนคือกลุ่มอุปกรณ์ภายในยานพาหนะที่มีกลุ่มระดับเสียง การกำหนดค่าการกำหนดเส้นทางสำหรับบริบท และการจัดการโฟกัสของตนเอง วิธีนี้ช่วยให้สามารถกำหนดค่าห้องโดยสารหลักเป็นโซนเสียงโซนหนึ่ง ส่วนแจ็คหูฟังของจอแสดงผลด้านหลังจะกำหนดค่าเป็นโซนที่ 2
เขตเหล่านี้ได้รับการกําหนดเป็นส่วนหนึ่งของ car_audio_configuration.xml
จากนั้น CarAudioService
จะอ่านการกำหนดค่าและช่วย AudioService กำหนดเส้นทางสตรีมเสียงตามโซนที่เชื่อมโยง แต่ละโซนจะยังคงกำหนดกฎสำหรับการกําหนดเส้นทางตามบริบทและ uid ของแอปพลิเคชัน เมื่อสร้างเพลเยอร์แล้ว CarAudioService
จะกำหนดว่าเพลเยอร์เชื่อมโยงกับโซนใด จากนั้นจะกำหนดว่า AudioFlinger ควรส่งเสียงไปยังอุปกรณ์ใดโดยอิงตามการใช้งาน
นอกจากนี้ โฟกัสจะได้รับการคงไว้แยกกันสำหรับโซนเสียงแต่ละโซน วิธีนี้ช่วยให้แอปพลิเคชันในโซนต่างๆ ผลิตเสียงได้อย่างอิสระโดยไม่รบกวนกันเอง ขณะที่แอปพลิเคชันยังคงคำนึงถึงการเปลี่ยนแปลงโฟกัสภายในโซนของตน CarZonesAudioFocus
ภายใน CarAudioService
มีหน้าที่จัดการโฟกัสสำหรับแต่ละโซน
รูปที่ 2 กำหนดค่าเสียงหลายโซน
HAL เสียง
การติดตั้งใช้งานเสียงสำหรับยานยนต์จะอาศัย HAL เสียงมาตรฐานของ Android ซึ่งประกอบด้วยรายการต่อไปนี้
IDevice.hal
. สร้างสตรีมอินพุตและเอาต์พุต, จัดการระดับเสียงหลักและการปิดเสียง และใช้สิ่งต่อไปนี้createAudioPatch
. เพื่อสร้างแพตช์ภายนอก-ภายนอกระหว่างอุปกรณ์IDevice.setAudioPortConfig()
เพื่อระบุระดับเสียงสำหรับสตรีมเวอร์ชันที่ใช้งานจริงแต่ละรายการ
IStream.hal
จัดการสตรีมมิงของตัวอย่างเสียงไปยังและจากฮาร์ดแวร์ควบคู่ไปกับตัวแปรอินพุตและเอาต์พุต
ประเภทอุปกรณ์ยานยนต์
ประเภทอุปกรณ์ต่อไปนี้เกี่ยวข้องกับแพลตฟอร์มยานยนต์
ประเภทอุปกรณ์ | คำอธิบาย |
---|---|
AUDIO_DEVICE_OUT_BUS |
เอาต์พุตหลักจาก Android (นี่คือวิธีที่ระบบส่งเสียงทั้งหมดจาก Android ไปยังรถ) ใช้สำหรับระบุที่อยู่เพื่อแยกแยะสตรีมสำหรับบริบทแต่ละรายการ |
AUDIO_DEVICE_OUT_TELEPHONY_TX |
ใช้สำหรับเสียงที่ส่งไปยังวิทยุมือถือเพื่อรับส่ง |
AUDIO_DEVICE_IN_BUS |
ใช้กับอินพุตที่ไม่ได้จัดประเภทไว้ |
AUDIO_DEVICE_IN_FM_TUNER |
ใช้กับอินพุตวิทยุกระจายเสียงเท่านั้น |
AUDIO_DEVICE_IN_TV_TUNER |
ใช้สำหรับอุปกรณ์ทีวี (หากมี) |
AUDIO_DEVICE_IN_LINE |
ใช้สำหรับแจ็คอินพุต AUX |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
เพลงที่ได้รับผ่านบลูทูธ |
AUDIO_DEVICE_IN_TELEPHONY_RX |
ใช้สำหรับเสียงที่ได้รับจากสัญญาณโทรศัพท์มือถือที่เชื่อมโยงกับการโทร |
การกำหนดค่าอุปกรณ์เสียง
อุปกรณ์เสียงที่ Android เห็นต้องกำหนดไว้ใน
/audio_policy_configuration.xml
ซึ่งมีคอมโพเนนต์ต่อไปนี้
- ชื่อโมดูล รองรับ "primary" (ใช้สำหรับกรณีการใช้งานยานยนต์), "A2DP", "remote_submix" และ "USB" ชื่อโมดูลและไดรเวอร์เสียงที่เกี่ยวข้องควรคอมไพล์เป็น
audio.primary.$(variant).so
- devicePorts มีรายการตัวระบุอุปกรณ์สำหรับอุปกรณ์อินพุตและเอาต์พุตทั้งหมด (รวมถึงอุปกรณ์ที่ต่อเชื่อมอย่างถาวรและอุปกรณ์แบบถอดออกได้) ที่เข้าถึงได้จากโมดูลนี้
- สําหรับอุปกรณ์เอาต์พุตแต่ละเครื่อง คุณสามารถกําหนดการควบคุมระดับสัญญาณที่ประกอบด้วยค่าขั้นต่ำ/สูงสุด/ค่าเริ่มต้น/ระยะห่างเป็นมิลลิเบล (1 มิลลิเบล = 1/100 dB = 1/1000 เบล)
- คุณสามารถใช้แอตทริบิวต์ที่อยู่บนอินสแตนซ์ devicePort เพื่อค้นหาอุปกรณ์ได้ แม้ว่าจะมีอุปกรณ์หลายเครื่องที่มีประเภทอุปกรณ์เดียวกับ
AUDIO_DEVICE_OUT_BUS
ก็ตาม - mixPorts มีรายการสตรีมเอาต์พุตและสตรีมอินพุตทั้งหมดที่ HAL เสียงแสดง อินสแตนซ์ mixPort แต่ละรายการจะถือเป็นสตรีมจริงไปยัง Android AudioService
- เส้นทาง กำหนดรายการการเชื่อมต่อที่เป็นไปได้ระหว่างอุปกรณ์อินพุตและเอาต์พุต หรือระหว่างสตรีมและอุปกรณ์
ตัวอย่างต่อไปนี้จะกำหนดอุปกรณ์เอาต์พุต bus0_phone_out ซึ่งระบบจะผสมสตรีมเสียง Android ทั้งหมดโดย mixer_bus0_phone_out เส้นทางจะนำสตรีมเอาต์พุตของ mixer_bus0_phone_out
ไปยังอุปกรณ์ 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>