การกำหนดเส้นทางเสียง

ใน Android 10 car_audio_configuration.xml จะแทนที่ car_volumes_groups.xml และ IAudioControl.getBusForContext ในไฟล์การกำหนดค่าใหม่ จะมีการกำหนดรายการโซน แต่ละโซนมีกลุ่มวอลุ่มตั้งแต่หนึ่งกลุ่มขึ้นไปพร้อมกับอุปกรณ์ที่เกี่ยวข้อง และอุปกรณ์แต่ละชิ้นมีบริบทที่ควรกำหนดเส้นทางภายในโซนนั้น จำเป็นต้องมีการแสดงบริบททั้งหมดภายในแต่ละโซน

การกำหนดค่าการกำหนดเส้นทางเสียง

ไฟล์นโยบายด้านเสียง ซึ่งโดยทั่วไปจะอยู่ในพาร์ติชันของผู้จำหน่าย แสดงถึงการกำหนดค่าฮาร์ดแวร์ด้านเสียงของบอร์ด อุปกรณ์ทั้งหมดที่อ้างอิงใน car_audio_configuration.xml จะต้องถูกกำหนดไว้ภายใน audio_policy_configuration.xml

การเปิดใช้งานการกำหนดเส้นทาง AAOS

หากต้องการใช้การกำหนดเส้นทางตาม AAOS คุณต้องตั้งค่าสถานะ audioUseDynamicRouting เป็น true :

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

เมื่อเป็น false การกำหนดเส้นทางและ CarAudioService ส่วนใหญ่จะถูกปิดใช้งาน และระบบปฏิบัติการจะกลับไปใช้ลักษณะการทำงานเริ่มต้นของ AudioService

โซนหลัก

ตามค่าเริ่มต้น เสียงทั้งหมดจะถูกส่งไปยังโซนหลัก สามารถมีได้เพียงโซนหลักเท่านั้น ซึ่งระบุไว้ในการกำหนดค่าโดยแอ็ตทริบิวต์ isPrimary="true"

การกำหนดค่าตัวอย่าง

ตัวอย่างเช่น รถยนต์อาจมีสองโซน ได้แก่ โซนหลักและระบบความบันเทิงที่เบาะหลัง ด้วยเหตุนี้ car_audio_configuration.xml ที่เป็นไปได้จะถูกกำหนดดังนี้:

<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>

ที่นี่โซนหลักได้แยกบริบทไปยังอุปกรณ์ต่างๆ ซึ่งช่วยให้ HAL สามารถใช้เอฟเฟกต์หลังการประมวลผลที่แตกต่างกันและมิกซ์กับเอาท์พุตของอุปกรณ์แต่ละชิ้นโดยใช้ฮาร์ดแวร์ของยานพาหนะ อุปกรณ์ได้รับการจัดออกเป็นสี่กลุ่มวอลุ่ม: สื่อ ระบบนำทาง การโทร และการเตือน หากระบบได้รับการกำหนดค่าให้ useFixedVolume ระดับเสียงสำหรับแต่ละกลุ่มจะถูกส่งผ่านไปยัง HAL เพื่อนำไปใช้กับเอาต์พุตของอุปกรณ์เหล่านี้

สำหรับโซนรอง เอาต์พุตที่คาดหวังจะผ่านอุปกรณ์เอาต์พุตตัวเดียว ในตัวอย่างนี้ การใช้งานทั้งหมดจะถูกส่งไปยังอุปกรณ์เดียวและกลุ่มวอลุ่มเพื่อให้ทุกอย่างง่ายขึ้น

การกำหนดค่าเสียงโซนผู้ครอบครอง

ใน Android 11 car_audio_configuration.xml ได้รับการขยายเพิ่มเติมเพื่อแนะนำสองฟิลด์ใหม่ ได้แก่ audioZoneId และ occupantZoneId ประการแรก สามารถใช้ audioZoneId เพื่อการจัดการโซนควบคุมที่ดีขึ้น ในทางกลับกัน occupantZoneId สามารถใช้เพื่อกำหนดค่าการกำหนดเส้นทางตาม ID ผู้ใช้ได้

หากต้องการใช้ฟิลด์ใหม่เหล่านี้ จำเป็นต้องใช้ V2 ของ car_audio_configuration.xml ทบทวนการกำหนดค่าเสียงด้านบนอีกครั้ง แต่ใช้ฟิลด์ใหม่สำหรับรหัสโซนผู้ครอบครองและการแมปรหัสโซนเสียง การกำหนดค่าใหม่ที่ไม่มีคำจำกัดความกลุ่มวอลุ่มสามารถตั้งค่าได้ดังนี้:

<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>

การกำหนดค่าด้านบนกำหนดการแมปสำหรับโซนหลักกับโซนผู้ครอบครอง 0 และ audioZoneId 1 กับ occupantZoneId 1 โดยทั่วไปการแมประหว่างโซนผู้ครอบครองและโซนเสียงสามารถกำหนดค่าได้ แต่การแมปจะต้องเป็นแบบหนึ่งต่อหนึ่ง ต่อไปนี้เป็นกฎที่กำหนดฟิลด์ใหม่สองฟิลด์:

  • audioZoneId สำหรับโซนหลักจะเป็นศูนย์เสมอ
  • หมายเลข audioZoneId และ occupantZoneId ไม่สามารถทำซ้ำได้
  • audioZoneId และ occupantZoneId สามารถมีการแมปแบบหนึ่งต่อหนึ่งเท่านั้น

