Audio驱动框架基于HDF驱动框架实现,包含内核态(KHDF),和用户态(UHDF), 对北向提供音频HDI接口
驱动架构主要由以下几部分组成。
drivers/hdf_core/framework/model/audio
及 device/board/xxx/yyy/audio_drivers
等: ADM相关驱动,KHDF部分drivers/peripheral/audio
: audio HAL 实现,UHDF部分foundation/multimedia/audio_framework
: audio framework 实现目录:foundation/multimedia/audio_framework/services/
client:
通过 Remote()->SendRequest
,和服务端进行通信(IPC),binder
server:
server端向上通过IPC与client交互,向下与HAL交互
使用PulseAudio进行音频流管理
foundation/multimedia/audio_framework/services/audio_service/client/src/audio_service_client.cpp
drivers/peripheral/audio/supportlibs/alsa_adapter
):drivers/peripheral/audio/supportlibs/adm_adapter
):所以,由此可以得到音频驱动适配的几种主流方案:
从下面代码目录结构可以很容易和上面的架构图一一对应
zdd@zdd-PC:~/WorkSpace/OHOS/oh-v3.2.2/drivers/peripheral/audio$ tree -L 2
.
├── audio.gni
├── BUILD.gn
├── bundle.json
├── config
├── hal
│ ├── hdi_binder
│ │ ├── proxy
│ │ └── server
│ ├── hdi_passthrough
│ └── pathselect
├── hdi_service
│ ├── binder
│ ├── BUILD.gn
│ ├── passthrough
│ ├── pathselect
│ └── supportlibs
├── interfaces
│ ├── 2.0
│ └── include
├── supportlibs
│ ├── adm_adapter
│ ├── alsa_adapter
│ ├── BUILD.gn
│ └── interfaces
└── test
├── BUILD.gn
├── fuzztest
├── resource
├── sample
├── systemtest
└── unittest
ADM流程基本上都是基于驱动消息机制(dispatch)实现:drivers/peripheral/audio/supportlibs/adm_adapter/src/audio_interface_lib_common.c
下面看看几种基本的ADM流程:
以rk3568平台,结合上面的启动流程看看audio相关的hcs文件
device_info.hcs
:...
audio :: host {
hostName = "audio_host";
priority = 110;
device_dai0 :: device {
device0 :: deviceNode {
policy = 1;
priority = 50;
preload = 0;
permission = 0666;
moduleName = "DAI_RK3568";
serviceName = "dai_service";
deviceMatchAttr = "hdf_dai_driver";
}
}
device_codec_0 :: device {
device0 :: deviceNode {
policy = 1;
priority = 50;
preload = 0;
permission = 0666;
moduleName = "CODEC_RK809";
serviceName = "codec_service_0";
deviceMatchAttr = "hdf_codec_driver_0";
}
}
device_codec_1 :: device {
device0 :: deviceNode {
policy = 1;
priority = 50;
preload = 0;
permission = 0666;
moduleName = "CODEC_RK817";
serviceName = "codec_service_1";
deviceMatchAttr = "hdf_codec_driver_1";
}
}
device_dsp :: device {
device0 :: deviceNode {
policy = 1;
priority = 50;
preload = 0;
permission = 0666;
moduleName = "DSP_RK3568";
serviceName = "dsp_service_0";
deviceMatchAttr = "hdf_dsp_driver";
}
}
device_dma :: device {
device0 :: deviceNode {
policy = 1;
priority = 50;
preload = 0;
permission = 0666;
moduleName = "DMA_RK3568";
serviceName = "dma_service_0";
deviceMatchAttr = "hdf_dma_driver";
}
}
device_audio :: device {
device0 :: deviceNode {
policy = 2;
priority = 60;
preload = 0;
permission = 0666;
moduleName = "HDF_AUDIO";
deviceMatchAttr = "hdf_audio_driver_0";
serviceName = "hdf_audio_codec_primary_dev0";
}
device1 :: deviceNode {
policy = 2;
priority = 60;
preload = 0;
permission = 0666;
moduleName = "HDF_AUDIO";
deviceMatchAttr = "hdf_audio_driver_1";
serviceName = "hdf_audio_codec_primary_dev11";
}
}
device_stream :: device {
device0 :: deviceNode {
policy = 2;
priority = 80;
preload = 0;
permission = 0666;
moduleName = "HDF_AUDIO_STREAM";
serviceName = "hdf_audio_render";
}
device1 :: deviceNode {
policy = 2;
priority = 80;
preload = 0;
permission = 0666;
moduleName = "HDF_AUDIO_STREAM";
serviceName = "hdf_audio_capture";
}
}
device_control :: device {
device0 :: deviceNode {
policy = 2;
priority = 80;
preload = 0;
permission = 0666;
moduleName = "HDF_AUDIO_CONTROL";
serviceName = "hdf_audio_control";
}
}
device_analog_headset :: device {
device0 :: deviceNode {
policy = 1;
priority = 90;
preload = 0;
permission = 0666;
moduleName = "AUDIO_ANALOG_HEADSET";
serviceName = "analog_headset_service";
deviceMatchAttr = "analog_headset_attr";
}
}
}
...
audio_config.hcs
:hcs
root {
platform {
template card_controller {
match_attr = "";
serviceName = "";
codecName = "";
platformName = "";
cpuDaiName = "";
codecDaiName = "";
dspName = "";
dspDaiName = "";
}
controller_0x120c1000 :: card_controller {
match_attr = "hdf_audio_driver_0";
serviceName = "hdf_audio_codec_primary_dev0";
codecName = "codec_service_0";
platformName = "dma_service_0";
cpuDaiName = "dai_service";
codecDaiName = "codec_dai";
dspName = "dsp_service_0";
dspDaiName = "dsp_dai";
}
controller_0x120c1001 :: card_controller {
match_attr = "hdf_audio_driver_1";
serviceName = "hdf_audio_codec_primary_dev11";
codecName = "codec_service_1";
platformName = "dma_service_0";
cpuDaiName = "dai_service";
codecDaiName = "rk817_dai";
dspName = "dsp_service_0";
dspDaiName = "dsp_dai";
}
}
}
codec_config.hcs
Code
root {
platform {
template codec_controller {
match_attr = "";
serviceName = "";
codecDaiName = "";
}
controller_0x120c1030 :: codec_controller {
match_attr = "hdf_codec_driver_0";
serviceName = "codec_service_0";
codecDaiName = "codec_dai";
regConfig {
/* reg, value */
initSeqConfig = [
0x13, 0xf4,
...
];
controlsConfig = [
/*array index, iface, mixer/mux, enable,*/
0, 2, 0, 1,
...
];
/* reg, rreg, shift, rshift, min, max, mask, invert, value */
ctrlParamsSeqConfig = [
0x31, 0x32, 0, 0, 0x00, 0xFF, 0xFF, 1, 0x00, // DACL/R Playback Volume
...
];
/* reg, rreg, shift, rshift, min, max, mask, invert, value */
daiParamsSeqConfig = [
0x45, 0x45, 0, 0, 0x0, 0xFF, 0xFF, 0, 0x0C, // PLL_PREDIV_BIT
...
];
ctrlSapmParamsSeqConfig = [
0x27, 0x27, 5, 5, 0x00, 0x1, 0x1, 1, 0x00, //LPGA MIC -- connect MIC1
...
];
/*
sapm
reg is 0xFFFF: component has no sapm register bit
sapmType, compNameIndex, reg, mask, shift, invert, kcontrolNews, kcontrolsNum
*/
sapmComponent = [
10, 0, 0x18, 0x1, 7, 1, 0, 0, //ADCL
...
];
/*array index, iface, mixer/mux, enable*/
sapmConfig = [
0, 2, 0, 1,
...
];
}
}
controller_0x120c1031 :: codec_controller {
match_attr = "hdf_codec_driver_1";
serviceName = "codec_service_1";
codecDaiName = "rk817_dai";
}
}
}
分布式音频是指多个设备之间音频外设跨设备协同使用的能力,如将设备A的音频通过设备B的Speaker进行播音,或者设备A使用设备B的Mic进行录音。
分布式音频不直接向应用提供接口,应用可以通过音频框架
的接口来调用分布式音频能力,使用方式与本地音频一致。
概念说明
主控端(source) :分布式音频控制端设备,向被控端设备发送指令,实现在被控端设备上音频播放和录制的功能;
被控端(sink) :分布式音频被控制端设备,接收来自主控端设备的指令,使本地音频外设为主控端设备所用,用来播音或录音。
为了能让大家更好的学习鸿蒙 (Harmony OS) 开发技术,这边特意整理了《鸿蒙 (Harmony OS)开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
入门必看:https://qr21.cn/FV7h05
HarmonyOS 概念:https://qr21.cn/FV7h05
如何快速入门:https://qr21.cn/FV7h05
开发基础知识:https://qr21.cn/FV7h05
基于ArkTS 开发:https://qr21.cn/FV7h05