Auto-Audio

Android Automotive OS (AAOS) basiert auf dem Android-Audiostack, um die Anwendungsfälle für die Nutzung als Infotainmentsystem in einem Fahrzeug zu unterstützen. AAOS ist für Infotainment-Töne (Medien, Navigation und Kommunikation) verantwortlich, aber nicht direkt für Glockentöne und Warnungen, die strenge Verfügbarkeits- und Zeitanforderungen haben. AAOS bietet Signale und Mechanismen, die dem Fahrzeug bei der Audioverwaltung helfen. Letztendlich entscheidet das Fahrzeug jedoch, welche Töne für den Fahrer und die Mitfahrer abgespielt werden sollen, damit sicherheitsrelevante und rechtliche Töne richtig und ohne Unterbrechung zu hören sind.

Da Android die Mediennutzung im Fahrzeug verwaltet, sollten externe Medienquellen wie der Radiotuner durch Apps dargestellt werden, die den Audiofokus und Medientastenereignisse für die Quelle verarbeiten können.

Android 11 enthält die folgenden Änderungen am Audiosupport für die Automobilbranche:

Android-Töne und ‑Streams

Audiosysteme in Fahrzeugen verarbeiten die folgenden Töne und Streams:

Streamorientiertes Architekturdiagramm

Abbildung 1: Streamorientiertes Architekturdiagramm

Android verwaltet die Töne, die von Android-Apps stammen, steuert diese Apps und leitet ihre Töne je nach Art des Tons an Ausgabegeräte an der HAL weiter:

  • Logische Streams, die in der Audionomenklatur als Quellen bezeichnet werden, sind mit Audioattributen getaggt.
  • Physische Streams, in der Audionomenklatur als Geräte bezeichnet, haben nach dem Mischen keine Kontextinformationen.

Aus Gründen der Zuverlässigkeit werden externe Töne (von unabhängigen Quellen wie Sicherheitsgurtwarnungen) außerhalb von Android, unter der HAL oder sogar in separater Hardware verwaltet. Systemintegratoren müssen einen Mixer bereitstellen, der einen oder mehrere Streams von Audioeingängen von Android akzeptiert und diese Streams dann auf geeignete Weise mit den externen Audioquellen kombiniert, die für das Fahrzeug erforderlich sind.

Die HAL-Implementierung und der externe Mixer sorgen dafür, dass sicherheitsrelevante externe Geräusche zu hören sind, und mischen die von Android bereitgestellten Streams zusammen und leiten sie an geeignete Lautsprecher weiter.

Android-Töne

Apps können einen oder mehrere Player haben, die über die standardmäßigen Android-APIs (z. B. AudioManager für die Fokussteuerung oder MediaPlayer für das Streaming) interagieren, um einen oder mehrere logische Streams von Audiodaten auszugeben. Diese Daten können einkanaliges Mono oder 7.1-Surround sein, werden aber als einzelne Quelle weitergeleitet und behandelt. Der App-Stream ist mit AudioAttributes verknüpft, die dem System Hinweise dazu geben, wie der Audioinhalt wiedergegeben werden soll.

Die logischen Streams werden über AudioService gesendet und an einen (und nur einen) der verfügbaren physischen Ausgabestreams weitergeleitet. Jeder dieser Streams ist die Ausgabe eines Mixers in AudioFlinger. Nachdem die Audioattribute in einen physischen Stream gemischt wurden, sind sie nicht mehr verfügbar.

Jeder physische Stream wird dann an die Audio-HAL zum Rendern auf der Hardware gesendet. In Automotive-Apps kann die Rendering-Hardware lokale Codecs (ähnlich wie bei Mobilgeräten) oder ein Remote-Prozessor über das physische Netzwerk des Fahrzeugs sein. In jedem Fall ist es Aufgabe der Audio HAL-Implementierung, die tatsächlichen Sample-Daten bereitzustellen und für ihre Wiedergabe zu sorgen.

Externe Streams

Audiostreams, die aus Zertifizierungs- oder Timinggründen nicht über Android geleitet werden sollten, können direkt an den externen Mixer gesendet werden. Ab Android 11 kann die HAL den Fokus für diese externen Töne anfordern, um Android zu informieren, damit entsprechende Maßnahmen ergriffen werden können, z. B. das Pausieren von Medien oder das Verhindern, dass andere Apps den Fokus erhalten.

Wenn externe Streams Medienquellen sind, die mit der von Android generierten Audioumgebung interagieren sollen (z. B. die MP3-Wiedergabe beenden, wenn ein externer Tuner aktiviert ist), müssen diese externen Streams von einer Android-App repräsentiert werden. Eine solche App würde den Audiofokus im Namen der Medienquelle anstelle der HAL anfordern und auf Fokusbenachrichtigungen reagieren, indem sie die externe Quelle bei Bedarf startet oder stoppt, um den Android-Fokusrichtlinien zu entsprechen. Die App ist auch für die Verarbeitung wichtiger Medienereignisse wie „Wiedergabe“/„Pause“ verantwortlich. Ein vorgeschlagener Mechanismus zur Steuerung solcher externer Geräte ist HwAudioSource.

