随着电信业务的发展 ,人们对话音编码的要求越来越高。不仅要求低延时、低码速率 ,而且要求有很高的话音质量。为此,国际电信联盟 (ITU)于 1 996年推出了G. 729算法。该算法在8kbps的传输码率下实现了较好的综合话音质量 ,且时延较短 ,可被广泛地应用于 IP电话、移动通信、多媒体网络通信等众多领域。ADSP2191是美国AD公司最新推出的一款定点DSP,特别适用于通讯,工业控制,语音/话音和医疗等方面。本文以ADSP-2191 EZ-KIT Lite评估板作为实现G.729语音编解码算法实验系统的基本硬件平台,实现G.729的算法。

一.G.729算法的描述

图1.1 G.729编码器原理图
 


图1.1给出了 CS-ACELP算法编码器原理框图.算法的帧长为 1 0 ms,分两个子帧进行处理 .采样输入的语音信号首先经过高通滤波器去除直流分量及低频分量的干扰,然后按每一帧提取10阶LP参数并转化为LSP(线谱对 )参数进行量化、编码;用量化后的LSP参数返求得的L P参数分别构成感觉加权滤波器 W(z)以及合成滤波器 1 / A(z);目标信号是从加权语音中除去感觉加权滤波器的零输入响应而求得的 ,目标信号经过自适应码本搜索及固定码本搜索后产生激励信号 ,分别乘以各自的增益 ,并共同激励合成滤波器,产生本地重建语音信号.对每帧提取 CELP模型参数 (包括线性预测参数、固定码本和自适应码本码矢量以及对应的增益 ),并将其编码后的比特流 (80 bit/ frame)送信道传输 .

二.系统平台的接口和硬件设计方案
ADSP-2191 EZ-KIT Lite评估板是AD公司设计用来在VisualDSP++开发环境中测试ADSP-2191数字信号处理器的性能的演示板。下面介绍它的接口和硬件设计方案。
2.1硬件接口:
外部存储区接口(EMI):外部存储区为一个512Kx8的flash存储器,该存储器被连到引导存储区选择脚(BMS)和存储器选择0脚(MS0),使得flash存储器既可用作DSP的引导加载存储区,也可在正常工作时用来存储有关信息。
音频接口SPORT0:与AD1885 SoundMAX编解码器相连,用户可以将输入语音接到编码器的麦克风输入通道,或者LINE_IN输入通道。另外,PF7接到AD1885的复位脚,从而DSP可以控制编码器的复位操作。
电话接口SPORT1:与AD1803电话编码器相连,使DSP在标准电话线上可用作调制解调器。这里主要通过AD1803的4个通用引脚对器进行控制。
JTAG仿真器接口:通过此接口可以访问DSP内外部存储区和专用寄存器。
主机接口和USB接口:以通过主机接口使自己开发的实验系统与EZ-KIT相连,也可以通过USB接口加载程序。另外,EZ-KIT Lite上还留有空的面包板,可供用户进行简单的系统扩展,增加新的功能。
PC机可以通过一个USB口或JTAG仿真器对ADSP2191进行操作或控制,用户也可以通过USB口不受任何限制地访问ADSP2191和评估板内核,板上配有的JTAG仿真器则使得PC机和目标板之间能快速方便地进行通讯。
2.2设计方案
G.729 算法实现的重点在于编解码算法的实现以及数据的采集、存储。该系统硬件结构的设计为算法的实现提供了一个良好的平台。图2.1为该评估板的系统硬件设计方案。它的设计符合AC\'97结构定义的音频信号处理要求。其中,ADSP-2191是AD公司专为通讯应用而设计的16位定点DSP,在实验系统中用作主控芯片,用于实现编解码算法。AD1885在系统中用作模/数、数/模转换器,它与ADSP-2191的SPORT0口相连。系统工作时,先由 AD1885以8KHz的采样率将话筒输入的模拟语音信号转换成标准的PCM数字信号,再经过SPORT0口输入到ADSP-2191,并存入数据缓冲,当采样的数据达到一个语音帧(30ms)时,ADSP-2191即进行编码处理,由于本系统仅是供研究用的实验系统,因此编码后的数据将直接进行解码,解码后的重构语音数据经过AD1885转换后,还原成模拟语音信号通过扬声器输出。该方案以ADSP2191为主控芯片,采用AD1885作为语音信号处理芯片。下面分别介绍它们的主要特征。

图2.1 EZ-KIT Lite系统硬件设计方案
 


