افزودن صدای فراگیر به برنامه واقعیت گسترده

دستگاه‌های XR قابل‌اعمال
این راهنمایی به شما کمک می‌کند برای این نوع دستگاه‌های واقعیت گسترده تجربه بسازید.
هدست‌های واقعیت گسترده
عینک واقعیت گسترده سیمی

ویژگی‌های صدای فراگیر در Jetpack SceneCore به شما امکان می‌دهد تا تجربه‌های شنیداری فراگیر را در برنامه‌های Android XR خود بسازید.

صدای فضایی نحوه درک صدا توسط کاربران در محیط سه‌بعدی را شبیه‌سازی می‌کند. این فناوری حس صدایی را ایجاد می‌کند که از همه جهات، ازجمله بالا و پایین کاربر، منتشر می‌شود. سیستم این کار را با شبیه‌سازی یک یا چند «بلندگوی مجازی» در مکان‌های خاص در فضای سه‌بعدی انجام می‌دهد.

برنامه‌های موجود که برای Android XR طراحی یا اصلاح نشده‌اند، صدایشان به‌طور خودکار در Android XR فضایی می‌شود. وقتی کاربر در فضای خود حرکت می‌کند، صدای همه برنامه‌ها از پانلی که واسط کاربر برنامه در آن ارائه می‌شود پخش خواهد شد. برای مثال، اگر زمان‌سنجی از برنامه ساعت به‌صدا درآید، صدا به‌نظر می‌رسد که از موقعیت پانل برنامه می‌آید. ‫Android XR به‌طور خودکار صدا را برای واقع‌گرایی موقعیتی تغییر می‌دهد. برای مثال، فاصله درک‌شده بین پانل برنامه و کاربر به‌طور نامحسوس بر حجم صدا تأثیر می‌گذارد تا حس واقع‌گرایی بیشتری ایجاد شود.

برای کسب اطلاعات بیشتر درباره نحوه پرداز کردن صدای فراگیر توسط برنامه‌های موجود، افزودن صدای استریو و صدای فراگیر به برنامه را در این صفحه بخوانید.

اگر برنامه خود را برای «واقعیت گسترده» بهینه‌سازی می‌کنید، Jetpack SceneCore ابزارهایی برای سفارشی‌سازی پیشرفته صدای فراگیر ارائه می‌دهد. می‌توانید صداها را به‌دقت در محیط سه‌بعدی قرار دهید، از صدای فراگیر برای میدان‌های صدای واقع‌گرایانه استفاده کنید، و از ادغام صدای فراگیر داخلی بهره ببرید.

انواع صدای فراگیر دردسترس در Android XR

‫Android XR از صدای موقعیتی، استریو، فراگیر، و صدای فراگیر پشتیبانی می‌کند.

صدای موقعیتی

صدای موضعی می‌تواند به‌گونه‌ای قرار گیرد که از نقطه خاصی در فضای سه‌بعدی پخش شود. برای مثال، می‌توانید مدل سه‌بعدی سگی داشته باشید که در گوشه محیط مجازی‌تان پارس می‌کند. می‌توانید چندین نهاد داشته باشید که از هریک از موقعیت‌های مربوطه خود صدا منتشر می‌کنند. برای پرداز کردن صدای موقعیتی، فایل‌ها باید مونو یا استریو باشند.

صدای استریو فضایی و صدای فراگیر

همه قالب‌های رسانه Android برای صدای موقعیتی، استریو، و فراگیر پشتیبانی می‌شوند. علاوه‌بر این قالب‌ها، دستگاه‌های Android XR ممکن است از قالب‌های صوتی Dolby Atmos، Dolby Digital، و Dolby Digital+ نیز پشتیبانی کنند.

صدای استریو به قالب‌های صوتی با دو کانال و صدای فراگیر به قالب‌های صوتی با بیش از دو کانال، مانند صدای فراگیر ۵.۱ یا صدای فراگیر ۷.۱ اشاره دارد. داده‌های صدای هر کانال با یک گوینده مرتبط است. برای مثال، هنگام پخش موسیقی استریو، کانال بلندگوی چپ ممکن است قطعات ساز متفاوتی نسبت‌به بلندگوی راست پخش کند.

از صدای فراگیر اغلب در فیلم‌ها و نمایش‌های تلویزیونی برای افزایش واقع‌گرایی و غوطه‌وری ازطریق استفاده از کانال‌های بلندگوی متعدد استفاده می‌شود. برای مثال، گفتگو اغلب از کانال بلندگوی مرکزی پخش می‌شود، درحالی‌که صدای پرواز هلیکوپتر ممکن است به‌صورت متوالی از کانال‌های مختلف استفاده کند تا حس پرواز هلیکوپتر در فضای سه‌بعدی شما را القا کند.

صدای Ambisonic

صدای Ambisonic (یا ambisonics) مانند یک جایگاه ویژه برای صدا است که یک فضای صوتی فراگیر برای کاربران شما فراهم می‌کند. از صدای فراگیر برای صداهای محیطی پس‌زمینه یا سناریوهای دیگری که می‌خواهید یک میدان صدای کاملاً کروی را که شنونده را احاطه می‌کند، بازسازی کنید، استفاده کنید. ‫Android XR از قالب صوتی فراگیر AmbiX در فراگیری صوتی مرتبه اول، دوم، و سوم پشتیبانی می‌کند. ما انواع فایل Opus (.ogg) و PCM/Wave (.wav) را توصیه می‌کنیم.

