【鸿蒙南向开发】OpenHarmony音频驱动audio适配方案

设备媒体
1000 0
Laval社区小助手 只看该作者 发表于 2023-10-30 16:47:50
详情可点击: audio 适配方案

1. 音频驱动可选四种集成方案

在这里插入图片描述

各类方案简述:
在这里插入图片描述

2. 进程示意图

在这里插入图片描述

名词释义:

在这里插入图片描述

3.1 方案 1 ADM 适配方法

参考 OH 社区提供的 Audio 方案

3.2 方案 2 alsa 适配方法

基于 openHarmony 3.2Beta3 以上的版本的适配

3.2.1 内核编译开关配置

需要在各自产品的 Linux kernel 配置文件中打开对应开关,路径如下:其中${product_name}表示您的产品名称

kernel/linux/config/linux-5.10/arch/arm64/configs/${product_name}_standard_defconfig

以 rk3568_standard_defconfig 为例配置如下:

CONFIG_SOUND=y
CONFIG_SND=y
​
# CONFIG_DRIVERS_HDF_AUDIO is not set
# CONFIG_DRIVERS_HDF_AUDIO_RK3568  is not set

3.2.2 产品化编译开关配置

需要在各自产品配置文件中打开对应开关,路径如下:其中 productcompany 表示您的企业名称,{product_company}表示您的企业名称,{product_name}表示您的产品名称

1.在 vendor${product_company}${product_name}\config.json 中将 alsa_lib 的控制开关打开

drivers_peripheral_audio_alsa_lib = true

2.在 drivers\peripheral\audio\audio.gni 中将 slas_lib 控制开关打开

drivers_peripheral_audio_alsa_lib = true

3.在 vendor${product_company}${product_name}\hals\audio\product.gni 中将 alsa 模式和 alsa_lib 打开

enable_audio_alsa_mode = true
...
drivers_peripheral_audio_alsa_lib = true

4.新增文件 vendor${product_company}${product_name}\hals\audio\alsa_adapter.json 配置声卡设备

{
    "adapters": [{
        "name": "primary",
        "cardId": "xxxx",
        "daiId": ""
    }]
}

注:"cardId"值在开发板中通过 cat /proc/asound/card0/id 查看,将值配入其中。 此参数使用的地方在 drivers\peripheral\audio\supportlibs\alsa_adapter\src\alsa_lib_common.c 中与 snd_ctl_card_info_get_id 得到的值进行校验

3.2.3 alsa-lib 和 alsa-utils 组件编译依赖添加

如需要重新实现 Audio HAL,则需要添加 alsa-lib 组件的编译依赖,可以采用以下两种方法进行添加。

在 drivers\peripheral\audio\bundle.json 中配置 alsa_lib 和 alsa_utils 库

"third_party": [
        "alsa-lib"
      ]
      
  "sub_component": [
        "//third_party/alsa-utils:alsa-utils"
      ],

3.2.4. 针对芯片的适配修改

3.2.4.1 播放的适配修改

1.在 drivers\peripheral\audio\supportlibs\alsa_adapter\src\alsa_lib_render.c 中 根据 alsa-utils 工具中 amixer 命令 amixer controls 在开发板中找到声音播放相关的通路配置,将其打开。不同芯片通路配置不一样,依照芯片功能配置通路

static int32_t InitMixerCtlElement(const char *adapterName, struct AudioCardInfo *cardIns, snd_mixer_t *mixer)
{
   ...
  if (strncmp(adapterName, PRIMARY, strlen(PRIMARY)) == 0) {
     pcmElement = snd_mixer_first_elem(mixer);
     if (pcmElement == NULL) {
         AUDIO_FUNC_LOGE("snd_mixer_first_elem failed.");
         return HDF_FAILURE;
     }
​
     ret = GetPriMixerCtlElement(cardIns, pcmElement,0);  // 增加一个变量区分render和capture  0表示render
     if (ret < 0) {
         AUDIO_FUNC_LOGE("Render GetPriMixerCtlElement failed.");
         re