अपने XR ऐप्लिकेशन में स्पेस ऑडियो जोड़ना

Jetpack SceneCore में स्पेस ऑडियो की सुविधाओं की मदद से, Android XR ऐप्लिकेशन में इमर्सिव ऑडियो अनुभव दिए जा सकते हैं.

स्पेशल ऑडियो की सुविधा से, यह पता चलता है कि उपयोगकर्ता 3D एनवायरमेंट में आवाज़ को कैसे सुनते हैं. इससे, उपयोगकर्ता के ऊपर और नीचे के साथ-साथ, चारों ओर से आवाज़ सुनाई देती है. यह सिस्टम, 3D स्पेस में एक या एक से ज़्यादा "वर्चुअल स्पीकर" को सिम्युलेट करके ऐसा करता है.

Android XR के लिए डिज़ाइन नहीं किए गए या जिनमें Android XR के लिए बदलाव नहीं किया गया है उन ऐप्लिकेशन का ऑडियो, Android XR में अपने-आप स्पेसिएलाइज़ हो जाता है. जब उपयोगकर्ता अपने स्पेस में एक जगह से दूसरी जगह जाएगा, तो ऐप्लिकेशन का पूरा ऑडियो उस पैनल से निकलेगा जिस पर ऐप्लिकेशन का यूज़र इंटरफ़ेस रेंडर किया गया है. उदाहरण के लिए, अगर किसी घड़ी वाले ऐप्लिकेशन का टाइमर बंद हो जाता है, तो ऑडियो ऐसा लगेगा जैसे वह ऐप्लिकेशन पैनल की जगह से आ रहा है. Android XR, जगह के हिसाब से साउंड को अपने-आप बदल देगा, ताकि आपको ज़्यादा असली अनुभव मिले. उदाहरण के लिए, ऐप्लिकेशन पैनल और उपयोगकर्ता के बीच की दूरी से, ऑडियो वॉल्यूम पर थोड़ा असर पड़ेगा. इससे, असल अनुभव मिलता है.

मौजूदा ऐप्लिकेशन, स्पेस ऑडियो को कैसे रेंडर करते हैं, इस बारे में ज़्यादा जानने के लिए, इस पेज पर अपने ऐप्लिकेशन में स्टीरियो और सराउंड साउंड जोड़ें लेख पढ़ें.

अगर आपको अपने ऐप्लिकेशन को एक्सआर के लिए ऑप्टिमाइज़ करना है, तो Jetpack SceneCore में स्पेशल ऑडियो को पसंद के मुताबिक बनाने के लिए बेहतर टूल उपलब्ध हैं. 3D एनवायरमेंट में साउंड को सटीक तौर पर पोज़िशन किया जा सकता है. साथ ही, असल साउंड फ़ील्ड के लिए ऐंबिसॉनिक ऑडियो का इस्तेमाल किया जा सकता है. इसके अलावा, डिवाइस में पहले से मौजूद सराउंड साउंड इंटिग्रेशन का फ़ायदा भी लिया जा सकता है.

Android XR में स्पेशल ऑडियो के उपलब्ध टाइप

Android XR में पोज़िशनल, स्टीरियो, सराउंड साउंड, और ऐंबिसॉनिक ऑडियो की सुविधा काम करती है.

ऑडियो की जगह की जानकारी

पोज़िशनल ऑडियो को 3D स्पेस में किसी खास पॉइंट से चलाया जा सकता है. उदाहरण के लिए, आपके वर्चुअल एनवायरमेंट के कोने में, कुत्ते के 3D मॉडल को भौंकते हुए दिखाया जा सकता है. आपके पास एक से ज़्यादा इकाइयां हो सकती हैं, जो अपनी जगह से आवाज़ें निकालती हैं. ऑडियो को जगह के हिसाब से रेंडर करने के लिए, फ़ाइलें मोनो या स्टीरियो होनी चाहिए.

स्पेसलाइज़्ड स्टीरियो और सराउंड साउंड

पोज़िशनल, स्टीरियो, और सराउंड साउंड के लिए, Android के सभी मीडिया फ़ॉर्मैट काम करते हैं.

स्टीरियो ऑडियो का मतलब है दो चैनलों वाले ऑडियो फ़ॉर्मैट. वहीं, सराउंड साउंड का मतलब है दो से ज़्यादा चैनलों वाले ऑडियो फ़ॉर्मैट. जैसे, 5.1 सराउंड साउंड या 7.1 सराउंड साउंड कॉन्फ़िगरेशन. हर चैनल का साउंड डेटा, एक स्पीकर से जुड़ा होता है. उदाहरण के लिए, स्टीरियो में संगीत चलाते समय, बाईं ओर के स्पीकर चैनल से दाईं ओर के स्पीकर चैनल से अलग इंस्ट्रूमेंट ट्रैक निकल सकते हैं.

