一、原理
Hi3520D音频(AUDIO)模块包括音频输入、音频输出、音频编码、音频编码和音频解码模块。音频输入和输出模块通过对Hi3520D芯片SIO设备的控制实现相应的音频输入输出功能;编码和解码模块则提供对ADPCM、G726、G711、PCM格式的音频编解码功能。
读取本地音频进行输出播放,主要原理如下:芯片利用DMA将内存中的数据传输到AO设备。AO设备通过I2S时序或PCM时序向AudioCodec发送数据。AudioCodec完成数字信号到模拟信号的转换过程,并输出模拟信号。
Hi3520D音频解码播放流程:
1、 音频输出属性初始化(通过结构体AIO_ATTR_S来进行设置);
2、 配置音频编解码模块(ACODEC);
3、 根据音频编码协议创建音频解码通道;
4、 设置AO设备属性;启用AO设备;启用AO通道(启用AO重采样,此项可选);
5、 绑定音频输出通道到音频解码通道;
6、 向每包待发送的音频数据头添加4字节的海思音频协议头;
7、 向音频解码通道发送组合后的音频数据包;
8、 播放声音。
二、调试过程
1、 制作原始音频数据(raw data)文件
Hi35XX系列芯片编解码所支持的音频格式主要是ADPCM、G726、G711、PCM等原始音频格式,常见的音频格式无法直接播放。因此若要输出播放本地音频,需先将音频转化成原始音频格式。
图1Adobe Audition启动界面
这里使用的是AdobeAudition音频处理软件(支持将音频转化成pcm raw data格式)。安装破解后,打开软件(不要在破解前打开),界面如图1所示。
在载入音频文件之前,打开Edit->Preferences->Media & Disk Cache,勾选DLMS使能,如图2所示。否则软件无法正常载入音频文件。
图2打开DLMS使能
通过File->Open或者File->Import->File载入音频文件。载入音频后,会出现如图3所示的界面。如果不出现右侧的波形图,则说明音频文件没有正确载入。载入后,可以播放试听。
图3载入音频文件
通过File->Saveas或File->Export->File导出特定格式的音频文件。导出前设置好导出格式即可,具体如下:Format选择libsndfile;在 Sample Type中设置SampleRate、Channels、BiteDepth等(按图示进行设置即可);在FormatSetting中,Format选择RawData,Encoding中选择16bit-PCM,ByteOrder选择默认即可。
设置完OK即可导出pcm格式的原始音频文件。
图4 输出格式设置
2、 系统和AUDIO模块的初始化
调用sample_comm_sys.c文件中的HI_S32SAMPLE_COMM_SYS_Init(VB_CONF_S*pstVbConf)接口即可。
3、 音频输出属性初始化
音频输出属性通过结构体AIO_ATTR_S进行配置,配置时调用HI_S32SAMPLE_COMM_AUDIO_CfgAcodec(AIO_ATTR_S*pstAioAttr)接口即可,由于我们用到的解码芯片是nvp6124,所以我们只需在该接口定义所在的文件sample_comm_audio.c增加宏定义#define HI_ACODEC_TYPE_NVP6124即可,也即实际调用的是HI_S32 SAMPLE_NVP6124_CfgAudio(constAIO_ATTR_S *pstAioAttr)接口,而这个接口实际是通过nvp6124驱动中的nvp6124_audio_format结构体和ioctl()接口来实现的。
4、 创建音频解码通道
音频解码通道的创建通过调用系统函数HI_S32HI_MPI_ADEC_CreateChn(AdChn,&stAdecAttr)实现,具体可参考HI_S32SAMPLE_COMM_AUDIO_StartAdec (ADEC_CHN AdChn, PAYLOAD_TYPE_E enType)的实现。指定好解码通道和解码文件的类型即可,这里分别为0和PT_LPCM。
5、 启动AO设备和AO通道
具体可参照HI_S32 SAMPLE_COMM_AUDIO_StartAo(AUDIO_DEVAoDevId, HI_S32 s32AoChnCnt, AIO_ATTR_S* pstAioAttr, AUDIO_SAMPLE_RATE_EenInSampleRate, HI_BOOL bResampleEn)。
HI_S32 HI_MPI_AO_SetPubAttr (AUDIO_DEVAoDevId, const AIO_ATTR_S *pstAttr)设置AO设备属性。注意pstAttr音频中设置的参数AO设备可支持且和音频文件的参数保持一致。
HI_S32 HI_MPI_AO_Enable(AUDIO_DEV AoDevId)设置AO设备使能。
HI_S32 HI_MPI_AO_EnableChn(AUDIO_DEV AoDevId,AO_CHN AoChn)设置解码通道使能。
这里不需要再像例程里那样进行重采样。
6、 绑定输出通道和音频解码通道
直接调用系统函数HI_S32 HI_MPI_SYS_Bind(MPP_CHN_S*pstSrcChn, MPP_CHN_S *pstDestChn)进行绑定即可。
具体可参考HI_S32SAMPLE_COMM_AUDIO_AoBindAdec(AUDIO_DEVAoDev, AO_CHN AoChn, ADEC_CHN AdChn)接口的实现。
7、 向音频文件添加海思音频协议头并向音频解码通道发送音频数据包
首先需要打开本地音频文件,直接调用fopen()函数即可,具体可参考或使用staticFILE *SAMPLE_AUDIO_OpenAdecFile(ADEC_CHNAdChn, PAYLOAD_TYPE_E enType)函数即可。
原始音频文件放在和应用同级目录下,这里默认命名为audio_chn0.pcm(与OpenAdecFile() 函数中设定的文件名称和类型相同即可)。
创建线程向解码器传输音频文件流解码,具体可参考和使用HI_S32SAMPLE_COMM_AUDIO_CreatTrdFileAdec(ADEC_CHNAdChn, FILE *pAdcFd) 主要是通过调用系统接口HI_S32HI_MPI_ADEC_SendStream(ADEC_CHN AdChn,const AUDIO_STREAM_S *pstStream, HI_BOOL bBlock)来实现的,在发送音频流数据前会添加4个字节的海思音频协议头{0,1,160,0}。
至此,即可实现对本地文件的播放。注意:需要避免整个程序退出,才能实现持续的播放,可通过getchar()等函数来实现(类似于opencv中图片的显示需要借助于waitKey());
8、 其他
设置音量和静音:在实现以上环节以后,可通过HI_S32HI_MPI_AO_SetVolume (AUDIO_DEVAoDevId, HI_S32 s32VolumeDb)和HI_S32HI_MPI_AO_SetMute (AUDIO_DEV AoDevId,HI_BOOL bEnable, AUDIO_FADE_S *pstFade)进行音量和静音设置
播放退出:退出播放时,需要将上面创建的通道、打开的设备、创建的关联等关闭释放和解除,具体可参考例程。
三、参考
1、主要参考文档:《HiMPPV3.0 媒体处理软件开发参考》,含有原理、API、错误码等。
2、参考sample_audio.c中的HI_S32SAMPLE_AUDIO_AdecAo(HI_VOID)接口函数。
3、 hi3520d音频输出调试成功(http://bbs.ebaina.com/forum.php?mod=viewthread&tid=9155)。
4、HI3520D音频(http://blog.csdn.net/dagefeijiqumeiguo/article/details/51763903)