Spatial Audio

Spatial Audio ist ein eindrucksvolles Audioerlebnis, das Nutzern das Gefühl vermittelt, als wären sie mitten im Geschehen, und Inhalte viel realistischer klingen lässt. Der von Pixel Buds Pro erzeugte räumliche Klang scheint dabei aus mehreren Lautsprechern zu kommen, ähnlich wie bei einem Surround-Soundsystem, aber über Kopfhörer.

In einem Film fängt der Ton eines Autos vielleicht hinter dem Nutzer an, bewegt sich nach vorne und wandert in die Ferne. In einem Videochat können Stimmen voneinander getrennt und um den Nutzer herum platziert werden, damit die Sprecher leichter zu erkennen sind.

Wenn deine Inhalte ein unterstütztes Audioformat verwenden, kannst du Spatial Audio zu deinem ab Android 13 (API-Level 33) heruntergeladen werden.

Funktionen abfragen

Mit der Klasse Spatializer können Sie die Verräumlichkeitsfähigkeiten und das Verhalten des Geräts abfragen. Rufen Sie zuerst eine Instanz der Spatializer aus der AudioManager ab:

Kotlin

val spatializer = audioManager.spatializer

Java

Spatializer spatializer = AudioManager.getSpatializer();

Nachdem du das Spatializer erhalten hast, überprüfe, ob die vier Bedingungen erfüllt sein müssen. „true“ für das Gerät, das Spatial Audio ausgibt:

Kriterien Prüfen
Unterstützt das Gerät die Verräumlichung? getImmersiveAudioLevel() ist nicht SPATIALIZER_IMMERSIVE_LEVEL_NONE
Ist die Spatialisierung verfügbar?
 Die Verfügbarkeit hängt von der Kompatibilität mit der aktuellen Audioausgabe ab.
isAvailable() ist true
Ist die räumliche Darstellung aktiviert? isEnabled() ist true
Kann eine Audiotracks mit den angegebenen Parametern räumlich erstellt werden? canBeSpatialized() ist true

Diese Bedingungen sind möglicherweise nicht erfüllt, wenn die Spatialisierung beispielsweise für den aktuellen Audiotrack nicht verfügbar ist oder auf dem Audioausgabegerät vollständig deaktiviert ist.

Erfassung von Kopfbewegungen

Bei unterstützten Headsets kann die Plattform den Klang Verräumlichung basierend auf der Kopfposition der Nutzenden. Um zu prüfen, ob ein Kopf-Tracker verfügbar für die aktuelle Audioausgabe-Routing, Anruf isHeadTrackerAvailable()

Kompatible Inhalte

Spatializer.canBeSpatialized() gibt an, ob Audio mit den angegebenen Eigenschaften mit der aktuellen Routing-Ausgabe für das Gerät räumlich lokalisiert werden kann. Diese Methode verwendet einen AudioAttributes und AudioFormat. Beide sind die nachfolgend ausführlicher beschrieben sind.

AudioAttributes

Ein AudioAttributes-Objekt beschreibt die Nutzung eines Audiostreams (z. B. Game Audio oder Standardmedien) sowie die Wiedergabeeigenschaften und den Inhaltstyp.

Verwende beim Aufrufen von canBeSpatialized() dieselbe AudioAttributes-Instanz wie für deine Player festgelegt. Beispiel: Sie die Jetpack Media3-Bibliothek verwenden und die AudioAttributes, verwende AudioAttributes.DEFAULT.

Spatial Audio deaktivieren

Wenn du angeben möchtest, dass deine Inhalte bereits verräumt wurden, rufe die setIsContentSpatialized(true) damit die Audiodaten nicht doppelt verarbeitet werden. Sie können auch die durch den Aufruf von setSpatializationBehavior(AudioAttributes.SPATIALIZATION_BEHAVIOR_NEVER)

AudioFormat

Ein AudioFormat-Objekt beschreibt Details zum Format und der Kanalkonfiguration eines Audiotracks.

