Thêm âm thanh không gian vào ứng dụng XR

Các tính năng âm thanh không gian trong Jetpack SceneCore cho phép bạn tạo ra trải nghiệm âm thanh sống động trong các ứng dụng Android XR.

Âm thanh không gian mô phỏng cách người dùng cảm nhận âm thanh trong môi trường 3D. Công nghệ này tạo ra cảm giác âm thanh phát ra từ mọi hướng, kể cả phía trên và phía dưới người dùng. Hệ thống thực hiện việc này bằng cách mô phỏng một hoặc nhiều "loa ảo" tại các vị trí cụ thể trong không gian 3D.

Các ứng dụng hiện có chưa được thiết kế hoặc sửa đổi cho Android XR sẽ tự động được không gian hoá âm thanh trong Android XR. Khi người dùng di chuyển trong không gian của họ, mọi âm thanh của ứng dụng sẽ phát ra từ bảng điều khiển mà giao diện người dùng của ứng dụng được kết xuất lên. Ví dụ: nếu một bộ hẹn giờ trong ứng dụng đồng hồ đổ chuông, thì âm thanh sẽ phát ra như thể nó đến từ vị trí của bảng điều khiển ứng dụng. Android XR sẽ tự động thay đổi âm thanh để mang đến trải nghiệm chân thực về vị trí. Ví dụ: khoảng cách cảm nhận được giữa bảng điều khiển ứng dụng và người dùng sẽ ảnh hưởng một cách tinh tế đến âm lượng để mang lại cảm giác chân thực hơn.

Để biết thêm thông tin về cách các ứng dụng hiện có kết xuất âm thanh không gian, hãy đọc bài viết Thêm âm thanh nổi và âm thanh vòm vào ứng dụng trên trang này.

Nếu bạn đang tối ưu hoá ứng dụng cho XR, thì Jetpack SceneCore sẽ cung cấp các công cụ để tuỳ chỉnh âm thanh không gian nâng cao. Bạn có thể định vị chính xác âm thanh trong môi trường 3D, sử dụng âm thanh đa hướng để tạo ra các trường âm thanh chân thực và tận dụng khả năng tích hợp âm thanh vòm có sẵn.

Các loại âm thanh không gian có trong Android XR

Android XR hỗ trợ âm thanh định vị, âm thanh nổi, âm thanh vòm và âm thanh đa hướng.

Âm thanh định hướng

Bạn có thể đặt âm thanh định hướng để phát từ một điểm cụ thể trong không gian 3D. Ví dụ: bạn có thể có một mô hình 3D về một chú chó đang sủa ở góc môi trường ảo của bạn. Bạn có thể có nhiều thực thể phát ra âm thanh từ mỗi vị trí tương ứng của chúng. Để kết xuất âm thanh vị trí, các tệp phải là đơn âm hoặc âm thanh nổi.

Âm thanh nổi và âm thanh vòm được mở rộng

Tất cả định dạng nội dung nghe nhìn trên Android đều được hỗ trợ cho âm thanh định vị, âm thanh nổi và âm thanh vòm.

Âm thanh nổi là định dạng âm thanh có 2 kênh và âm thanh vòm là định dạng âm thanh có nhiều hơn 2 kênh, chẳng hạn như cấu hình âm thanh vòm 5.1 hoặc âm thanh vòm 7.1. Dữ liệu âm thanh của mỗi kênh được liên kết với một loa. Ví dụ: khi phát nhạc ở chế độ âm thanh nổi, kênh loa trái có thể phát các bản nhạc cụ khác với kênh loa phải.

Âm thanh vòm thường được dùng trong phim và chương trình truyền hình để tăng tính chân thực và sống động thông qua việc sử dụng nhiều kênh loa. Ví dụ: hộp thoại thường phát từ kênh loa trung tâm, trong khi âm thanh của một chiếc máy bay trực thăng có thể sử dụng các kênh khác nhau theo trình tự để tạo cảm giác như chiếc máy bay trực thăng đang bay xung quanh không gian 3D của bạn.

Âm thanh đa hướng

Âm thanh Ambisonic (hoặc ambisonics) giống như một hộp bầu trời cho âm thanh, mang đến một không gian âm thanh sống động cho người dùng. Sử dụng âm thanh đa hướng cho âm thanh môi trường xung quanh hoặc các trường hợp khác mà bạn muốn mô phỏng trường âm thanh toàn cầu bao quanh người nghe. Android XR hỗ trợ định dạng âm thanh đa hướng AmbiX trong âm thanh đa hướng bậc một, bậc hai và bậc ba. Bạn nên dùng các loại tệp Opus (.ogg) và PCM/Wave (.wav).

Sử dụng âm thanh không gian với Jetpack SceneCore

Để triển khai âm thanh không gian bằng Jetpack SceneCore, bạn cần kiểm tra các chức năng không gian và chọn một API để tải âm thanh không gian.

Kiểm tra các chức năng không gian

Trước khi sử dụng các tính năng âm thanh không gian, hãy kiểm tra để đảm bảo Session hỗ trợ âm thanh không gian. Trong tất cả các đoạn mã ở các phần sau, các chức năng sẽ được kiểm tra trước khi cố gắng phát âm thanh được mở rộng.

Tải âm thanh không gian