Ausgabegeräte

Auf Audio-HAL-Ebene stellt der Gerätetyp AUDIO_DEVICE_OUT_BUS ein generisches Ausgabegerät für die Verwendung in Fahrzeugaudiosystemen bereit. Das Busgerät unterstützt adressierbare Ports (bei denen jeder Port der Endpunkt für einen physischen Stream ist) und ist voraussichtlich der einzige unterstützte Ausgabegerätetyp in einem Fahrzeug.

Eine Systemimplementierung kann einen Bus-Port für alle Android-Töne verwenden. In diesem Fall mischt Android alles zusammen und liefert es als einen Stream aus. Alternativ kann die HAL einen Bus-Port für jede CarAudioContext bereitstellen, um die gleichzeitige Bereitstellung beliebiger Tontypen zu ermöglichen. So kann die HAL-Implementierung die verschiedenen Töne nach Belieben mischen und leiser stellen.

Die Zuweisung von Audiokontexten zu Ausgabegeräten erfolgt über car_audio_configuration.xml.

Mikrofon

Beim Aufnehmen von Audio erhält die Audio-HAL einen openInputStream-Aufruf mit einem AudioSource-Argument, das angibt, wie die Mikrofoneingabe verarbeitet werden soll.

Die VOICE_RECOGNITION-Quelle (insbesondere Google Assistant) erwartet einen Stereomikrofonstream mit einem Echounterdrückungseffekt (falls verfügbar), der sonst nicht verarbeitet wird. Das Beamforming wird voraussichtlich von Assistant durchgeführt.

Mehrkanaliger Mikrofoneingang

Wenn du Audio von einem Gerät mit mehr als zwei Kanälen (Stereo) aufnehmen möchtest, verwende eine Kanalindexmaske anstelle einer Positionsindexmaske (z. B. CHANNEL_IN_LEFT). Beispiel:

final AudioFormat audioFormat = new AudioFormat.Builder()
    .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
    .setSampleRate(44100)
    .setChannelIndexMask(0xf /* 4 channels, 0..3 */)
    .build();
final AudioRecord audioRecord = new AudioRecord.Builder()
    .setAudioFormat(audioFormat)
    .build();
audioRecord.setPreferredDevice(someAudioDeviceInfo);

Wenn sowohl setChannelMask als auch setChannelIndexMask festgelegt sind, wird für AudioRecord nur der von setChannelMask festgelegte Wert verwendet (maximal zwei Kanäle).

Gleichzeitige Aufnahme

Seit Android 10 unterstützt das Android-Framework die gleichzeitige Erfassung von Eingaben, jedoch mit Einschränkungen zum Schutz der Privatsphäre der Nutzer. Im Rahmen dieser Einschränkungen werden virtuelle Quellen wie AUDIO_SOURCE_FM_TUNER ignoriert und können daher gleichzeitig mit einer regulären Eingabe (z. B. dem Mikrofon) erfasst werden. HwAudioSources werden auch nicht als Teil der Einschränkungen für gleichzeitige Aufnahmen berücksichtigt.

Apps, die für die Verwendung mit AUDIO_DEVICE_IN_BUS-Geräten oder sekundären AUDIO_DEVICE_IN_FM_TUNER-Geräten entwickelt wurden, müssen diese Geräte explizit identifizieren und AudioRecord.setPreferredDevice() verwenden, um die Logik zur Auswahl der Standardquelle von Android zu umgehen.

Audionutzung

AAOS verwendet AudioAttributes.AttributeUsages hauptsächlich für Routing, Lautstärkeanpassungen und Fokusverwaltung. Die Verwendungen geben an, warum der Stream wiedergegeben wird. Daher sollte für alle Streams und Audiofokusanfragen eine Verwendung für die Audiowiedergabe angegeben werden. Wenn beim Erstellen eines AudioAttributes-Objekts keine explizite Angabe gemacht wird, wird standardmäßig USAGE_UNKNOWN verwendet. Dieses Zeichen wird derzeit wie USAGE_MEDIA behandelt. Bei der Medienwiedergabe sollte man sich jedoch nicht darauf verlassen.

Systemnutzung

In Android 11 wurden die Systemnutzungen eingeführt. Diese Verwendungen verhalten sich ähnlich wie die zuvor festgelegten Verwendungen, mit der Ausnahme, dass neben android.permission.MODIFY_AUDIO_ROUTING auch System-APIs verwendet werden müssen. Die neuen Systemnutzungen sind:

  • USAGE_EMERGENCY
  • USAGE_SAFETY
  • USAGE_VEHICLE_STATUS
  • USAGE_ANNOUNCEMENT

