音效

从 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
  • 如果 sessionAudioSessionConsts.DEVICE,系统会忽略 AudioIoHandle
  • 使用 IDevice::createAudioPatch() 方法在音频 HAL 上选择设备时,device 由音频框架向其分配的唯一 AudioPortHandle 进行标识。

音频 HAL

如需支持设备效果功能,音频 HAL 必须使用 IDevice::createAudioPatch() API 实现音频路由控件。报告 trueIDevice::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。