Bạn có thể dùng bất kỳ API nào sau đây để tải âm thanh không gian để sử dụng trong Jetpack SceneCore.

  • SoundPool: Lý tưởng cho các hiệu ứng âm thanh ngắn có kích thước dưới 1 MB, được tải trước và có thể sử dụng nhiều lần. Đây là một cách hay để tải âm thanh cho âm thanh định vị.
  • ExoPlayer: Lý tưởng để tải nội dung âm thanh nổi và âm thanh vòm, chẳng hạn như nhạc và video. Ngoài ra, chế độ này còn cho phép phát nội dung nghe nhìn ở chế độ nền.
  • MediaPlayer: Cung cấp cách đơn giản nhất để tải âm thanh đa hướng.
  • AudioTrack: Cung cấp khả năng kiểm soát cao nhất đối với cách tải dữ liệu âm thanh. Cho phép ghi trực tiếp các vùng đệm âm thanh hoặc nếu bạn tổng hợp hoặc giải mã tệp âm thanh của riêng mình.

Thêm âm thanh định hướng vào ứng dụng

Nguồn âm thanh theo vị trí được xác định bằng PointSourceParamsEntity được liên kết. Vị trí và hướng của Entity quyết định vị trí mà PointSourceParams được kết xuất trong không gian 3D.

Ví dụ về âm thanh định hướng

Ví dụ sau đây tải một tệp âm thanh hiệu ứng âm thanh vào một nhóm âm thanh và phát lại tệp đó tại vị trí của 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
}

Các điểm chính về mã

  • Bước đầu tiên là kiểm tra xem tính năng Âm thanh không gian hiện có hoạt động hay không bằng cách sử dụng spatialCapabilities.
  • Việc đặt contentType thành CONTENT_TYPE_SONIFICATION và usage thành USAGE_ASSISTANCE_SONIFICATION cho phép hệ thống coi tệp âm thanh này là một hiệu ứng âm thanh.
  • Ví dụ trên tải tệp âm thanh vào nhóm ngay trước khi sử dụng để giữ mã cùng nhau cho đơn giản. Tốt nhất là bạn nên tải tất cả hiệu ứng âm thanh không đồng bộ khi tải ứng dụng để tất cả tệp âm thanh đều có sẵn trong nhóm khi bạn cần.

Thêm âm thanh nổi và âm thanh vòm vào ứng dụng

Bạn nên thêm âm thanh nổi và âm thanh vòm vào ứng dụng bằng cách sử dụng Exoplayer. Để biết thêm thông tin về cách sử dụng tính năng Âm thanh không gian với Exoplayer, hãy tham khảo hướng dẫn về Âm thanh không gian.

Vị trí đặt loa âm thanh nổi và loa âm thanh vòm

Với tính năng định vị loa âm thanh vòm, các loa âm thanh vòm ảo sẽ được định vị và định hướng tương ứng với một loa trung tâm, xung quanh người dùng theo cấu hình ITU tiêu chuẩn.

Theo mặc định, loa kênh trung tâm được đặt trên mainPanelEntity của ứng dụng. Điều này bao gồm cả những ứng dụng di động có âm thanh được không gian hoá tự động bằng Android XR.

Đối với âm thanh nổi, vị trí đặt loa tương tự như âm thanh vòm, ngoại trừ việc chỉ có các kênh bên trái và bên phải được đặt ở phía bên trái và bên phải của bảng điều khiển, tương ứng.

Nếu có nhiều bảng điều khiển và bạn muốn chọn bảng điều khiển phát âm thanh, hoặc nếu bạn muốn âm thanh nổi hoặc âm thanh vòm hiển thị tương ứng với một Entity khác, bạn có thể dùng PointSourceAttributes để xác định vị trí của kênh trung tâm. Các kênh còn lại sẽ được đặt như đã đề cập trước đó. Trong những trường hợp này, bạn cũng phải sử dụng MediaPlayer.

Khi người dùng di chuyển trong không gian của họ, các loa ảo âm thanh nổi và âm thanh vòm sẽ di chuyển và điều chỉnh để đảm bảo rằng các loa luôn ở vị trí tối ưu.

Nếu bạn đã định cấu hình MediaPlayer hoặc ExoPlayer để tiếp tục phát âm thanh nổi hoặc âm thanh vòm ở chế độ nền, thì vị trí loa ảo sẽ thay đổi khi ứng dụng chuyển sang chế độ nền. Vì không có bảng điều khiển hoặc điểm nào khác trong không gian để cố định âm thanh, nên âm thanh không gian sẽ di chuyển theo người dùng (nói cách khác, âm thanh sẽ "cố định theo đầu").

Ví dụ về âm thanh vòm

Ví dụ sau đây tải một tệp âm thanh 5.1 bằng MediaPlayer và đặt kênh trung tâm của tệp thành 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
}

Các điểm chính về mã

Thêm trường âm thanh đa hướng vào ứng dụng

Cách đơn giản nhất để phát lại trường âm thanh đa hướng là tải tệp bằng MediaPlayer. Vì âm thanh đa hướng áp dụng cho toàn bộ cảnh âm thanh, nên bạn không cần chỉ định Entity để cung cấp vị trí. Thay vào đó, bạn tạo một thực thể của SoundFieldAttributes với thứ tự ambisonic thích hợp, chỉ định số lượng kênh.

Ví dụ về Ambisonics

Ví dụ sau đây phát một trường âm thanh đa hướng bằng cách sử dụng 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
}

Các điểm chính về mã

  • Tương tự như các đoạn mã trước, bước đầu tiên là kiểm tra xem các chức năng Âm thanh không gian có được cung cấp hay không bằng cách sử dụng hasCapability().
  • contentType và mức sử dụng chỉ mang tính chất thông tin.
  • AMBISONICS_ORDER_FIRST_ORDER báo hiệu cho SceneCore rằng tệp trường âm thanh xác định 4 kênh.