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

دستگاه‌های 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+ پشتیبانی کنند.

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

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

صدای امبیسونیک

صدای امبیسونیک (یا امبیسونیکس) مانند یک جعبه آسمان برای صدا است، که یک چشم‌انداز صوتی فراگیر برای کاربران شما فراهم می‌کند. از آمبیسونیک برای صداهای محیطی پس‌زمینه یا سناریوهای دیگری استفاده کنید که می‌خواهید یک میدان صوتی کروی کامل را که شنونده را احاطه کرده است، بازتولید کنید. 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 در کجای فضای سه‌بعدی پرداز شود. setPointSourceParams را در SpatialMediaPlayer فراخوانی کنید تا PointSourceParams و 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
}

نکات کلیدی درباره کد

  • As with the previous snippets, the first step is to check if Spatial Audio capabilities are available using spatialCapabilities.
  • contentType و استفاده از آن صرفاً جنبه اطلاعاتی دارد.
  • SpatializerConstants.AmbisonicsOrder.FIRST_ORDER به SceneCore سیگنال می‌دهد که فایل میدان صدا چهار کانال را تعریف می‌کند.