to top

Configuring Audio Policies

In this document

Android 7.0 introduces a new audio policy configuration file format (XML) for describing your audio topology.

Previous Android releases required using the 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 applications such as televisions and automobiles.

Android 7.0 deprecates the audio_policy.conf and adds support for defining audio topology using an XML file format that is more human-readable, has a wide range of editing and parsing tools, and is flexible enough to describe complex audio topologies.

Note: Android 7.0 preserves support for using audio_policy.conf; this legacy format is used by default. To use the XML file format, include the build option USE_XML_AUDIO_POLICY_CONF := 1 in device makefile.

Advantages of the XML format

As in the .conf file, the new XML file enables defining the number and types of output an input stream profiles, devices usable for playback and capture, and audio attributes. In addition, the XML format offers the following enhancements:

  • Audio profiles are now structured similar to HDMI Simple Audio Descriptors and enable a different set of sampling rates/channel masks for each audio format.
  • Explicit definitions of all possible connections between devices and streams. Previously, an implicit rule made it possible to interconnect 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 now defines connection limitations.
  • Support for includes avoids repeating standard A2DP, USB, or reroute submit definitions.
  • Customizable volume curves. 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. To view a simple audio policy configuration in the new XML file format, view the example below.

Show audio policy example

<?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 (new) is now separated from the mix port descriptor, enabling description of routes from device to device or stream to device.

Volume tables are simple lists of points defining the curve used to translate form 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 cannot contain Xinclude elements.

Use includes to avoid copying standard Android Open Source Project (AOSP) audio HAL modules configuration 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 reorganization

Android 7.0 splits AudioPolicyManager.cpp into several modules to make it more maintainable and to highlight what is configurable. The new organization of frameworks/av/services/audiopolicy includes the following modules:

Module Description
/managerdefault Includes the generic interfaces and behavior implementation common to all applications. Similar to AudioPolicyManager.cpp with engine functionality and common concepts abstracted away.
/common Defines base classes (e.g data structures for input output audio stream profiles, audio device descriptors, audio patches, audio port, etc.). 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 (i.e. a call state of forced usage) that can alter the routing decision.

Available in two versions, customized and default; use build option USE_CONFIGURABLE_AUDIO_POLICY to select.

/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 current Nexus and AOSP implementations.
/service Includes binder interfaces, threading and locking implementation with interface to the rest of the framework.

Configuration using parameter-framework

Android 7.0 reorganizes audio policy code to make it easier to understand and maintain while also supporting an audio policy defined entirely by configuration files. The reorganization and audio policy design is based on Intel's parameter framework, a plugin-based and rule-based framework for handling parameters.

Using the new 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 and Android Configurable Audio Policy.

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 application 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 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 a Galaxy Nexus shows a dynamic channel mask, which means the audio policy manager queries the actual channel masks supported by the HDMI sink after connection.

audio_hw_modules {
  primary {
    outputs {
        ...
        hdmi {
          sampling_rates 44100|48000
          channel_masks dynamic
          formats AUDIO_FORMAT_PCM_16_BIT
          devices AUDIO_DEVICE_OUT_AUX_DIGITAL
          flags AUDIO_OUTPUT_FLAG_DIRECT
        }
        ...
    }
    ...
  }
  ...
}

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 does not support multichannel audio.

Media codecs

Ensure the audio codecs your hardware and drivers support are properly declared for your product. For details, see Exposing Codecs to the Framework.