Dźwięk przestrzenny

Dźwięk przestrzenny to niezwykłe doznania dźwiękowe, które zabierają użytkowników jest w centrum akcji, dzięki czemu filmy brzmią bardziej realistycznie. Dźwięk jest „przestrzenny” aby uzyskać efekt wielu głośników, podobny do dźwięku przestrzennego konfiguracji, ale przez słuchawki.

Na przykład w filmie dźwięk samochodu może rozpoczynać się za plecami użytkownika, poruszać się na przód i dalej. Na czacie wideo głosy mogą być są rozdzielone i rozmieszczone wokół użytkownika, co ułatwia rozpoznanie osób mówiących.

Jeśli Twoje treści są w obsługiwanym formacie audio, możesz dodać dźwięk przestrzenny aplikacji w wersji na Androida 13 (poziom API 33).

Zapytanie o możliwości

Użyj zajęć Spatializer, aby: zapytań dotyczących możliwości i działań urządzeń w obszarze przestrzennym. Zacznij od pobrania wystąpienie Spatializer z AudioManager:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Po otrzymaniu Spatializer sprawdź, czy spełnione są 4 warunki true (prawda) dla urządzenia do odtwarzania dźwięku przestrzennego:

Kryteria Sprawdź
Czy urządzenie obsługuje stosowanie przestrzeni przestrzennej? getImmersiveAudioLevel() nie jest SPATIALIZER_IMMERSIVE_LEVEL_NONE
Czy jest dostępna analiza przestrzenna? Dostępność funkcji
zależy od zgodności z bieżącym kierowaniem wyjścia audio.
isAvailable() to true
Czy przestrzennia jest włączona? isEnabled() to true
Czy ścieżkę audio z podanymi parametrami można zastosować w przestrzeni przestrzennej? canBeSpatialized() to true

Te warunki mogą nie zostać spełnione, np. jeśli przestrzeń jest niedostępna dla bieżącej ścieżki audio lub całkowicie wyłączone na urządzeniu wyjściowym audio.

Monitorowanie ruchów głowy

W przypadku obsługiwanych zestawów słuchawkowych platforma może dostosować na podstawie położenia głowy użytkownika. Aby sprawdzić, czy tracker jest dla bieżącego kierowania wyjścia audio, wywołanie isHeadTrackerAvailable()

Zgodne treści

Spatializer.canBeSpatialized() wskazuje, czy dźwięk o podanych właściwościach może zostać przestrzenny za pomocą aktualne ustawienia routingu urządzenia wyjściowego. Ta metoda wymaga AudioAttributes i AudioFormat, oba są omówiono szczegółowo poniżej.

AudioAttributes

Obiekt AudioAttributes opisuje użycie strumień audio (na przykład dźwięk z gry) lub standardowych multimediów), oraz sposób odtwarzania i typ treści.

Dzwoniąc pod numer canBeSpatialized(), użyj tego samego wystąpienie AudioAttributes ustawione dla Player. Na przykład, jeśli używasz biblioteki Jetpack Media3 i nie dostosowano AudioAttributes, użyj AudioAttributes.DEFAULT.

Wyłączanie dźwięku przestrzennego

Aby wskazać, że treść została już przestrzenna, użyj wywołania setIsContentSpatialized(true) aby dźwięk nie został przetworzony podwójnie. Możesz też dostosować w celu całkowitego wyłączenia tej funkcji przez wywołanie setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)

AudioFormat

Obiekt AudioFormat opisuje dane dotyczące formatu i konfiguracji kanału ścieżki audio.

Podczas tworzenia instancji AudioFormat przekazywanej do canBeSpatialized(): ustaw kodowanie format wyjściowy spodziewany przez dekoder. Skonfiguruj także maska kanału która pasuje do konfiguracji kanału. Zapoznaj się z W sekcji Domyślne zachowanie przestrzenne znajdziesz wskazówki na temat konkretne wartości.

Wykrywaj zmiany w: Spatializer

Aby wykrywać zmiany stanu urządzenia Spatializer, możesz dodać detektor dzięki Spatializer.addOnSpatializerStateChangedListener(). Podobnie, aby obserwować zmiany w dostępności trackera, zadzwoń do: Spatializer.addOnHeadTrackerAvailableListener().

