The Android 10 release includes a significant refactoring of the audio policy manager to provide more flexibility to support complex automotive use cases:
- OEM-specific routing strategies.
- Customizable volume groups for groups of legacy stream types using the same volume curves.
- Routing strategies declared by the audio policy engine instead of being hard coded.
- Volume curves and groups managed by the audio policy engine.
- Internal refactoring preparing for a future split between common code and configurable code and offering richer audio device management. For example, the use of all device properties not just its type in policy rules.
Android 7.0 introduced a audio policy configuration file format (XML) for describing your audio topology.
Previous Android releases required using
device/<company>/<device>/audio/audio_policy.conf
to declare the audio devices present on your product (you can see an example of
this file for the Galaxy Nexus audio hardware in
device/samsung/tuna/audio/audio_policy.conf
). However, CONF is a
simple, proprietary format that is too limited to describe complex topologies for
verticals like televisions and automobiles.
Android 7.0 deprecated audio_policy.conf
and added support
for defining an audio topology using an XML file format that's more
human-readable, has a wide range of editing and parsing tools, and is flexible
enough to describe complex audio topologies. Android 7.0 uses the
USE_XML_AUDIO_POLICY_CONF
build flag for choosing the XML
format of config files.
Advantages of the XML format
As in the CONF file, the XML file enables defining the number and types of output and input stream profiles, devices usable for playback and capture, and audio attributes. In addition, the XML format offers the following enhancements:
- In Android 10, more than one active recording app is
allowed simultaneously.
- Recording start is never rejected due to a concurrency situation.
- The
registerAudioRecordingCallback(AudioManager.AudioRecordingCallback cb)
callback notifies clients of capture path changes.
- In the following situations, a client gets silent audio samples:
- A privacy-sensitive use case (for example,
VOICE_COMMUNICATION
) is active. - The client doesn't have a foreground service or foreground UI.
- Specials roles are recognized by the policy:
- Accessibility service: Can record even if a privacy-sensitive use case is active.
- Assistant: Considered privacy sensitive if the UI is on top.
- A privacy-sensitive use case (for example,
- Audio profiles have a structure similar to HDMI simple audio descriptors, enabling a different set of sampling rates/channel masks for each audio format.
- There are explicit definitions for all possible connections between devices and streams. Previously, an implicit rule made it possible to connect all devices attached to the same HAL module, preventing the audio policy from controlling connections requested with audio patch APIs. In the XML format, the topology description defines connection limitations.
- Support for includes avoids repeating standard A2DP, USB, or reroute submit definitions.
- Volume curves are customizable. Previously, volume tables were hardcoded. In the XML format, volume tables are described and can be customized.
The template at
frameworks/av/services/audiopolicy/config/audio_policy_configuration.xml
shows many of these features in use.
File format and location
The new audio policy configuration file is
audio_policy_configuration.xml
and is located in
/system/etc
. The following examples show a simple audio policy configuration in the
XML file format for Android 12 and for the versions below
Android 12.
Show audio policy example for Android 12
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <audioPolicyConfiguration version="7.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <globalConfiguration speaker_drc_enabled="true"/> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>Speaker</item> <item>Earpiece</item> <item>Built-In Mic</item> </attachedDevices> <defaultOutputDevice>Speaker</defaultOutputDevice> <mixPorts> <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="primary input" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address=""> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000 16000 48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> </devicePorts> <routes> <route type="mix" sink="Earpiece" sources="primary output"/> <route type="mix" sink="Speaker" sources="primary output"/> <route type="mix" sink="Wired Headset" sources="primary output"/> <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/> </routes> </module> <xi:include href="a2dp_audio_policy_configuration.xml"/> </modules> <xi:include href="audio_policy_volumes.xml"/> <xi:include href="default_volume_tables.xml"/> </audioPolicyConfiguration>
Show audio policy example for versions below Android 12
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <audioPolicyConfiguration version="1.0" xmlns:xi="http://www.w3.org/2001/XInclude"> <globalConfiguration speaker_drc_enabled="true"/> <modules> <module name="primary" halVersion="3.0"> <attachedDevices> <item>Speaker</item> <item>Earpiece</item> <item>Built-In Mic</item> </attachedDevices> <defaultOutputDevice>Speaker</defaultOutputDevice> <mixPorts> <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="primary input" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </mixPort> </mixPorts> <devicePorts> <devicePort tagName="Earpiece" type="AUDIO_DEVICE_OUT_EARPIECE" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Speaker" role="sink" type="AUDIO_DEVICE_OUT_SPEAKER" address=""> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Wired Headset" type="AUDIO_DEVICE_OUT_WIRED_HEADSET" role="sink"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </devicePort> <devicePort tagName="Built-In Mic" type="AUDIO_DEVICE_IN_BUILTIN_MIC" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> <devicePort tagName="Wired Headset Mic" type="AUDIO_DEVICE_IN_WIRED_HEADSET" role="source"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="8000,16000,48000" channelMasks="AUDIO_CHANNEL_IN_MONO"/> </devicePort> </devicePorts> <routes> <route type="mix" sink="Earpiece" sources="primary output"/> <route type="mix" sink="Speaker" sources="primary output"/> <route type="mix" sink="Wired Headset" sources="primary output"/> <route type="mix" sink="primary input" sources="Built-In Mic,Wired Headset Mic"/> </routes> </module> <xi:include href="a2dp_audio_policy_configuration.xml"/> </modules> <xi:include href="audio_policy_volumes.xml"/> <xi:include href="default_volume_tables.xml"/> </audioPolicyConfiguration>
The top-level structure contains modules that correspond to each audio HAL hardware module, where each module has a list of mix ports, device ports, and routes:
- Mix ports describe the possible config profiles for streams that can be opened at the audio HAL for playback and capture.
- Device ports describe the devices that can be attached with their type (and optionally address and audio properties, if relevant).
- Routes is separated from the mix port descriptor, enabling the description of routes from device to device or stream to device.
Volume tables are simple lists of points defining the curve used to translate from a UI index to a volume in dB. A separate include file provides default curves, but each curve for a given use case and device category can be overwritten.
Show volume table example
<?xml version="1.0" encoding="UTF-8"?> <volumes> <reference name="FULL_SCALE_VOLUME_CURVE"> <point>0,0</point> <point>100,0</point> </reference> <reference name="SILENT_VOLUME_CURVE"> <point>0,-9600</point> <point>100,-9600</point> </reference> <reference name="DEFAULT_VOLUME_CURVE"> <point>1,-4950</point> <point>33,-3350</point> <point>66,-1700</point> <point>100,0</point> </reference> </volumes>
Show volumes example
<?xml version="1.0" encoding="UTF-8"?> <volumes> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_VOICE_CALL" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_SYSTEM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_RING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA"ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_SPEAKER"> <point>1,-5500</point> <point>20,-4300</point> <point>86,-1200</point> <point>100,0</point> </volume> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_MUSIC" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ALARM" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_NOTIFICATION" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_BLUETOOTH_SCO" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ENFORCED_AUDIBLE" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_DTMF" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="SILENT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="SILENT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_TTS" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="SILENT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_ACCESSIBILITY" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="DEFAULT_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_REROUTING" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_HEADSET" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_SPEAKER" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EARPIECE" ref="FULL_SCALE_VOLUME_CURVE"/> <volume stream="AUDIO_STREAM_PATCH" deviceCategory="DEVICE_CATEGORY_EXT_MEDIA" ref="FULL_SCALE_VOLUME_CURVE"/> </volumes>
File inclusions
The XML Inclusions (XInclude) method can be used to include audio policy configuration information located in other XML files. All included files must follow the structure described above with the following restrictions:
- Files can contain only top-level elements.
- Files can't contain XInclude elements.
Use includes to avoid copying standard Android Open Source Project (AOSP) audio HAL module configurations information to all audio policy configuration files (which is prone to errors). A standard audio policy configuration XML file is provided for the following audio HALs:
- A2DP:
a2dp_audio_policy_configuration.xml
- Reroute submix:
rsubmix_audio_policy_configuration.xml
- USB:
usb_audio_policy_configuration.xml
Audio policy code organization
AudioPolicyManager.cpp
is split into several modules
to make it easy to maintain and configure. The organization of
frameworks/av/services/audiopolicy
includes the
following modules.
Module | Description |
---|---|
/managerdefault |
Includes the generic interfaces and behavior implementation common to all
apps. Similar to AudioPolicyManager.cpp with engine
functionality and common concepts abstracted away. |
/common |
Defines base classes (for example, data structures for input output audio stream
profiles, audio device descriptors, audio patches, and audio ports). This was previously
defined inside AudioPolicyManager.cpp . |
/engine |
Implements the rules that define which device and volumes should be used for a given use case. It implements a standard interface with the generic part, such as to get the appropriate device for a given playback or capture use case, or to set connected devices or external state (that is, a call state of forced usage) that can alter the routing decision. Available in two versions: configurable and default. For the information on how to select the version, see Configuration using Parameter Framework. |
/engineconfigurable |
Policy engine implementation that relies on Parameter Framework (see below). Configuration is based on the Parameter Framework and where the policy is defined by XML files. |
/enginedefault |
Policy engine implementation based on previous Android Audio Policy Manager implementations. This is the default and includes hard-coded rules that correspond to Nexus and AOSP implementations. |
/service |
Includes binder interfaces, threading, and locking implementation with the interface to the rest of the framework. |
Configuration using Parameter Framework
Audio policy code is organized to make it easy to understand and maintain while also supporting an audio policy defined entirely by configuration files. The organization and audio policy design is based on Intel's Parameter Framework, a plugin-based and rule-based framework for handling parameters.
Using the configurable audio policy enables vendors OEMs to:
- Describe a system's structure and its parameters in XML.
- Write (in C++) or reuse a backend (plugin) for accessing described parameters.
- Define (in XML or in a domain-specific language) conditions/rules upon which a given parameter must take a given value.
AOSP includes an example of an audio policy configuration file that uses the Parameter
Framework at Frameworks/av/services/audiopolicy/engineconfigurable/parameter-framework/example/Settings/PolicyConfigurableDomains.xml
. For
details, refer to Intel documentation on the
Parameter Framework.
In Android 10 or lower, the configurable audio policy
is selected using the build option USE_CONFIGURABLE_AUDIO_POLICY
.
In Android 11 or higher, the version of the audio policy
engine is selected in the audio_policy_configuration.xml
file.
To select the configurable audio policy engine, set the value of the engine_library
attribute of the globalConfiguration
element to configurable
as in the following example:
<audioPolicyConfiguration> <globalConfiguration engine_library="configurable" /> ... </audioPolicyConfiguration>
Audio policy routing APIs
Android 6.0 introduced a public Enumeration and Selection API that sits on top of the audio patch/audio port infrastructure and allows app developers to indicate a preference for a specific device output or input for connected audio records or tracks.
In Android 7.0, the Enumeration and Selection API is verified by CTS tests
and is extended to include routing for native C/C++ (OpenSL ES) audio streams.
The routing of native streams continues to be done in Java, with the addition of
an AudioRouting
interface that supersedes, combines, and deprecates
the explicit routing methods that were specific to the AudioTrack
and
AudioRecord
classes.
For details on the Enumeration and Selection API, refer to
Android
configuration interfaces and OpenSLES_AndroidConfiguration.h
.
For details on audio routing, refer to
AudioRouting.
Multi-channel support
If your hardware and driver supports multichannel audio via HDMI, you can
output the audio stream directly to the audio hardware (this bypasses the
AudioFlinger mixer so it doesn't get downmixed to two channels.) The audio HAL
must expose whether an output stream profile supports multichannel audio
capabilities. If the HAL exposes its capabilities, the default policy manager
allows multichannel playback over HDMI. For implementation details, see
device/samsung/tuna/audio/audio_hw.c
.
To specify that your product contains a multichannel audio output, edit the
audio policy configuration file to describe the multichannel output for your
product. The following example from
frameworks/av/services/audiopolicy/config/primary_audio_policy_configuration_tv.xml
shows a dynamic channel mask, which means that the audio policy manager queries the channel
masks supported by the HDMI sink after connection.
Show HDMI device config example
<module name="primary" halVersion="2.0"> <attachedDevices> <item>Speaker</item> </attachedDevices> <defaultOutputDevice>Speaker</defaultOutputDevice> <mixPorts> <mixPort name="primary output" role="source" flags="AUDIO_OUTPUT_FLAG_PRIMARY"> <profile name="" format="AUDIO_FORMAT_PCM_16_BIT" samplingRates="48000" channelMasks="AUDIO_CHANNEL_OUT_STEREO"/> </mixPort> <mixPort name="direct" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT" /> <mixPort name="tunnel" role="source" flags="AUDIO_OUTPUT_FLAG_DIRECT|AUDIO_OUTPUT_FLAG_HW_AV_SYNC" /> </mixPorts> <devicePorts> <devicePort tagName="Speaker" type="AUDIO_DEVICE_OUT_SPEAKER" role="sink" /> <devicePort tagName="Out Aux Digital" type="AUDIO_DEVICE_OUT_AUX_DIGITAL" role="sink" encodedFormats="AUDIO_FORMAT_AC3 AUDIO_FORMAT_IEC61937" /> </devicePorts> <routes> <route type="mix" sink="Speaker" sources="primary output"/> <route type="mix" sink="Out Aux Digital" sources="primary output,direct,tunnel"/> </routes> </module>
You can also specify a static channel mask such as
AUDIO_CHANNEL_OUT_5POINT1
. AudioFlinger's mixer downmixes the
content to stereo automatically when sent to an audio device that doesn't
support multichannel audio.
Media codecs
Ensure that the audio codecs your hardware and drivers support are properly declared for your product. For details, see Exposing Codecs to the Framework.