אודיו לרכב

מערכת ההפעלה Android Automotive (AAOS) מבוססת על מחסנית השמע של אנדרואיד כדי לתמוך במקרים של שימוש להפעלה כמערכת המידע והבידור ברכב. AAOS אחראית על צלילי מידע בידור (כלומר, מדיה, ניווט ותקשורת) אך אינה אחראית ישירות לצלצולים ואזהרות שיש להם דרישות זמינות ותזמון קפדניות. בעוד ש-AAOS מספקת אותות ומנגנונים שיעזרו לרכב לנהל אודיו, בסופו של דבר זה תלוי ברכב לבצע את הקריאה לגבי אילו צלילים יש להשמיע לנהג ולנוסעים, מה שמבטיח שצלילים קריטיים לבטיחות וצלילי רגולציה יישמעו כראוי ללא הַפרָעָה.

מכיוון ש-Android מנהלת את חווית המדיה של הרכב, מקורות מדיה חיצוניים כגון מקלט הרדיו צריכים להיות מיוצגים על ידי אפליקציות, שיכולות להתמודד עם מיקוד אודיו ואירועי מפתח מדיה עבור המקור.

אנדרואיד 11 כולל את השינויים הבאים לתמיכה באודיו הקשורה לרכב:

צלילים וזרמים של אנדרואיד

מערכות שמע לרכב מטפלות בצלילים ובזרמים הבאים:

דיאגרמת ארכיטקטורה ממוקדת בזרם

איור 1. דיאגרמת ארכיטקטורה ממוקדת זרמים

אנדרואיד מנהלת את הצלילים המגיעים מאפליקציות אנדרואיד, שולטת באפליקציות הללו ומנתבת את הצלילים שלהן למכשירי פלט ב-HAL בהתבסס על סוג הצליל:

  • זרמים לוגיים , הידועים כמקורות במינוח האודיו הליבה, מתויגים עם תכונות אודיו .
  • לזרמים פיזיים , הידועים כמכשירים במינוח אודיו הליבה, אין מידע הקשר לאחר ערבוב.

לצורך אמינות, צלילים חיצוניים (המגיעים ממקורות עצמאיים כמו פעמוני אזהרה של חגורות בטיחות) מנוהלים מחוץ לאנדרואיד, מתחת ל-HAL או אפילו בחומרה נפרדת. מיישמי מערכת חייבים לספק מיקסר המקבל זרם אחד או יותר של קלט קול מאנדרואיד ולאחר מכן משלב את הזרמים הללו בצורה מתאימה עם מקורות הקול החיצוניים הנדרשים על ידי הרכב.

מימוש ה-HAL והמיקסר החיצוני אחראים לוודא שהצלילים החיצוניים הקריטיים לבטיחות נשמעים ולערבוב בזרמים המסופקים על ידי אנדרואיד וניתובם לרמקולים מתאימים.

צלילי אנדרואיד

לאפליקציות עשויות להיות נגן אחד או יותר המקיימים אינטראקציה דרך ממשקי ה-API הסטנדרטיים של אנדרואיד (לדוגמה, AudioManager לבקרת מיקוד או MediaPlayer לסטרימינג) כדי לפלוט זרם לוגי אחד או יותר של נתוני אודיו. נתונים אלה יכולים להיות מונו ערוץ יחיד או 7.1 סראונד, אך הם מנותבים ומטופלים כמקור יחיד. זרם האפליקציה משויך ל- AudioAttributes שנותנים למערכת רמזים לגבי אופן הביטוי של האודיו.

הזרמים הלוגיים נשלחים דרך AudioService ומנותבים לאחד (ורק אחד) מזרמי הפלט הפיזיים הזמינים, שכל אחד מהם הוא פלט של מיקסר בתוך AudioFlinger. לאחר ערבוב תכונות האודיו לזרם פיזי, הן אינן זמינות עוד.

לאחר מכן כל זרם פיזי מועבר ל- Audio HAL לצורך רינדור בחומרה. באפליקציות רכב, חומרת רינדור יכולה להיות קודקים מקומיים (בדומה למכשירים ניידים) או מעבד מרוחק ברחבי הרשת הפיזית של הרכב. כך או כך, תפקידו של יישום Audio HAL לספק את נתוני הדגימה בפועל ולגרום להם להיות נשמעים.