Wenn du AudioFormat instanzierst, um sie an canBeSpatialized() zu übergeben, muss die Codierung mit dem vom Decoder erwarteten Ausgabeformat übereinstimmen. Außerdem sollten Sie eine Kanalmaske der zur Kanalkonfiguration deines Contents passt. Im Abschnitt Standardverhalten für die Spatialisierung findest du Informationen zu den zu verwendenden Werten.

Änderungen an Spatializer überwachen

Wenn Sie auf Änderungen des Status von Spatializer hören möchten, können Sie einen Listener mit Spatializer.addOnSpatializerStateChangedListener() hinzufügen. Wenn Sie Änderungen an der Verfügbarkeit eines Kopf-Trackers beobachten möchten, rufen Sie Spatializer.addOnHeadTrackerAvailableListener() auf.

Das kann nützlich sein, wenn du die Titelauswahl während der Wiedergabe mithilfe der Callbacks des Listeners anpassen möchtest. Wenn ein Nutzer beispielsweise sein Headset mit dem Gerät verbindet oder trennt, gibt der onSpatializerAvailableChanged-Callback an, ob der Spatializer-Effekt für die neue Audioausgabe-Weiterleitung verfügbar ist. An dieser Stelle kannst du die Logik für die Titelauswahl deines Players an die neuen Funktionen des Geräts anpassen. Weitere Informationen zu Informationen zum Verhalten der Trackauswahl von ExoPlayer (siehe ExoPlayer und Spatial Audio) .

ExoPlayer und Spatial Audio

In den jüngsten Releases von ExoPlayer ist die Verwendung von Spatial Audio noch einfacher. Wenn du die eigenständige ExoPlayer-Bibliothek (Paketname com.google.android.exoplayer2) verwendest, wird die Plattform in Version 2.17 für die Ausgabe von räumlichem Audio konfiguriert. In Version 2.18 werden Einschränkungen für die Anzahl der Audiokanäle eingeführt. Wenn du das ExoPlayer-Modul aus der Media3-Bibliothek (Paketname androidx.media3) verwendest, sind diese Updates in den Versionen 1.0.0-beta01 und höher enthalten.

Nach der Aktualisierung der ExoPlayer-Abhängigkeit auf die neueste Version Inhalte enthalten, die räumlich räumlich dargestellt werden können.

Einschränkungen bei der Anzahl der Audiokanäle

Wenn alle vier Bedingungen für Spatial Audio erfüllt sind, wählt ExoPlayer einen Audiotrack mit mehreren Kanälen aus. Andernfalls wählt ExoPlayer stattdessen einen Stereotrack aus. Wenn sich die Spatializer-Eigenschaften ändern, wird ExoPlayer löst eine neue Trackauswahl aus, um einen Audiotrack auszuwählen, der mit dem aktuellen Properties. Beachte, dass es bei der neuen Titelauswahl zu einer kurzen Pufferung kommen kann.

Wenn du die Einschränkungen bei der Anzahl der Audiokanäle deaktivieren möchtest, musst du die Parameter für die Titelauswahl im Player wie unten gezeigt festlegen:

Kotlin

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

Java

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

Ebenso kannst du die Parameter einer vorhandenen Titelauswahl aktualisieren, um Einschränkungen bei der Anzahl der Audiokanäle zu deaktivieren:

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()
);

Wenn die Einschränkungen für die Anzahl der Audiokanäle deaktiviert sind und Inhalte mehrere Audios haben wählt ExoPlayer zunächst den Track mit den meisten Kanälen aus auf dem Gerät abgespielt werden kann. Enthält der Inhalt beispielsweise eine und einem Stereo-Audiotrack. Das Gerät unterstützt beider Wiedergaben abgespielt wird, wählt ExoPlayer den Multi-Channel-Track aus. Weitere Informationen zum Anpassen dieses Verhaltens findest du unter Audiotrackauswahl.

Auswahl des Audiotracks

