ویژگیهای صدای فضایی در Jetpack SceneCore به شما این امکان را میدهد که تجربیات صوتی فراگیر را در برنامههای Android XR خود ایجاد کنید.
صدای فضایی، نحوهی درک صدا توسط کاربران را در یک محیط سهبعدی شبیهسازی میکند. این فناوری، حس انتشار صدا از همه جهات، از جمله بالا و پایین کاربر را ایجاد میکند. این سیستم این کار را با شبیهسازی یک یا چند «بلندگوی مجازی» در مکانهای خاص در فضای سهبعدی انجام میدهد.
برنامههای موجودی که برای اندروید XR طراحی یا اصلاح نشدهاند، صدایشان به طور خودکار در اندروید XR فضاییسازی میشود. با حرکت کاربر در فضای خود، تمام صدای برنامه از پنلی که رابط کاربری برنامه روی آن رندر شده است، پخش میشود. به عنوان مثال، اگر یک تایمر از یک برنامه ساعت به صدا درآید، صدا طوری به نظر میرسد که انگار از موقعیت پنل برنامه میآید. اندروید XR به طور خودکار صدا را برای واقعگرایی موقعیتی تغییر میدهد. به عنوان مثال، فاصله درک شده بین پنل برنامه و کاربر، به طور نامحسوسی بر میزان صدا تأثیر میگذارد تا حس واقعگرایی بیشتری ایجاد شود.
برای اطلاعات بیشتر در مورد نحوهی رندر صدای فضایی توسط برنامههای موجود، بخش «افزودن صدای استریو و فراگیر به برنامهی خود» را در این صفحه مطالعه کنید.
اگر در حال بهینهسازی برنامه خود برای واقعیت افزوده (XR) هستید، Jetpack SceneCore ابزارهایی برای سفارشیسازی پیشرفته صدای فضایی ارائه میدهد. میتوانید صداها را دقیقاً در محیط سهبعدی قرار دهید، از صدای فراگیر برای میدانهای صوتی واقعگرایانه استفاده کنید و از ادغام صدای فراگیر داخلی بهرهمند شوید.
انواع صدای فضایی موجود در اندروید XR
اندروید XR از صدای موقعیتی، استریو، فراگیر و صدای فراگیر پشتیبانی میکند.
صدای موقعیتی
یک صدای موقعیتی میتواند طوری تنظیم شود که از یک نقطه خاص در فضای سهبعدی پخش شود. برای مثال، میتوانید یک مدل سهبعدی از پارس کردن سگی در گوشه محیط مجازی خود داشته باشید. میتوانید چندین موجودیت داشته باشید که از هر یک از موقعیتهای مربوطه خود صدا منتشر میکنند. برای رندر کردن صدای موقعیتی، فایلها باید مونو یا استریو باشند.
صدای استریو و فراگیر فضایی
تمام فرمتهای رسانهای اندروید برای صدای موضعی، استریو و فراگیر پشتیبانی میشوند. علاوه بر این فرمتها، دستگاههای اندروید XR ممکن است از فرمتهای صوتی Dolby Atmos ، Dolby Digital و Dolby Digital+ نیز پشتیبانی کنند.
صدای استریو به فرمتهای صوتی با دو کانال و صدای فراگیر به فرمتهای صوتی با بیش از دو کانال، مانند تنظیمات صدای فراگیر ۵.۱ یا صدای فراگیر ۷.۱ اشاره دارد. دادههای صوتی هر کانال با یک بلندگو مرتبط است. به عنوان مثال، هنگام پخش موسیقی به صورت استریو، کانال بلندگوی چپ ممکن است آهنگهای ساز متفاوتی نسبت به کانال راست منتشر کند.
صدای فراگیر اغلب در فیلمها و برنامههای تلویزیونی برای افزایش واقعگرایی و غوطهوری از طریق استفاده از چندین کانال بلندگو استفاده میشود. به عنوان مثال، دیالوگ اغلب از یک کانال بلندگوی مرکزی پخش میشود در حالی که صدای پرواز هلیکوپتر ممکن است از کانالهای مختلف به ترتیب استفاده کند تا این حس را ایجاد کند که هلیکوپتر در فضای سهبعدی شما پرواز میکند.
صدای آمبیسونیک
صدای Ambisonic (یا ambisonics) مانند یک جعبه آسمان برای صدا است که یک منظره صوتی فراگیر را برای کاربران شما فراهم میکند. از ambisonics برای صداهای محیطی پسزمینه یا سایر سناریوهایی که میخواهید یک میدان صوتی کاملاً کروی را که شنونده را احاطه کرده است، تکرار کنید، استفاده کنید. اندروید XR از فرمت صوتی AmbiX ambisonic در ambisonics مرتبه اول، دوم و سوم پشتیبانی میکند. ما انواع فایلهای Opus ( .ogg ) و PCM/Wave ( .wav ) را توصیه میکنیم.
استفاده از صدای فضایی با Jetpack SceneCore
پیادهسازی صدای مکانی با Jetpack SceneCore شامل بررسی قابلیتهای مکانی و انتخاب یک API برای بارگذاری صدای مکانی است.
بررسی قابلیتهای مکانی
قبل از استفاده از ویژگیهای صدای مکانی، بررسی کنید که آیا Session از صدای مکانی پشتیبانی میکند یا خیر. در تمام قطعه کدهای بخشهای بعدی، قبل از تلاش برای پخش صدای مکانی، قابلیتها بررسی میشوند.
بارگذاری صدای فضایی
شما میتوانید از هر یک از APIهای زیر برای بارگذاری صدای فضایی جهت استفاده در Jetpack SceneCore استفاده کنید.
-
SoundPool: برای جلوههای صوتی کوتاه که حجم آنها کمتر از ۱ مگابایت است، ایدهآل است. این جلوهها از قبل بارگذاری میشوند و صداها میتوانند بارها و بارها استفاده شوند. این یک روش عالی برای بارگذاری صدا برای صدای موقعیتی است. -
ExoPlayer: ایدهآل برای بارگذاری محتوای استریو و صدای فراگیر مانند موسیقی و ویدیو. همچنین امکان پخش رسانه در پسزمینه را فراهم میکند. -
MediaPlayer: سادهترین راه برای بارگذاری صدای فراگیر (ambisonic) را ارائه میدهد. -
AudioTrack: بیشترین کنترل را بر نحوه بارگذاری دادههای صوتی فراهم میکند. امکان نوشتن مستقیم بافرهای صوتی یا اگر فایلهای صوتی خود را سنتز یا رمزگشایی کردهاید، فراهم میکند.
پشتیبانی از فرمت رسانه را بررسی کنید
برخی از فرمتهای رسانهای توسط پلتفرم اندروید پشتیبانی میشوند. با این حال، یک دستگاه خاص اندروید XR ممکن است از فرمتهای اضافی مانند Dolby Atmos پشتیبانی کند. برای جستجوی پشتیبانی از فرمتهای رسانهای، از AudioCapabilities در ExoPlayer استفاده کنید:
val audioCapabilities = AudioCapabilities.getCapabilities(context, androidx.media3.common.AudioAttributes.DEFAULT, null) 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 در فضای سهبعدی کجا رندر شود.
مثال صوتی موقعیتی
مثال زیر یک فایل صوتی با افکت صوتی را در یک استخر صدا بارگذاری میکند و آن را در موقعیت 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(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بررسی کنید که آیا قابلیتهای Spatial Audio در حال حاضر در دسترس هستند یا خیر. - تنظیم contentType روی
CONTENT_TYPE_SONIFICATIONو usage رویUSAGE_ASSISTANCE_SONIFICATIONبه سیستم اجازه میدهد تا با این فایل صوتی به عنوان یک جلوه صوتی رفتار کند. - مثال قبلی، فایل صوتی را بلافاصله قبل از استفاده در pool بارگذاری میکند تا کد برای سادگی، یکپارچه بماند. در حالت ایدهآل، شما باید تمام جلوههای صوتی خود را به صورت ناهمزمان هنگام بارگذاری برنامه بارگذاری کنید تا تمام فایلهای صوتی در صورت نیاز در pool در دسترس باشند.
صدای استریو و فراگیر را به برنامه خود اضافه کنید
روش پیشنهادی برای افزودن صدای استریو و فراگیر به برنامه شما استفاده از Exoplayer است. برای اطلاعات بیشتر در مورد نحوه استفاده از Spatial Audio با Exoplayer ، به راهنمای Spatial Audio مراجعه کنید.
موقعیت بلندگوهای استریو و صدای فراگیر
با موقعیتیابی بلندگوهای صدای فراگیر، بلندگوهای صدای فراگیر مجازی نسبت به بلندگوی مرکزی، در اطراف کاربر در یک پیکربندی استاندارد 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(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 }
نکات کلیدی در مورد کد
- همانند مثال صدای موقعیتی ، اولین قدم بررسی این است که آیا قابلیتهای صدای مکانی با استفاده از
spatialCapabilitiesدر دسترس هستند یا خیر. - تنظیم
contentTypeرویAudioAttributes.CONTENT_TYPE_MUSICو usage رویAudioAttributes.USAGE_MEDIAبه سیستم اجازه میدهد تا این فایل صوتی را به عنوان صدای فراگیر (surround sound) در نظر بگیرد.
میدانهای صوتی فراگیر (ambisonic) را به برنامه خود اضافه کنید
سادهترین راه برای پخش میدانهای صوتی ambisonic، بارگذاری فایل با یک MediaPlayer است. از آنجایی که صدای ambisonic به کل منظره صوتی اعمال میشود، نیازی به مشخص کردن یک Entity برای ارائه موقعیت ندارید. در عوض، شما یک نمونه از SoundFieldAttributes با ترتیب ambisonic مناسب ایجاد میکنید که تعداد کانالها را مشخص میکند.
مثال آمبیونیک
مثال زیر یک میدان صوتی فراگیر (ambisonic) را با استفاده از 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 }
نکات کلیدی در مورد کد
- همانند قطعه کدهای قبلی، اولین قدم بررسی این است که آیا قابلیتهای Spatial Audio با استفاده از
hasCapability()در دسترس هستند یا خیر. -
contentTypeو کاربرد آن صرفاً جنبهی اطلاعرسانی دارد. -
AMBISONICS_ORDER_FIRST_ORDERبه SceneCore سیگنال میدهد که فایل میدان صدا چهار کانال را تعریف میکند.