Automobil-Audio

Android Automotive OS (AAOS) baut auf dem Kern-Android-Audio-Stack auf, um die Anwendungsfälle für den Betrieb als Infotainmentsystem in einem Fahrzeug zu unterstützen. AAOS ist für Infotainment-Sounds (also Medien, Navigation und Kommunikation) verantwortlich, aber nicht direkt für Glockenspiele und Warnungen, für die strenge Verfügbarkeits- und Zeitanforderungen gelten. Während AAOS Signale und Mechanismen bereitstellt, die das Fahrzeug bei der Audioverwaltung unterstützen, ist es letztendlich Sache des Fahrzeugs, festzulegen, welche Geräusche für den Fahrer und die Passagiere abgespielt werden sollen, um sicherzustellen, dass sicherheitskritische Geräusche und behördliche Geräusche ordnungsgemäß gehört werden Unterbrechung.

Da Android das Medienerlebnis des Fahrzeugs verwaltet, sollten externe Medienquellen wie der Radiotuner durch Apps repräsentiert werden, die Audiofokus und Medientastenereignisse für die Quelle verarbeiten können.

Android 11 enthält die folgenden Änderungen an der Audiounterstützung für Automobile:

Android-Sounds und -Streams

Automotive-Audiosysteme verarbeiten die folgenden Sounds und Streams:

Stream-zentriertes Architekturdiagramm

Abbildung 1. Stream-zentriertes Architekturdiagramm

Android verwaltet die Sounds, die von Android-Apps kommen, steuert diese Apps und leitet ihre Sounds basierend auf der Art des Sounds an Ausgabegeräte im HAL weiter:

  • Logische Streams , in der Kern-Audionomenklatur als Quellen bezeichnet, sind mit Audioattributen gekennzeichnet.
  • Physische Streams , in der Kern-Audionomenklatur als Geräte bezeichnet, verfügen nach dem Mischen über keine Kontextinformationen.

Aus Gründen der Zuverlässigkeit werden externe Töne (die von unabhängigen Quellen wie Sicherheitsgurt-Warntönen stammen) außerhalb von Android, unterhalb des HAL oder sogar in separater Hardware verwaltet. Systemimplementierer müssen einen Mixer bereitstellen, der einen oder mehrere Sound-Streams von Android akzeptiert und diese Streams dann auf geeignete Weise mit den für das Fahrzeug erforderlichen externen Soundquellen kombiniert.

Die HAL-Implementierung und der externe Mixer sind dafür verantwortlich, dass die sicherheitskritischen Außengeräusche gehört werden und die von Android bereitgestellten Streams eingemischt und an geeignete Lautsprecher weitergeleitet werden.

Android-Sounds

Apps verfügen möglicherweise über einen oder mehrere Player, die über die Standard-Android-APIs (z. B. AudioManager für die Fokussteuerung oder MediaPlayer für Streaming) interagieren, um einen oder mehrere logische Streams von Audiodaten auszugeben. Bei diesen Daten kann es sich um Einkanal-Mono- oder 7.1-Surround-Daten handeln, sie werden jedoch als eine einzige Quelle weitergeleitet und behandelt. Der App-Stream ist mit AudioAttributen verknüpft, die dem System Hinweise dazu geben, wie das Audio ausgedrückt werden soll.

Die logischen Streams werden über AudioService gesendet und an einen (und nur einen) der verfügbaren physischen Ausgabestreams weitergeleitet, von denen jeder der Ausgang eines Mixers in AudioFlinger ist. Nachdem die Audioattribute zu einem physischen Stream zusammengemischt wurden, sind sie nicht mehr verfügbar.

Jeder physische Stream wird dann zum Rendern auf der Hardware an den Audio-HAL übermittelt. In Automobil-Apps kann es sich bei der Rendering-Hardware um lokale Codecs (ähnlich wie bei Mobilgeräten) oder einen Remote-Prozessor im physischen Netzwerk des Fahrzeugs handeln. In jedem Fall ist es die Aufgabe der Audio-HAL-Implementierung, die tatsächlichen Beispieldaten bereitzustellen und dafür zu sorgen, dass sie hörbar werden.