การกำหนดเส้นทางผ่าน UID ของแอปพลิเคชัน

ชุดของ API ที่ซ่อนอยู่ถูกนำมาใช้กับ CarAudioManager ในปี 10 เพื่อให้แอปสามารถสืบค้นและตั้งค่าโซนเสียงและโฟกัสได้

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

API ข้างต้นอนุญาตให้แอปพลิเคชันบุคคลที่หนึ่งจัดการการกำหนดเส้นทางเสียงตาม UID ของแอปพลิเคชัน ด้วยเหตุนี้ จึงจำเป็นต้องมีทั้ง ID โซนเสียงและ UID ของแอปพลิเคชันด้วย ด้วยข้อมูลดังกล่าวในมือ คุณสามารถตั้งค่าการกำหนดเส้นทางเสียงได้โดยใช้ CarAudioManager#setZoneIdForUid API

การเปลี่ยนโซนสำหรับแอป

ตามค่าเริ่มต้น เส้นทางเสียงทั้งหมดไปยังโซนหลัก หากต้องการอัปเดตแอปพลิเคชันที่จะกำหนดเส้นทางไปยังโซนอื่น ให้ใช้ 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 หมายเหตุ: สตรีมและโฟกัสไม่สามารถสลับโซนแบบไดนามิกได้ ดังนั้นจึงต้องหยุดการเล่นและขอโฟกัสอีกครั้งเพื่อเปลี่ยนโซน

การกำหนดเส้นทางด้วย ID ผู้ใช้

แม้ว่าการกำหนดเส้นทางตาม UID ของแอปพลิเคชันจะช่วยให้สามารถควบคุมการกำหนดเส้นทางเสียงของแต่ละแอปพลิเคชันได้อย่างละเอียด แต่ยังกำหนดให้กำหนดเส้นทางเสียงสำหรับแต่ละแอปพลิเคชันก่อนที่แอปพลิเคชันจะขอโฟกัสเสียงและเล่นเสียงจริงๆ เพื่อบรรเทาปัญหานี้และอำนวยความสะดวกเพิ่มเติมให้กับแอปพลิเคชันของบริษัทอื่นในการเล่นเสียงโดยไม่มีการดัดแปลง CarAudioService จะใช้โซนผู้โดยสารในรถยนต์และการแมปโซนเสียงเพื่อกำหนดเส้นทางตามรหัสผู้ใช้ ด้วยวิธีนี้ เมื่อผู้ใช้เข้าสู่ระบบโซนผู้โดยสาร บริการเครื่องเสียงรถยนต์จะได้รับแจ้ง ด้วยสัญญาณนี้ การจัดการโฟกัสเสียงและการกำหนดเส้นทางจะได้รับการกำหนดค่าโดยอัตโนมัติสำหรับโซนเสียงทั้งหมด

การกำหนดเส้นทางตาม UID ของแอปพลิเคชันยังคงสามารถใช้ได้ แต่ต้องทำโดยไม่ขึ้นอยู่กับการกำหนดเส้นทาง ID ผู้ใช้ ซึ่งหมายความว่าหากมีการกำหนดการแมปโซนผู้ครอบครองไปยังโซนเครื่องเสียงรถยนต์ การกำหนดเส้นทางตาม UID จะถูกปิดใช้งานและการพยายามเรียก CarAudioManager#setZoneidForUid จะทำให้เกิดข้อผิดพลาด

แม้ว่าการกำหนดเส้นทางเสียงและการจัดการโฟกัสจะง่ายขึ้นด้วยการจัดการโซนผู้ครอบครอง ผู้ใช้ยังคงต้องถูกกำหนดให้กับโซนผู้ครอบครอง ซึ่งสามารถทำได้โดยใช้ CarOccupantZoneManager#assignProfileUserToOccupantZone API นี้ต้องได้รับสิทธิ์ในการจัดการผู้ใช้ ความคาดหวังในปัจจุบันคือ OEM จะต้องจัดการผู้ใช้ในการกำหนดโซนผู้ครอบครองผ่าน UI ของระบบบางประเภท เมื่อเปิดใช้งานแอปพลิเคชันเสร็จแล้ว การกำหนดเส้นทางเสียง การจัดการโฟกัสทั้งหมดจะถูกกำหนดค่าให้กับผู้ใช้โดยอัตโนมัติ

การกำหนดเส้นทางด้วย setPreferredDevice

นอกจากการเปลี่ยนแปลงข้างต้นแล้ว Android 11 ยังมี API ใหม่เพื่อค้นหาอุปกรณ์เอาท์พุตที่เกี่ยวข้องกับแต่ละโซน CarAudioManager#getOutputDeviceForUsage(int ZoneId, int การใช้งาน)

API สามารถใช้เพื่อค้นหาอุปกรณ์เอาต์พุตสำหรับโซนเฉพาะและการใช้งานแอตทริบิวต์เสียง ในลักษณะนี้แอปพลิเคชันบุคคลที่หนึ่งสามารถกำหนดเส้นทางเสียงไปยังโซนต่างๆ ได้โดยใช้ setPreferredDevice API ของเครื่องเล่น getOutputDeviceForUsage API ต้องใช้ PERMISSION_CAR_CONTROL_AUDIO_SETTINGS และเป็น API ของระบบ ด้านล่างนี้เป็นตัวอย่างการค้นหาอุปกรณ์สื่อสำหรับโซนเฉพาะและการกำหนดเส้นทางไปยังอุปกรณ์นั้นโดยใช้ setPreferredDevice API

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