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
orTYPE_POST_PROC
set inEffectDescriptor.flags
). - If the effect implementation is HW accelerated
(flag
HW_ACC_TUNNEL
set inEffectDescriptor.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 beAudioSessionConsts.DEVICE
. AudioIoHandle
is ignored if thesession
isAudioSessionConsts.DEVICE
.- The
device
is identified by its uniqueAudioPortHandle
assigned by the audio framework when the device is selected at the audio HAL withIDevice::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.