Jest to przydatne, gdy chcesz dostosować wybór ścieżek podczas odtwarzania za pomocą wywołań zwrotnych słuchacza. Na przykład, gdy użytkownik łączy lub rozłącza swoje zestawu słuchawkowego z urządzenia onSpatializerAvailableChanged wywołanie zwrotne wskazuje, czy efekt przestrzenny jest dostępny dla nowych kierowania wyjścia audio. W tym momencie możesz rozważyć zaktualizowanie śledzić logikę wyboru pod kątem nowych możliwości urządzenia. Więcej informacji: Sposób wyboru ścieżek przez ExoPlayer znajdziesz w sekcji ExoPlayer i dźwięk przestrzenny. .

ExoPlayer i dźwięk przestrzenny

Najnowsze wersje ExoPlayer ułatwiają korzystanie z dźwięku przestrzennego. Jeśli używasz samodzielna biblioteka ExoPlayer (nazwa pakietu com.google.android.exoplayer2), wersja 2.17 konfiguruje platformę tak, aby wydawała dźwięk przestrzenny, 2.18 wprowadza ograniczenia liczby kanałów audio. Jeśli używasz modułu ExoPlayer z biblioteki Media3 (nazwa pakietu androidx.media3), wersje 1.0.0-beta01 i nowszych zawierają te same aktualizacje.

Po zaktualizowaniu zależności ExoPlayer do najnowszej wersji aplikacja musi zawierać treści, które można umieścić w przestrzeni przestrzennej.

Ograniczenia liczby kanałów audio

Jeśli zostaną spełnione wszystkie 4 warunki dotyczące dźwięku przestrzennego, ExoPlayer wybierze: wielokanałową ścieżkę audio. W przeciwnym razie ExoPlayer wybiera ścieżkę stereo. Jeśli właściwości Spatializer ulegną zmianie, ExoPlayer uruchamia wybór nowej ścieżki audio, która pasuje do obecne właściwości. Pamiętaj, że wybór nowego utworu może spowodować krótką przez okres ponownego buforowania.

Aby wyłączyć ograniczenia liczby kanałów audio, ustaw parametry wyboru ścieżki w odtwarzaczu, jak pokazano poniżej:

Kotlin

exoPlayer.trackSelectionParameters = DefaultTrackSelector.Parameters.Builder(context)
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  new DefaultTrackSelector.Parameters.Builder(context)
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

Można również zaktualizować parametry istniejącego selektora ścieżki, aby wyłączyć takie ograniczenia liczby kanałów audio:

Kotlin

val trackSelector = DefaultTrackSelector(context)
...
trackSelector.parameters = trackSelector.buildUponParameters()
  .setConstrainAudioChannelCountToDeviceCapabilities(false)
  .build()

Java

DefaultTrackSelector trackSelector = new DefaultTrackSelector(context);
...
trackSelector.setParameters(
  trackSelector
    .buildUponParameters()
    .setConstrainAudioChannelCountToDeviceCapabilities(false)
    .build()
);

z wyłączonymi ograniczeniami liczby kanałów audio, jeśli treści zawierają wiele ścieżek dźwiękowych; utworów, ExoPlayer początkowo wybiera utwór z największą liczbą kanałów, można odtworzyć na urządzeniu. Jeśli na przykład treści zawierają wielokanałową i stereofoniczną ścieżkę audio, a urządzenie obsługuje jednocześnie, ExoPlayer wybierze ścieżkę wielokanałową. Zobacz Wybór ścieżki dźwiękowej – szczegółowe informacje o tym, jak dostosować to działanie.

Wybór ścieżki audio

Gdy ograniczenia liczby kanałów audio ExoPlayer jest wyłączone, ExoPlayer nie wybiera automatycznie ścieżki dźwiękowej która pasuje do właściwości mechanizmu przestrzennego urządzenia. Zamiast tego możesz: dostosuj logikę wyboru ścieżek w aplikacji ExoPlayer, ustawiając wybór ścieżki przed lub w trakcie odtwarzania. Domyślnie ExoPlayer wybiera dźwięk ścieżki, które są takie same jak ścieżka początkowa pod względem typu MIME. (kodowanie), liczbę kanałów i częstotliwość próbkowania.

Zmiana parametrów wyboru ścieżki