ADSP2191主要特征:ADSP-2191是16位定点DSP,处理能力为160MIPS;片内有160Kbyte存储器,可配置成 32Kx16bit数据区和32Kx24bit程序区;全通明的指令Cache使得单周期内可以完成双操作数取址,这可以大大提高程序执行的效率;可以分别配置成8bit或16bit,芯片的地址转换功能和数据打包功能可方便实现与外部数据总线接口,以及与外部SRAM、FLASH或EPROM相连;同时外部的时钟频率可调以便与低速存储设备接口;外部主机可通过16位的主机接口对DSP的整个存储空间、引导加载空间或内部I/O空间进行读写操作;同时也可配置成8位的主机接口,以便与低功耗微控制器接口;两个可进行DMA操作的全双工SPI兼容口,可与多种SPI兼容设备进行通讯。内核的特殊结构和丰富的指令系统支持并行操作,在一个指令周期内,ADSP-2191可以完成5个操作,包括:产生下一个指令地址;取下一条指令;执行1~2次数据搬移;更新 1~2个地址指针;执行运算。而且,在执行这些操作的同时,处理器还可以通过两个串口、UART口或SPI口接受/发送数据,或者通过外存接口访问外部存储器。在对G.729算法程序的改造和优化的过程中可以充分利用这些特征,提高程序的执行效率。
AD1885主要特征:AD1885符合 AC\'97语音编码器结构的所有要求。它支持多路编解码和可变的取样率;通过同一条链接与3个编解码器通讯,内部集成有耳机驱动器,以及内置的PHAT Stereo 3D增强设备等。该系统主要利用AD1885的A/D和D/A功能。

三.G.729算法的软件设计
EZ-KIT工作时,由AD1885为ADSP-2191串口提供帧接收和发送的同步信号,软件设计中以此为中断请求信号,在中断服务程序中从数据接收寄存器读取输入数据,将其存入接收缓冲区,同时将欲发送的数据从发送缓冲区取出写入发送寄存器,然后中断返回。编码器的接收缓冲区及解码器的发送缓冲区设置为1024字的FIFO(先进先出队列),以免由于数据处理速度的冲突而发生错误。本程序采用查询和中断相结合的工作模式。主程序以查询方式检测相关标志,以确定是否开始进行编解码处理。因为ADSP-2191对语音数据的编解码处理时间相对比较长,因此放在主程序中完成,中断程序只完成数据的传输,符合中断服务程序尽量简短的要求。
3.1 软件设计中的关键技术
语音编码技术的实时性很强,要求其数据的存储和传输必须通畅迅速。为了达到性能上的要求,根据硬件的特点在编程过程中应该特别注意以下几方面:
FIFO 的运用:因为G.729算法的运算量不平衡,如果某一帧语音所需的运算量特别大,编解码延时可能过长,在下一帧数据到来时,上一帧数据还没有处理完,如果没有足够大的缓冲区,会丢失数据。为了实时处理语音和合成语音,避免数据覆盖,软件设置FIFO作为数据缓冲区,大小设置为语音帧长度的4倍左右。在中断程序中,将接收到的数据存入FIFO,只有当其中的数据达到一个语音帧的长度后,才将数据由FIFO取出,送入编码数据缓冲区。同样地,经过解码的数据也是存入发送FIFO,在中断到来时,从发送FIFO中取得数据,送到发送寄存器中输出。程序中利用ADSP-2191的结构特性,将FIFO设置为循环缓冲区(Circ-Buf),这样在指针到达缓冲区的底部时,系统会自动修改指针指向缓冲区的头部,而不需人为地修改。
数据精度的处理:ADSP- 2191是定点DSP芯片,为确保运算精度和防止数据溢出,在实现过程中主要采用了两种方法:一是对某些精度要求较高的运算,将计算的中间变量采用32位来表示;二是对于幅度范围变化比较大的变量或数组,如激励增益、自适应码本的自相关数组等,采用标量浮点或块浮点表示,用一个字存储使该数或数组规格化所需的左移位数(EXP),其余字存储规格化后的尾数,不仅能够提高运算速度,还可以确保数据的精度。
系统初始化中对SPORT0和AD1885的配置方式:根据 AC\'97的定义,系统中将ADSP-2191的串口SPORT0配置成AC-link,用来对音频转换器AD1885和控制芯片ADSP-2191之间的数据进行分时处理:由AD1885提供串行传输的位时钟,即AD1885的BIT_CLOCK引脚通过一个驱动器与ADSP-2191 SPORT0口的RCLK0和TCLK0引脚相连,AD1885的SYNC引脚与ADSP-2191的RFS0相连,ADSP-2191以此作为接收和发送音频数据帧的同步信号;BIT_CLOCK的频率为12.288MHz,因此同步采样频率可以通过设定SPORT0口的分频系数,对此频率值进行分频后得到音频数据在每个BIT_CLOCK的上升沿变化,因此AC-Link在每个下降沿采样该数据。在开始传送每个音频数据帧之前,SYNC为高电平,此阶段称为"标志段",随后SYNC一直为低电平,称为"数据段"。在程序中初始化SPORT0时,设置其工作模式为多通道,自动缓冲DMA,前同步,16位数据格式。在设置AD1885的工作模式时,定义其分时工作模式的时间片分配如下:

 

