首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

鸿蒙OpenHarmony【外设驱动使用之Audio】 子系统

  • 25-03-06 16:21
  • 3368
  • 8822
blog.csdn.net

Audio

Audio驱动概述

多媒体系统是物联网设备开发中不可缺少的一部分,Audio作为其中重要的一个模块,Audio驱动模型的构建显得尤为重要。

本文主要介绍基于HDF(Hardware Driver Foundation)驱动框架开发的Audio驱动,包括Audio驱动的架构组成和功能部件。芯片厂商可以根据此驱动架构,进行各自驱动的开发及HAL层接口的调用。

Audio驱动框架介绍

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

驱动架构主要由以下几部分组成。

  • HDI adapter:实现Audio HAL层驱动(HDI接口适配),给Audio服务(frameworks)提供所需的音频硬件驱动能力接口。包含 Audio Manager、Audio Adapter、Audio Control、Audio Capture、Audio Render等接口对象。
  • Audio Interface Lib:配合内核中的Audio Driver Model使用,实现音频硬件的控制、录音数据的读取、播放数据的写入。它里面包括Stream_ctrl_common 通用层,主要是为了和上层的Audio HDI Adapter层进行对接。
  • ADM(Audio Driver Model):音频驱动框架模型,向上服务于多媒体音频子系统,便于系统开发者能够更便捷的根据场景来开发应用。向下服务于具体的设备厂商,对于Codec和DSP设备厂商来说,可根据ADM模块提供的向下统一接口适配各自的驱动代码,就可以实现快速开发和适配OpenHarmony系统。
  • Audio Control Dispatch: 接收lib层的控制指令并将控制指令分发到驱动层。
  • Audio Stream Dispatch: 接收lib层的数据并将数据分发到驱动层。
  • Card Manager: 多声卡管理模块。每个声卡含有Dai、Platform、Codec、Dsp、SAPM模块。
  • Platform Drivers: 驱动适配层。
  • SAPM(Smart Audio Power Manager):电源管理模块,对整个ADM电源进行功耗策略优化。

Audio驱动开发

以下将基于Audio驱动框架,并以Hi3516DV300平台为例,介绍相关驱动开发的具体步骤。

Audio ADM模块框架介绍

Audio驱动对HDI层提供三个服务hdf_audio_render、hdf_audio_capture、hdf_audio_control。开发板dev目录下驱动服务节点如下:

# ls -l hdf_audio*
crw-rw---- 1 system system 247,   6 1970-01-01 00:00 hdf_audio_capture             // 音频数据录音流服务。
crw-rw---- 1 root   root   247,   4 1970-01-01 00:00 hdf_audio_codec_primary_dev0  // 音频声卡设备0名称。
crw-rw---- 1 root   root   247,   4 1970-01-01 00:00 hdf_audio_codec_primary_dev11 // 音频声卡设备1名称。
crw-rw---- 1 system system 247,   5 1970-01-01 00:00 hdf_audio_control             // 音频控制流服务。
crw-rw---- 1 system system 247,   7 1970-01-01 00:00 hdf_audio_render              // 音频数据播放流务。
shell
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

音频声卡设备包括的驱动服务:

hdf_audio_codec_primary_dev0

  • dma_service_0 : dma服务
  • dai_service : CPU dai服务
  • codec_service_0 : codec服务(可以是smartPA)
  • dsp_service_0 : dsp 服务(可选项)

hdf_audio_codec_primary_dev11

  • dma_service_0 : dma服务
  • dai_service : CPU dai服务
  • codec_service_1 : codec服务(可以是smartPA)
  • dsp_service_0 : dsp服务(可选项)
启动流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 系统启动时Audio模块的Platform、Codec、Dsp、Dai各个驱动首先被加载,各驱动从各自私有配置文件中获取配置信息,并将获取的配置信息保存到各驱动的Data数据结构中。
  2. 各驱动模块调用ADM注册接口将自己添加到各驱动模块的链表中。
  3. ADM模块读取hdf_audio_driver_0和hdf_audio_driver_1配置信息,加载各模块的具体设备。
  4. ADM模块调用各模块的初始化函数对各模块设备进行初始化。
  5. 将初始化成功的音频设备添加到cardManager链表。
播放流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 播放音频时,Interface Lib层通过播放流服务下发Render Open指令,Audio Stream Dispatch服务收到指令后分别调用各模块的函数接口对指令进行下发。
  2. Interface Lib层通过控制服务下发通路选择指令,Control Dispatch控制服务收到指令后调用Dai模块接口设置通路。
  3. Interface Lib层通过播放流服务下发硬件参数,Audio Stream Dispatch服务收到参数后分别调用各模块参数设置接口,对硬件参数进行设置。
  4. Interface Lib层通过播放流服务下发播放启动指令,Audio Stream Dispatch服务收到指令后分别调用各模块启动接口,对各模块进行启动设置。
  5. Interface Lib层通过播放流服务下发音频数据,Audio Stream Dispatch服务收到数据后调用Platform AudioPcmWrite接口将音频数据传给Dma。
  6. Interface Lib层通过播放流服务下发播放停止指令,Audio Stream Dispatch服务收到指令后分别调用各模块停止接口,对各模块进行停止设置。
  7. Interface Lib层通过播放流服务下发Render Close指令,Audio Stream Dispatch服务收到指令后调用Platform AudioRenderClose对已申请资源进行释放。
控制流程

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 设置音量,首先Interface Lib层通过控制服务下发获取音量范围指令,Control Dispatch控制服务收到指令后进行解析,并调用Codec模块Get函数,获取可设置音量的范围。
  2. Interface Lib层通过控制服务下发设置音量指令,Control Dispatch控制服务收到指令后进行解析,并调用Codec模块Set函数设置音量。

