ניהול עוצמת הקול

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

שימוש בנפחים קבועים

הטמעות של AAOS צריכות לשלוט בעוצמת הקול באמצעות מגבר חומרה במקום היא מיקסר תוכנות. כדי להימנע מתופעות לוואי, כדאי להגדיר את הדגל config_useFixedVolume מוגדר כ-true (שכבת-על לפי הצורך):

<resources>
    <!-- Car uses hardware amplifier for volume. -->
    <bool name="config_useFixedVolume">true</bool>
</resources>

כשהדגל config_useFixedVolume לא מוגדר (או מוגדר כ-False), אפליקציות יכולות לקרוא ל-AudioManager.setStreamVolume() ולשנות את עוצמת הקול לפי סוג הסטרימינג במיקסר התוכנה. יכול להיות שזה לא רצוי בגלל את ההשפעה הפוטנציאלית על אפליקציות אחרות ואת העובדה שהפחתה בנפח שמערבל התוכנה יוצר פחות ביטים משמעותיים שזמינים באות כאשר התקבל במגבר החומרה.

קבוצות נפח אחסון

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

הגדרה של קבוצות נפח אחסון

CarAudioService משתמש בקבוצות של עוצמת הקול שהוגדרו ב-car_audio_configuration.xml:

<audioZoneConfiguration version="2.0">
    <zones>
        <zone name="primary zone" isPrimary="true">
            <volumeGroups>
                <group>
                    <device address="bus0_media_out">
                        <context context="music"/>
                    </device>
                </group>
                <group>
                    <device address="bus1_navigation_out">
                        <context context="navigation"/>
                    </device>
                    <device address="bus2_voice_command_out">
                        <context context="voice_command"/>
                    </device>
                </group>
                ...
            </volumeGroups>
        </zone>
     </zones>
</audioZoneConfiguration>

הטמעה של car_audio_configuration.xml לדוגמה.

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

הגדרת היתרונות של קבוצת נפח

לכל קבוצת נפח יש ערכי מינימום, מקסימום וברירות מחדל, וגם גודל שלב. הם נקבעים לפי הערכים שהוגדרו audio_policy_configuration.xml בשביל המכשירים המשויכים עם קבוצת עוצמת הקול.

<devicePort tagName="bus0_media_out" role="sink" type="AUDIO_DEVICE_OUT_BUS" address="bus0_media_out">
  <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
  <gains>
    <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
      minValueMB="-3200" maxValueMB="600" defaultValueMB="0" stepValueMB="100"/>
  </gains>
</devicePort>

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

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

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

מזהים של קבוצות נפח אחסון

קבוצות נפח אחסון מזוהות בזמן ריצה לפי סדר ההגדרה שלהן בקובץ ה-XML. המזהים נעים בין 0 ל-N-1 באזור אודיו, כאשר N הוא מספר הקבוצות של עוצמת הקול תחום זה. באופן הזה, המזהים של קבוצות נפח אחסון לא ייחודיים בכל התחומים. המזהים האלה משמשים ל-CarAudioManager ממשקי API שמשויכים לקבוצות נפח אחסון. כל ממשק API שמקבלת groupId בלי zoneId, תקבל כברירת מחדל את הערך אזור האודיו הראשי.

ניהול עוצמת הקול במספר אזורים

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

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

טיפול באירועים מרכזיים של נפח אחסון

ב-Android מוגדרים כמה קודי מפתחות לבקרת עוצמת הקול, כולל KEYCODE_VOLUME_UP, KEYCODE_VOLUME_DOWN וגם KEYCODE_VOLUME_MUTE. כברירת מחדל, מערכת Android מנתבת את מקש עוצמת הקול אירועים לאפליקציות. בהטמעות של כלי רכב צריך לאלץ את האירועים המרכזיים האלה CarAudioService, שיכול להתקשר לאחר מכן ל-setGroupVolume או setMasterMute לפי הצורך.

כדי לאלץ את ההתנהגות הזו, צריך להגדיר את config_handleVolumeKeysInWindowManager דיווח ל-true:

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

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

עמעום ואיזון

שתי הגרסאות של AudioControl HAL כוללות ממשקי API להגדרת עמעום ואיזון את הרכב. יש ממשקי API תואמים של CarAudioManager שמעבירים ערכים ועד AudioControl HAL. ממשקי ה-API האלה מחייבים android.car.permission.CAR_CONTROL_AUDIO_VOLUME

ממשקי ה-API של AudioControl API הם:

  • setBalanceTowardRight(float value) משנה את עוצמת הקול של הרמקול הצד הימני (+) או השמאלי (-) של הרכב. 0.0 במרכז, +1.0 נכון לחלוטין, הערך 1.0- נשאר במלואו, וערך מחוץ לטווח של -1 עד 1 הוא שגיאה.
  • setFadeTowardFront(float value) – העברת עוצמת הקול של הרמקול לכיוון הצד הקדמי (+) או האחורי (-) של הרכב. הספרה 0.0 במרכז, +1.0 קדימה במלואה, הערך -1.0 מקביל לספירה לאחור, וערך מחוץ לטווח של -1 עד 1 הוא שגיאה.

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

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

הנמכה של עוצמת השמע