फ़िल्मों और टीवी शो में अक्सर सराउंड साउंड का इस्तेमाल किया जाता है. इससे, कई स्पीकर चैनलों का इस्तेमाल करके, रीयलिस्टिक और बेहतर अनुभव मिलता है. उदाहरण के लिए, अक्सर डायलॉग, सेंटर स्पीकर चैनल से चलता है. वहीं, हेलीकॉप्टर के उड़ने की आवाज़ के लिए, अलग-अलग चैनलों का क्रम में इस्तेमाल किया जा सकता है, ताकि यह एहसास मिले कि हेलीकॉप्टर आपके 3D स्पेस के आस-पास उड़ रहा है.

ऐंबिसॉनिक ऑडियो

ऐम्बिसॉनिक ऑडियो (या ऐम्बिसॉनिक्स) ऑडियो के लिए स्काईबॉक्स की तरह होता है. इससे, आपके उपयोगकर्ताओं को बेहतर साउंडस्केप मिलता है. बैकग्राउंड में, आस-पास की आवाज़ों या ऐसी अन्य स्थितियों के लिए एम्बिसॉनिक्स का इस्तेमाल करें जहां आपको सुनने वाले के चारों ओर मौजूद साउंड फ़ील्ड को दोहराना हो. Android XR, फ़र्स्ट-, सेकंड-, और थर्ड-ऑर्डर ऐम्बिसॉनिक्स में AmbiX ऐम्बिसॉनिक ऑडियो फ़ॉर्मैट के साथ काम करता है. हमारा सुझाव है कि आप Opus (.ogg) और PCM/Wave (.wav) फ़ाइल टाइप का इस्तेमाल करें.

Jetpack SceneCore के साथ स्पेशल ऑडियो की सुविधा का इस्तेमाल करना

Jetpack SceneCore की मदद से स्पेशल ऑडियो की सुविधा लागू करने के लिए, स्पेशल ऑडियो की सुविधाओं की जांच करना और स्पेशल ऑडियो लोड करने के लिए एपीआई चुनना ज़रूरी है.

स्पेस ऑडियो की सुविधाएं देखना

स्पीशल ऑडियो की सुविधाओं का इस्तेमाल करने से पहले, देख लें कि Session पर स्पीशल ऑडियो काम करता है या नहीं. नीचे दिए गए सेक्शन में मौजूद सभी कोड स्निपेट में, स्पेसिएलाइज़्ड ऑडियो चलाने की कोशिश करने से पहले, सुविधाओं की जांच की जाती है.

स्पेशल ऑडियो लोड करना

Jetpack SceneCore में इस्तेमाल करने के लिए, स्पेशल ऑडियो को लोड करने के लिए इनमें से किसी भी एपीआई का इस्तेमाल किया जा सकता है.

  • SoundPool: यह विकल्प, छोटे साउंड इफ़ेक्ट के लिए सबसे सही है. इनका साइज़ 1 एमबी से कम होना चाहिए. ये इफ़ेक्ट पहले से लोड हो जाते हैं और इनका बार-बार इस्तेमाल किया जा सकता है. यह पोज़िशनल ऑडियो के लिए ऑडियो लोड करने का एक शानदार तरीका है.
  • ExoPlayer: संगीत और वीडियो जैसे स्टीरियो और सराउंड साउंड वाले कॉन्टेंट को लोड करने के लिए आदर्श. इससे बैकग्राउंड में मीडिया चलाने की सुविधा भी मिलती है.
  • MediaPlayer: ऐंबिसॉनिक ऑडियो को लोड करने का सबसे आसान तरीका उपलब्ध कराता है.
  • AudioTrack: ऑडियो डेटा को लोड करने के तरीके पर ज़्यादा से ज़्यादा कंट्रोल देता है. ऑडियो के बफ़र को सीधे तौर पर लिखने की अनुमति देता है. इसके अलावा, अगर आपने अपनी ऑडियो फ़ाइलों को सिंथेसाइज़ या डिकोड किया है, तो भी यह काम करता है.

अपने ऐप्लिकेशन में पोज़िशनल ऑडियो जोड़ना

जगह के हिसाब से साउंड सोर्स की जानकारी, PointSourceAttributes और उससे जुड़े Entity से मिलती है. Entity की पोज़िशन और ओरिएंटेशन से यह तय होता है कि PointSourceAttribute को 3D स्पेस में कहां रेंडर किया जाए.

पोज़िशनल ऑडियो का उदाहरण