Externe Streams

Soundstreams, die (aus Zertifizierungs- oder Timing-Gründen) nicht über Android geleitet werden sollten, können direkt an den externen Mixer gesendet werden. Ab Android 11 ist HAL nun in der Lage, den Fokus für diese externen Sounds anzufordern, um Android darüber zu informieren, dass es entsprechende Maßnahmen ergreifen kann, z. B. das Anhalten von Medien oder das Verhindern, dass andere den Fokus erhalten.

Wenn externe Streams Medienquellen sind, die mit der von Android erzeugten Klangumgebung interagieren sollen (z. B. die MP3-Wiedergabe stoppen, wenn ein externer Tuner eingeschaltet wird), sollten diese externen Streams durch eine Android-App dargestellt werden. Eine solche App würde den Audiofokus im Namen der Medienquelle anstelle des HAL anfordern und auf Fokusbenachrichtigungen reagieren, indem sie die externe Quelle nach Bedarf startet/stoppt, um in die Android-Fokusrichtlinie zu passen. Die App ist auch für die Verarbeitung wichtiger Medienereignisse wie Wiedergabe/Pause verantwortlich. Ein vorgeschlagener Mechanismus zur Steuerung solcher externen Geräte ist HwAudioSource .

Ausgabegeräte

Auf der Audio-HAL-Ebene stellt der Gerätetyp AUDIO_DEVICE_OUT_BUS ein generisches Ausgabegerät für den Einsatz in Fahrzeug-Audiosystemen bereit. Das Busgerät unterstützt adressierbare Ports (wobei jeder Port der Endpunkt für einen physischen Stream ist) und dürfte der einzige unterstützte Ausgabegerätetyp in einem Fahrzeug sein.

Eine Systemimplementierung kann einen Bus-Port für alle Android-Sounds verwenden. In diesem Fall mischt Android alles zusammen und liefert es als einen Stream. Alternativ kann der HAL einen Bus-Port für jeden CarAudioContext bereitstellen, um die gleichzeitige Bereitstellung jedes Tontyps zu ermöglichen. Dies ermöglicht es der HAL-Implementierung, die verschiedenen Sounds nach Wunsch zu mischen und zu ducken.

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

Mikrofoneingang

Bei der Audioaufnahme empfängt die Audio-HAL einen openInputStream Aufruf, der ein AudioSource Argument enthält, das angibt, wie die Mikrofoneingabe verarbeitet werden soll.

Die VOICE_RECOGNITION Quelle (insbesondere der Google Assistant) erwartet einen Stereo-Mikrofon-Stream mit Echounterdrückungseffekt (falls verfügbar), auf den jedoch keine andere Verarbeitung angewendet wird. Das Beamforming wird voraussichtlich vom Assistenten durchgeführt.

Mehrkanaliger Mikrofoneingang

Um Audio von einem Gerät mit mehr als zwei Kanälen (Stereo) aufzunehmen, verwenden Sie 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, verwendet AudioRecord nur den durch setChannelMask festgelegten Wert (maximal zwei Kanäle).

Gleichzeitige Erfassung

Ab Android 10 unterstützt das Android-Framework die gleichzeitige Erfassung von Eingaben, jedoch mit Einschränkungen zum Schutz der Privatsphäre des Benutzers. Im Rahmen dieser Einschränkungen werden virtuelle Quellen wie AUDIO_SOURCE_FM_TUNER ignoriert und dürfen daher gleichzeitig mit einem regulären Eingang (z. B. dem Mikrofon) erfasst werden. HwAudioSources werden auch nicht als Teil der gleichzeitigen Aufnahmebeschränkungen betrachtet.

Apps, die für die Verwendung mit AUDIO_DEVICE_IN_BUS Geräten oder mit sekundären AUDIO_DEVICE_IN_FM_TUNER Geräten entwickelt wurden, müssen darauf angewiesen sein, diese Geräte explizit zu identifizieren und AudioRecord.setPreferredDevice() zu verwenden, um die Android-Standardquellenauswahllogik zu umgehen.

