XR アプリに空間オーディオを追加する

対応する XR デバイス
このガイダンスは、次のようなタイプの XR デバイス向けのエクスペリエンスを構築する際に役立ちます。
[
XR Headsets
]
有線 XR ゴーグル

Jetpack SceneCore の空間オーディオ機能を使用すると、Android XR アプリケーション内で没入感あふれるオーディオ エクスペリエンスを作成できます。

空間オーディオは、ユーザーが 3D 環境で音を知覚する方法をシミュレートします。ユーザーの上や下など、あらゆる方向から音が聞こえるような感覚を作り出します。これは、3D 空間の特定の場所に 1 つ以上の「仮想スピーカー」をシミュレートすることで実現されます。

Android XR 向けに設計または変更されていない既存のアプリでは、音声が Android XR で自動的に空間化されます。ユーザーが空間内を移動すると、アプリの UI がレンダリングされるパネルからすべてのアプリの音声が出力されます。たとえば、時計アプリでタイマーが鳴ると、音声はアプリのパネルの位置から聞こえるように聞こえます。Android XR は、位置のリアルさを実現するために音声を自動的に変更します。たとえば、アプリのパネルとユーザーの間の距離がわずかに変化すると、音声の音量に影響し、リアルさを高めます。

既存のアプリが空間オーディオをレンダリングする方法について詳しくは、このページのアプリにステレオとサラウンド音声を追加するをご覧ください。

アプリを XR 向けに最適化する場合、Jetpack SceneCore には高度な空間オーディオのカスタマイズを行うためのツールが用意されています。3D 環境で音を正確に配置したり、アンビソニックス オーディオを使用してリアルな音場を実現したり、組み込みのサラウンド音声統合を利用したりできます。

Android XR で利用できる空間オーディオのタイプ

Android XR は、ポジショナル オーディオ、ステレオ、サラウンド音声、アンビソニックス オーディオをサポートしています。

ポジショナル オーディオ

ポジショナル オーディオは、3D 空間の特定のポイントから再生されるように配置できます。 たとえば、仮想環境の隅で犬が吠えている3D モデルを作成できます。複数のエンティティがそれぞれの位置から音を出すようにできます。ポジショナル オーディオをレンダリングするには、ファイルがモノラルまたはステレオである必要があります。

空間化されたステレオとサラウンド音声

すべての Android メディア形式 が、ポジショナル オーディオ、ステレオ、およびサラウンド音声でサポートされています。これらの形式に加えて、Android XR デバイスは ドルビー アトモスドルビー デジタルドルビー デジタル プラスの音声形式をサポートしている場合があります。

ステレオ音声は 2 つのチャネルを持つ音声形式を指し、サラウンド音声は 5.1 サラウンド サウンド7.1 サラウンド サウンド 構成など、3 つ以上のチャネルを持つ音声形式を指します。各チャンネルの音声データは 1 つのスピーカーに関連付けられています。たとえば、ステレオで音楽を再生する場合、左のスピーカー チャンネルは右のスピーカー チャンネルとは異なる楽器トラックを出力することがあります。

サラウンド音声は、映画やテレビ番組で複数のスピーカー チャンネルを使用して、リアルさと没入感を高めるために使用されることがよくあります。たとえば、会話はセンター スピーカー チャンネルから再生され、ヘリコプターが飛ぶ音は、ヘリコプターが 3D 空間を飛び回っているような感覚を与えるために、複数のチャンネルを順番に使用することがあります。

アンビソニックス オーディオ

アンビソニックス オーディオ(またはアンビソニックス)は、音声のスカイボックスのようなもので、 ユーザーに没入感あふれるサウンドスケープを提供します。アンビソニックスは、背景の環境音や、リスナーを取り囲む全方位の音場を再現する場合に使用します。Android XR は、1 次、2 次、3 次の アンビソニックスで AmbiX アンビソニックス オーディオ形式をサポートしています。Opus.ogg)ファイル タイプと PCM/Wave.wav)ファイル タイプをおすすめします。

Jetpack SceneCore で空間オーディオを使用する

Jetpack SceneCore で空間オーディオを実装するには、空間機能を確認し、空間オーディオを読み込むための API を選択します。

空間機能を確認する

空間オーディオ機能を使用する前に、Session が空間オーディオをサポートしていることを確認します。以降のセクションのすべてのコード スニペットでは、空間化された音声の再生を試みる前に機能が確認されます。

空間オーディオを読み込む

次のいずれかの API を使用して、Jetpack SceneCore で使用する空間オーディオを読み込むことができます。

  • SoundPool: サイズが 1 MB 未満の短い効果音に最適です。事前に読み込まれ、音を繰り返し使用できます。 これは、ポジショナル オーディオの音声を読み込むのに最適な方法です。
  • ExoPlayer: 音楽や動画などのステレオおよびサラウンド音声コンテンツの読み込みに最適です。バックグラウンドでのメディア再生も可能です。
  • MediaPlayer: アンビソニックス オーディオを読み込む最も簡単な方法です。
  • AudioTrack: 音声データの読み込み方法を最も細かく制御できます。 音声のバッファを直接書き込むことができます。また、独自の音声ファイルを合成またはデコードした場合にも使用できます。

メディア形式のサポートを確認する

一部のメディア形式は Android プラットフォームでサポートされていますただし、特定の Android XR デバイスは、ドルビー アトモスなどの追加の形式をサポートしている場合があります。メディア形式のサポートをクエリするには、ExoPlayer's 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 空間でレンダリングされる場所が決まります。 setPointSourceParamsSpatialMediaPlayer を呼び出して、MediaPlayer インスタンスに PointSourceParams とそれに関連付けられた entity を設定します。

ポジショナル オーディオの例

次の例では、効果音の音声ファイルをサウンドプールに読み込み、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 を使用して 5.1 音声ファイルを読み込み、ファイルのセンター チャンネルを 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 の インスタンスを作成します。

アンビソニックスの例

次の例では、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
}

コードのポイント

  • 前のスニペットと同様に、最初の手順は空間オーディオ 機能が利用可能かどうかをhasCapability()を使用して確認することです。
  • contentType と usage は参考情報です。
  • AMBISONICS_ORDER_FIRST_ORDER は、音場ファイルが 4 つのチャンネルを定義していることを SceneCore に通知します。