Funkcje dźwięku przestrzennego w Jetpack SceneCore umożliwiają tworzenie wciągających wrażeń dźwiękowych w aplikacjach na Androida XR.
Dźwięk przestrzenny symuluje sposób, w jaki użytkownicy odbierają dźwięk w środowisku 3D. Tworzy on wrażenie, że dźwięk dochodzi ze wszystkich kierunków, w tym z góry i z dołu. System robi to, symulując co najmniej 1 „wirtualny głośnik” w określonych lokalizacjach w przestrzeni 3D.
W przypadku istniejących aplikacji, które nie zostały zaprojektowane ani zmodyfikowane pod kątem Androida XR, dźwięk jest automatycznie przestrzenny w Androidzie XR. Gdy użytkownik porusza się w przestrzeni, cały dźwięk aplikacji będzie emitowany z panelu, na którym jest renderowany interfejs aplikacji. Jeśli na przykład w aplikacji zegara włączy się minutnik, dźwięk będzie dochodził z pozycji panelu aplikacji. Android XR automatycznie zmieni dźwięk, aby uzyskać realizm pozycyjny. Na przykład odczuwalna odległość między panelem aplikacji a użytkownikiem będzie subtelnie wpływać na głośność dźwięku, co zwiększy realizm.
Więcej informacji o tym, jak istniejące aplikacje renderują dźwięk przestrzenny, znajdziesz na tej stronie w sekcji Dodawanie dźwięku stereo i przestrzennego do aplikacji.
Jeśli optymalizujesz aplikację pod kątem XR, Jetpack SceneCore udostępnia narzędzia do zaawansowanego dostosowywania dźwięku przestrzennego. Możesz precyzyjnie umieszczać dźwięki w środowisku 3D, używać dźwięku ambisonicznego do tworzenia realistycznych pól dźwiękowych i korzystać z wbudowanej integracji dźwięku przestrzennego.
Typy dźwięku przestrzennego dostępne w Androidzie XR
Android XR obsługuje dźwięk pozycyjny, stereo, przestrzenny i ambisoniczny.
Dźwięk pozycyjny
Dźwięk pozycyjny można ustawić tak, aby był odtwarzany z określonego punktu w przestrzeni 3D. Możesz na przykład mieć model 3D psa szczekającego w rogu swojego wirtualnego środowiska. Możesz mieć wiele obiektów emitujących dźwięk z każdej z ich pozycji. Aby renderować dźwięk pozycyjny, pliki muszą być mono lub stereo.
Przestrzenny dźwięk stereo i przestrzenny
Wszystkie formaty multimediów Androida są obsługiwane w przypadku dźwięku pozycyjnego, stereo i przestrzennego. Oprócz tych formatów urządzenia z Androidem XR mogą obsługiwać Dolby Atmos, Dolby Digital i Dolby Digital+ formaty audio.
Dźwięk stereo odnosi się do formatów audio z 2 kanałami, a dźwięk przestrzenny odnosi się do formatów audio z więcej niż 2 kanałami, takich jak dźwięk przestrzenny 5.1 lub dźwięk przestrzenny 7.1. Dane dźwiękowe każdego kanału są powiązane z 1 głośnikiem. Na przykład podczas odtwarzania muzyki w stereo kanał lewego głośnika może emitować inne ścieżki instrumentów niż kanał prawego głośnika.
Dźwięk przestrzenny jest często używany w filmach i programach telewizyjnych, aby zwiększyć realizm i immersję dzięki zastosowaniu wielu kanałów głośnikowych. Na przykład dialogi są często odtwarzane z kanału głośnika centralnego, a dźwięk lecącego helikoptera może wykorzystywać różne kanały w sekwencji, aby stworzyć wrażenie, że helikopter lata wokół Twojej przestrzeni 3D.
Dźwięk ambisoniczny
Dźwięk ambisoniczny (lub ambisonics) jest jak skybox dla dźwięku,
zapewniając użytkownikom wciągający krajobraz dźwiękowy. Używaj ambisonics do dźwięków otoczenia w tle lub w innych sytuacjach, w których chcesz odtworzyć pełne sferyczne pole dźwiękowe otaczające słuchacza. Android XR obsługuje format dźwięku ambisonicznego
AmbiX w ambisonics pierwszego, drugiego i trzeciego rzędu. Zalecamy używanie typów plików Opus (.ogg) i
PCM/Wave (.wav).
Używanie dźwięku przestrzennego z Jetpack SceneCore
Implementacja dźwięku przestrzennego za pomocą Jetpack SceneCore obejmuje sprawdzenie możliwości przestrzennych i wybranie interfejsu API do wczytywania dźwięku przestrzennego.
Sprawdzanie możliwości przestrzennych
Zanim zaczniesz korzystać z funkcji dźwięku przestrzennego, sprawdź, czy Session obsługuje
dźwięk przestrzenny. We wszystkich fragmentach kodu w kolejnych sekcjach możliwości są sprawdzane przed próbą odtworzenia dźwięku przestrzennego.
Wczytywanie dźwięku przestrzennego
Do wczytywania dźwięku przestrzennego do użycia w Jetpack SceneCore możesz użyć dowolnego z tych interfejsów API.
SoundPool: idealny do krótkich efektów dźwiękowych o rozmiarze mniejszym niż 1 MB. Są one wczytywane z wyprzedzeniem i można ich używać wielokrotnie. To świetny sposób na wczytywanie dźwięku do dźwięku pozycyjnego.ExoPlayer: idealny do wczytywania treści stereo i dźwięku przestrzennego, takich jak muzyka i filmy. Umożliwia też odtwarzanie multimediów w tle.MediaPlayer: najprostszy sposób na wczytywanie dźwięku ambisonicznego.AudioTrack: zapewnia największą kontrolę nad sposobem wczytywania danych audio. Umożliwia bezpośrednie zapisywanie buforów dźwięku lub jeśli masz zsyntetyzowane lub zdekodowane własne pliki audio.
Sprawdzanie obsługi formatu multimediów
Niektóre formaty multimediów są obsługiwane przez platformę Android. Jednak
konkretne urządzenie z Androidem XR może obsługiwać dodatkowe formaty, takie jak
Dolby Atmos. Aby sprawdzić obsługę formatu multimediów, użyj
AudioCapabilities ExoPlayera:
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. }
Sprawdzanie tych możliwości może wiązać się z blokowaniem wywołań i nie powinno być wywoływane w wątku głównym.
Dodawanie dźwięku pozycyjnego do aplikacji
Źródła dźwięku pozycyjnego są definiowane przez PointSourceParams i powiązany z nimi
Entity. Położenie i orientacja Entity określają, gdzie PointSourceParams jest renderowany w przestrzeni 3D. Aby ustawić PointSourceParams i powiązany z nim entity w instancji MediaPlayer, wywołaj
setPointSourceParams w
SpatialMediaPlayer.
Przykład dźwięku pozycyjnego
Ten przykład wczytuje plik audio z efektem dźwiękowym do puli dźwięków i odtwarza go w pozycji 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(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 }
Najważniejsze informacje o kodzie
- Pierwszym krokiem jest sprawdzenie, czy dostępne są możliwości dźwięku przestrzennego
za pomocą
spatialCapabilities. - Ustawienie contentType na
CONTENT_TYPE_SONIFICATIONi użycie naUSAGE_ASSISTANCE_SONIFICATIONpozwala systemowi traktować ten plik audio jako efekt dźwiękowy. - W poprzednim przykładzie plik audio jest wczytywany do puli bezpośrednio przed jego użyciem, aby uprościć kod. Najlepiej wczytywać wszystkie efekty dźwiękowe asynchronicznie podczas wczytywania aplikacji, aby wszystkie pliki audio były dostępne w puli, gdy ich potrzebujesz.
Dodawanie dźwięku stereo i przestrzennego do aplikacji
Zalecanym sposobem dodawania dźwięku stereo i przestrzennego do aplikacji jest użycie
Exoplayer. Więcej informacji o tym, jak używać dźwięku przestrzennego z Exoplayer,
znajdziesz w przewodniku po dźwięku przestrzennym.
Pozycjonowanie głośników stereo i dźwięku przestrzennego
W przypadku pozycjonowania głośników dźwięku przestrzennego wirtualne głośniki dźwięku przestrzennego są ustawiane i orientowane względem głośnika centralnego wokół użytkownika w standardowej konfiguracji ITU.
Domyślnie głośnik kanału centralnego jest umieszczany w aplikacji's
mainPanelEntity. Dotyczy to aplikacji mobilnych, w których dźwięk jest automatycznie przestrzenny w Androidzie XR.
W przypadku stereo rozmieszczenie głośników jest podobne do dźwięku przestrzennego, z tym że tylko kanały lewy i prawy są umieszczone odpowiednio po lewej i prawej stronie panelu.
Jeśli masz kilka paneli i chcesz wybrać, który panel ma emitować dźwięk, lub jeśli chcesz, aby dźwięk stereo lub przestrzenny był renderowany względem innego Entity, możesz użyć PointSourceAttributes, aby zdefiniować lokalizację kanału centralnego. Pozostałe kanały zostaną umieszczone w sposób opisany wcześniej. W takich
sytuacjach musisz też użyć MediaPlayer.
Gdy użytkownik porusza się w przestrzeni, wirtualne głośniki stereo i dźwięku przestrzennego będą się przesuwać i dostosowywać, aby zawsze znajdowały się w optymalnej pozycji.
Jeśli skonfigurujesz MediaPlayer lub ExoPlayer tak, aby odtwarzały dźwięk stereo lub przestrzenny w tle, pozycjonowanie wirtualnych głośników zostanie zmienione, gdy aplikacja będzie działać w tle. Ponieważ nie ma panelu ani innego punktu w przestrzeni, do którego można by przypiąć dźwięk, dźwięk przestrzenny porusza się wraz z użytkownikiem (czyli jest „przywiązany do głowy”).
Przykład dźwięku przestrzennego
Ten przykład wczytuje plik audio 5.1 za pomocą MediaPlayer i ustawia kanał centralny pliku jako 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(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 }
Najważniejsze informacje o kodzie
- Podobnie jak w przypadku przykładu dźwięku pozycyjnego, pierwszym krokiem jest sprawdzenie, czy dostępne są możliwości dźwięku przestrzennego, za pomocą
spatialCapabilities. - Ustawienie
contentTypenaAudioAttributes.CONTENT_TYPE_MUSICi użycie naAudioAttributes.USAGE_MEDIApozwala systemowi traktować ten plik audio jako dźwięk przestrzenny.
Dodawanie pól dźwięku ambisonicznego do aplikacji
Najprostszym sposobem odtwarzania pól dźwięku ambisonicznego jest wczytanie pliku za pomocą MediaPlayer. Ponieważ dźwięk ambisoniczny dotyczy całego krajobrazu dźwiękowego, nie musisz określać Entity, aby podać pozycję. Zamiast tego utwórz instancję SoundFieldAttributes z odpowiednim rzędem ambisonicznym określającym liczbę kanałów.
Przykład ambisonics
Ten przykład odtwarza pole dźwięku ambisonicznego za pomocą 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 }
Najważniejsze informacje o kodzie
- Podobnie jak w przypadku poprzednich fragmentów kodu, pierwszym krokiem jest sprawdzenie, czy dostępne są możliwości dźwięku przestrzennego
, za pomocą
hasCapability(). contentTypei użycie mają charakter wyłącznie informacyjny.AMBISONICS_ORDER_FIRST_ORDERinformuje SceneCore, że plik pola dźwiękowego definiuje 4 kanały.