מערכת ההפעלה Android Automotive OS (AAOS) מבוססת על סטאק האודיו של Android כדי לתמוך בתרחישי השימוש לתפעול כמערכת מידע ובידור ברכב. AAOS אחראית על צלילים של מערכות בידור (כלומר מדיה, ניווט ותקשורת), אבל היא לא אחראית ישירות על צפצופים והתראות שיש להן דרישות זמינות ותזמון קפדניות. מערכת AAOS מספקת אותות ומנגנונים שיעזרו לרכב לנהל את האודיו, אבל בסופו של דבר הרכב הוא זה שמחליט אילו צלילים צריך להשמיע לנהג ולנוסעים, כדי לוודא שצלילים קריטיים לבטיחות וצלילים רגולטוריים נשמעים בצורה תקינה ללא הפרעה.
מערכת Android מנהלת את חוויית המדיה ברכב, ולכן מקורות מדיה חיצוניים כמו מכשיר הרדיו צריכים להיות מיוצגים על ידי אפליקציות שיכולות לטפל בפוקוס האודיו ובאירועי מפתח של מדיה עבור המקור.
ב-Android 11 יש שינויים בתמיכה באודיו שקשור לכלי רכב:
- בחירה אוטומטית של אזור אודיו על סמך מזהה המשתמש המשויך
- שימושים חדשים במערכת לתמיכה בצליל ספציפי לכלי רכב
- תמיכה ב-HAL audio focus
- התמקדות באודיו עם עיכוב בשידורים לא חולפים
- הגדרת משתמש לניהול האינטראקציה בין הניווט לשיחות
צלילים ומקורות נתונים ב-Android
מערכות אודיו לרכב מטפלות בצלילים ובשידורים הבאים:
איור 1. תרשים ארכיטקטורה שמתמקד בסטרימינג
מערכת Android מנהלת את הצלילים שמגיעים מאפליקציות ל-Android, שולחת אותם למכשירי הפלט ב-HAL בהתאם לסוג הקול:
- שידורים לוגיים, שנקראים מקורות במינוח הבסיסי של אודיו, מתויגים באמצעות מאפייני אודיו.
- שידורים פיזיים, שנקראים 'מכשירים' במינוח של אודיו ליבה, לא מכילים מידע על ההקשר אחרי המיקס.
כדי לשמור על מהימנות, צלילים חיצוניים (שמגיעים ממקורות עצמאיים, כמו צפצופים של אזהרה לחגירת חגורות בטיחות) מנוהלים מחוץ ל-Android, מתחת ל-HAL או אפילו בחומרה נפרדת. מפתחי המערכות חייבים לספק מיקסר שמקבל שידור אחד או יותר של קלט אודיו מ-Android, ולאחר מכן משלבים את השידורים האלה באופן מתאים עם מקורות האודיו החיצוניים הנדרשים ברכב.
הטמעת ה-HAL והמיקסר החיצוני אחראים לוודא שהצלילים החיצוניים שחשובים לבטיחות נשמעים, ולמיקס של הסטרימינג ש-Android מספקת ולניתוב שלו לרמקולים מתאימים.
צלילים ב-Android
אפליקציות יכולות לכלול נגן אחד או יותר שמקיים אינטראקציה דרך ממשקי ה-API הרגילים של Android (לדוגמה, AudioManager לצורך בקרת המיקוד או MediaPlayer לצורך סטרימינג) כדי לשדר שידור לוגית אחד או יותר של נתוני אודיו. הנתונים האלה יכולים להיות מונו בערוץ יחיד או סראונד 7.1, אבל הם מנותבים ומטופלים כמקור יחיד. הסטרימינג של האפליקציה משויך ל-AudioAttributes שמספקים למערכת רמזים לגבי האופן שבו צריך להביע את האודיו.
ההזרמים הלוגיים נשלחים דרך AudioService ומנותבים לאחד (וגם רק לאחד) מהזרמים הפיזיים הזמינים של הפלט, שכל אחד מהם הוא הפלט של מיקסר ב-AudioFlinger. אחרי שמערבבים את מאפייני האודיו לשידור פיזי, הם כבר לא זמינים.
לאחר מכן, כל שידור פיזי מועבר ל-Audio HAL לצורך עיבוד (רנדרינג) בחומרה. באפליקציות לכלי רכב, חומרת הרינדור יכולה להיות קודיקים מקומיים (בדומה למכשירים ניידים) או מעבד מרוחק ברשת הפיזית של הרכב. בכל מקרה, תפקיד ההטמעה של Audio HAL הוא לספק את נתוני הדגימה בפועל ולהפוך אותם לקולות שאפשר לשמוע.
מקורות חיצוניים
אפשר לשלוח ישירות למיקסר החיצוני מקורות קול שלא צריך לנתב דרך Android (מסיבות שקשורות לאישור או לתזמון). החל מ-Android 11, ה-HAL יכול לבקש להתמקד בצלילים החיצוניים האלה כדי להודיע ל-Android שיוכל לבצע פעולות מתאימות, כמו השהיית המדיה או מניעת התמקדות של אחרים.
אם מקורות אודיו חיצוניים הם מקורות מדיה שצריכים לקיים אינטראקציה עם סביבת האודיו שמערכת Android יוצרת (לדוגמה, להפסיק את ההפעלה של קובץ MP3 כשמפעילים מכוון חיצוני), מקורות האודיו החיצוניים האלה צריכים להיות מיוצגים על ידי אפליקציית Android. אפליקציה כזו תבקש להתמקד באודיו בשם מקור המדיה במקום HAL, ותגיב להתראות על התמקדות על ידי הפעלה או השבתה של המקור החיצוני לפי הצורך, בהתאם למדיניות ההתמקדות של Android. האפליקציה אחראית גם לטיפול באירועים מרכזיים של מדיה, כמו הפעלה/השהיה. אחד המנגנונים המוצעים לשלוט במכשירים חיצוניים כאלה הוא HwAudioSource.
התקני פלט
ברמת Audio HAL, סוג המכשיר AUDIO_DEVICE_OUT_BUS
מספק מכשיר פלט גנרי לשימוש במערכות אודיו ברכב. מכשיר האוטובוס תומך ביציאות שניתן לשלוח אליהן כתובות (כל יציאה היא נקודת הקצה של שידור פיזי), והוא אמור להיות סוג מכשיר הפלט היחיד שנתמך ברכב.
הטמעה של מערכת יכולה להשתמש ביציאת אוטובוס אחת לכל הצלילים ב-Android. במקרה כזה, Android משלבת את כל הצלילים ומעבירה אותם כסטרימינג אחד.
לחלופין, ה-HAL יכול לספק יציאת בורר אחת לכל CarAudioContext
כדי לאפשר העברה בו-זמנית של כל סוג של צליל. כך אפשר לשלב את הקולות השונים ולהפחית את עוצמת הקול שלהם לפי הצורך בהטמעת HAL.
הקצאת הקשרי האודיו למכשירי הפלט מתבצעת באמצעות car_audio_configuration.xml
.
קלט מיקרופון
כשמצלמים אודיו, ה-HAL של האודיו מקבל קריאה מסוג openInputStream
שכוללת ארגומנט AudioSource
שמציין איך צריך לעבד את הקלט מהמיקרופון.
המקור VOICE_RECOGNITION
(במיוחד Google Assistant) מצפה לשידור מיקרופון סטריאופוני עם אפקט ביטול הד (אם הוא זמין), אבל ללא עיבוד אחר.
יצירת האלומה צפויה להתבצע על ידי Assistant.
קלט מיקרופון בכמה ערוצים
כדי לתעד אודיו ממכשיר עם יותר משני ערוצים (סטריאו), צריך להשתמש במסכת אינדקס ערוצים במקום במסכת אינדקס מיקומי (כמו 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
(עד שני ערוצים).
צילום בו-זמנית
החל מ-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
. בנוסף, אם מוגדרים ב-builder גם שימוש במערכת וגם שימוש, תופיע הודעת השגיאה IllegalArgumentException
במהלך ה-build.
כדי לבדוק איזה שימוש משויך למכונה של AudioAttributes
, צריך להפעיל את הפונקציה AudioAttributes#getSystemUsage
.
הפונקציה מחזירה את השימוש או את השימוש במערכת שמשויך.
הקשרים של אודיו
כדי לפשט את ההגדרה של אודיו ב-AAOS, שימושים דומים מקובצים ב-CarAudioContext
. הקשרי האודיו האלה משמשים לאורך CarAudioService
כדי להגדיר ניתוב, קבוצות עוצמת קול וניהול של מוקד האודיו.
ההקשרים של האודיו ב-Android 11 הם:
CarAudioContext | Associated 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 |
מיפוי בין הקשרים של אודיו לבין שימושים. השורות המודגשות מייצגות שימוש חדש במערכת.
אודיו בכמה אזורים
בתחום הרכב יש קבוצה חדשה של תרחישים לדוגמה לגבי משתמשים בו-זמניים שמקיימים אינטראקציה עם הפלטפורמה ומחפשים לצרוך מדיה נפרדת. לדוגמה, הנהג יכול להפעיל מוזיקה בתא הנוסעים בזמן שהנוסעים במושב האחורי צופים בסרטון YouTube במסך האחורי. אודיו בכמה תחומים מאפשר להפעיל בו-זמנית מקורות אודיו שונים באזורים שונים ברכב.
החל מגרסה 10 של Android, אודיו במספר תחומים מאפשר ליצרני ציוד מקורי להגדיר אודיו באזורים נפרדים. כל תחום הוא אוסף של מכשירים ברכב, עם קבוצות נפח, הגדרות ניתוב להקשרים וניהול של מוקד. כך אפשר להגדיר את תא הנוסעים הראשי כאזור אודיו אחד, ואת שקעי האוזניות במסך האחורי כאזור שני.
התחומים מוגדרים כחלק מ-car_audio_configuration.xml
.
לאחר מכן, CarAudioService
קורא את ההגדרות ועוזר ל-AudioService לנתב את שידורי האודיו על סמך האזור המשויך להם. בכל תחום עדיין מוגדרים כללים לניתוב על סמך הקשרים וה-uid של האפליקציות. כשיוצרים נגן, CarAudioService
קובע לאיזה תחום הנגן משויך, ולאחר מכן, על סמך השימוש, קובע לאיזה מכשיר AudioFlinger צריך לנתב את האודיו.
כמו כן, המיקוד נשמר בנפרד לכל אזור אודיו. כך אפליקציות באזורים שונים יכולות ליצור אודיו באופן עצמאי בלי להפריע אחת לשנייה, ועדיין לשמור על שינויים במיקוד באזור שלהן. CarZonesAudioFocus
בתוך CarAudioService
אחראי לניהול המיקוד בכל אזור.
איור 2. הגדרת אודיו בכמה תחומים
Audio HAL
הטמעות אודיו לכלי רכב מסתמכות על Android Audio HAL הסטנדרטי, שכולל את הרכיבים הבאים:
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 |
מוזיקה שהתקבלה דרך Bluetooth. |
AUDIO_DEVICE_IN_TELEPHONY_RX |
משמש לאודיו שמתקבל מהרדיו הסלולרי שמשויך לשיחה בטלפון. |
הגדרת מכשירי אודיו
מכשירי אודיו שגלויים ל-Android צריכים להיות מוגדרים ב-/audio_policy_configuration.xml
, שכולל את הרכיבים הבאים:
- שם המודול. תמיכה ב-'primary' (משמש לתרחישי שימוש ברכב), ב-'A2DP', ב-'remote_submix' וב-'USB'. צריך לקמפל את שם המודול ואת מנהל האודיו התואם ל-
audio.primary.$(variant).so
. - devicePorts. מכיל רשימה של מתארי מכשירים לכל מכשירי הקלט והפלט (כולל מכשירים מחוברים באופן קבוע ומכשירים נשלפים) שאפשר לגשת אליהם מהמודול הזה.
- לכל מכשיר פלט, אפשר להגדיר בקרת רווח שמכילה ערכים של מינימום/מקסימום/ברירת מחדל/שלב במיליבלים (1 מיליבלים = 1/100 דציבלים = 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>