זרמים חיצוניים

זרמי סאונד שאסור לנתב דרך אנדרואיד (מסיבות הסמכה או תזמון) עשויים להישלח ישירות למיקסר החיצוני. החל מ-Android 11, ה-HAL יכול כעת לבקש מיקוד עבור צלילים חיצוניים אלה כדי ליידע את אנדרואיד כך שהוא יוכל לנקוט בפעולות מתאימות כגון השהיית מדיה או מניעת מיקוד מאחרים.

אם זרמים חיצוניים הם מקורות מדיה שאמורים לקיים אינטראקציה עם סביבת הסאונד ש-Android מייצרת (לדוגמה, הפסק את השמעת MP3 כאשר מקלט חיצוני מופעל), הזרמים החיצוניים האלה צריכים להיות מיוצגים על ידי אפליקציית Android. אפליקציה כזו תבקש מיקוד אודיו בשם מקור המדיה במקום ה-HAL, ותגיב להודעות מיקוד על ידי הפעלה/עצירה של המקור החיצוני לפי הצורך כדי להשתלב במדיניות המיקוד של אנדרואיד. האפליקציה אחראית גם לטיפול באירועי מפתח במדיה כגון הפעלה/השהיה. מנגנון אחד שהוצע לשליטה במכשירים חיצוניים מסוג זה הוא HwAudioSource .

התקני פלט

ברמת Audio HAL, ההתקן מסוג AUDIO_DEVICE_OUT_BUS מספק התקן פלט גנרי לשימוש במערכות שמע לרכב. התקן האוטובוס תומך ביציאות הניתנות להתייחסות (כאשר כל יציאה היא נקודת הסיום לזרם פיזי) וצפוי להיות סוג התקן הפלט הנתמך היחיד ברכב.

מימוש מערכת יכול להשתמש ביציאת אוטובוס אחת עבור כל צלילי האנדרואיד, ובמקרה זה אנדרואיד מערבבת הכל יחד ומעבירה אותו כזרם אחד. לחלופין, ה-HAL יכול לספק יציאת אוטובוס אחת לכל CarAudioContext כדי לאפשר אספקה ​​במקביל מכל סוג צליל. זה מאפשר למימוש HAL לערבב ולבלוע את הצלילים השונים כרצונך.

הקצאת הקשרי שמע להתקני פלט מתבצעת דרך car_audio_configuration.xml .

כניסת מיקרופון

בעת לכידת אודיו, ה- Audio HAL מקבל שיחת openInputStream הכוללת ארגומנט AudioSource המציין כיצד יש לעבד את קלט המיקרופון.

מקור ה- VOICE_RECOGNITION (במיוחד Google Assistant) מצפה לזרם מיקרופון סטריאו בעל אפקט ביטול הד (אם זמין) אך לא הוחל עליו עיבוד אחר. ה-Beamforming צפוי להתבצע על ידי ה-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 (מקסימום שני ערוצים).

לכידה במקביל

החל מאנדרואיד 10, מסגרת האנדרואיד תומכת בלכידת קלט במקביל, אך עם הגבלות להגנה על פרטיות המשתמש. כחלק מהמגבלות אלו, מתעלמים ממקורות וירטואליים כגון 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 , אין להסתמך על התנהגות זו להפעלת מדיה.

שימושי מערכת

באנדרואיד 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 . זה מחזיר את השימוש או את השימוש במערכת המשויכים.

הקשרי אודיו

כדי לפשט את התצורה של אודיו AAOS, שימושים דומים קובצו לתוך CarAudioContext . הקשרי אודיו אלה משמשים ברחבי CarAudioService כדי להגדיר ניתוב, קבוצות עוצמת קול וניהול מיקוד אודיו.

הקשרי האודיו באנדרואיד 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

מיפוי בין הקשרי אודיו ושימושים. השורות המודגשות מיועדות לשימושים חדשים במערכת .

אודיו מרובה אזורים

