Spatial Audio

Spatial Audio ist ein immersives Audioerlebnis, bei dem Nutzer in den Mittelpunkt des Geschehens. Dadurch klingen Inhalte realistischer. Der Ton ist „räumlich“ um einen Effekt aus mehreren Lautsprechern zu erzeugen, der einem Surround-Sound ähnelt. Einrichtung ü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 Video-Chat können Stimmen getrennt und um den Nutzer herum platziert, damit die Sprecher leichter identifiziert werden können.

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

Abfrage von Funktionen

Mit der Klasse Spatializer können Sie die Verräumlichkeitsfähigkeiten und das Verhalten des Geräts abfragen. Zuerst abrufen eine Instanz von Spatializer aus dem AudioManager:

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 Verräumlichung verfügbar?
Die Verfügbarkeit hängt von der Kompatibilität mit dem aktuellen Audioausgaberouting ab.
isAvailable() ist true
Ist die Raumisierung aktiviert? isEnabled() ist true
Kann eine Audiotracks mit den angegebenen Parametern räumlich erstellt werden? canBeSpatialized() ist true

Diese Bedingungen werden möglicherweise nicht erfüllt, z. B. wenn die Verräumlichung nicht verfügbar ist für den aktuellen Audiotrack oder wird auf dem Audioausgabegerät vollständig deaktiviert.

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 dem das aktuelle Routing des Ausgabegeräts. Diese Methode verwendet einen AudioAttributes und AudioFormat. Beide sind die nachfolgend ausführlicher beschrieben sind.

AudioAttributes

Ein AudioAttributes-Objekt beschreibt die Verwendung eines Audiostream (z. B. Audio eines Spiels) oder Standardmedien), sowie dessen Wiedergabeverhalten und Inhaltstyp.

Verwenden Sie beim Aufrufen von canBeSpatialized() dasselbe AudioAttributes-Instanz wie für Ihre Player festgelegt. Wenn beispielsweise Sie die Jetpack Media3-Bibliothek verwenden und die AudioAttributes, verwende AudioAttributes.DEFAULT.

Spatial Audio deaktivieren

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

AudioFormat

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

Wenn Sie die AudioFormat instanziieren, die an canBeSpatialized() übergeben werden soll, gilt Folgendes: Codierung festlegen in dasselbe Ausgabeformat, das vom Decodierer erwartet wird. Außerdem sollten Sie eine Kanalmaske der zur Kanalkonfiguration deines Contents passt. Weitere Informationen finden Sie im Im Abschnitt Standardmäßiges Raumisierungsverhalten finden Sie Informationen dazu, Werte angeben.

Änderungen an Spatializer überwachen

Sie können einen Listener hinzufügen, um auf Änderungen am Status des Spatializers zu warten. mit Spatializer.addOnSpatializerStateChangedListener(). Um auf Veränderungen bei der Verfügbarkeit eines Kopf-Trackers zu warten, Rufen Sie Spatializer.addOnHeadTrackerAvailableListener() auf.

Dies kann nützlich sein, wenn Sie die Titelauswahl während der Wiedergabe anpassen möchten. mithilfe der Callbacks des Listeners. Beispiel: Wenn ein Nutzer eine Verbindung zu einem Headset vom Gerät, das onSpatializerAvailableChanged Callback zeigt an, ob der Raumklang-Effekt für den neuen Routing der Audioausgabe. Nun kannst du die Einstellungen deines Players Auswahllogik verfolgen, damit sie den neuen Funktionen des Geräts entspricht. Weitere Informationen zu Informationen zum Verhalten der Trackauswahl von ExoPlayer (siehe ExoPlayer und Spatial Audio) .

ExoPlayer und Spatial Audio

Mit den jüngsten Releases von ExoPlayer ist die Einführung von Spatial Audio noch einfacher. Wenn Sie die eigenständige ExoPlayer-Bibliothek (Paketname com.google.android.exoplayer2) In der Version 2.17 ist die Plattform so konfiguriert, dass Raumklang-Audio ausgegeben wird. Mit 2.18 wurden Einschränkungen bei der Anzahl der Audiokanäle eingeführt. Wenn Sie das ExoPlayer-Modul aus der Media3-Bibliothek verwenden, (Paketname androidx.media3), Versionen 1.0.0-beta01 und neuere enthalten dieselben Updates.

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

Einschränkungen für die Anzahl der Audiokanäle

Wenn alle vier Bedingungen für Spatial Audio erfüllt sind, wählt der ExoPlayer ein Mehrkanal-Audiotrack. Ist dies nicht der Fall, wählt ExoPlayer stattdessen eine Stereospur 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 diese neue Titelauswahl zu einer kurzen Zeitraum für die erneute Pufferung aus.

Legen Sie die Parameter für die Trackauswahl fest, um die Beschränkungen für die Anzahl der Audiokanäle zu deaktivieren. im Player ein:

Kotlin

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

Java

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

Ebenso können Sie die Parameter einer vorhandenen Track-Auswahl aktualisieren, um Einschränkungen für die Anzahl der Audiokanäle:

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 finden Sie in der Weitere Informationen zur Anpassung dieses Verhaltens finden Sie unter Auswahl von Audiotiteln.

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

Wenn Sie die Parameter für die Titelauswahl mitten während der Wiedergabe ändern, eine Unterbrechung der Wiedergabe. Weitere Informationen zur Feinabstimmung des Titels des Players stehen im Menü 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 Multi-Channel-Netzwerks 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. Dadurch wird sichergestellt, Der Audiodecoder gibt eine Mehrkanal-PCM aus, damit die Plattform verräumt.

    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 Praxisbeispiel findest du im ExoPlayer-MediaCodecAudioRenderer.java. 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 verwenden wir AudioFormat.CHANNEL_OUT_5POINT1 für einen 5.1-Audiotrack. Für Stereo-Audiospuren verwendest du 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:

Um die Verfügbarkeit von Spatial Audio für das aktuelle Routing zu prüfen, führe den Befehl adb shell dumpsys audio auf Ihrem Gerät. Sie sollten Folgendes sehen: Parameter in der Ausgabe, während die Wiedergabe aktiv ist:

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