音效

从 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。