Audioverwendungen

AAOS nutzt AudioAttributes.AttributeUsages hauptsächlich für Routing, Lautstärkeanpassungen und Fokusverwaltung. Verwendungen sind eine Darstellung des „Warum“ der Stream abgespielt wird. Daher sollten alle Streams und Audio-Fokus-Anfragen eine Verwendung für ihre Audiowiedergabe angeben. Wenn dies beim Erstellen eines AudioAttributes-Objekts nicht ausdrücklich festgelegt wird, wird die Verwendung standardmäßig auf USAGE_UNKNOWN gesetzt. Obwohl dies derzeit genauso behandelt wird wie USAGE_MEDIA , sollte man sich bei der Medienwiedergabe nicht auf dieses Verhalten verlassen.

Systemnutzungen

In Android 11 wurden die Systemnutzungen eingeführt. Diese Verwendungen verhalten sich ähnlich wie die zuvor festgelegten Verwendungen, außer dass sie für die Verwendung System-APIs sowie android.permission.MODIFY_AUDIO_ROUTING erfordern. Die neuen Systemverwendungen sind:

  • USAGE_EMERGENCY
  • USAGE_SAFETY
  • USAGE_VEHICLE_STATUS
  • USAGE_ANNOUNCEMENT

Um ein AudioAttributes mit einer Systemverwendung zu erstellen, verwenden Sie AudioAttributes.Builder#setSystemUsage anstelle von setUsage . Der Aufruf dieser Methode mit einer nicht systembezogenen Verwendung führt dazu, dass eine IllegalArgumentException ausgelöst wird. Wenn außerdem sowohl eine Systemnutzung als auch eine Nutzung für einen Builder festgelegt wurden, wird beim Erstellen eine IllegalArgumentException ausgelöst.

Um zu überprüfen, welche Verwendung einer AudioAttributes Instanz zugeordnet ist, rufen Sie AudioAttributes#getSystemUsage auf. Dies gibt die zugeordnete Nutzung oder Systemnutzung zurück.

Audiokontexte

Um die Konfiguration von AAOS-Audio zu vereinfachen, wurden ähnliche Verwendungen in CarAudioContext gruppiert. Diese Audiokontexte werden im gesamten CarAudioService verwendet, um Routing, Lautstärkegruppen und Audiofokusverwaltung zu definieren.

Die Audiokontexte in Android 11 sind:

CarAudioContext Zugehörige Attributverwendungen
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 zwischen Audiokontexten und -verwendungen. Hervorgehobene Zeilen gelten für neue Systemverwendungen .

Mehrzonen-Audio

Mit der Automobilindustrie kommen neue Anwendungsfälle hinzu, bei denen gleichzeitige Benutzer mit der Plattform interagieren und separate Medien konsumieren möchten. Beispielsweise kann ein Fahrer in der Kabine Musik abspielen, während die Passagiere auf dem Rücksitz ein YouTube-Video auf dem Fonddisplay ansehen. Multizonen-Audio ermöglicht dies, indem es die gleichzeitige Wiedergabe verschiedener Audioquellen in verschiedenen Bereichen des Fahrzeugs ermöglicht.

Mit Multizonen-Audio ab Android 10 können OEMs Audio in separate Zonen konfigurieren. Jede Zone ist eine Sammlung von Geräten im Fahrzeug mit eigenen Volumengruppen, Routing-Konfiguration für Kontexte und Fokusmanagement. Auf diese Weise könnte die Hauptkabine als eine Audiozone konfiguriert werden, während die Kopfhöreranschlüsse des hinteren Displays als zweite Zone konfiguriert werden könnten.

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

Der Fokus wird auch für jede Audiozone unabhängig beibehalten. Dies ermöglicht es Anwendungen in verschiedenen Zonen, unabhängig voneinander Audio zu produzieren, ohne sich gegenseitig zu stören, während Anwendungen weiterhin Fokusänderungen innerhalb ihrer Zone berücksichtigen. CarZonesAudioFocus innerhalb CarAudioService ist für die Fokusverwaltung für jede Zone verantwortlich.

