在DM642上实现音频采集并以G.723.1进行实时编解码

本文讲述了在TI DM642平台上,结合TLV320AIC23实现音频采集与播放,并基于G.723.1标准进行编解码的实验。通过中断方式和代码优化,实现了采集编码与解码播放的同时进行,解决了编码程序执行时间过长导致的录音文件断断续续问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2010年10月份开始到11年一月期间,也就是保研的事定下来以后,根据老师安排,我就在实验室用TI公司的DM642(用的是SSD的开发板)改编了一段用ITU的G.723.1标准的采集和编码、解码和播放程序。主要功能是实现麦克风采集和编码同时进行,解码和话筒播放同时进行。

本来觉得挺简单的,起码比实验室师兄们做的H.264的视频编解码改编简单,因为音频的数据量小的多嘛!基本不用做啥优化的。不过后来改编的时候倒还真的要做点程序优化来提高编解码速度,这倒不是主要工作量,而是音频的采集、播放、编码解码的输入输出等程序接口问题困扰了我很久。
废话不说,先上图:两边就是两个程序实现功能的原理图

    上图为本实验需要实现的最终原理图:左侧是发送端,用话筒采集话音并实时根据G.723.1编码,编码后的码流通过网络传输给接收端,接收端解码接收到的码流并实时地播放输出给耳机。

 

 

    但是由于本实验不涉及数据的传输,所以,期望获得的程序只包含发送端的采集和编码程序,以及接收端的解码和播放程序,前者的输出用写入硬盘的PCM文件模拟,后者的输入用从硬盘中读取的PCM文件模拟。

    为了确保采集与编码、解码与播放能同时进行,需要满足以下条件:发送端的编码速率V2大于采集速度V1,接收端解码速率V4大于播放速度V3。

1、  AD芯片TLV320AIC23配合DM642完成音频的采集与播放

    音频的采集与播放的原理:TLV320AIC23对输入的模拟信号进行采样、量化和编码,数据自动传给多信道缓冲串行端口McBsp。若要采集声音信息,需用与AIC23采样频率相同的频率从McBsp中取数到DM642的内存中;播放与采集类似:以一定频率将数写入McBspMcBsp自动将数据传给AIC23,输出到耳机播放。

    程序的实现过程:

    首先通过I2C总线设置AIC23,通过修改寄存器的值控制用AIC23进行ADDA转换时的相应功能,包括AD转换的采样率(44.1khz)、麦克风输出的音量等。

    在配置McBsp的相关寄存器,控制McBsp的相关功能。

    程序采用中断方式采集和播放,属计数器0中断(中断源、中断标志、中断返回标志不明,初步推断中断与AIC23的采样频率有关,中断频率与采样频率相同,另外,试验证明,对McBsp的写操作是中断返回的前提),中断服务子程序实现一次采集和播放。

2、  G.723.1为标准,在DM642上对音频文件进行编解码。

        编码原理,解码原理(略,主要是这都是ITU提供的现成的程序Coder和Decoder,弄清楚函数的输入和输出的是什么数据及其类型之后,拿来用就行了)。

    编码程序的接口:编码函数Coder的输入为一帧数据,short Databuff[240],共480字节,输出为char Line[24],共24字节。但是G.723.1编码后的帧格式,总共有三种:24字节的数据率为6.3kbps的帧,20字节的数据率为5.3kbps的帧,4字节的静音插入描述帧SID,这三种帧格式都是以首字的前两个比特来确定的。所以在对编码后的帧进行保存时要注意:先根据Coder()输出Line[24]的前两个比特来确定其帧格式,在按具体的帧格式保存,否则会在解码时出现“所选数据率不匹配”导致的无法解码的问题。编码程序的接口与解码程序的类似,也需要注意上述问题。

3、  优化G.723.1编解码代码,使得采集与编码,解码与播放能同时进行。

    为了满足原理图中提出的条件,对发送端与接收端的程序作以下修改:

       1、只调用一次fwrite或者fread。这是因为:fwritefread函数都是涉及读写硬盘操作的函数,调用周期过长,如果把fwritefread放在负责编码或解码的中断子程序中,将会导致没编码或每解码一帧都会调用一次fwritefread,大大减缓了编码和解码的速度。所以在本实验中采用一次性调用fwritefread,在编码之后将数据从芯片内存一次性写入硬盘,或在解码之前将数据从硬盘一次性读入芯片内存。

       2、优化编码函数Coder与解码函数Decod。这是因为:

本实验将G.723.1采集代码与编码代码相结合,试图实现采集和编码同时完成。将程序执行后录得的已编码文件经独立的解码程序解码:发现解码后的文件普遍存在时间短”——(几分钟的录音播放时只有几秒的时间),有较长时间的静音间隔的特点。推断这是由于采样时间设定不合适引起的。

    为验证这一推断:试验比较了带Coder的录音和不带Coder的录音,发现带Coder的录音回放的声音断断续续,且时间远小于录音的时间,而不带Coder的录音却不存在这样的现象。此外,还在CCS的软件仿真环境中用Profile选项测定了Coder的执行时间,具体操作(载入.out文件后,选择profile>clock>enableProfile>setupenable时钟并将Coder函数使能,Profile>viewer查看全部时间,count是执行次数),得Coder的执行时间是0.007s左右,即每处理240个比特需要0.007s时间,每秒处理20408比特,但是采样率是44.1Khz,设每个采样点用8比特来表示,1s采样352800比特,采样速度比处理速度快十倍以上,说明Coder 程序执行时间过长,导致获得的录音文件断断续续。

    为了加快Coder的速度,我们考虑采用C代码优化的方法来优化代码,改善实时录音并播放的情况,采用的具体优化方法如下:

1、 将频繁调用的函数改为宏定义函数,即在头文件中使用#define定义函数,此外,还根据现成的优化代码修改了这些函数,做了简化和删减,在不改变编码效果的前提下提高代码执行效率,效果是,Coder的执行时间从原本的0.007s减少到0.001s

2、在CCSProject选项的Build Options选择对编译器进行优化——效果是,Coder的执行时间从0.001s减少到0.0008s

3、对Coder 中大量出现的循环体进行修改。1)增加循环体内容来减少循环次数,提高执行速度;2)将数组元素用指针表示而不是用下标表示;3)把#pragma MUST_ITERATE( , , )放在循环体之前,告知开发板循环次数,改善软件流水,效果略有改善,Coder的执行时间在0.0007s左右。

3、修改CMD文件,将绝大多数段都放在片内存储器IRAM上,以保证调用周期尽量短。

       执行优化代码,达到了实时录音并压缩的功能。解码并播放程序的优化过程与之相似。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值