Automotive audio implementations rely on the standard Android Audio HAL, which includes the following:
IDevice
(hardware/interfaces/audio/2.0/IDevice.hal
). Creates input and output streams, handles master volume and muting, and uses:createAudioPatch
to create external-external patches between devices.IDevice.setAudioPortConfig()
to provide volume for each physical stream.
IStream
(hardware/interfaces/audio/2.0/IStream.hal
). Along with the input and output variants, manages the streaming of audio samples to and from the hardware.
Automotive device types
The following device types are relevant for automotive platforms.
Device type | Description |
---|---|
AUDIO_DEVICE_OUT_BUS |
Primary output from Android (this is how all audio from Android is delivered to the vehicle). Used as the address for disambiguating streams for each context. |
AUDIO_DEVICE_OUT_TELEPHONY_TX |
Used for audio routed to the cellular radio for transmission. |
AUDIO_DEVICE_IN_BUS |
Used for inputs not otherwise classified. |
AUDIO_DEVICE_IN_FM_TUNER |
Used only for broadcast radio input. |
AUDIO_DEVICE_IN_TV_TUNER |
Used for a TV device if present. |
AUDIO_DEVICE_IN_LINE |
Used for AUX input jack. |
AUDIO_DEVICE_IN_BLUETOOTH_A2DP |
Music received over Bluetooth. |
AUDIO_DEVICE_IN_TELEPHONY_RX |
Used for audio received from the cellular radio associated with a phone call. |
Routing audio sources
Most audio sources should be captured using AudioRecord
or a
related Android mechanism. The data can then be assigned
AudioAttributes and played through
AndroidTrack
either by relying on the default Android routing
logic or by explicitly calling setPreferredDevice()
on the
AudioRecord
or AudioTrack
objects.
For sources with dedicated hardware connections to the external mixer or
with extremely tight latency requirements, you can use
createAudioPatch()
and releaseAudioPatch()
to
activate and deactivate routes between external devices (without involving
AudioFlinger
in the transport of samples).
Configuring audio devices
Audio devices visible to Android must be defined in
/audio_policy_configuration.xml
, which includes the
following components:
- module name. Supports "primary" (used for automotive
use cases), "A2DP", "remote_submix", and "USB". The module name and the
corresponding audio driver should be compiled to
audio.primary.$(variant).so
. - devicePorts. Contains a list of device descriptors for
all input and output devices (includes permanently attached devices and
removable devices) that are accessible from this module.
- For each output device, you can define gain control that consists of min/max/default/step values in millibel (1 millibel = 1/100 dB = 1/1000 bel).
- The address attribute on a
devicePort
instance can be used to find the device, even if there are multiple devices with the same device type asAUDIO_DEVICE_OUT_BUS
.
- mixPorts. Contains a list of all output and input streams
exposed by the audio HAL. Each
mixPort
instance can be considered as a physical stream to AndroidAudioService
. - routes. Defines a list of possible connections between input and output devices or between stream and device.
The following example defines an output device bus0_phone_out
in
which all Android audio streams are mixed by
mixer_bus0_phone_out
. The route takes output stream of
mixer_bus0_phone_out
to device 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>
Specifying devicePorts
Automotive platforms should specify a devicePort
instance for each
physical stream that is input to and output from Android. For output,
each devicePort
instance should be of type AUDIO_DEVICE_OUT_BUS
,
and addressed by integers (that is, Bus 0, Bus 1, etc.). mixPort
instances
should be created in 1:1 relation to the devicePort
instances and should
allow specification of the data formats that can be routed to each bus.
Automotive implementations can use multiple input device types, including
FM_TUNER
(reserved for broadcast radio input), MIC
device for handling microphone input, and TYPE_AUX_LINE
for
representing analog line input. All other input streams are assigned to
AUDIO_DEVICE_IN_BUS
and discovered by enumerating the devices with
a AudioManager.getDeviceList()
call. Individual sources can be
differentiated by AudioDeviceInfo.getProductName()
.
You can also define external devices as ports, then use those ports to
interact with external hardware with the
IDevice::createAudioPatch
method of the Audio HAL (exposed through a
new CarAudioManager
entry point).
When the bus-based audio driver is present, you must set the
audioUseDynamicRouting
flag to true
:
<resources> <bool name="audioUseDynamicRouting">true</bool> </resources>
For details, see
device/generic/car/emulator/audio/overlay/packages/services/Car/service/res/values/config.xml
.