从 Android 11 开始,在为音频捕获或播放选择指定音频设备时,设备制造商可以自动附加和启用特定的音效。一项重大改进是,完全在音频 HAL(输入设备和输出设备之间的直接连接)之下实现的音频路径上插入的音效可以由音效框架控制。
此功能主要面向汽车原始设备制造商 (OEM),但也可用于其他 Android 设备类型。一个示例应用是在通过音频 DSP 直接连接到免提时在 FM 调谐器输出中插入语音增强效果。
前提条件
至于任何其他音效,效果都必须由供应商库实现,并在 audio_effects.xml 配置文件中列出。
效果必须为预处理或后处理类型(TYPE_PRE_PROC 标志,或在 EffectDescriptor.flags 中设置的 TYPE_PRE_PROC)。
如果效果实现经过硬件加速(在 EffectDescriptor.flags 中设置的 HW_ACC_TUNNEL 标志),可以将其附加到完全在 HAL 之下连接的音频路径(音频 HAL 处未打开播放或捕获音频流)。
创建和启用设备效果
您可以使用以下两种方法之一实例化设备专用音效。
使用音效配置文件
此方法允许以静态方式创建音效,该音效被系统性地附加到任何音频路径并被启用,同时选择一个指定的设备作为接收器或源。
具体方法是在 audio_effects.xml 文件中添加特定的部分,如下所示:
使用系统 API
已向 android.media.audiofx.AudioEffect 类添加了新的 @SystemApi 构造函数,用于创建和启用设备效果:
AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAttributes device);
通过指定独一无二的音效 ID 和音频设备描述符来创建效果后,便可使用现有 AudioEffect API 启用或停用该效果。
API 也可以用来查询实现是否支持给定设备/效果的组合。
static boolean isEffectSupportedForDevice(
@NonNull UUID uuid, @NonNull AudioDeviceAttributes device);
新增的 HAL API
音效 HAL
音效 HAL V6.0 为 createEffect() 方法提供了新的签名,支持创建附加到设备的效果:
IEffectFactory::createEffect(Uuid uid, AudioSession session,
AudioIoHandle ioHandle, AudioPortHandle device)
指定的 AudioSession 必须为 AudioSessionConsts.DEVICE。
如果 session 为 AudioSessionConsts.DEVICE,系统会忽略 AudioIoHandle。
使用 IDevice::createAudioPatch() 方法在音频 HAL 上选择设备时,device 由音频框架向其分配的唯一 AudioPortHandle 进行标识。
音频 HAL
如需支持设备效果功能,音频 HAL 必须使用 IDevice::createAudioPatch() API 实现音频路由控件。报告 true 的 IDevice::supportsAudioPatches() 方法指明了这一点。
IDevice::addDeviceEffect(AudioPortHandle device, uint64_t effectId) 和 IDevice::removeDeviceEffect(AudioPortHandle device, uint64_t effectId) 这两种新增的 API 方法用于告知 HAL 实现在给定设备上启用或停用了设备效果。
设备由其 AudioPortHandle ID 标识,此 ID 在通过 IDevice::createAudioPatch() 方法创建音频补丁程序时使用。
如果在启用或停用效果时,音频 HAL 与效果 HAL 之间需要协调,实现可以使用音频 HAL API。