Aby zmienić parametry wyboru ścieżki w odtwarzaczu ExoPlayer, użyj funkcji Player.setTrackSelectionParameters() Bieżące parametry ExoPlayer można też uzyskać za pomocą parametru Player.getTrackSelectionParameters() Aby na przykład wybrać stereofoniczną ścieżkę dźwiękową w trakcie odtwarzania:

Kotlin

exoPlayer.trackSelectionParameters = exoPlayer.trackSelectionParameters
  .buildUpon()
  .setMaxAudioChannelCount(2)
  .build()

Java

exoPlayer.setTrackSelectionParameters(
  exoPlayer.getTrackSelectionParameters()
    .buildUpon()
    .setMaxAudioChannelCount(2)
    .build()
);

Pamiętaj, że zmiana parametrów wyboru ścieżki w trakcie odtwarzania może spowodować przerwy w odtwarzaniu. Więcej informacji o dostrajaniu ścieżki odtwarzacza parametrów wyboru są dostępne w wybór ścieżki w dokumentacji ExoPlayer.

Domyślne zachowanie przestrzeni

Domyślne zachowanie przestrzenne na Androidzie obejmuje te zachowania które mogą być dostosowywane przez OEM:

  • Przestrzenne są tylko treści wielokanałowe, a nie materiały stereo. Jeśli nie używasz ExoPlayer, w zależności od formatu Twojego wielokanałowego treści audio, może być konieczne skonfigurowanie maksymalnej liczby kanałów które mogą być wysyłane przez dekoder audio na dużą liczbę. Dzięki temu dekoder dźwięku wysyła wielokanałowy PCM, aby platforma stała się przestrzenna.

    Kotlin

    val mediaFormat = MediaFormat()
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99)
    

    Java

    MediaFormat mediaFormat = new MediaFormat();
    mediaFormat.setInteger(MediaFormat.KEY_MAX_OUTPUT_CHANNEL_COUNT, 99);
    

    Przykład działania znajdziesz w przewodniku firmy ExoPlayer MediaCodecAudioRenderer.java. Aby samodzielnie wyłączyć przestrzennie, niezależnie od producenta OEM Więcej informacji znajdziesz w sekcji o wyłączaniu dźwięku przestrzennego.

  • AudioAttributes: dźwięk kwalifikuje się do przekształcenia przestrzennego jeśli usage jest ustawiona na USAGE_MEDIA lub USAGE_GAME.

  • AudioFormat: użyj maski kanału, która zawiera co najmniej AudioFormat.CHANNEL_OUT_QUAD kanałów (przedni lewy, przedni prawy, tylny lewy i tylny prawy), na który będzie odtwarzany dźwięk. i nie mogą być wykorzystywane w przestrzeni. W poniższym przykładzie używamy wyrażenia AudioFormat.CHANNEL_OUT_5POINT1 w przypadku ścieżki audio 5.1. W przypadku stereofonicznej ścieżki audio użyj AudioFormat.CHANNEL_OUT_STEREO.

    Jeśli korzystasz z Media3, możesz użyć Util.getAudioTrackChannelConfig(int channelCount) aby przekonwertować liczbę kanałów na maskę kanału.

    Dodatkowo ustaw kodowanie na AudioFormat.ENCODING_PCM_16BIT jeśli dekoder jest skonfigurowany tak, by wysyłał wielokanałowy PCM.

    Kotlin

    val audioFormat = AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build()
    

    Java

    AudioFormat audioFormat = new AudioFormat.Builder()
      .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
      .setChannelMask(AudioFormat.CHANNEL_OUT_5POINT1)
      .build();
    

Przetestuj dźwięk przestrzenny

Sprawdź, czy na urządzeniu testowym włączony jest dźwięk przestrzenny:

  • W przypadku przewodowych zestawów słuchawkowych otwórz Ustawienia systemu > Dźwięk i wibracje > Przestrzenny audio.
  • W przypadku słuchawek bezprzewodowych otwórz Ustawienia systemu > Połączone urządzenia > Ikona koła zębatego dla urządzenia bezprzewodowego > Dźwięk przestrzenny.

Aby sprawdzić dostępność dźwięku przestrzennego dla bieżącego routingu, uruchom adb shell dumpsys audio na urządzeniu. Strona powinna wyglądać tak: parametrów w danych wyjściowych, gdy odtwarzanie jest aktywne:

Spatial audio:
mHasSpatializerEffect:true (effect present)
isSpatializerEnabled:true (routing dependent)