#define TAG_PHASE 0 #define COMMAND_ADDRESS_SLOT 1
#define COMMAND_DATA_SLOT 2 #define STATUS_ADDRESS_SLOT 1
#define STATUS_DATA_SLOT 2 #define LEFT 3
#define RIGHT 4
 

3.2算法程序的优化
ITU-T用标准ANSIC语言给出了G.729标准语音压缩算法模块, ADSP2191也支持C编译器,但是如果对C程序模块不作任何的修改而直接移植到DSP开发平台上运行,则会由于C编译器优化后的代码并行性太差,不能充分利用DSP的硬件结构和软件资源而降低运行效率。
浮点运算的定点实现:ADSP2191是定点DSP,但是在G.729中有大量的浮点小数运算,因此如何用定点的DSP实现浮点运算是本软件设计必须考虑的问题。实际中,可以采用数的定标来解决这一问题。数的定标就是由程序员决定一个数的小数点处于DSP芯片字长的第几位,Q表示法是一种常用的定标方法。浮点数与定点数的转换关系可表示为:浮点数X转换为定点数Y,Y=(int)X*2Q;定点数Y转换为浮点数X,X=(float)Y*2(-Q). 合理使用Q的定标值可解决定点的DSP芯片处理浮点运算的问题,同时可提高运算精度。
循环展开:使用具有并行能力的DSP开发软件时,要充分利用DSP的字长和数目众多的运算单元,尽量把循环体展开,通过增加每次循环中执行的指令数来减少总的循环次数,可使得在同样的时钟周期内能运行更多的指令,提高循环效率。
提高寄存器的利用率:DSP芯片内部的运算单元运行效率很高,但若寄存器和数据总线之间的数据交换频繁,将使DSP的执行效率降低,因为DSP在进行内存操作时,往往需要若干周期的延迟。为了减少耗时的内存操作,可以在程序进入循环体前,将要频繁使用的数据预先放入寄存器,然后反复调用,可以提高一部分效率。
使用内联函数:内联函数是在某些DSP汇编指令前加上"-inline"构成,它可以方便地实现某些需若干C语句才能实现的功能,是一种非常简便高效的优化方法。它的调用格式和普通C函数一样,但在编译时编译器会自动将inline用对应的汇编指令替代。ADSP-2191中的许多运算逻辑指令都可以做这样处理,如饱和绝对值、饱和乘、饱和加、左移、右移等。
C和汇编混合编程技术:在程序中,利用ADSP2191的C和汇编混合编程技术,即在C程序中内嵌汇编语句-采用asm()嵌入式汇编编程方式,特别是在一些运算指令中,可以用寄存器直接存放参与运算的数据,充分利用DSP执行汇编指令的高速快捷的特点,生成精炼的程序代码,并且节约了存放中间变量的内存空间。下面的例子中,就是用嵌入式汇编编程实现16位数相乘的函数:

static __inline int mult(int a, int b){
int __res;
asm("MX0=%1; MR=MX0*%2 (SS); MR=MR+MX0*%2 (SS);sat mr; %0=MR1;"
:"=e" (__res)
: "e" (a),"B" (b)
: "MX0", "MR0", "MR1", "MR2");
return __res;
}

函数的返回值放在乘法单元MR中,修改以后,经过实际测试,效率可以提高3/4。
合理分配资源:ADSP2191具有并行处理能力,它的三个功能模块:ALU、乘加器、移位器的操作可以和对程序存储区、数据存储取的存取操作并行进行。而G.729标准算法模块中,有大量的运算是在内存中的中间变量之间进行的,而且其结果需要存放到指定的存储区中,如果按C程序中那样依次进行,会降低指令执行的速度,因此,在分配程序和数据空间时,利用程序指针和数据指针可以同时进行内存存取的特点,尽量将进行运算的变量存放在不同的空间,以保证程序指针和数据指针所指的空间位于内存的不同块,从而减少计算时间,提高速度。
利用DSP的寻址特点,调整数据存放的方式:在程序中有大量有关FIR和IIR滤波器的计算,需要用一些预先给出的数据表中的数据参与运算,而这些运算又通常是依次进行的(先计算FIR,后计算IIR),如果各自分配数据指针,就会由于要不断修改和保存指针而影响程序执行的效率。因此利用DSP的寻址特点以及数目众多的寄存器,将有关的数据间隔存放,比如,在对语音数据进行后感知加权滤波计算时,就需要用零、极点系数计算相关系数,可以将FIR和IIR系数统一在一个连续的存储区存放,偶数单元存放FIR,奇数单元存放IIR,这样就可以只用一个数据指针就可以实现对两组系数的寻址,在不增加存储空间的情况下,提高了速度又避免了破坏有关的指针。

五.实验结果
通过解决实时实现G.729的一些难点和针对ADSP2191优越的性能对源程序做了C语言和汇编语言两级优化,在ADSP2191 EZ-KITE上实现了G.729的全部功能,并通过了全部的测试矢量,并且具有良好的语音合成质量。一路全双工的G.729编解码的运算量约为 20.5MIPS。