إضافة ميزة "الصوت المكاني" إلى تطبيق الواقع المعزّز

تتيح لك ميزات الصوت المكاني في Jetpack SceneCore إنشاء تجارب صوتية immersive في تطبيقات Android XR.

تحاكي ميزة "الصوت المكاني" كيفية سماع المستخدمين للصوت في بيئة ثلاثية الأبعاد. ويخلق ذلك شعورًا بأنّ الصوت ينبعث من جميع الاتجاهات، بما في ذلك من فوق وأسفل المستخدِم. وينفّذ النظام ذلك من خلال محاكاة "مكبّر صوت افتراضي" واحد أو أكثر في مواقع جغرافية محدّدة في الفضاء الثلاثي الأبعاد.

يتم تلقائيًا تحويل الصوت في التطبيقات الحالية التي لم يتم تصميمها أو تعديلها لتعمل على Android XR إلى صوت محيطي في Android XR. وعندما يتحرك المستخدم في المساحة، سيتم بث جميع أصوات التطبيق من اللوحة التي يتم عرض واجهة مستخدم التطبيق عليها. على سبيل المثال، إذا انتهت مدة الموقّت في تطبيق ساعة، سيبدو الصوت كأنّه مصدره موضع لوحة التطبيق. سيغيّر نظام التشغيل Android XR الصوت تلقائيًا لتوفير تجربة واقعية. على سبيل المثال، فإنّ المسافة المتأثّرة بين لوحة التطبيق والمستخدم ستؤثّر بشكلٍ طفيف في مستوى الصوت لتوفير شعور أكبر بالواقعية.

لمزيد من المعلومات حول كيفية عرض التطبيقات الحالية للصوت المكاني، يُرجى الاطّلاع على مقالة إضافة صوت ستيريو وصوت محيطي إلى تطبيقك في هذه الصفحة.

إذا كنت بصدد تحسين تطبيقك ليعمل على أجهزة الواقع الممتد، يوفّر Jetpack SceneCore أدوات ل تخصيص الصوت المكاني المتقدّم. يمكنك تحديد موضع الأصوات بدقة في البيئة الثلاثية الأبعاد، واستخدام الصوت المحيطي لإنشاء حقول صوتية واقعية، والاستفادة من ميزة دمج الصوت المحيطي المضمّنة.

أنواع الصوت المكاني المتاحة في Android XR

يتيح Android XR استخدام الصوت الثنائي الاتجاه والصوت الاستيريو والصوت المحيطي والصوت المحيطي الشامل.

الصوت المكاني

يمكن ضبط الصوت المكاني لتشغيله من نقطة معيّنة في الفضاء الثلاثي الأبعاد. على سبيل المثال، يمكنك استخدام نموذج ثلاثي الأبعاد لكلب ينبح في أحد أركان بيئتك الافتراضية. يمكنك أن يكون لديك عناصر متعددة تُصدر صوتًا من كل موضع منها. لعرض الصوت المكاني، يجب أن تكون الملفات مونو أو استيريو.

صوت استيريو وصوت محيطي بتقنية "الصوت المكاني"

تتوفّر جميع تنسيقات وسائط Android للصوت المكاني والستيريو والمحيطي.

يشير الصوت الاستيريو إلى تنسيقات الصوت التي تتضمّن قناتين، ويشير الصوت المحيطي إلى تنسيقات الصوت التي تتضمّن أكثر من قناتين، مثل الصوت المحيطي بتقنية 5.1 أو الصوت المحيطي بتقنية 7.1. ترتبط بيانات الصوت في كل قناة بمكبّر صوت واحد. على سبيل المثال، عند تشغيل الموسيقى بصوت استيريو، قد تُصدر قناة مكبّر الصوت الأيسر قنوات مختلفة عن قناة مكبّر الصوت الأيمن.

غالبًا ما يتم استخدام الصوت المحيطي في الأفلام والبرامج التلفزيونية لتعزيز الواقعية والانغماس من خلال استخدام قنوات مكبّرات صوت متعددة. على سبيل المثال، يتم غالبًا تشغيل الحوار من قناة مكبّر صوت مركزي، في حين قد يستخدم صوت طائرةهليكوبتر تحلّق قنوات مختلفة بالتسلسل لإعطاء انطباع بأنّه تحلّق الطائرةهليكوبتر حول المساحة الثلاثية الأبعاد.

الصوت المحيطي

