AUDIO 模块包括音频输入、音频输出、音频编码、音频解码四个子模块。音频输入和
输出模块通过对 Hi35xx 芯片 SIO 接口的控制实现音频输入输出功能。音频编码和解码模块提供对 G711、G726、ADPCM 格式的音频编解码功能,并支持录制和播放 LPCM格式的原始音频文件。
音频输入输出接口 SIO(Sonic Input/Output),用于和 Audio Codec 对接,完成声音的录制和播放。
对每个 SIO 接口的音频输入和音频输出功能,软件分别用 AI 和 AO 两个模块来管理,称之为 AI 设备和 AO 设备,并按照 SIO 序号为其编号。例如与 SIO0 接口对应的软件设备分别为 AiDev0 和 AoDev0。
HI3518录音和播放原理:
录音:原始音频信号以模拟信号的形式给出后,通过 Audio Codec,按一定采样率和采样精度转换为数字信号。 Audio Codec 以 I2S 时序或 PCM 时序的方式,将数字信号传输给SIO 接口,SIO 支持多路复用的接收模式。Hi35xx 芯片利用 DMAC 将 SIO 接口中的音频数据保存到内存中,完成录音操作。
播放:Hi35xx 芯片利用 DMAC 将内存中的数据传输到 SIO 接口。SIO 接口通过 I2S 时序或 PCM 时序向 Audio CODEC 发送数据。Audio Codec 完成数字信号到模拟信号的转换过程,并输出模拟信号。
Hi35xx音频部分的编码类型 G711、G726、ADPCM_DVI4 与 ADPCM_ORG_DVI4是使用硬编码,ADPCM_IMA 是使用 CPU 软件解码,其中 Hi3518/Hi3516C 芯片没有硬件编码模块,所有的编码方式都使用软件编码;而所有的解码功能基于独立封装的海思音频编解码库,核心解码器工作在用户态,使用 CPU 软件解码。SDK 支持通过 SYS模块的绑定接口,将一个 AI 通道绑定到 AENC 通道,实现录音编码功能;也可以将一个 ADEC 通道绑定到 AO 通道,实现解码播放功能。
使用海思语音编解码库进行 G711、G726、ADPCM 格式的编码,编码后的码流遵循以下表格中描述的帧结构,即在每帧码流数据的净荷数据之前填充有 4 个字节的帧头;使用语音编解码库进行以上格式的解码时,需要读取相应的帧头信息。
这4个字节的帧头内容即为如下数组中的值:
static char aryHeard[4] = {0,1,160,0}; //hisi audio header
利用ACODEC库进行音频解码播放时,每发送一包音频数据到解码通道前,都必须先把这个数组中的内容组合到包的头部位置,否则解码出错。
G711、G726、ADPCM编码协议的采样率均为8KHz。
其中,Hi3518/Hi3516C 使用内部 audio codec。Hi3518A/Hi3516C 支持双声道,左右声道输入,左右声道输出。Hi3518C 只支持单声道,左声道输入、左声道输出。
音频 AI 和 AO 支持的最大通道数为 16 通道(其中 Hi3518/Hi3516C 芯片受内置 codec 限制,只支持 2 通道),且配置 AI 和 AO 设备时需要将通道配置为偶数。
Hi3518/Hi3516C 只支持 16bit 位宽。
Hi3518A/Hi3518C/Hi3516C 提供一个内置的 Audio Codec,并在芯片内部对接到 SIO0接口,即 SIO0 接口只能通过内置的 Audio Codec 完成声音的播放及录制。因为 AudioCodec 不能发送同步时钟,所以 SIO0 接口只能配置为 I2S 时序的主模式(MASTER)。用户需要正确配置 SIO0 和 Audio Codec 对接时序才可接收或发送音频数据。
Audio Codec 分为模拟部分和数字部分。模拟部分可以通过模拟混音(MICPGA)选择由麦克风输入(MICIN) 或线性输入(LINEIN),模拟混音支持增益调节。数字部分有 ADC 和 DAC,完成模拟信号和数字信号之间的转换,并且可分别调节音量。用户在进行音量调节时,可综合模拟部分和数字部分的音量调节,建议优先调节模拟部分音量。
Audio Codec 支持去加重滤波、pop 音抑制和高通滤波,并默认开启这些功能。
Audio Codec 的用户态接口以 ioctl 形式体现,其形式如下:
int ioctl (int fd,
unsigned long cmd,
……
);
该函数是 Linux 标准接口,具备可变参数特性。但在 Audio Codec 中,实际只需要 3 个参数。因此,其语法形式等同于:
int ioctl (int fd,
unsigned long cmd,
CMD_DATA_TYPE *cmddata);
其中,CMD_DATA_TYPE 随参数 cmd 的变化而变化。
综上所述,HI3518C音频子系统初始化时应该作以下软件配置:
音频编码录制流程:
1、音频输入属性(见AIO_ATTR_S结构体);
2、配置音频编码、解码模块(ACODEC);
3、设置AI设备属性;启用AI设备;启用AI通道;(启用AI噪声抑制、启用AI重采样,此两项可选。);
4、根据音频编码协议创建音频编码通道;
5、绑定音频编码通道到音频输入通道;
6、HI_MPI_AENC_GetFd(AENC_CHN AeChn)获取音频编码通道的Fd;
7、HI_MPI_AENC_GetStream从编码通道获取编码之后的音频数据;
8、用户保存或者转发此数据。
音频解码播放流程:
1、音频输出属性(见AIO_ATTR_S结构体)初始化;
2、配置音频编码、解码模块(ACODEC);
3、根据音频编码协议创建音频解码通道;
4、设置AO设备属性;启用AO设备;启用 AO通道(启用AO重采样,此项可选);
5、绑定音频输出通道到音频解码通道;
6、向每包待发送的音频数据头添加4字节的海思音频协议头;
7、HI_MPI_ADEC_SendStream向音频解码通道发送组合之后的音频数据包;
8、播放声音。
Hi35xx SIO 支持扩展的多路接收的 I2S 及 PCM 接口时序,对接 CODEC 的时序模式选择、同步时钟、采样位宽等配置必须与 Hi35xx SIO 的配置保持一致,否则可能采集不到正确的数据。上面代码中AUDIO_POINT_NUM = 320,则通过调用口HI_MPI_AENC_GetStream从音频编码通道获取到的每包音频数据大小都为324字节(320字节的净荷数据+4字节海思音频数据头),使用ACODEC进行解码播放时,每次调用HI_MPI_ADEC_SendStream将音频数据发往音频解码通道时,数据长度也必须是324字节(320字节的净荷数据+4字节海思音频数据头)。
在音频初始化配置完毕后,需要首先对ACODEC模块进行配置,在配置ACODEC模块时,注意:
1、要把MICIN静音(MUTE)功能关闭。
2、输入设备选用LINEIN。
此处我有一点疑惑,设备的输入明明接的是MIC,我一开始也是未加思索就选择MICIN来进行配置ACODEC的,但是音频编码流程完毕后获取到的音频数据播放时只有“沙沙沙”的背景音,听不到话筒端的说话声音,纠结了两天,其它各项参数确定没有问题了,尝试着把MICIN改为LINEIN,声音OK,无语。。。。。。
目前听到的采集到的声音和解码播放的声音都很清晰,只是有点小,后续再尝试通过ioctl及相应的ACODEC模块给出的各种增益调节命令来调整音频监听与对讲的音量大小。。。。。。