从 Android 11 开始,在选择某个音频设备以将其用于捕获或播放音频时,设备制造商可以自动附加和启用特定的音效。一项重大改进是,完全在音频 HAL(输入设备和输出设备之间的直接连接)之下实现的音频路径上插入的音效现在可以由音效框架控制。
此功能主要面向汽车原始设备制造商 (OEM),但也可用于其他 Android 设备类型。一个示例应用是在通过音频 DSP 直接连接到音响设备时在 FM 调谐器输出中插入语音增强效果。
前提条件
- 至于任何其他音效,效果都必须由供应商库实现,并在
audio_effects.xml
配置文件中列出。 - 效果必须为预处理或后处理类型(
TYPE_PRE_PROC
标志,或在EffectDescriptor.flags
中设置的TYPE_POST_PROC
)。 - 如果效果实现经过硬件加速(在
EffectDescriptor.flags
中设置了HW_ACC_TUNNEL
标志),可以将其附加到完全在 HAL 之下连接的音频路径(在音频 HAL 中没有打开任何播放或捕获音频流)。
创建和启用设备效果
您可以使用以下两种方法之一实例化设备专用音效。
使用音效配置文件
此方法允许以静态方式创建音效,相应音效会被系统性地附加到任何音频路径并被启用,同时选择一个指定的设备作为接收器或源。
具体方法是在 audio_effects.xml
文件中添加特定的版块,如下所示:
<deviceEffects> <devicePort type="AUDIO_DEVICE_IN_BUILTIN_MIC" address="bottom"> <apply effect="agc"/> </devicePort> </deviceEffects>
使用系统 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。