Audio effects

Starting in Android 11, the device manufacturers have the ability to automatically attach and enable specific audio effects when a given audio device is selected for audio capture or playback. One major improvement is that audio effects inserted on an audio path entirely implemented below the audio HAL (direct connection between an input device and an output device) can be controlled by the audio effects framework.

This feature is primarily targeted at automotive OEMs but can also be used in other Android form factors. An example app is inserting a voice enhancement effect on the FM tuner output when directly connected to the speaker through the audio DSP.

Prerequisites

  • As for any other audio effect, the effect must be implemented by a vendor library and listed in the audio_effects.xml configuration file.
  • The effect must be of type preprocessing or postprocessing (flag TYPE_PRE_PROC or TYPE_POST_PROC set in EffectDescriptor.flags).
  • If the effect implementation is HW accelerated (flag HW_ACC_TUNNEL set in EffectDescriptor.flags), it can be attached to an audio path entirely connected below the HAL (no playback or capture audio stream opened at the audio HAL).

Create and enable a device effect

Device-specific audio effects can be instantiated using one of the two methods below.

Use an audio effects configuration file

This method allows for the static creation of an audio effect that is systematically attached and enabled to any audio path selecting a specified device as sink or source.

This is done by adding a specific section in the audio_effects.xml file as follows:

<deviceEffects>
<devicePort type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom">
      	<apply effect="agc"/>
      </devicePort>
  </deviceEffects>
  

Use a system API

A new @SystemApi constructor has been added to the android.media.audiofx.AudioEffect class to create and enable a device effect:

AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAttributes device);

After the effect is created by specifying the unique audio effect ID and audio device descriptor, it can be enabled or disabled with existing AudioEffect APIs.

An API is also available to query if an implementation supports a given device/effect combination.

static boolean isEffectSupportedForDevice(
            @NonNull UUID uuid, @NonNull AudioDeviceAttributes device);

New HAL APIs

Audio effect HAL

The audio effect HAL V6.0 has a new signature for the createEffect() method allowing the creation of an effect attached to a device:

IEffectFactory::createEffect(Uuid uid, AudioSession session,
AudioIoHandle ioHandle, AudioPortHandle device)
  • The AudioSession specified must be AudioSessionConsts.DEVICE.
  • AudioIoHandle is ignored if the session is AudioSessionConsts.DEVICE.
  • The device is identified by its unique AudioPortHandle assigned by the audio framework when the device is selected at the audio HAL with IDevice::createAudioPatch() method.

Audio HAL

To support the device effect feature, the audio HAL must implement audio routing control using the IDevice::createAudioPatch() API. This is indicated by the IDevice::supportsAudioPatches() method reporting true.

Two new API methods, IDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) and IDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) tell the HAL implementation that a device effect has been enabled or disabled on a given device.

The device is identified by its AudioPortHandle ID, which is used when an audio patch is created with the IDevice::createAudioPatch() method.

The Audio HAL APIs can be used by an implementation if coordination is needed between the audio and effect HALs when an effect is enabled or disabled.