目录
- 一、概述
- 二、main 函数解析
- 三、main_inner 函数解析
- 四、sample_audio_ai_ao 函数解析
- 4.1 Audio Codec相关配置
- 五
一、概述
上篇文章 【海思SS528】MPP媒体处理软件V5.0 | 音频模块 - 学习笔记 学习了海思MPP媒体处理平台的一小部分音频知识,这篇文章继续学习与音频相关的例程,这样可以更好理解《MPP 媒体处理软件 V5.0 开发参考.pdf》中的音频模块知识。
本篇文章涉及到的SDK文件及路径说明:
- 《MPP 媒体处理软件 V5.0 开发参考.pdf》:在SDK的路径为
SS528ReleaseDoc\software\board\MPP
- 《22AP30 H.265编解码处理器用户指南.pdf》:在SDK的路径为
SS528ReleaseDoc\hardware\chip
- sample_audio.c :在SDK的路径为
SS528V100_SDK_V2.0.0.3/mpp/sample/audio/sample_audio.c
二、main 函数解析
先看 main 函数,主要做了以下工作:
- 判断程序输入参数,错误的话,就打印程序功能及用法;
- 初始化系统和VB:sample_comm_sys_init
- 初始化 AAC 编码和解码:hi_mpi_aenc_aac_init、hi_mpi_adec_aac_init
- 根据输入参数,调用对应例子:main_inner
- 退出程序时的反初始化:hi_mpi_aenc_aac_deinit、hi_mpi_adec_aac_deinit、sample_comm_sys_exit
从main函数来看,主要的内容在
main_inner
函数。下面是main函数的代码:
/* function : main */
#ifdef __LITEOS__
hi_s32 app_main(int argc, char *argv[])
#else
hi_s32 main(int argc, char *argv[])
#endif
{
hi_s32 ret;
hi_vb_cfg vb_conf;
hi_u32 index;
if (argc != 2) { /* 2:argv num */
sample_audio_usage();
return HI_FAILURE;
}
if (!strncmp(argv[1], "-h", 2)) { /* 2:arg num */
sample_audio_usage();
return HI_FAILURE;
}
if ((strlen(argv[1]) != 1) ||
(argv[1][0] < '0' || argv[1][0] > '6')) { /* 6:arg num */
sample_audio_usage();
return HI_FAILURE;
}
index = atoi(argv[1]);
sample_sys_signal(&sample_audio_handle_sig);
#if defined(OT_VQE_USE_STATIC_MODULE_REGISTER)
ret = sample_audio_register_vqe_module();
if (ret != HI_SUCCESS) {
return HI_FAILURE;
}
#endif
ret = memset_s(&vb_conf, sizeof(hi_vb_cfg), 0, sizeof(hi_vb_cfg));
if (ret != EOK) {
printf("%s: vb_config init failed with %d!\n", __FUNCTION__, ret);
return HI_FAILURE;
}
ret = sample_comm_sys_init(&vb_conf);
if (ret != HI_SUCCESS) {
printf("%s: system init failed with %d!\n", __FUNCTION__, ret);
return HI_FAILURE;
}
hi_mpi_aenc_aac_init();
hi_mpi_adec_aac_init();
main_inner(index);
hi_mpi_aenc_aac_deinit();
hi_mpi_adec_aac_deinit();
sample_comm_sys_exit();
return ret;
}
三、main_inner 函数解析
main_inner函数主要是根据程序输入的第二个参数来决定调用哪个例子,分别以下几种:
- sample_audio_ai_ao:从 AI 设备采集音频,然后从 AO 设备播放,最简单的一个例子;
- sample_audio_ai_aenc:从 AI 设备采集音频,然后进行编码写文件,最后再解码且从 AO 设备播放;
- sample_audio_adec_ao:从文件读取音频数据,解码,从 AO 设备播放;
- sample_audio_ai_vqe_process_ao:
- sample_audio_ai_hdmi_ao:
- sample_audio_ai_to_ao_sys_chn:
- sample_audio_ai_to_ext_resample:
这后面几个例子,还没使用,后面补充。2023-06-30 21:25:34
main_inner的代码如下,这也是没什么内容的一个函数。
static hi_void main_inner(hi_u32 index)
{
switch (index) {
case 0: { /* 0:ai->ao */
sample_audio_ai_ao();
break;
}
case 1: { /* 1:ai->aenc->adec->ao */
sample_audio_ai_aenc();
break;
}
case 2: { /* 2:file->adec->ao */
sample_audio_adec_ao();
break;
}
case 3: { /* 3:ai->ao vqe */
sample_audio_ai_vqe_process_ao();
break;
}
case 4: { /* 4:ai->ao hdmi */
sample_audio_ai_hdmi_ao();
break;
}
case 5: { /* 5:ai->ao synchn */
sample_audio_ai_to_ao_sys_chn();
break;
}
case 6: { /* 6:resample test */
sample_audio_ai_to_ext_resample();
break;
}
default: {
break;
}
}
}
四、sample_audio_ai_ao 函数解析
这是 sample_audio.c 的第一个例子,可以带我们熟悉AI设备和AO设备的启用流程。
这个例子已经涉及到很多AI和AO的API函数了,需要对开发文档《MPP 媒体处理软件 V5.0 开发参考.pdf》中音频相关的API函数有一定了解,可以再阅读过程碰到不认识的API再去开发文档查询。
4.1 Audio Codec相关配置
正式阅读代码前,先看一下有关Audio Codec的相关配置,因为在初始化参数时会使用到,如果AIO参数没有配置好的话,可能出现各种问题。
我使用的板子没有使用内置的Audio Codec,而是使用 ES7243S 去做采集音频的模数转换,采样率、采集精度、声道是驱动工程师写驱动时写死的,而 sample_audio.c 的例子中提供了sample_comm_audio_cfg_acodec
对Audio codec进行设置的,不设置的话,程序一跑就退出了。根据我的情况,我用不上这个函数,所以要注释掉,并且配置AIO参数时,也配置好对应的采样率、采集精度、声道和AI设备号。我的采样率、采集精度、声道和AI设备号如下:
- 采样率:48kHz
- 采样精度:16bit
- 声道:双声道
- AI设备号:1
五
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