Audio驱动公共函数介绍

函数名 功能
CodecDeviceReadReg codec寄存器读函数
CodecDeviceWriteReg codec寄存器写函数
CodecDaiRegI2cRead codec dai通过I2C接口读寄存器函数
CodecDaiRegI2cWrite codec dai通过I2C接口写寄存器函数
CodecDeviceRegI2cRead codec通过I2C接口读寄存器函数
CodecDeviceRegI2cWrite codec通过I2C接口写寄存器函数
CodecDeviceInitRegConfig codec初始化函数
CodecDaiDeviceStartupRegConfig codec启动函数
CodecSetCtlFunc codec设置set和get接口实现函数
CodecSetConfigInfoOfControls codec设置控制功能函数接口和寄存器信息的函数
CodecGetConfigInfo codec获取HCS配置信息函数
CodecGetDaiName codec获取HCS配置dai名称函数
CodecGetServiceName codec获取HCS配置服务名称函数
DaiDeviceReadReg dai读寄存器函数
DaiDeviceWriteReg dai写寄存器函数
DaiSetConfigInfoOfControls dai设置控制功能函数接口和寄存器信息的函数
DaiGetConfigInfo dai获取HCS配置信息函数

Audio驱动开发步骤

已有平台开发

ADM适配已有平台(Hi3516DV300)Codec或Smart PA的驱动开发流程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 根据芯片说明将相关寄存器信息配置到Codec或Smart PA的私有HCS中。
  • 如果新添加Codec或Smart PA和已适配Codec或Smart PA的工作流程相同则不需要实现Codec或Smart PA的操作函数集和配置编译文件。
  • 进行编译调试验证。
新平台开发

ADM适配新平台Audio驱动开发流程:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Audio驱动需要将Audio相关的Codec(可选)、Dai、DMA、DSP(可选)、Smart PA(可选)驱动进行适配。

  • 根据芯片说明将各模块驱动的寄存器信息配置到各模块的私有配置文件中。
  • 实现各模块的操作函数集。
  • 修改配置Audio模块编译文件。
  • 进行编译调试验证。

Audio驱动开发实例

代码路径:device/board/hisilicon/hispark_taurus/audio_drivers

下面以Hi3516DV300为例,介绍Audio的Codec驱动、Dai驱动、Platform驱动开发步骤。

Codec驱动开发实例

代码路径:device/board/hisilicon/hispark_taurus/audio_drivers/codec/hi3516

codec驱动开发主要包含如下几个重要步骤:

  1. 定义填充一个具体的codec。
  2. 实现codec回调函数。
  3. 注册绑定到HDF框架。
  4. 配置HCS和Makefile。
Codec数据结构填充

Codec模块需要填充如下3个结构体:

  • g_codecData:codec设备的操作函数集和私有数据集。
  • g_codecDaiDeviceOps:codecDai的操作函数集,包括启动传输和参数配置等函数接口。
  • g_codecDaiData:codec的数字音频接口的操作函数集和私有数据集。
struct CodecData g_codecData = {
  .Init = CodecDeviceInit,      // codec设备初始化(适配新平台需重新实现)
  .Read = AudioDeviceReadReg,   // 读寄存器(现有框架已实现可使用)
  .Write = AudioDeviceWriteReg, // 写寄存器(现有框架已实现可使用)
};

struct AudioDaiOps g_codecDaiDeviceOps = {
  .Startup = CodecDaiStartup,   // 启动传输(适配新平台需重新实现)
  .HwParams = CodecDaiHwParams, // 参数配置(适配新平台需重新实现)
};

struct DaiData g_codecDaiData = {
  .DaiInit = CodecDaiDeviceInit, // codecdai设备初始化(适配新平台需重新实现)
  .ops = &g_codecDaiDeviceOps,   // codecdai操作函数
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
codecDevice和codecDai设备初始化

CodecDeviceInit将完成AIAO的设置、寄存器默认值初始化、g_audioControls插入到controls链、电源管理初始化、通路选择设置等。

int32_t CodecDeviceInit(struct AudioCard *audioCard, struct CodecDevice *codec)
{
    ...
    /* hi3516平台AIAO的Set和Get注册 */
    CodecSetCtlFunc(codec->devData, AudioCodecAiaoGetCtrlOps, AudioCodecAiaoSetCtrlOps)
    ...
    /* hi3516平台codec寄存器IoRemap */
    CodecHalSysInit();
    ...
    /* hi3516平台codec寄存器默认值初始化 */
    CodecRegDefaultInit(codec->devData->regCfgGroup);
    ...
    /* hi3516平台g_audioControls挂到Control链表上 */
    AudioAddControls(audioCard, codec->devData->controls, codec->devData->numControls);
    ...
    /* hi3516平台codec加载到sapm */
    AudioSapmNewComponents(audioCard, codec->devData->sapmComponents, codec->devData->numSapmComponent);
    ...
    /* hi3516平台codec加挂到通路选择链表上 */
    AudioSapmAddRoutes(audioCard, g_audioRoutes, HDF_ARRAY_SIZE(g_audioRoutes);
    ...
    AudioSapmNewControls(audioCard);
    ...
    /* hi3516平台codec电源管理 */
    AudioSapmSleep(audioCard);
    ...
    return HDF_SUCCESS;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

CodecDaiDeviceInit将完成codecDai侧初始化,hi3516此处未涉及,接口保留:

int32_t CodecDaiDeviceInit(struct AudioCard *card, const struct DaiDevice *device)

{
    ...
    AUDIO_DRIVER_LOG_DEBUG("codec dai device name: %s\n", device->devDaiName);
    (void)card;
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
注:本文转载自blog.csdn.net的的文章"https://blog.csdn.net/zxc95279527q/article/details/143082686"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

123
硬件开发
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top