Konfigurieren Sie Mehrzonen-Audio

Abbildung 2. Mehrzonen-Audio konfigurieren

Audio-HAL

Automotive-Audio-Implementierungen basieren auf dem Standard-Android-Audio-HAL, das Folgendes umfasst:

  • IDevice.hal . Erstellt Eingabe- und Ausgabeströme, verwaltet die Hauptlautstärke und Stummschaltung und verwendet:
    • createAudioPatch . Um Extern-Extern-Patches zwischen Geräten zu erstellen.
    • IDevice.setAudioPortConfig() , um Lautstärke für jeden physischen Stream bereitzustellen.
  • IStream.hal . Verwaltet zusammen mit den Eingabe- und Ausgabevarianten das Streaming von Audio-Samples zur und von der Hardware.

Gerätetypen für Kraftfahrzeuge

Die folgenden Gerätetypen sind für Automotive-Plattformen relevant.

Gerätetyp Beschreibung
AUDIO_DEVICE_OUT_BUS Primäre Ausgabe von Android (auf diese Weise werden alle Audiodaten von Android an das Fahrzeug geliefert). Wird als Adresse zur eindeutigen Unterscheidung von Streams für jeden Kontext verwendet.
AUDIO_DEVICE_OUT_TELEPHONY_TX Wird für Audiosignale verwendet, die zur Übertragung an das Mobilfunkgerät weitergeleitet werden.
AUDIO_DEVICE_IN_BUS Wird für Eingaben verwendet, die nicht anderweitig klassifiziert sind.
AUDIO_DEVICE_IN_FM_TUNER Wird nur für den Rundfunkeingang verwendet.
AUDIO_DEVICE_IN_TV_TUNER Wird für ein TV-Gerät verwendet, falls vorhanden.
AUDIO_DEVICE_IN_LINE Wird für die AUX-Eingangsbuchse verwendet.
AUDIO_DEVICE_IN_BLUETOOTH_A2DP Über Bluetooth empfangene Musik.
AUDIO_DEVICE_IN_TELEPHONY_RX Wird für Audiosignale verwendet, die vom Mobilfunkgerät im Zusammenhang mit einem Telefonanruf empfangen werden.

Audiogeräte konfigurieren

Für Android sichtbare Audiogeräte müssen in /audio_policy_configuration.xml definiert werden, das die folgenden Komponenten enthält:

  • Modulname. Unterstützt „primär“ (wird für Anwendungsfälle im Automobilbereich verwendet), „A2DP“, „remote_submix“ und „USB“. Der Modulname und der entsprechende Audiotreiber sollten zu audio.primary.$(variant).so kompiliert werden.
  • Geräteports. Enthält eine Liste von Gerätedeskriptoren für alle Eingabe- und Ausgabegeräte (einschließlich dauerhaft angeschlossener Geräte und entfernbarer Geräte), auf die von diesem Modul aus zugegriffen werden kann.
    • Für jedes Ausgabegerät können Sie eine Verstärkungsregelung definieren, die aus Min.-/Max.-/Standard-/Schrittwerten in Millibel besteht (1 Millibel = 1/100 dB = 1/1000 Bel).
    • Das Adressattribut einer devicePort-Instanz kann verwendet werden, um das Gerät zu finden, auch wenn mehrere Geräte mit demselben Gerätetyp wie AUDIO_DEVICE_OUT_BUS vorhanden sind.
  • mixPorts. Enthält eine Liste aller vom Audio-HAL bereitgestellten Ausgabe- und Eingabestreams. Jede mixPort-Instanz kann als physischer Stream für Android AudioService betrachtet werden.
  • Routen. Definiert eine Liste möglicher Verbindungen zwischen Eingabe- und Ausgabegeräten oder zwischen Stream und Gerät.

Das folgende Beispiel definiert ein Ausgabegerät bus0_phone_out, in dem alle Android-Audiostreams von mixer_bus0_phone_out gemischt werden. Die Route führt den Ausgabestrom von mixer_bus0_phone_out zum Gerät bus0_phone_out .

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