איך מוסיפים אודיו מרחבי לאפליקציית XR

התכונות של אודיו מרחבי ב-Jetpack SceneCore מאפשרות לכם ליצור חוויות אודיו עשירות באפליקציות Android XR.

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

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

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

אם אתם מבצעים אופטימיזציה של האפליקציה שלכם ל-XR, ‏ Jetpack SceneCore מספק כלים להתאמה אישית מתקדמת של אודיו מרחבי. אתם יכולים למקם צלילים בצורה מדויקת בסביבה תלת-ממדית, להשתמש באודיו אמביסוני כדי ליצור שדות צליל מציאותיים וליהנות משילוב מובנה של סראונד.

סוגים של אודיו מרחבי שזמינים ב-Android XR

‫Android XR תומך באודיו מיקומי, סטריאו, סראונד ואמביסוניק.

אודיו מיקומי

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

סטריאו מרחבי וצליל סראונד

כל פורמטי המדיה של Android נתמכים עבור אודיו מרחבי, סטריאו וסראונד.

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

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

אודיו אמביסוני

אודיו אמביסוניק (או אמביסוניקס) הוא כמו תא צפייה פרטי לאודיו, ומספק למשתמשים סביבת צליל סוחפת. משתמשים באמביסוניקס לצלילי רקע של הסביבה או בתרחישים אחרים שבהם רוצים לשכפל שדה צליל כדורי מלא שמקיף את המאזין. ‫Android XR תומך בפורמט האודיו האמביסוני AmbiX באמביסוניקס מסדר ראשון, שני ושלישי. אנחנו ממליצים על סוגי הקבצים Opus ‏ (.ogg) ו-PCM/Wave ‏ (.wav).

שימוש באודיו מרחבי עם Jetpack SceneCore

כדי להטמיע אודיו מרחבי באמצעות Jetpack SceneCore, צריך לבדוק את היכולות המרחביות ולבחור API לטעינת אודיו מרחבי.

בדיקת יכולות מרחביות

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

טעינת אודיו מרחבי

אפשר להשתמש בכל אחד מממשקי ה-API הבאים כדי לטעון אודיו מרחבי לשימוש ב-Jetpack SceneCore.

  • SoundPool: מתאים לאפקטים קצרים של צלילים בגודל של פחות מ-1MB. הם נטענים מראש ואפשר להשתמש בצלילים שוב ושוב. זו דרך מצוינת לטעון אודיו לאודיו מרחבי.
  • ExoPlayer: מתאים במיוחד לטעינת תוכן סטריאו וסראונד, כמו מוזיקה וסרטונים. היא מאפשרת גם הפעלת מדיה ברקע.
  • MediaPlayer: הדרך הכי פשוטה לטעון אודיו אמביסוני.
  • AudioTrack: מאפשר שליטה רבה יותר באופן טעינת נתוני האודיו. מאפשרת לכתוב ישירות מאגרי אודיו, או אם ביצעתם סינתזה או פענוח של קובצי אודיו משלכם.

הוספת אודיו מרחבי לאפליקציה

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

דוגמה לאודיו מיקומי

בדוגמה הבאה, קובץ אודיו של אפקט קולי נטען למאגר הצלילים ומושמע במיקום של Entity.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities
    .hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)
) { // The session has spatial audio capabilities
    val maxVolume = 1F
    val lowPriority = 0
    val infiniteLoop = -1
    val normalSpeed = 1F

    val soundPool = SoundPool.Builder()
        .setAudioAttributes(
            AudioAttributes.Builder()
                .setContentType(CONTENT_TYPE_SONIFICATION)
                .setUsage(USAGE_ASSISTANCE_SONIFICATION)
                .build()
        )
        .build()

    val pointSource = PointSourceParams(entity)

    val soundEffect = appContext.assets.openFd("sounds/tiger_16db.mp3")
    val pointSoundId = soundPool.load(soundEffect, lowPriority)

    soundPool.setOnLoadCompleteListener { soundPool, sampleId, status ->
        // wait for the sound file to be loaded into the soundPool
        if (status == 0) {
            SpatialSoundPool.play(
                session = session,
                soundPool = soundPool,
                soundID = pointSoundId,
                params = pointSource,
                volume = maxVolume,
                priority = lowPriority,
                loop = infiniteLoop,
                rate = normalSpeed
            )
        }
    }
} else {
    // The session does not have spatial audio capabilities
}

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

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

הוספת סטריאו וסאונד היקפי לאפליקציה

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

מיקום הרמקולים של סטריאו וצליל סראונד

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

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

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

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

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

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

דוגמה לצליל סראונד

בדוגמה הבאה נטען קובץ אודיו 5.1 באמצעות MediaPlayer, והערוץ המרכזי של הקובץ מוגדר כ-Entity.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val pointSourceAttributes = PointSourceParams(session.scene.mainPanelEntity)

    val mediaPlayer = MediaPlayer()

    val fivePointOneAudio = appContext.assets.openFd("sounds/aac_51.ogg")
    mediaPlayer.reset()
    mediaPlayer.setDataSource(fivePointOneAudio)

    val audioAttributes =
        AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()

    SpatialMediaPlayer.setPointSourceParams(
        session,
        mediaPlayer,
        pointSourceAttributes
    )

    mediaPlayer.setAudioAttributes(audioAttributes)
    mediaPlayer.prepare()
    mediaPlayer.start()
} else {
    // The session does not have spatial audio capabilities
}

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

הוספת שדות קול אמביסוניים לאפליקציה

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

דוגמה ל-Ambionics

בדוגמה הבאה מושמע שדה קול אמביסוני באמצעות MediaPlayer.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val soundFieldAttributes =
        SoundFieldAttributes(SpatializerConstants.AMBISONICS_ORDER_FIRST_ORDER)

    val mediaPlayer = MediaPlayer()

    val soundFieldAudio = appContext.assets.openFd("sounds/foa_basketball_16bit.wav")

    mediaPlayer.reset()
    mediaPlayer.setDataSource(soundFieldAudio)

    val audioAttributes =
        AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
            .setUsage(AudioAttributes.USAGE_MEDIA)
            .build()

    SpatialMediaPlayer.setSoundFieldAttributes(
        session,
        mediaPlayer,
        soundFieldAttributes
    )

    mediaPlayer.setAudioAttributes(audioAttributes)
    mediaPlayer.prepare()
    mediaPlayer.start()
} else {
    // The session does not have spatial audio capabilities
}

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

  • כמו בדוגמאות הקודמות, השלב הראשון הוא לבדוק אם יש תמיכה באודיו מרחבי באמצעות hasCapability().
  • המידע על contentType והשימוש הוא למטרות מידע בלבד.
  • התג AMBISONICS_ORDER_FIRST_ORDER מאותת ל-SceneCore שקובץ שדה הקול מגדיר ארבעה ערוצים.