استفاده از صدای فراگیر با Jetpack SceneCore

پیاده‌سازی صدای فراگیر با Jetpack SceneCore شامل بررسی قابلیت‌های فراگیر و انتخاب یک API برای بار کردن صدای فراگیر است.

بررسی قابلیت‌های فضایی

پیش‌از استفاده از ویژگی‌های صدای فراگیر، بررسی کنید که Session از صدای فراگیر پشتیبانی کند. در همه تکه‌کدهای بخش‌های زیر، قابلیت‌ها قبل‌از تلاش برای پخش صدای فضایی بررسی می‌شوند.

بار کردن صدای فراگیر

می‌توانید از هریک از میاناهای برنامه‌سازی کاربردی زیر برای بار کردن صدای فراگیر برای استفاده در Jetpack SceneCore استفاده کنید.

  • SoundPool: ایده‌آل برای جلوه‌های صوتی کوتاه که کمتر از ۱ مگابایت حجم دارند، این جلوه‌ها ازقبل بارگذاری می‌شوند و می‌توان از صداها به‌طور مکرر استفاده کرد. این روشی عالی برای بار کردن صدا برای صدای موقعیتی است.
  • ExoPlayer: ایده‌آل برای بارگذاری محتوای استریو و صدای فراگیر مانند موسیقی و ویدیو. همچنین امکان پخش رسانه در پس‌زمینه را فراهم می‌کند.
  • MediaPlayer: ساده‌ترین راه برای بار کردن صدای فراگیر را ارائه می‌دهد.
  • AudioTrack: بیشترین کنترل را بر نحوه بارگیری داده‌های صوتی فراهم می‌کند. اجازه می‌دهد مستقیماً بافرهای صوتی بنویسید یا اگر فایل‌های صوتی خودتان را ترکیب یا رمزگشایی کرده‌اید.

بررسی پشتیبانی از قالب رسانه

برخی‌از قالب‌های رسانه توسط پلاتفرم Android پشتیبانی می‌شوند. بااین‌حال، یک دستگاه Android XR خاص ممکن است از قالب‌های اضافی مانند Dolby Atmos پشتیبانی کند. برای پُرسمان کردن درباره پشتیبانی از قالب رسانه، از AudioCapabilities در ExoPlayer استفاده کنید:

val audioCapabilities = AudioCapabilities.getCapabilities(
    context,
    androidx.media3.common.AudioAttributes.DEFAULT,
    null,
    emptyList()
)

if (audioCapabilities.supportsEncoding(C.ENCODING_AC3)) {
    // Device supports playback of the Dolby Digital media format.
}
if (audioCapabilities.supportsEncoding(C.ENCODING_E_AC3)) {
    // Device supports playback of the Dolby Digital Plus media format.
}
if (audioCapabilities.supportsEncoding(C.ENCODING_E_AC3_JOC)) {
    // Device supports playback of the Dolby Digital Plus with Dolby Atmos media format.
}

بررسی این قابلیت‌ها ممکن است به‌طور بالقوه شامل مسدود کردن تماس‌ها باشد، و نباید در رشته اصلی فراخوانی شود.

افزودن صدای موقعیتی به برنامه

منابع صدای موقعیتی توسط PointSourceParams و Entity مرتبط تعریف می‌شوند. موقعیت و جهت Entity تعیین می‌کند که PointSourceParams در فضای سه‌بعدی کجا پرداز شود. برای تنظیم PointSourceParams و setPointSourceParams را در SpatialMediaPlayer فراخوانی کنید تا entity مرتبط با آن در نمونه MediaPlayer تنظیم شود.

مثال صدای موقعیتی

مثال زیر فایل صوتی جلوه صوتی را در استخر صدا بار می‌کند و آن را در موقعیت Entity پخش می‌کند.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.contains(SpatialCapability.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()

    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,
                entity = entity,
                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 را برای ادامه پخش صدای فراگیر یا استریو از پس‌زمینه پیکربندی کرده باشید، موقعیت بلندگوی مجازی هنگام پس‌زمینه‌ای شدن برنامه تغییر خواهد کرد. ازآنجایی‌که هیچ پانل یا نقطه دیگری در فضا برای ثابت کردن صدا وجود ندارد، صدای فراگیر با کاربر حرکت می‌کند (به‌عبارت دیگر، «سرقفل‌شده» است).

نمونه صدای فراگیر

مثال زیر یک فایل صوتی ۵.۱ را بااستفاده از MediaPlayer بار می‌کند و کانال مرکزی فایل را روی Entity تنظیم می‌کند.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.contains(SpatialCapability.SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val pointSourceAttributes = PointSourceParams()

    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,
        entity = session.scene.mainPanelEntity,
    )

    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.contains(SpatialCapability.SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val soundFieldAttributes =
        SoundFieldAttributes(SpatializerConstants.AmbisonicsOrder.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 اطلاع می‌دهد که فایل فیلد صدا چهار کانال را تعریف می‌کند.