यहां दिए गए उदाहरण में, साउंड इफ़ेक्ट वाली ऑडियो फ़ाइल को साउंड पूल में लोड किया गया है और 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_ASSISTANCE_SONIFICATION पर सेट करने से, सिस्टम इस ऑडियो फ़ाइल को साउंड इफ़ेक्ट के तौर पर इस्तेमाल करता है.
  • ऊपर दिए गए उदाहरण में, ऑडियो फ़ाइल को इस्तेमाल करने से पहले ही पूल में लोड किया जाता है, ताकि कोड को आसानी से एक साथ रखा जा सके. आम तौर पर, आपको अपने ऐप्लिकेशन को लोड करते समय, सभी साउंड इफ़ेक्ट को अलग-अलग लोड करना चाहिए, ताकि ज़रूरत पड़ने पर सभी ऑडियो फ़ाइलें पूल में उपलब्ध हों.

अपने ऐप्लिकेशन में स्टीरियो और सराउंड साउंड जोड़ना

अपने ऐप्लिकेशन में स्टीरियो और सराउंड साउंड जोड़ने के लिए, Exoplayer का इस्तेमाल करने का सुझाव दिया जाता है. Exoplayer के साथ स्पेशल ऑडियो की सुविधा इस्तेमाल करने के तरीके के बारे में ज़्यादा जानने के लिए, स्पेशल ऑडियो की गाइड देखें.

स्टीरियो और सराउंड साउंड स्पीकर की पोज़िशनिंग

सराउंड साउंड स्पीकर की पोज़िशनिंग की सुविधा की मदद से, वर्चुअल सराउंड साउंड स्पीकर को सेंटर स्पीकर के हिसाब से पोज़िशन किया जाता है. साथ ही, इन्हें उपयोगकर्ता के आस-पास स्टैंडर्ड ITU कॉन्फ़िगरेशन में रखा जाता है.

डिफ़ॉल्ट रूप से, सेंटर चैनल स्पीकर को ऐप्लिकेशन के mainPanelEntity पर रखा जाता है. इसमें ऐसे मोबाइल ऐप्लिकेशन भी शामिल हैं जिनके ऑडियो को Android XR की मदद से अपने-आप स्पेसिएलाइज़ किया गया है.

स्टीरियो के लिए, स्पीकर की जगह तय करने का तरीका सराउंड साउंड जैसा ही होता है. हालांकि, इसमें पैनल की बाईं और दाईं ओर सिर्फ़ बायां और दायां चैनल होता है.

अगर आपके पास एक से ज़्यादा पैनल हैं और आपको यह चुनना है कि कौनसा पैनल ऑडियो चलाए या आपको किसी दूसरे Entity के हिसाब से स्टीरियो या सराउंड ऑडियो रेंडर करना है, तो सेंटर चैनल की जगह तय करने के लिए PointSourceAttributes का इस्तेमाल करें. बाकी चैनलों को पहले बताए गए क्रम में रखा जाएगा. इन स्थितियों में, आपको MediaPlayer का भी इस्तेमाल करना होगा.

जब उपयोगकर्ता अपने स्पेस में एक जगह से दूसरी जगह जाता है, तो स्टीरियो और सराउंड साउंड वाले वर्चुअल स्पीकर, उपयोगकर्ता की जगह के हिसाब से अपने-आप अडजस्ट हो जाएंगे. इससे यह पक्का किया जा सकेगा कि स्पीकर हमेशा सही जगह पर हों.

अगर आपने बैकग्राउंड में स्टीरियो या सराउंड साउंड चलाने के लिए, MediaPlayer या ExoPlayer को कॉन्फ़िगर किया है, तो ऐप्लिकेशन के बैकग्राउंड में जाने पर, वर्चुअल स्पीकर की पोज़िशन बदल जाएगी. स्पेस में कोई पैनल या ऐसा कोई दूसरा पॉइंट नहीं होता जहां आवाज़ को ऐंकर किया जा सके. इसलिए, स्पेस ऑडियो उपयोगकर्ता के साथ चलता है. दूसरे शब्दों में, इसे "हेड-लॉक" कहा जाता है.

सराउंड साउंड का उदाहरण

नीचे दिए गए उदाहरण में, MediaPlayer का इस्तेमाल करके 5.1 ऑडियो फ़ाइल लोड की गई है. साथ ही, फ़ाइल के सेंटर चैनल को 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
}

कोड के बारे में खास जानकारी

  • जगह के हिसाब से ऑडियो के उदाहरण की तरह, पहला चरण यह देखना है कि फ़िलहाल जगह के हिसाब से ऑडियो की सुविधाएं उपलब्ध हैं या नहीं. इसके लिए, getSpatialCapabilities() का इस्तेमाल करें.
  • contentType को CONTENT_TYPE_MUSIC और इस्तेमाल को USAGE_MEDIA पर सेट करने से, सिस्टम इस ऑडियो फ़ाइल को सराउंड साउंड के तौर पर इस्तेमाल करता है.

अपने ऐप्लिकेशन में एमबीआई साउंड फ़ील्ड जोड़ना

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 को यह सिग्नल देता है कि साउंड फ़ील्ड फ़ाइल में चार चैनल हैं.