Wenn Sie eine AudioAttributes mit Systemnutzung erstellen möchten, verwenden Sie AudioAttributes.Builder#setSystemUsage anstelle von setUsage. Wenn diese Methode für eine nicht systeminterne Verwendung aufgerufen wird, wird eine IllegalArgumentException geworfen. Wenn für einen Builder sowohl eine Systemnutzung als auch eine Nutzung festgelegt wurde, wird beim Erstellen eine IllegalArgumentException ausgegeben.

Wenn Sie prüfen möchten, welche Nutzung mit einer AudioAttributes-Instanz verknüpft ist, rufen Sie AudioAttributes#getSystemUsage auf. Es wird die zugehörige Nutzung oder Systemnutzung zurückgegeben.

Audiokontexte

Zur Vereinfachung der Konfiguration von AAOS-Audio wurden ähnliche Verwendungen in CarAudioContext gruppiert. Diese Audiokontexte werden in CarAudioService verwendet, um Routing, Lautstärkegruppen und die Verwaltung des Audiofokus zu definieren.

Die Audiokontexte in Android 11 sind:

CarAudioContext Zugehörige AttributeUsages
MUSIC UNKNOWN, GAME, MEDIA
NAVIGATION ASSISTANCE_NAVIGATION_GUIDANCE
VOICE_COMMAND ASSISTANT, ASSISTANCE_ACCESSIBILITY
CALL_RING NOTIFICATION_RINGTONE
CALL VOICE_COMMUNICATION, VOICE_COMMUNICATION_SIGNALING
ALARM ALARM
NOTIFICATION NOTIFICATION, NOTIFICATION_*
SYSTEM_SOUND ASSISTANCE_SONIFICATION
EMERGENCY EMERGENCY
SAFETY SAFETY
VEHICLE_STATUS VEHICLE_STATUS
ANNOUNCEMENT ANNOUNCEMENT

Zuordnung von Audiokontexten und Verwendungen Die hervorgehobenen Zeilen beziehen sich auf neue Systemnutzungen.

Multizonen-Audio

Die Automobilbranche bringt neue Anwendungsfälle mit sich, bei denen mehrere Nutzer gleichzeitig mit der Plattform interagieren und separate Medien nutzen möchten. So kann beispielsweise der Fahrer Musik in der Kabine abspielen, während sich die Passagiere auf dem Rücksitz ein YouTube-Video auf dem Rücksitzdisplay ansehen. Das ist mit einem Multizonen-Audiosystem möglich, da verschiedene Audioquellen gleichzeitig in verschiedenen Bereichen des Fahrzeugs wiedergegeben werden können.

Mit der Audiowiedergabe in mehreren Zonen ab Android 10 können OEMs Audio in separaten Zonen konfigurieren. Jede Zone besteht aus mehreren Geräten im Fahrzeug mit eigenen Lautstärkegruppen, Routingkonfigurationen für Kontexte und Fokusverwaltung. So kann der Hauptraum als Audiozone konfiguriert werden, während die Kopfhörerbuchsen des Rückbildschirms als zweite Zone konfiguriert werden.

Die Zonen sind als Teil von car_audio_configuration.xml definiert. CarAudioService liest dann die Konfiguration und hilft AudioService, Audiostreams basierend auf der zugehörigen Zone weiterzuleiten. In jeder Zone werden weiterhin Regeln für das Routing basierend auf Kontexten und der Anwendungs-UID definiert. Wenn ein Player erstellt wird, bestimmt CarAudioService, welcher Zone der Player zugewiesen ist, und dann basierend auf der Nutzung, an welches Gerät der AudioFlinger die Audioinhalte weiterleiten soll.

Der Fokus wird auch für jede Audiozone unabhängig beibehalten. So können Anwendungen in verschiedenen Zonen unabhängig voneinander Audio produzieren, ohne sich gegenseitig zu stören, während Änderungen des Fokus innerhalb ihrer Zone berücksichtigt werden. CarZonesAudioFocus in CarAudioService ist für die Verwaltung des Fokus für jede Zone verantwortlich.

Mehrzonen-Audio konfigurieren

Abbildung 2. Mehrzonen-Audio konfigurieren

Audio HAL

Audioimplementierungen für die Automobilbranche basieren auf der standardmäßigen Android Audio HAL, die Folgendes umfasst:

  • IDevice.hal: Erstellt Eingabe- und Ausgabestreams, verwaltet die Lautstärke und Stummschaltung und verwendet:
    • createAudioPatch. Externe ‑ externe Patches zwischen Geräten erstellen.
    • IDevice.setAudioPortConfig(), um das Volume für jeden physischen Stream anzugeben.
  • IStream.hal. Verwaltet zusammen mit den Eingabe- und Ausgabevarianten das Streaming von Audiosamples von und zur Hardware.

