अपने 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 के सभी मीडिया फ़ॉर्मैट इस्तेमाल किए जा सकते हैं. इन फ़ॉर्मैट के अलावा, Android XR डिवाइसों में Dolby Atmos, Dolby Digital, और Dolby Digital+ ऑडियो फ़ॉर्मैट काम कर सकते हैं.

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

देखें कि मीडिया फ़ॉर्मैट काम करता है या नहीं

कुछ मीडिया फ़ॉर्मैट, Android प्लैटफ़ॉर्म पर काम करते हैं. हालांकि, कोई Android XR डिवाइस Dolby Atmos जैसे अन्य फ़ॉर्मैट के साथ काम कर सकता है. मीडिया फ़ॉर्मैट के साथ काम करने की सुविधा के बारे में क्वेरी करने के लिए, ExoPlayer के AudioCapabilities का इस्तेमाल करें:

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 को 3D स्पेस में कहां रेंडर किया जाए.

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

यहां दिए गए उदाहरण में, साउंड इफ़ेक्ट वाली ऑडियो फ़ाइल को साउंड पूल में लोड किया गया है. साथ ही, इसे Entity की जगह पर वापस चलाया गया है.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities
    .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 = 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 का इस्तेमाल करके उपलब्ध है या नहीं.
  • contentType को CONTENT_TYPE_SONIFICATION और usage को USAGE_ASSISTANCE_SONIFICATION पर सेट करने से, सिस्टम इस ऑडियो फ़ाइल को साउंड इफ़ेक्ट के तौर पर इस्तेमाल कर पाता है.
  • ऊपर दिए गए उदाहरण में, ऑडियो फ़ाइल को पूल में तुरंत लोड किया जाता है. ऐसा इसलिए किया जाता है, ताकि कोड को एक साथ रखा जा सके और उसे आसानी से समझा जा सके. सबसे सही तरीका यह है कि आप अपने ऐप्लिकेशन को लोड करते समय, सभी साउंड इफ़ेक्ट को एसिंक्रोनस तरीके से लोड करें. इससे, जब आपको ऑडियो फ़ाइलों की ज़रूरत होगी, तब वे पूल में उपलब्ध होंगी.

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

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

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

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

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

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

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

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

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

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

यहां दिए गए उदाहरण में, MediaPlayer का इस्तेमाल करके 5.1 ऑडियो फ़ाइल लोड की गई है. साथ ही, फ़ाइल के सेंटर चैनल को Entity के तौर पर सेट किया गया है.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.hasCapability(SpatialCapabilities.SPATIAL_CAPABILITY_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
}

कोड के बारे में मुख्य बातें

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

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

Ambionics का उदाहरण

यहां दिए गए उदाहरण में, MediaPlayer का इस्तेमाल करके ऐम्बिसॉनिक साउंड फ़ील्ड चलाया गया है.

// Check spatial capabilities before using spatial audio
if (session.scene.spatialCapabilities.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(
        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 को यह सिग्नल मिलता है कि साउंड फ़ील्ड फ़ाइल में चार चैनल तय किए गए हैं.