إنّ تقنية Ambisonic الصوتية (أو Ambisonics) تشبه إطار الصورة العلوي للمحتوى الصوتي، ويؤدي استخدامها إلى توفير تجربة صوتية غامرة للمستخدمين. استخدِم تقنية ambisonics لتسجيل الأصوات البيئية في الخلفية أو في سيناريوهات أخرى تريد فيها محاكاة مجال صوتي كامل يحيط بالمستمع. يتوافق Android XR مع تنسيق الصوت المحيطي AmbiX بدرجات الصعوبة الأولى والثانية والثالثة للصوت المحيطي. ننصحك بأنواع الملفات Opus (.ogg) و PCM/Wave (.wav).

استخدام ميزة "الصوت المكاني" مع Jetpack SceneCore

يتضمن تنفيذ ميزة "الصوت المكاني" باستخدام Jetpack SceneCore التحقّق من ميزات الصوت المكاني واختيار واجهة برمجة تطبيقات لتحميل محتوى الصوت المكاني.

التحقّق من الإمكانات المكانية

قبل استخدام ميزات الصوت المكاني، تأكَّد من أنّ Session يتيح استخدام ميزة الصوت المكاني. في جميع مقتطفات الرموز البرمجية في الأقسام التالية، يتم التحقّق من الإمكانات قبل محاولة تشغيل الصوت المكاني.

تحميل الصوت المكاني

يمكنك استخدام أي من واجهات برمجة التطبيقات التالية لتحميل محتوى صوتي مكاني لاستخدامه في Jetpack SceneCore.

  • SoundPool: مثالية للتأثيرات الصوتية القصيرة التي تقلّ مساحتها عن 1 ميغابايت، ويتم تحميلها مسبقًا ويمكن استخدامها بشكل متكرّر. وهذه طريقة رائعة لتحميل الصوت لميزة "الصوت المكاني".
  • ExoPlayer: مثالي لتحميل محتوى صوت الاستيريو والصوت المحيطي، مثل الموسيقى والفيديوهات. تتيح أيضًا تشغيل الوسائط في الخلفية.
  • MediaPlayer: يوفّر أبسط طريقة لتحميل الصوت المحيطي.
  • AudioTrack: يوفّر أكبر قدر من التحكّم في كيفية تحميل بيانات الصوت. يسمح هذا الخيار بكتابة ملفّات تخزين مؤقتة للمحتوى الصوتي مباشرةً أو إذا كنت قد عالجت الملفات الصوتية أو فكّ تشفيرها.

إضافة ميزة "الصوت المكاني" إلى تطبيقك

يتم تحديد مصادر الصوت الموضعية من خلال PointSourceAttributes و Entity المرتبط بها. يحدّد موضع Entity واتجاهه مكان عرض PointSourceAttribute في الفضاء الثلاثي الأبعاد.

مثال على الصوت المكاني

في المثال التالي، يتم تحميل ملف صوتي لمؤثر صوتي إلى مجموعة مؤثرات صوتية ويُعاد تشغيله في موضع Entity.

// Check spatial capabilities before using spatial audio
if (xrSession.getSpatialCapabilities().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 = PointSourceAttributes(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 = xrSession,
                soundPool = soundPool,
                soundID = pointSoundId,
                attributes = pointSource,
                volume = maxVolume,
                priority = lowPriority,
                loop = infiniteLoop,
                rate = normalSpeed
            )
        }
    }
} else {
    // The session does not have spatial audio capabilities
}

نقاط رئيسية حول الرمز

  • الخطوة الأولى هي التحقّق مما إذا كانت ميزات "الصوت المكاني" متاحة حاليًا باستخدام getSpatialCapabilities().
  • يؤدي ضبط 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 (xrSession.getSpatialCapabilities().hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_SPATIAL_AUDIO)) {
    // The session has spatial audio capabilities

    val pointSourceAttributes = PointSourceAttributes(xrSession.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.setPointSourceAttributes(
        xrSession,
        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 (xrSession.getSpatialCapabilities().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(
        xrSession,
        mediaPlayer,
        soundFieldAttributes)

    mediaPlayer.setAudioAttributes(audioAttributes)
    mediaPlayer.prepare()
    mediaPlayer.start()

} else {
    // The session does not have spatial audio capabilities
}

نقاط رئيسية حول الرمز

  • كما هو الحال مع المقتطفات السابقة، الخطوة الأولى هي التحقّق مما إذا كانت ميزات "الصوت المكاني" متوفرة حاليًا باستخدام getSpatialCapabilities().
  • يُرجى العِلم أنّ contentType وusage هما معلومات فقط.
  • يشير العنصر AMBISONICS_ORDER_FIRST_ORDER إلى SceneCore بأنّ ملف حقل الصوت يحدّد أربع قنوات.