Wenn die Einschränkungen der Audiokanalanzahl von ExoPlayer deaktiviert ist, wählt der ExoPlayer nicht automatisch einen Audiotrack aus. das mit den Eigenschaften des Raumsensors des Geräts übereinstimmt. Stattdessen können Sie Logik der Trackauswahl von ExoPlayer durch Festlegen der Trackauswahl anpassen vor oder während der Wiedergabe. Standardmäßig wählt ExoPlayer Audio aus Tracks, die in Bezug auf den MIME-Typ mit dem anfänglichen Track identisch sind (Codierung), Kanalanzahl und Abtastrate.

Parameter für die Titelauswahl ändern

Um die Track-Auswahlparameter des ExoPlayers zu ändern, verwende Player.setTrackSelectionParameters() Ebenso können Sie die aktuellen Parameter von ExoPlayer Player.getTrackSelectionParameters() So kannst du beispielsweise einen Stereo-Audiotrack während der Wiedergabe auswählen:

Kotlin

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

Java

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

Hinweis: Wenn Sie die Parameter für die Titelauswahl während der Wiedergabe ändern, kann es zu Unterbrechungen kommen. Weitere Informationen zum Optimieren der Parameter für die Titelauswahl des Players findest du im Abschnitt Titelauswahl der ExoPlayer-Dokumentation.

Standardverhalten für Verräumlichung

Das Standardverhalten für Verräumlichung in Android umfasst die folgenden Verhaltensweisen die von OEMs angepasst werden können:

  • Nur Multi-Channel-Inhalte werden räumlich dargestellt, keine Stereoinhalte. Wenn Sie ExoPlayer nicht verwenden, ist abhängig vom Format Ihres Mehrkanal- Audioinhalte haben, müssen Sie möglicherweise die maximale Anzahl von Kanälen konfigurieren. die von einem Audiodecoder an eine große Zahl ausgegeben werden kann. So wird sichergestellt, dass der Audiodecoder PCM mit mehreren Kanälen für die Plattform ausgibt, um eine räumliche Audiowiedergabe zu ermöglichen.

    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);

    Ein Beispiel in der Praxis findest du in der MediaCodecAudioRenderer.java von ExoPlayer. So deaktivieren Sie die Raumisierung unabhängig vom OEM selbst: Informationen zur Anpassung findest du unter Spatial Audio deaktivieren.

  • AudioAttributes: Audio kann verräumt werden wenn die usage ist entweder auf USAGE_MEDIA festgelegt oder USAGE_GAME.

  • AudioFormat: Verwenden Sie eine Kanalmaske, die mindestens den Parameter AudioFormat.CHANNEL_OUT_QUAD (vorn links, vorn rechts, hinten links und hinten rechts), damit die Audiospur für Verräumlichkeiten infrage kommen. Im folgenden Beispiel wird AudioFormat.CHANNEL_OUT_5POINT1 für einen 5.1-Audiotrack verwendet. Verwenden Sie für einen Stereo-Audiotrack AudioFormat.CHANNEL_OUT_STEREO.

    Wenn Sie Media3 verwenden, können Sie Util.getAudioTrackChannelConfig(int channelCount) nutzen. , um eine Kanalanzahl in eine Kanalmaske umzuwandeln.

    Legen Sie außerdem die Codierung auf AudioFormat.ENCODING_PCM_16BIT fest. wenn der Decoder für die Ausgabe von Multi-Channel-PCM konfiguriert ist.

    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();

Spatial Audio testen

Achte darauf, dass Spatial Audio auf deinem Testgerät aktiviert ist:

  • Bei kabelgebundenen Headsets navigieren Sie zu Systemeinstellungen > Ton & Vibration > Räumlich Audio.
  • Bei kabellosen Headsets navigiere zu Systemeinstellungen > Verbundene Geräte > Zahnradsymbol für Ihr Mobilgerät > Spatial Audio:

Wenn du prüfen möchtest, ob Spatial Audio für die aktuelle Weiterleitung verfügbar ist, führe den Befehl adb shell dumpsys audio auf deinem Gerät aus. Sie sollten Folgendes sehen: Parameter in der Ausgabe, während die Wiedergabe aktiv ist:

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