关键词:TMS320VC5416 声码器 变速率 自适应
在当前的各种通信系统中,实时的语音编解码通常都在数字信号处理器(DSP)上实现。TI公司生产的C54系列DSP具有高性能、低功耗的特点,许多语音编解码算法都可以在它上面实现。但传统的语音编解码算法都是固定速率的,它们无法适应不断变化的网络情况和满足质量要求,缺乏灵活性。而且,一般的单速率语音编解码算法的程序量大都在30KWord以下,运算量也大都在30MIPS以下。TI公司新近推出的TMS320VC5416芯片拥有128KWord的片上RAM空间和160MIPS的运算能力,只承载单一速率的语音编解码算法显然是一种极大的浪费。
清华大学自主开发的正弦激励线性预测(SELP)系列低速率语音编码算法由于采用了合理的激励模型,在2.4kbps、1.2kbps和0.6kbps三个速率上都具有很好的重建语音质量。其中,2.4kbps速率算法的重建语音质量与国际上流行的相同速率的高质量AMBE算法相当,0.6kbps算法重建语音的可懂度也能达到90%以上,十分适合应用在各种军用语音通信系统中。
本文详细介绍了利用TMS320VC5416 DSP实现的自适应变速率SELP声码器。该声码器可根据不同的速率要求自动实时地切换到不同速率的算法进行语音通信,具有很好的通用性和灵活性。
1 声码器系统的结构和原理
声码器通信系统是建立在通用的MODEM平台上的,可以按照2.4kbps、1.2kbps和0.6kbps中的任一个速率实现全双工语音通信。图1为整个通信系统的原理框图。
MODEM平台负责对数字码流进行调制解调和通信,声码器则负责按照MODEM的要求对语音进行编解码。MODEM把话筒提供的模拟语音送给声码器编码并将声码器的解码语音送给听筒。MODEM还负责给声码器提供码流传送时钟,声码器则按照这个时钟与MODEM交换数字码流。另外,MODEM和声码器之间还有一些控制信号线用来彼此交换状态信息。表1是MODEM和声码器之间的主要接口关系。
表1 MODEM和声码器的主要接口
功 能
AinMODEM至声码器模拟语音输入Aout声码器至MODEM模拟语音输出CLKMODEM至声码器码流传送时钟,声码器按照CLK的频率进行编解码TXD声码器至MODEM声码器至MODEM的数据线,在CLK的下降沿有效RXDMODEM至声码器MODEM至声码器的数据线,在CLK的上升沿有效PTTMODEM至声码器PCM码有效标志RTS声码器至MODEM发送码流有效标志CDMODEM至声码器接收码流有效标志虽然MODEM可以根据网络条件和外界要求自动改变速率,但是却没有专门的信号线用来通知声码器进行速率转换。注意到码流传送时钟CLK是根据速率要求实时变化的,所以声码器通过检测CLK的频率就可以得到当前的速率转换信息。
声码器的核心部分是一片TMS320VC5416 DSP芯片,负责编解码和控制工作。另外,还有一片TI公司生产的TLC320AIC10芯片,负责语音的数模/模数(AD/DA)转换;一片FPGA,负责数字逻辑转换;一片2Mbit容量的8位FLASH存储器29LV020,负责存储所有程序和数据并在上电时加载到DSP的片内RAM上。声码器还有一个软件狗对系统工作状态进行实时监控,并在需要时对整个声码器进行复位。图2是声码器的原理框图。
当MODEM需要声码器进行编码时,它通过PTT信号通知声码器,并同时向声码器发送模拟语音信号。声码器利用其中的AD/DA芯片将其采样量化为PCM数字信号送给DSP,DSP则根据MODEM提供的时钟信号CLK的频率选择不同速率的编码算法对输入PCM信号进行编码,然后把码流通过TXD送回给MODEM,并同时通过RTS信号通知MODEM码流有效,MODEM就可以将码流进行调制并发送。接收时,也是由MODEM解调出码流后按照CLK的频率通过RXD发给声码器,并同时通过CD信号通知声码器码流有效,声码器则对接收的码流进行解码,并利用AD/DA将解码后的PCM语音转换为模拟语音信号送回MODEM。据此就可以设计出声码器的工作流程,如图3所示。
其中的帧同步捕捉指的是对接收到的码流的分帧工作,因为SELP是基于帧结构的编解码算法,所以在解码之前需要先利用帧同步算法捕捉到每帧的起始位置。这里采用的是基于计数器的帧同步捕捉算法。
另外,由于声码器的码流收发都是按照CLK频率连续进行的,而基于帧结构的SELP编解码器对码流的输入输出却是每帧进行一次的,所以对于发送和接收码流都需要设置循环缓冲区并对每个缓冲区设置一读一写两个指针。这两个指针间的距离应大于一倍帧长。但由于声码器中给AD/DA提供采样时钟的晶振有一定误差,所以导致这两个指针移动速度不同。以输入码流缓冲区为例,其读指针应由SELP编码器控制,而编码器被调用的频率由本地晶振的频率决定,所以读指针的移动速度由本地晶振控制。写指针则是由码流输入部分控制,其移动速度实际上是由对方的解码速度决定的,也就是受对方声码器的晶振控制。所以在编码后和解码前都需要进行指针调整,也就是检查码流缓冲区的读写指针间距,并根据需要丢弃一帧或复制一帧。
声码器设计和实现中的主要难点在于硬件接口的设计和FLASH上电加载部分,下面分别进行介绍。
2 硬件接口的设计
TMS320VC5416片上有三个多通道缓冲串口(MCBSP),每个MCBSP都可以作为串口使用或被初始化成通用I/O口使用。其中,MCBSP0按照串口的工作方式与AD/DA相连,这部分比较简单,按照典型的连接方式即可实现。但是码流收发部分则不同,因为这部分只有一根同步时钟线CLK和输入输出两根数据线,所以很难直接利用MCBSP按串口方式实现收发。于是把MCBSP1初始化成通用I/O,将RXD与I/O口输入脚DR1相连,TXD与I/O口的输出脚DX1相连,将CLK与初始化为I/O口的输入脚FSR1相连。这样在程序中就可以很方便地随时读写这三根信号线,再将时钟中断的频率设为50kHz(远高于CLK可能出现的最高频率2.4kHz),就可以在时钟中断中实时监测CLK的变化。若发现CLK的上升沿则读取RXD的状态并存入码流接收缓冲区,若发现CLK的下降沿则从码流发送缓冲区取出1bit送至TXD。这样就成功地实现了码流的收发。
MCBSP1被初始化为通用I/O后一共能提供6根I/O引脚线,除去码流收发占用的3根之外还有3根,正好可以用来连接PTT、RTS和CD信号线。这样,就可以在占用最少的DSP资源的情况下实现码流收发和控制功能。
另一个主要问题就是速率的自适应问题,也就是说,声码器必须能够根据CLK的频率自动选择合适的编解码算法。在上述连接方式下,这个问题也就很容易解决了,只需设立一个计数器,对CLK的每个周期中发生的时钟中断个数进行计数即可。这样,根据计数值就可以很方便地计算出CLK的频率。例如,时钟中断的频率是50kHz,那么当CLK的频率是2.4kHz时,计数器的值就应该在50/2.4=20.8左右,当CLK的频率是1.2kHz时,则在41.7左右;当CLK的频率是0.6kHz时,则在83.3左右。从图2的流程中可以看出,在程序初始化前就需要检测CLK频率,并根据CLK的频率选择合适的编解码算法,进行相应的初始化。在程序的执行过程中也要对CLK的频率进行实时监测,若发现频率改变就立即重新初始化声码器。这样就能够保证声码器实时地跟踪CLK的变化,实现自适应速率切换。
对于软件狗所需的周期变化信号,则通过DSP上的输出引脚XF给出,并在程序中及时翻转XF的电平得到。
3 上电加载部分(Bootload)的实现
TMS320VC5416 DSP片内ROM中有固化的自加载程序(Bootloader),但它对被加载程序的大小有限制。在使用8bit FLASH的情况下,只能加载小于16KWord的内容。而三个速率的SELP算法程序区和数据区的总数据量远远超过16K