הנמכה של עוצמת השמע מתרחש כשהרכב מפחית את עוצמת הקול בשידור אחד כדי שניתן יהיה לשמוע בצורה ברורה יותר שידור אחר שמושמע בו-זמנית. ב-AAOS, ההטמעה של 'הנמכה של עוצמת השמע' תלויה בהטמעה ב-HAL כי יכול להיות שיש הרבה צלילים מחוץ ל-Android, שאין למערכת ההפעלה שליטה עליהם. ב-Android 11, המידע העיקרי שזמין ל-HAL כדי לקבל החלטות מושכלות הוא האם שני מכשירי פלט שידורים פעילים.

מתי לוותר

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

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

התנהגות מומלצת של פונקציית החלמה

ברשימה הבאה מפורטות אינטראקציות אפשריות בו-זמנית שבהן מומלץ להפסיק את השימוש בפונקציית השיפור ליישום:

  • EMERGENCY אפשר להסתיר או להשתיק את כל התוכן חוץ מ-SAFETY כדי מוודאים שהנהג שומע את הצליל
  • SAFETY אפשר להוסיף או לסמן את כל הפריטים מלבד EMERGENCY כדי לוודא הנהג שומע את הצליל
  • NAVIGATION הוספת הפרעות לכל הפריטים חוץ מ-SAFETY ו- EMERGENCY
  • CALL מוסיפים למערכת את כל הפריטים חוץ מ-SAFETY, EMERGENCY וגם NAVIGATION
  • VOICE ברווז CALL_RING
  • יצרני הציוד המקורי הם אלה שקובעים את רמת החשיבות של VEHICLE_SOUNDS הפעיל ואם צריך לנמנם צלילים אחרים כדי לוודא שהנהג ישמע אותם.
  • של MUSIC ושל ANNOUNCEMENT צריך להשפיע על כל ההגדרות. היוצא מן הכלל העיקרי הוא צלילי אינטראקציה במגע, שמושמעים כרגע בתור SYSTEM_SOUND

שיקולים נוספים שאפשר להתחשב בהם

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

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

צלילים חיוניים להגנה על הבטיחות

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

קביעת ממשק המשתמש להגדרות עוצמת הקול

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

בממשק המשתמש של הגדרות הרכב, packages/apps/Car/Settings/res/xml/car_volume_items.xml מכיל רכיבי ממשק משתמש (משאבי כותרת וסמל) שמשויכים לכל מוגדר AudioAttributes.USAGE. הקובץ הזה מספק עיבוד סביר של את VolumeGroups המוגדר באמצעות המשאבים שמשויכים השימוש המזוהה בכל VolumeGroup.

לדוגמה, הדוגמה הבאה מגדירה VolumeGroup ככולל את שני הסוגים voice_communication וגם voice_communication_signalling ברירת המחדל של ממשק המשתמש של הגדרות הרכב מעבד את קבוצת הנפח באמצעות המשאבים המשויכים עם voice_communication, כי זו המילה הראשונה בקובץ.

<carVolumeItems xmlns:car="http://schemas.android.com/apk/res-auto">
    <item car:usage="voice_communication"
          car:title="@*android:string/volume_call"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="voice_communication_signalling"
          car:title="@*android:string/volume_call"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="media"
          car:title="@*android:string/volume_music"
          car:icon="@*android:drawable/ic_audio_media"/>
    <item car:usage="game"
          car:title="@*android:string/volume_music"
          car:icon="@*android:drawable/ic_audio_media"/>
    <item car:usage="alarm"
          car:title="@*android:string/volume_alarm"
          car:icon="@*android:drawable/ic_audio_alarm"/>
    <item car:usage="assistance_navigation_guidance"
          car:title="@string/navi_volume_title"
          car:icon="@drawable/ic_audio_navi"/>
    <item car:usage="notification_ringtone"
          car:title="@*android:string/volume_ringtone"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="assistant"
          car:title="@*android:string/volume_unknown"
          car:icon="@*android:drawable/ic_audio_vol"/>
    <item car:usage="notification"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_communication_request"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_communication_instant"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_communication_delayed"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="notification_event"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="assistance_accessibility"
          car:title="@*android:string/volume_notification"
          car:icon="@*android:drawable/ic_audio_ring_notif"/>
    <item car:usage="assistance_sonification"
          car:title="@*android:string/volume_unknown"
          car:icon="@*android:drawable/ic_audio_vol"/>
    <item car:usage="unknown"
          car:title="@*android:string/volume_unknown"
          car:icon="@*android:drawable/ic_audio_vol"/>
</carVolumeItems>

המאפיינים והערכים שנעשה בהם שימוש בהגדרה שלמעלה מוצהרים ב- packages/apps/Car/Settings/res/values/attrs.xml הגדרות עוצמת הקול ממשק המשתמש משתמש בממשקי ה-API הבאים של CarAudioManager שמבוססים על VolumeGroup.

  • getVolumeGroupCount() כדי לדעת כמה פקדים יש לצייר.
  • getGroupMinVolume() ו-getGroupMaxVolume() כדי להגיע לגבול התחתון ולגבול העליון.
  • getGroupVolume() כדי לקבל את עוצמת הקול הנוכחית.
  • registerVolumeChangeObserver() כדי לקבל התראות על שינויים בעוצמת הקול.