ACELP 算法的DSP 全汇编实现
2012-07-20权进国林孝康
权进国,夏 晶,林孝康
(清华大学深圳研究生院信息学部,深圳 518055)
1 ACELP 算法的原理
TETRA 标准中的语音压缩编解码采用ACELP算法,这是一种改进型的CELP,其码率被压缩至4.567kb/s。ACELP 算法以30ms为一帧,每帧又分成4个子帧,每子帧7.5ms。采用8k 采样速率,每帧有240个抽样,每子帧有60个抽样。ACELP 算法的输入为16bit 线性PCM 编码后的数字语音信号。输入语音在编码器中经过预处理和加窗后,首先进行LP 分析,用Levinson-Durbin 算法求出LP参数。由于LP参数较敏感,微小的变动可能影响整个频谱,直接量化传输LP参数会严重影响合成语音质量。因此,通常将LP参数转化成LSP参数进行量化编码并传输。LSP参数与LP参数是等效的,但变动单个LSP参数仅影响局部频谱。由于编解码器中的滤波器实际使用的是LP参数,因此,还需要再将LSP参数变换成LP参数。
之后,进行长时预测分析。长时预测分析的目的是发现最佳基音参数:基音滤波器的延迟和增益。为简化长时预测分析,该过程通常分成开环基音搜索和闭环基音搜索两步进行。开环基音搜索是进行基音粗估计。闭环基音搜索是基音周期的细搜索过程。
完成长时预测分析后,下一步将进行固定码本搜索。在固定码本搜索中,采用代数码本结构和聚焦搜索技术。固定码本搜索的目的是找到最佳代数码字和增益参数。
解码功能包括对传输参数的解码(LP 滤波器参数解码、自适应码本矢量解码、固定码矢量解码、自适应码本和固定码本增益解码)以及合成重建语音。
2 ACELP 算法在TI C54x DSP 上的全汇编实现
TMS320C54x是TI 公司生产的16 位定点DSP,适合远程通信等实时嵌入式应用的需要。经统计,若用C 语言在C54x DSP 上实现ACELP 算法,那么未经优化的C 程序需要约700MIPS的处理能力才能保证在30ms 内完成ACELP 算法,C45x DSP的处理能力与之相差甚远。由此可见,若用C 语言实现,那么ACELP 算法难以应用到需要实时处理的场合。因此,为了能在C54x 上实时实现ACELP 算法,需要将C 程序转成C54x的汇编程序,并尽量优化以降低运算量和存储量。在进行DSP的软件调试和开发过程中,采用了TI 公司的集成开发环境TMS320C5000 CCS2.0。
2.1 编程及调试
2.1.1 编程
由于程序规模较大,又是在DSP 汇编级别上实现,因此保持原C 程序所具有的模块化和结构化有利于程序的编写、检查和阅读,尤其有利于汇编程序的调试。所以在编写汇编程序时尽量保持与原C程序在结构和流程上一致,只在极少需要优化的地方对汇编程序结构进行调整。
汇编程序要解决的一个重要问题是函数调用时的参数传递问题。为此,定义了coeff_1,coeff_2......coeff_10 等10个16bit的全局变量。如果参数是32bit,则用累加器A 和B 传递。对于静态变量,需要在数据区开辟专门的区域进行存储,以保证不会被错误的更改。函数内需要使用临时变量时,则从堆栈中开辟一段存储区,函数调用结束即可释放这段存储区。
2.1.2 优化
编写DSP 程序,要想提高效率就要充分利用DSP 芯片的各种硬件资源,并适当对结构进行一些调整,下面是用到的一些方法:
(1)去掉一些不必要的子程序调用
C 程序中有大量的子程序调用,其中有不少子程序在汇编中用简单的几条指令就可以实现,这样的子程序在汇编中可以去掉,因为调用这些子程序所造成的流水线中断相对于子程序本身来说代价过高。去掉一些不必要的子程序并对主程序进行少许结构上的调整可以达到优化程序的目的。
(2)循环指令rptb 和rpt的使用
C54x 专门提供了块循环指令rptb,充分使用该指令可以有效的减少指令周期。对于多重循环,块循环应尽量放在最内层,尤其是在代数码本搜索函数中。
把循环尽可能的压缩至一条指令,这样可以用rpt 指令实现,以便减少循环开销。
(3)展开循环次数较少的循环
循环会造成流水线中断、增加循环开销,为尽可能避免这一点,可以将循环次数较少的循环展开。比如:Chebps 函数被调用次数很多,该函数中存在一个循环,其循环次数仅为4,该循环应该展开。
(4)充分利用存储器映射寄存器
存储器映射寄存器间传递参数及间接寻址等都是行之有效的优化方法。
(5)移位
对于某些移位位数未定的移位,可以考虑使用rpt 和sfta 结合来完成。另外使用指令中的移位功能,利用带ASM的移位指令格式,一般可以节约一个指令周期,在一般情况下也许不必在意,但是对于调用次数多达100 来次的Chebps 函数,节省每一条指令都意义重大。
(6)充分利用各种延迟指令
转移指令会造成指令中断,浪费指令周期,可以利用指令的流水线等待周期预先执行一两条其他指令,但应注意这一两条指令不应影响延时指令的执行条件。
(7)针对具体函数进行结构上的调整
比如:代数码本搜索D4i60_16 函数,由于最内层和次内层会有门限判断,只有超过门限时下一层循环才会开始执行。因此,可以考虑将那些只在下一层循环才会用到的一些变量放到门限判断之后去计算,这样就避免了一些无谓的运算。但是对于前两层循环,则应尽量把计算放在第一层循环。
(8)使用并行指令
并行指令使用的场合一般比较苛刻,但如果能够比较好的使用并行指令,仍然不失为一种优化的方法。
(9)巧妙使用DSP 汇编指令
巧妙的使用DSP 汇编指令可以有效的降低运算量,提高运算速度。
如使用ADDM 指令,C54x 可以使用ADDM 指令把存储器变量直接加上一个立即数,这在某些循环中十分有用。
尽量使用xc 指令代替条件转移指令,使用xc指令比使用条件转移指令节省指令周期,但是只有某些场合适合用xc 代替条件转移指令,有时需要注意潜在的流水线冲突。
又如跳转指令banz,使用banz 比使用一般的跳转指令节省指令周期。移动缓冲区指令delay,可以快速地在两个相邻变量间进行赋值,调整变量存储器的结构以方便的使用delay 指令很重要。尤其是在D4i60_16的最内层循环中使用delay 指令可以大大降低运算量。
2.1.3 调试
ETSI 提供ACELP 算法C 程序的同时也提供了相应的测试序列,只要通过了这些测试序列即可认为程序基本正确。测试文件包括三个:TE1 _46.CHD、TE2_128.PCM、TE3_46.SPE。解码器输入TE1_46.CHD,输出TE2_128.PCM;编码器输入TE2_128.PCM,输出TE3_46.SPE。程序编写完毕后需要分别以TE1_46.CHD 和TE2_128.PCM 作为解码器和编码器的输入,并将经解码和编码后得到的数据分别与TE2_128.PCM 和TE3_46.SPE 比较。
在CCS 里读文件与在VC 中不一样,CCS 里每次只能读出8 位并存放在低8 位,高8 位将置零。因此每一个抽样的16 位数据将读两次,并需要编程将两次读出的8 位合并成一个完整的16 位数据。写文件则相反,首先需要将一个完整的16 位数据分成两个8 位数据,存在两个字的低8 位,再将这两个字写入文件。具体来讲,编码器每次需读出480 字的数据,再将这480 字的数据合并成240 字,即得到240 抽样的16bit 量化数据,以此作为编码器输入。最后得到的输出为138bit,ACELP 算法实际用138字来表示该输出,写文件前需要先将138 字拆成276 字,然后再写入文件。
采用以上步骤,用全汇编实现并优化ACELP 算法,经过统计,运算量和存储量为:编码部分13.3MIPS,解码部分1.2MIPS,程序空间13.8K 字,数据空间13K 字。TMS320VC5410的处理能力达100MIPS,内 部RAM 有64K × 16bit,这 样 采 用TMS320C5410 芯片即可实时实现ACELP 算法。
3 实验结果
图1(a)是长为1 分钟的原始语音波形,图1(b)是编解码器对(a)处理后得到的合成语音。其中横轴表示采样点数,纵轴表示幅度。可以看出,尽管ACELP 编解码是参数编码,而不是波形编码,但ACELP 仍然相当好的从波形上恢复出了原始语音。试听结果也表明,ACELP 算法可以获得很高的合成语音质量。
图1 原始语音与合成语音的波形比较
4 结束语
为实现全数字集群系统TETRA的语音编码方案,需设计DSP 系统优化以实现其核心代数码激励线性预测(ACELP)算法。这是一种CELP 改进算法,在码率降到4kb/s~8kb/s时,仍然能保证很高的语音质量。课题重点研究了这种ACELP 算法在TI DSP TMS320C5410 芯片上实现的软、硬件设计,以及用全汇编实现此算法的一些关键技术,并给出了实际实验结果。实验结果表明,经该方法实现后的ACELP 算法可以获得很高的合成语音质量。
[1]ETSI.Terrestrial Trunked Radio(TETRA);Speech codec for full- rate traffic channel;Part2:TETRA codec[S].ETS 300 395-2.ETSI.February 1998.Second Edition.
[2]王炳锡.语音编码[M].西安:西安电子科技大学出版社,2002.
[3]汪安民.TMS320C54xx DSP 实用技术[M].北京:清华大学出版社,2002.
[4]刘益成.TMS320C54x DSP 应用程序设计与开发[M].北京:北京航空航天大学出版社,2002.