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 giú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, bao gồm 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 tạo âm thanh không gian trong Android XR. Khi người dùng di chuyển trong không gian của họ, tất cả âm thanh của ứng dụng sẽ được phát ra từ bảng điều khiển mà giao diện người dùng của ứng dụng được hiển thị. Ví dụ: nếu đồng hồ hẹn giờ của ứng dụng đồng hồ kêu, âm thanh sẽ giống như phát ra từ vị trí bảng điều khiển ứng dụng. Android XR sẽ tự động thay đổi âm thanh để tạo hiệu ứng 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 để tạo 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, 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 ambisonic cho trường âm thanh chân thực và tận dụng tính năng tích hợp âm thanh vòm.

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

Android XR hỗ trợ âm thanh vị trí, âm thanh nổi, âm thanh vòm và âm thanh ambisonic.

Âm thanh vị trí

Âm thanh vị trí có thể được định vị để 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. Bạn có thể có nhiều thực thể phát âm thanh từ mỗi vị trí tương ứng. Để kết xuất âm thanh vị trí, tệp phải là âm thanh đơn âm hoặc âm thanh nổi.

Âm thanh nổi và âm thanh vòm theo không gian

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

Âm thanh nổi là các định dạng âm thanh có hai kênh và âm thanh vòm là các định dạng âm thanh có nhiều hơn hai 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 phải.

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

Âm thanh Ambisonic

Âm thanh Ambisonic (hoặc âm thanh ambisonic) giống như một hộp bầu trời cho âm thanh, mang đến cho người dùng một không gian âm thanh sống động. Sử dụng âm thanh ambisonics cho âm thanh môi trường trong nền hoặc các trường hợp khác mà bạn muốn mô phỏng trường âm thanh hình cầu bao quanh người nghe. Android XR hỗ trợ định dạng âm thanh âm thanh 360 độ AmbiX ở chế độ âm thanh 360 độ thứ nhất, thứ hai và thứ 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

Việc triển khai âm thanh không gian bằng Jetpack SceneCore liên quan đến việc kiểm tra các tính 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 rằng Session hỗ trợ âm thanh không gian. Trong tất cả các đoạn mã trong các phần sau, các tính năng sẽ được kiểm tra trước khi phát âm thanh không gian.

Tải âm thanh không gian

Bạn có thể sử 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ác hiệu ứng này được tải trước và có thể sử dụng lại. Đây là một cách hay để tải âm thanh cho âm thanh vị trí.
  • ExoPlayer: Lý tưởng để tải nội dung âm thanh nổi và âm thanh nổi như nhạc và video. Ngoài ra, 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 ambisonic.
  • AudioTrack: Cung cấp nhiều quyền kiểm soát nhất về cách tải dữ liệu âm thanh. Cho phép ghi trực tiếp 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 vị vào ứng dụng

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

Ví dụ về âm thanh vị trí

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

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 có đang hoạt động hay không bằng cách sử dụng getSpatialCapabilities().
  • 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ước 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. Lý tưởng 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 sử dụng Exoplayer để thêm âm thanh nổi và âm thanh vòm vào ứng dụng. Để 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à âm thanh vòm

Với tính năng định vị loa âm thanh vòm, loa âm thanh vòm ảo được đặt và định hướng tương ứng với 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ả các ứng dụng di động có âm thanh được Android XR tự động tạo không gian.

Đố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 ở 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ể sử 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 xung quanh không gian của họ, loa ảo âm thanh nổi và âm thanh vòm sẽ di chuyển và điều chỉnh để đảm bảo 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í của loa ảo sẽ được thay đổi khi ứng dụng chạy ở 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 để neo âm thanh, nên âm thanh không gian sẽ di chuyển cùng người dùng (nói cách khác, âm thanh này "được khoá đầu").

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

Ví dụ sau đây tải 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 (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
}

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

Thêm trường âm thanh âm thanh nổi vào ứng dụng

Cách đơn giản nhất để phát lại trường âm thanh âm thanh nổi là tải tệp bằng MediaPlayer. Vì âm thanh ambisonic áp dụng cho toàn bộ không gian â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ự âm thanh nổi thích hợp chỉ định số lượng kênh.

Ví dụ về Ambionics

Ví dụ sau đây phát trường âm thanh âm thanh nổi bằng 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
}

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

  • Cũng như các đoạn mã trước, bước đầu tiên là kiểm tra xem tính năng Âm thanh không gian có đang hoạt động hay không bằng cách sử dụng getSpatialCapabilities().
  • contentType và usage 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 bốn kênh.