עם הרכב מגיע סט חדש של מקרי שימוש סביב משתמשים בו-זמנית המקיימים אינטראקציה עם הפלטפורמה ומחפשים לצרוך מדיה נפרדת. לדוגמה, נהג יכול להשמיע מוזיקה בתא הנוסעים בזמן שהנוסעים במושב האחורי צופים בסרטון יוטיוב בתצוגה האחורית. אודיו מרובה אזורים מאפשר זאת על ידי מתן אפשרות למקורות שמע שונים לנגן במקביל דרך אזורים שונים של הרכב.

אודיו מרובה אזורים שמתחיל באנדרואיד 10 מאפשר ליצרני OEM להגדיר את האודיו לאזורים נפרדים. כל אזור הוא אוסף של מכשירים בתוך הרכב עם קבוצות נפח משלו, תצורת ניתוב להקשרים וניהול מיקוד. באופן זה, תא הנוסעים הראשי יכול להיות מוגדר כאזור שמע אחד, בעוד ששקעי האוזניות של הצג האחורי יוגדרו כאזור שני.

האזורים מוגדרים כחלק מ- car_audio_configuration.xml . לאחר מכן CarAudioService קורא את התצורה ומסייע ל-AudioService לנתב זרמי אודיו על סמך האזור המשויך להם. כל אזור עדיין מגדיר כללים לניתוב בהתבסס על הקשרים ו-Uid של היישומים. כאשר נגן נוצר, CarAudioService קובע לאיזה אזור הנגן משויך, ולאחר מכן בהתבסס על השימוש, לאיזה מכשיר ה-AudioFlinger צריך לנתב את האודיו.

המיקוד נשמר גם באופן עצמאי עבור כל אזור שמע. זה מאפשר ליישומים באזורים שונים להפיק אודיו באופן עצמאי מבלי להפריע זה לזה, בעוד יישומים עדיין מכבדים את השינויים במיקוד בתוך האזור שלהם. CarZonesAudioFocus בתוך CarAudioService אחראית לניהול המיקוד עבור כל אזור.

הגדר אודיו מרובה אזורים

איור 2. הגדר אודיו מרובה אזורים

אודיו HAL

יישומי אודיו לרכב מסתמכים על ה-Android Audio HAL הסטנדרטי, הכולל את הדברים הבאים:

  • IDevice.hal . יוצר זרמי קלט ופלט, מטפל בעוצמת הקול וההשתקה הראשית ומשתמש ב:
    • createAudioPatch . ליצירת תיקונים חיצוניים-חיצוניים בין מכשירים.
    • IDevice.setAudioPortConfig() כדי לספק נפח עבור כל זרם פיזי.
  • IStream.hal . יחד עם גרסאות הקלט והפלט, מנהל את הזרמת דגימות השמע אל החומרה וממנה.

סוגי מכשירי רכב

סוגי המכשירים הבאים רלוונטיים עבור פלטפורמות רכב.

סוג מכשיר תיאור
AUDIO_DEVICE_OUT_BUS פלט ראשי מאנדרואיד (כך כל האודיו מאנדרואיד מועבר לרכב). משמשת ככתובת לחלוקת זרמים לכל הקשר.
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 .
  • יציאות מכשירים. מכיל רשימה של מתארי התקנים עבור כל התקני הקלט והפלט (כולל התקנים מחוברים לצמיתות והתקנים נשלפים) שניתן לגשת אליהם ממודול זה.
    • עבור כל התקן פלט, ניתן להגדיר בקרת רווח המורכבת מערכי min/max/ברירת מחדל/צעד במיליבל (1 מיליליבל = 1/100 dB = 1/1000 בל).
    • ניתן להשתמש בתכונת הכתובת במופע devicePort כדי למצוא את ההתקן, גם אם יש מספר מכשירים עם אותו סוג מכשיר כמו AUDIO_DEVICE_OUT_BUS .
  • mixPorts. מכיל רשימה של כל זרמי הפלט והקלט שנחשפו על ידי HAL האודיו. כל מופע mixPort יכול להיחשב כזרם פיזי ל-Android AudioService.
  • מסלולים. מגדיר רשימה של חיבורים אפשריים בין התקני קלט ופלט או בין זרם להתקן.

הדוגמה הבאה מגדירה התקן פלט bus0_phone_out שבו כל זרמי האודיו של אנדרואיד מעורבבים על ידי 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>