Gerätetypen für die Automobilbranche

Die folgenden Gerätetypen sind für Automobilplattformen relevant.

Gerätetyp Beschreibung
AUDIO_DEVICE_OUT_BUS Hauptausgabe von Android (über diese wird der gesamte Audioinhalt von Android an das Fahrzeug übertragen). Wird als Adresse für die Behebung von Mehrdeutigkeit bei Streams für jeden Kontext verwendet.
AUDIO_DEVICE_OUT_TELEPHONY_TX Wird für Audio verwendet, das zur Übertragung an das Mobilfunknetz weitergeleitet wird.
AUDIO_DEVICE_IN_BUS Wird für Eingaben verwendet, die nicht anderweitig klassifiziert werden.
AUDIO_DEVICE_IN_FM_TUNER Wird nur für die Eingabe von Rundfunkradio verwendet.
AUDIO_DEVICE_IN_TV_TUNER Wird für ein Fernsehgerät verwendet, falls vorhanden.
AUDIO_DEVICE_IN_LINE Wird für den AUX-Eingang verwendet.
AUDIO_DEVICE_IN_BLUETOOTH_A2DP Über Bluetooth empfangene Musik
AUDIO_DEVICE_IN_TELEPHONY_RX Wird für Audio verwendet, das vom Mobilfunknetz empfangen wird, das mit einem Telefonanruf verknüpft ist.

Audiogeräte konfigurieren

Für Android sichtbare Audiogeräte müssen in /audio_policy_configuration.xml definiert werden. Dazu gehören die folgenden Komponenten:

  • Modulnamen Unterstützt „primary“ (für Anwendungsfälle in der Automobilbranche), „A2DP“, „remote_submix“ und „USB“. Der Modulname und der entsprechende Audiotreiber sollten für audio.primary.$(variant).so kompiliert werden.
  • devicePorts Enthält eine Liste von Gerätebeschreibungen für alle Eingabe- und Ausgabegeräte (einschließlich fest angeschlossener und externer Geräte), auf die über dieses Modul zugegriffen werden kann.
    • Für jedes Ausgabegerät können Sie eine Verstärkungsregelung mit Min/Max/Standard/Schrittwerten in Millibel definieren (1 Millibel = 1/100 dB = 1/1.000 bel).
    • Mit dem Adressattribut einer devicePort-Instanz kann das Gerät gefunden werden, auch wenn es mehrere Geräte mit demselben Gerätetyp wie AUDIO_DEVICE_OUT_BUS gibt.
  • mixPorts. Enthält eine Liste aller Ausgabe- und Eingabestreams, die von der Audio-HAL freigegeben werden. Jede mixPort-Instanz kann als physischer Stream für den Android AudioService betrachtet werden.
  • Routen Hier wird eine Liste möglicher Verbindungen zwischen Eingabe- und Ausgabegeräten oder zwischen Stream und Gerät definiert.

Im folgenden Beispiel wird ein Ausgabegerät „bus0_phone_out“ definiert, in dem alle Android-Audiostreams von „mixer_bus0_phone_out“ gemischt werden. Die Route leitet den Ausgabestream von mixer_bus0_phone_out an das Gerät bus0_phone_out weiter.

<audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude">
    <modules>
        <module name="primary" halVersion="3.0">
            <attachedDevices>
                <item>bus0_phone_out</item>
<defaultOutputDevice>bus0_phone_out</defaultOutputDevice>
            <mixPorts>
                <mixPort name="mixport_bus0_phone_out"
                         role="source"
                         flags="AUDIO_OUTPUT_FLAG_PRIMARY">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                </mixPort>
            </mixPorts>
            <devicePorts>
                <devicePort tagName="bus0_phone_out"
                            role="sink"
                            type="AUDIO_DEVICE_OUT_BUS"
                            address="BUS00_PHONE">
                    <profile name="" format="AUDIO_FORMAT_PCM_16_BIT"
                            samplingRates="48000"
                            channelMasks="AUDIO_CHANNEL_OUT_STEREO"/>
                    <gains>
                        <gain name="" mode="AUDIO_GAIN_MODE_JOINT"
                                minValueMB="-8400"
                                maxValueMB="4000"
                                defaultValueMB="0"
                                stepValueMB="100"/>
                    </gains>
                </devicePort>
            </devicePorts>
            <routes>
                <route type="mix" sink="bus0_phone_out"
                       sources="mixport_bus0_phone_out"/>
            </routes>
        </module>
    </modules>
</audioPolicyConfiguration>