CN1179226A - 基于合成的分析的线性预测语音编码器 - Google Patents
基于合成的分析的线性预测语音编码器 Download PDFInfo
- Publication number
- CN1179226A CN1179226A CN 96192752 CN96192752A CN1179226A CN 1179226 A CN1179226 A CN 1179226A CN 96192752 CN96192752 CN 96192752 CN 96192752 A CN96192752 A CN 96192752A CN 1179226 A CN1179226 A CN 1179226A
- Authority
- CN
- China
- Prior art keywords
- pulse
- excitation
- bit
- vector
- code book
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Pending
Links
Images
Landscapes
- Compression, Expansion, Code Conversion, And Decoders (AREA)
Abstract
描述了一种基于合成的分析的线性预测语音编码器。该语音编码器包括一个合成部分,该部分包括一个混合激励,该混合激励包括一个多脉冲激励(MPE;34)和一个变换二进制脉冲激励(TBPE;36)。
Description
技术领域
该发明涉及一种基于合成的分析的线性预测语音编码器。这种语音编码器使用在例如蜂窝无线电通信系统中。
发明背景
一种基于合成的分析的语音编码器[1]在合成部分包括三个主要组成部分,即:一个线性预测编码(LPC)合成滤波器,一个自适应编码本,和一些种类的固定激励。语音合成是通过用LPC合成滤波器滤波激励向量而产生合成的语音信号来完成的。通过将来自自适应编码本和固定激励的换算后的矢量相加形成了激励失量。基于合成的分析的编码器的分析部分主要包括LPC分析部分和激励分析部分。激励分析是搜索用于激励部分的索引或其它参数,例如,码本的索引,激励的增益参数,或激励脉冲的幅度和位置。
在基于合成的分析的语音编码器中使用的激励结构对于重构语音的质量,搜索的复杂度,以及对比特误差的耐受强度都是很重要的。为了获得高质量,激励必须要充分,即,脉冲样和噪声样的部分都要包括。为了获得低复杂性,激励需要某种程度的结构化,这是因为在结构化的码本中,对激励码的搜索趋向于低复杂性。为了在移动无线电环境中获得高的耐受强度,对激励码的未保护比特的比特误差的敏感度必须低。
为了获得激励的充分性,建议采用所谓的混合激励过程[2~8]。该混合通常包括脉冲和噪声序列。在一开始,语音的塞音和浊音部分需要脉冲样的激励。对于清音声音,需要噪声样的序列。
为了获得低复杂度、结构化的激励,有几种方法已经被建议采用。多脉冲激励(MPE)在[9]中被描述,它包括由位置和幅度描述的脉冲。规则脉冲激励(RPE)在[10]中被描述,它包括一个序列的由网格(第一脉冲的位置)和脉冲幅度描述的规则(等距离)间隔的脉冲。变换二进制脉冲激励(TBPE)在[11~12]中被描述,它包括一个二进制序列的被成形矩阵变换以获得规则间隔脉冲的高斯样序列的脉冲序列。矢量
和激励(VSE)在[13]中被描述,它包括一些被组合成输出矢量的基础矢量。该基础矢量被乘以+1或-1并被加起来以形成激励矢量,对于所有这些结构化的激励,存在低复杂度搜索方法。
为了获得最高有效比特[14]的耐受强度保护,索引分配[15]和相位位置编码[16]被建议采用。
发明概要
该发明的一个目标是在移动无线电环境中既提供高质量(激励充分性),低搜索复杂度又提供高耐受强度的基于合成的分析的线性预测语音编码器。
这个问题以相应于权利要求1的语音编码器来解决。
附图简要描述
该发明,连同它的进一步的目标和有益之处可以通过参考下面与附图一起进行的描述而更好地被理解。
图1是一种典型的基于合成的分析的线性预测编码器的方框图;
图2图解说明了多脉冲激励(MPE)的原理;
图3图解说明了用于多脉冲激励的一种比特分配方案;
图4是图解说明图3中定义的多脉冲激励的比特误差敏感度的图;
图5:a-e图解说明了相位位置编码的多脉冲激励的原理;
图6a图解说明了变换后的二进制脉冲激励的原理(TBPE);
图6b图解说明了用于只有两个脉冲的特殊情形的TBPE;
图7图解说明了一种用于变换二进制脉冲激励的比特分配方案;
图8是图解说明变换二进制脉冲激励的比特误差敏感度的图;
图9图解说明了一种用于相应于该发明的一个优选实施方案中的复合多脉冲和变换二进制脉冲激励的比特分配方案;
图10是图解说明相应于该发明的一个优选实施方案中的复杂多脉冲和变换二进制脉冲激励的比特误差敏感度的图;
图11比较在图4,8和10中被图解说明,并按比特误差敏感度被分类的比特误差敏感度;
图12是相应于该发明的语音编码器的一种优选实施方案的方框图。
优选实施方案的详细描述
下面的描述将参考欧洲GSM系统。但是,该发明的原理被评价为
也可以应用于其它的蜂窝系统。
图1表示一种典型的基于合成的分析的线性预测语音编码器的方框图。该编码器包括垂直的中央虚线左边的合成部分和该线右边的分析部分。合成部分主要包括两部分,即,激励码产生部分10和一个LPC合成滤波器12,激励码产生部分包括一个自适应码本14,一个固定的码本16和一个加法器18。来自自适应码本14的经选择的矢量aI(n)被乘以一个增益因子gI来形成信号P(n)。以同样的方法,来自固定码本16的激励矢量被乘以一个增益因子gI来形成信号f(n)。信号P(n)和信号f(n)在加法器18中相加来形成激励矢量ex(n),该矢量激励LPC合成滤波器12来形成一个估计语音信号矢量_(n)。
在分析部分,在加法器20中,估计矢量_(n)被从实际语音信号矢量s(n)中减去来形成误差信号e(n)。该误差信号被传送到加权滤波器22来形成加权了的误差矢量ew(n)。在单元24中,该加权的误差矢量的分量被平方并求和来形成该加权误差矢量能量的测量值。
通过选择增益gI与来自自适应码本14的矢量的组合及增益gJ与来自给出最小能量值的固定码本16的矢量的组合,最小化单元26最小化该加权的误差矢量,经过滤波器12的滤波后,这最佳的近似了语音信号矢量s(n)。这种优化分为两步,在第一步假设f(n)=0,并判定来自自适应码本14的最佳矢量和相应的gI。在附录中给出了一种用于判定这些参数的算法。当这些参数被判定后,相应于一种类似的算法一个矢量和其相应的增益gJ被从固定码本16中选取出。在这种情况下,自适应码本14的判定后的参数被锁定到他们的判定值。
通过在LPC分析器28中分析语音信号帧来为每一个语音信号帧(160个样本)修改滤小器12的滤波器参数。这种修改用在分析器28和滤波器12之间的虚线连接来标记。另外,在加法器18和自适应码本14之间有一个延迟单元30。按这种方法,自适应码本14被最终选取的激励矢量ex(n)修改。这在子帧基础上完成,其中每一帧被划分成4个子帧(40个样本)。
如同上面注意到的,所使用的固定码本的激励结构对于重构语音的质量,搜索的复杂度和对比特误差的耐受强度都是很重要的。为了获得高质量,激励需要是比较充分的,即,既包括脉冲样的成分,又包括噪声样的成分。为了获得低复杂度,激励需要某种程度的结构化。在结构
化的码本中,对激励码的搜索趋于相对低的复杂度。为了获得在移动无线电环境中的高耐受强度,对于激励码的未保护比特的比特误差敏感度必须低。这对于激励码的受保护(信道编码的)比特不是同样重要的。因此,激励码中的比特误差敏感度应该在受保护和未受保护的比特之间有差别。通常,未受保护类的比特会限制在高BER信道中的性能。
如上所示,高耐受度可通过信道编码而达到,但是对于冗余信道的比特编码而言带宽限制通常使它只能达到60%~80%的总开销。由于通常来说高性能意味着需要约1/2或更多的编码率,因此并非所有的比特都可以受到保护。一些比特对于比特误差有非常强的耐受力,以便无需信道保护即可发送。为了获得非常高的性能,应特别注意下列事实,即未保护的比特通常限制了性能的提高。
已知图2中图解说明的多脉冲激励在更高的比特率下提供高质量。例如,已知每40个样本(或5毫秒)6~8个脉冲就给出很好的质量。图2图解说明了在一个子帧上分布的6个脉冲。激励矢量可以用这些脉冲的位置(在例子中的位置7,9,14,25,29,39)和幅度(在例子中的AMP1-AMP6)来描述。在[9]中描述了找出这些参数的方法。通常,幅度仅仅表示激励矢量的形状。因此,块增益被用来表示该基本矢量形状的放大。图3表示一种典型的包括6个脉冲的多脉冲激励的比特分配格式的例子。在该例中,5比例被用于一个分级量化的块增益(标定脉冲),1个比特用于每个脉冲的符号,两个比特用于每个脉冲幅度的分级量化,(40中取6的组合)=22比特用于使用组合位置编码方案的脉冲位置编码(见[1],第360页和附录)。这些加起来为5+6+12+22=45比特/5毫秒=9kb/s。
已知对于某些比特,多脉冲激励的比特误差敏感度相对要高。这在图4中给予图解说明。该图图解说明了对于激励的每一个比特位置上的100%BER,重构语音的信号噪声比。因此,图3格式中的每一比特位置被分别设置为错误的值,而所有其它的比特位置是正确的。重构信号被拿来与原始信号相比并计算出信号噪声比。这样,图4中每条线的长度表示了重构语音对该比特位置上的误差的敏感度。在图中,高SNR表示低比特误差敏感度。
从图4可以看出,块增益的最有效比特(比特3~5)对比特误差非常敏感,然而块增益的最低比特(比特1-2)却不太敏感。此外,
脉冲(比特28,31,34,37,40和43)的符号对比特误差也很敏感。幅度比特(比例29,30,32,33,35,36,38,39,41,42,44和45)对比特误差不太敏感。取决于使用的位置编码方案,脉冲位置比特(比特6-27)或多或少地对比特误差敏感。对于一种组合的方案,如图3和图4中所示,所有的脉冲位置被联合编码进一个码字。该码字中的比特误差会使所有的脉冲位置移动,使得很多的比特(比特11-27)对比特误差敏感。
降低脉冲位置编码的比特误差敏感度的一个方法是限制脉冲位置。该类型的一种编码方案是相位位置编码[16]。这种脉冲位置编码方案比组合方案具有更高的编码效率,但是,代价是语音质量的某种程度的降低。图5a-e图解说明了相位位置编码的原理。在相位位置编码中,全部的位置被划分成一些子块,图中有4个子块。每个子块包含一些相位,图中有10个相位。一种限制被强加在允许的脉冲位置上。在每个相位上只允许有一个脉冲。这意味着可以通过描述脉冲的相位位置和子块位置对位置编码。相位位置通过使用组合方案被编码。子块位置的最有效比特将具有较高的比特误差敏感度。另一方面,相位位置码字的最低比特将具有更低的比特误差敏感度。
在图5a-e中,假设脉冲由产生图2中脉冲的相同信号产生。在第一步,最强脉冲的位置被判定。这对应于图2中位置7的脉冲。该脉冲在图5a中被表示出。由于脉冲位置7对应于相位7,所有其它子块的相位7都被交叉画出作为其余脉冲的禁止脉冲位置。在图5b中,第二强的脉冲被判定在位置14,它对应于子块2和相位4,这意味着对于其它脉冲,相位4是禁止的。在图5c和5d中,以同样的方法判定了位置25和29的脉冲。下一个要判定的脉冲是对应于图2中位置9上脉冲的脉冲。然而,相位9现在是禁止的。因此,该脉冲必须被定位在仍旧允许的一个相位位置。位置的选取的要求是它会给出目标激励的最好的近似。在该例中,该脉冲被定位在子块1的相位8。注意到由于该脉冲被相对于图2中相应的脉冲(AMP2)而转移,其幅度可能也会改变。最后,对应于图2中位置37上脉冲的其余脉冲被判定。该相位(7)也是禁止的。而在子块4的相位位置6上产生了一个脉冲。该脉冲用图5e中的虚线表示出。
多脉冲激励的一个主要问题是接收端的解码器不知道哪个脉冲是
最重要的。最重要的脉冲也是对比特误差最敏感的脉冲。最重要的脉冲通常首先在编码器的顺序搜索中被发现,并且通常具有最大的幅度。由于位置编码的原因,最敏感的信息被分布在(各)比特上。这提高了所有比特的敏感度大小,而不是象希望的那样,给出不相等的比特误差敏感度。针对这一点的一个解决方法将是把脉冲分成两组。第一组将包括首先发现的脉冲。这使得第一组对比特误差更敏感。此外,把激励编码分成两部分并使用相位位置编码将会使各比特对比特误差敏感的程度更加不等。这种分割方法的一个缺点是第二组的编码效率更低一些。因此,需要对激励第二组的更有效的编码。低的误差敏感度也是需要的,因为这些比特是要被未受保护地发送的候选比特。
已知一种在低比特率时比多脉冲激励提供更高质量的随机码本激励。然而,搜索一个随机码本的复杂度是较高的,使得其实现如果不是不可能也是困难的。存在降低复杂度的技术,例如,移位稀疏码本。然而,即使采用了这些技术,对于更高的比特率,复杂度仍然太高。另外一个缺点是比特误差敏感度。一个单个的比特误差将使得解码器使用一个来自码本的完全不同的随机序列。
已知在相等的比特率下提供近似接近随机激励效率的变换二进制脉冲激励(TBPE)。这种码本的结构使搜索效率非常高。在ROM中的存储需求也很低。变换矩阵被使用以使得激励更象高斯状的(激励)。具有脉冲规则间隔的固有结构使得激励变得稀疏。这种方法的主要缺点是当保持低复杂度搜索方法而码本大小增加时,质量下降了。当比特率提高时,规律间隔限制了性能的提高。TBPE在[11-12]中被详细描述,并参考图6a-b在下面进一步描述。
图6a图解说明了变换二进制脉冲激励背后的原理。二进制脉冲码本可以包括包含例如10个分量的矢量。如图6a中图解说明的一样,每个矢量分量或者向上指向(+1)或者向下指向(-1)。二进制码本包含这些矢量的所有可能的组合。该码本的矢量可以被看作为指向一个10维“立方体”“拐角”的所有矢量的集合。因此,这些矢量尖端均匀分布在一个10维球体的表面上。
此外,TBPE包含一个或多个变换矩阵(图6a中的矩阵1和矩阵2)。这些是存贮在ROM中的预先计算出的矩阵。这些矩阵对存贮在二进制脉冲码本中的矢量进行操作以产生一个变换后的矢量的集合。最
后,变换后的矢量被分布在激励脉冲网格的集合上。结果是用于每个矩阵的4种不同形式的规则间隔的“随机”码本。一个来自其中一个码本(基于网格2)的矢量被作为最终结果表示在图6a中。搜索程序的目标是找到二进制码本的二进制脉冲码本索引,变换矩阵和激励脉冲网格,它们一起给出最小加权的误差。
在图6b中进一步图解说明了矩阵变换步骤。在这种情况下,二进制脉冲码本被假设为仅包括两个位置(这是一种不实际的假设,但是它帮助图解说明了变换步骤之后的原理。)在图6b的左边部分图解说明了二进制脉冲码本的所有可能的二进制矢量。这些矢量可以被看作相等于指向一个二维“立方体”的“拐角”的矢量,该“立方体”是一个正方形,在图6b的左边部分中由点线表示出。这些矢量现在被一个矩阵变换,该矩阵可以是例如一个正交矩阵,它变换整个“立方体”。变换二进制矢量包括单个变换矢量分别在X和Y轴的投影。产生的变换二进制码在图6b的右边部分被图解说明。在变换之后,如同参考图6a解释的一样,变换的矢量被分布在网格集合上。
图7表示了一种典型的TBPE激励的比特分配格式。在该例中使用了一种两级TBPE码本,其中TBPE码本1是一个40个样本的码本,第二级被划分成两个20个样本的TBPE码本2A,2B。码本1使用了10比特用于二进制脉冲码本索引,两比特用于码本1的网格,一比特用于码本1的矩阵,四比特用于码本1的增益。码本2A,2B使用了2×6比特用于二进制脉冲码本索引,2×2比特用于码本网格,2×2比特用于码本矩阵,2×4比特用于码本增益。这加起来为45bits/5ms=9kb/s。
图7定义的变换二进制脉冲激励的比特误差敏感度,在图8中被表示出。TBPE的固有结构给出二进制脉冲码本中的反射编码的索引。这意味着在汉明平均距离上接近的码字在激励矢量距离上也接近。单个比特误差将仅仅改变其中一个规则脉冲的符号。因此,在图8中,索引中的比特位置具有粗略相等的敏感度。(比特1-10用于二进制脉冲码本1,比特18-23用于二进制脉冲码本2A,比特32-37用于二进制脉冲码本2B)。包括索引,网格和矩阵的第一码本具有更高的敏感度。矩阵比特(比特13)表示了在该例中一个非常高的敏感度。此外,第一码本的码本增益(比特14-17)表示了比第二码本增益高(比特
28-31,42-45)的敏感度。一个问题是该敏感度分布在各比特之上。该敏感度通常低于多脉冲激励比特的敏感度,但是仅仅是微弱不等的误差敏感度。然而,该结构结合了固有索引分配和低复杂度。这使得TBPE成为替换上面讨论的多脉冲激励第二部分的一个强有力的候选者。
该发明建议的结构是使用少量多脉冲和一种TBPE码本的混合激励。脉冲的位置最好以一种受限位置编码方案被编码,例如上面讨论的相位位置编码。使用脉冲和变换二进制脉冲(噪声)序列的混合激励改进了质量。MPE和TBPE搜索都是低复杂度方案。多脉冲比特和TBPE的混合表示出了不相等程度很强的误差敏感度,在一些比特未受保护的情况下,这适合了一种不等误差保护方案。
图9图解说明了该发明的一个优选实施方案中比特分配格式的例子。在该例中,有3个多脉冲和一个具有4个网格和两个矩阵的13比特索引(13个二进制脉冲)的TBPE码本。相位位置编码通过使用十个子块和四个相位而被执行。这给出用于子块位置的3×2log(10)=10比特,用于相位码字的(4中取3的组合)=2比特,用于脉冲符号的3×1比特,用于脉冲幅度的3×2比特,用于块增益的四比特,用于二进制脉冲码本索引的13比特,用于网格的2比特,用于矩阵的1比特和用于码本增益的4比特。所有这些加起来为10+2+3+6+4+13+2+1+4=45bits/5ms=9kb/s。
图10图解说明了相应于该发明的优选实施方案的混合激励的比特敏感度。图10中明显的是少数的多脉冲(比特1-21)比TBPE码本索引(比特26-24)对比特误差更敏感。相位位置编码使得用于脉冲定位的一些比特对比特误差更不敏感(子块位置的比特1-3,相位码字的比特11-12)。这些脉冲幅度(比特14-15,17-18,20-21)的敏感度小于其符号(比特13,16,19)。TBPE索引中的比特(比特26-38)在敏感度上相等,并且与脉冲符号和位置相比,敏感度非常低。多脉冲块增益的一些比特(比特24-25)具有更高的敏感度。用于变换矩阵的比特(比特41)也是敏感的。
在该应用中讨论的并在图4,8和10中图解说明的三种方案就误差敏感度在图11中被比较,在图11中,每个方案的比特被按照比特误差敏感度顺序,由最高敏感度到最低敏感度而分类。
从图11中可以看出,多脉冲激励(MPE)和混合激励(MPE&TBPE)具有最强的误差敏感度不相等性。TBPE激励只有最平坦的敏感度,并且该敏感度通常低于MPE激励的敏感度,混合激励通常具有比多脉冲激励更低的敏感度,这使得混合激励耐受度更高。混合激励也具有一些非常敏感的比特(比特1-12)和一些不敏感比特(比特25-45),这使得该激励对于不相等误差保护变得完善。由于混合激励不敏感比特数大于多脉冲激励的,未受保护类比特的性能在低质量信道中会更好。
图12图解说明了相应于该发明的语音编码器的一个优选实施方案,图1中的语音编码器和图12中的语音编码器的基本的差别是图1中的固定码本被混合激励产生器32所替代,该产生器包括多脉冲激励(MPE)产生器34和变换二进制脉冲激励(TBPE)产生器36。在图12中,对应的块增益分别由gM和gT表示。来自产生器34,36的激励在加法器18中相加,并且混合激励被加到加法器18中的自适应码本激励上。
下面给出了使用在相应于该发明的混合激励编码器结构中的算法的一个例子。该算法包括在语音编码器中有关的所有部分。该算法包括六个主要部分。构成混合激励的MPE和TBPE部分被展开以表示混合激励结构分析的内容。基于一帧的部分,例如,对于每个160个样本的帧,是LPC分析部分,该部分计算并量化短时合成滤波器。剩余的五个部分是基于子帧的,例如,它们为每个40样本的子帧所使用。这些中的第一个是子帧预处理,即参数提取;第二个是长时分析或自适应码本分析;第三个是MPE分析;第四个是TBPE分析,第五个是状态更改。示例算法:LPC分析:
对每一子帧(1-4),循环
子帧预处理
LTP分析(自适应码书搜索)
多脉冲激励(MPE)
计算加权滤波器的脉冲响应
计算脉冲响应的自相关函数
计算LTP分析后加权的残差与脉冲响应的互相关函数
搜索MPE位置和幅度
量化幅度和块增益
创建新的MPE矢量
构成位置码字
构成MPE分析后新的加权残差
变换的二进制脉冲激励(TBPE)
计算加权滤波器的脉冲响应
计算MPE分析后加权残差与脉冲响应的互相关函数
对每一矩阵,循环
对每一网格,循环
计算矩阵互相关函数
根据互相关函数的符号来近似脉冲
形成加权的TBPE新方法并比较
形成TBPE码字
量化TBPE增益
形成TBPE新方法矢量状态更改。
该算法的详细描述可以在附带的C++程序列表中找到。
该技术领域的技术人员会明白在不偏离附加的权利要求定义的该发明的思想和范围的情况下,可以对该发明做各种的修正和改变。
附录
该附录总结了一种用于在穷举搜索中判定最佳自适应译码本索引i和相应的增益gi的算法,图1中也表示出了该信号。
ex(n)=p(n) 激励矢量 (f(n)=0)
p(n)=gi·ai(n) 换算后的自适应译码本
矢量
_(n)=h(n)*p(n) 合成的语音
(*=卷积)
e(n) =s(n)-_(n) 误差矢量
ew(n)=w(n)*(s(n)-_(n)) 加权的误差
E =∑[ew(n)]2 n=0..N-1 平方后的加权误差
N =40(for example) 矢量长度
sw(n)=w(n)*s(n) 加权语音
hw(n)=w(n)*h(n) 合成滤波器的加权脉冲
响应 在自适应译码本中搜索最佳索引 牵引i的增益
C++ PROGRAM LISTINGS F_SpeMain.cc /* * 类 F_SpeMain * * 用于语音编码器的主类 * * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB * */ #include ″F_SpeMain.hh″ #include <iostream.h> F_SpeMain∷F_SpeMain(const FloatVec& inTemp): F_hugeSpeechFrame(F_hugeFrameLength), F_lspPrev(F_nrCoeff), F_ltpHistory(F_historyLength), F_weightFilterRingState(F_nrCoeff) { for (int i=0;i<F_frameLength;i++) F_hugeSpeechFrame[i]=0.0; /* * insert first ′delay′samples to be compatible with prestudy * coder */ for (i=F_frameLength;i<F_hugeFrameLength;i++) F_hugeSpeechFrame[i]=inTemp[i-F_frameLength]; for (i=0;i<F_nrCoeff;i++) F_lspPrev[i]=F_lspInit[i]; for (i=0;i<F_historyLength;i++) F_ltpHistory[i]=0.0; for (i=0;i<F_nrCoeff;i++) F_weightFilterRingState[i]=0.0; } void F_SpeMain∷main(const FloatVec& F_speechFrame, ShortVec& F_analysisData) { /* 局域变量 */ FloatVec F_lspCurr(F_nrCoeff); ShortVec F_lspVQCodes(F_nLspTables); Float F_energy; Shortint F_energyCode; ShortVec F_ltpLagCodes(F_nrOfSubframes); ShortVec F_ltpGainCodes(F_nrOfSubframes); ShortVec F_mpeBlockMaxCodes(F_nrOfSubframes); ShortVec F_mpeAmpCodes(F_nrOfSubframes); ShortVec F_mpeSignCodes(F_nrOfSubframes); ShortVec F_mpePositionCodes(F_nrOfSubframes); ShortVec F_tbpeGainCodes(F_nrOfSubframes); <dp n="d12"/> ShortVec F_tbpeGridCodes(F_nrOfSubframes); ShortVec F_tbpeMatrixCodes(F_nrOfSubframes); ShortVec F_tbpeIndexCodes(F_nrOfSubframes); F_speFrame.main (F_speechFrame, /* in */ F_lspPrev, /* in */ F_hugeSpeechFrame, /* in/out */ F_lspCurr, /* out */ F_lspVQCodes, /* out */ F_energy, /* out */ F_energyCode) ; /* out */ for (int F_subframeNr=0;F_subframeNr<F_nrOfSubframes; F_subframeNr++) { /*子帧局域变量*/ Float F_excNormFactor; FloatVec F_wCoeff(F_nrCoeff); FloatVec F_wSpeechSubframe(F_subframeLength); FloatVec F_ltpExcitation(F_subframeLength); FloatVec F_wLtpResidual(F_subframeLength); FloatVec F_mpeInnovation(F_subframeLength); FloatVec F_wMpeResidual(F_subframeLength); FloatVec F_tbpeInnovation(F_subframeLength); F_speSubPre.main(F_hugeSpeechFrame, /* in * / F_subframeNr, /* in */ F_lspCurr, /* in * / F_lspPrev, /* in */ F_energy, /* in */ F_weightFilterRingState, /* in */ F_excNormFactor, /* out */ F_wCoeff, /* out */ F_wSpeechSubframe); /* out */ F_speSubLtp.main(F_wSpeechSubframe, /* in */ F_wCoeff, /* in */ F_ltpHistory, /* in */ F_wLtpResidual, /* out */ F_ltpExcitation, /* out */ F_ltpLagCodes[F_subframeNr], /* out */ F_ltpGainCodes[F_subframeNr]); /* out */ F_speSubMpe.main(F_wCoeff, /* in */ F_excNormFactor, /* in */ F_wLtpResidual, /* in */ F_mpeInnovation, /* out */ F_mpePositionCodes[F_subframeNr], /* out */ F_mpeAmpCodes[F_subframeNr], /* out */ F_mpeSignCodes[F_subframeNr], /* out */ F_mpeBlockMaxCodes[F_subframeNr], /* out */ F_wMpeResidual); /* out */ <dp n="d13"/> F_speSubTbpe.main( F_wMpeResidual, /* in */ F_wCoeff, /* in */ F_excNormFactor, /* in */ F_tbpeInnovation, /* out */ F_tbpeGainCodes[F_subframeNr], /* out */ F_tbpeIndexCodes[F_subframeNr], /* out */ F_tbpeGridCodes[F_subframeNr], /* out */ F_tbpeMatrixCodes[F_subframeNr]); /* out */ F_speSubPost.main(F_ltpExcitation, /* in */ F_tbpeInnovation, /* in */ F_mpeInnovation, /* in */ F_wCoeff, /* in */ F_ltpHistory, /* in/out */ F_weightFilterRingState); /* out */ } F_spePost.main(F_lspCurr, /* in */ F_energyCode, /* in */ F_lspVQCodes, /* in */ F_ltpGainCodes, /* in */ F_ltpLagCodes, /* in */ F_mpeBlockMaxCodes, /* in */ F_meAmpCodes, /* in */ F_mpeSignCodes, /* in */ F_mePositionCodes, /* in */ F_tbpeGainCodes, /* in */ F_tbpeIndexCodes, /* in */ F_tbpeMatrixCodes, /* in */ F_tbpeGridCodes, /* in */ F_lspPrev, /* out */ F_analysisData); /* out */ } <dp n="d14"/> F_SpeSubMpe.cc /* * 类 F_SpeSubMpe * 多脉冲新方法分析 * * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB * */ #include ″F_SpeSubMpe.hh″ #include ″ShortVec.hh″ #include <iostream.h> #include <stdlib.h> #include <math.h> F_SpeSubMpe∷F_SpeSubMpe() { } void F_SpeSubMpe∷main(const FloatVec& F_wCoeff, const Float F_excNormFactor, const FloatVec& F_wLtpResidual, FloatVec& F_mpeInnoVation, Shortint& F_mpePositionCode, Shortint& F_mpeAmpCode, Shortint& F_mpeSignCode, Shortint& F_mpeBlockMaxCode, FloatVec& F_wMpeResidual) { /*暂时变量*/ FloatVec F_impResp(F_mpeTruncLen); FloatVec F_autoCorr(F_subframeLength); FloatVec F_crossCorr(F_subframeLength); FloatVec F_crossCorrUpd(F_subframeLength); FloatVec F_pulseAmp(F_nMpePulses); ShortVec F_posTaken(F_subframeLength); ShortVec F_mpePosVector(F_nMpePulses); ShortVec F_mpeAmpVector(F_nMpePulses); ShortVec F_mpeSignVector(F_nMpePulses); /*计算脉冲响应*/ F_calcImpResp( F_wCoeff, F_impResp); /*计算自相关*/ F_autoCorrelate( F_impResp, F_autoCorr); /*计算互相关*/ F_crossCorrelate( F_impResp, F_wLtpResidual, F_crossCorr); /*初始化并搜索第一脉冲*/ F_searchInit( F_crossCorr, F_autoCorr, <dp n="d15"/> F_crossCorrUpd, F_mpePosVector, F_pulseAmp, F_posTaken); /*搜索其余脉冲*/ F_searchRest( F_autoCorr, F_crossCorr, F_crossCorrUpd, F_mpeposVector, F_pulseAmp, F_posTaken); /*量化blockmax和脉冲幅度*/ F_openLoopQuantize( F_excNormFactor, F_pulseAmp, F_mpeAmpVector, F_mpeSignVector, F_mpeBlockMaxCode); /*构造改进矢量*/ F_makeInnVector( F_pulseAmp, F_mpePosVector, F_mpeInnovation); /*排序脉冲位置*/ F_orderPositions( F_mpePosVector, F_mpeAmpVector, F_mpeSignVector); /*构造码字位置*/ F_makeCodeWords( F_mpePosVector, F_mpePositionCode, F_mpeAmpVector, F_mpeAmpCode, F_mpeSignVector, F_mpeSignCode); /*构造新的加权残余*/ F_makeMpeResidual( F_mpeInnovation, F_wCoeff, F_wLtpResidual, F_wMpeResidual); } Shortint_F SpeSubMpe∷F_maxMagIndex(const FloatVec& F_corrVec, const ShortVec& F_posTaken) { /*寻找矢量最大幅度的索引,不包括 使用过的位置*/ /*暂时矢量*/ <dp n="d16"/> Float max; Float temp; int maxI; /* 移位到可能位置 */ for (int i=0;i<F_subframeLength && F_posTaken[i];i++); max=fabs(F_corrVec[i]); maxI=i; while(i<F_subframeLength) { temp=fabs(F_corrVec[i]); if(!F_posTaken[i] && temp>max) { max=temp; maxI=i; } i++; } return maxI; } void F_SpeSubMpe∷F_solveNewAmps(const FloatVec& F_a, const FloatVec& F_c, const Shortint F_nPulse, FloatVec& F_b) { /* 临时变量* / Float den; switch (F_nPulse) { case 1: /* 这种切换在该应用中是过时的*/ cerr <<″F_SpeSubMpe∷F_solveNewAmps case l should never occur″<< endl; exit(-1); case 2: den=F_a[0]*F_a[0]-F_a[1]*F_a[1]; if (den==0.0) { cerr <<″MPE singular matrix″<<endl; break; } Float denInv=1.0/den; F_b[0]=(F_c[0]*F_a[0]-F_c[1]*F_a[1]) * denInv; F_b[1]=(F_c[1]*F_a[0]-F_c[0]*F_a[1]) * denInv; break; case 3: /* Kramers 法则 */ den=F_a[0]*F_a[0]*F_a[0]+F_a[1]*F_a[3]*F_a[2]+ F_a[2]*F_a[3]*F_a[3]-F_a[1]*F_a[1]*F_a[0]- F_a[0]*F_a[3]*F_a[3]-F_a[2]*F_a[0]*F_a[2]; if (den==0.0) { <dp n="d17"/> cerr<<″MPE singular matrix″<<endl; break; } denInv=1.0/den; F_b[0]=(F_c[0]*F_a[0]*F_a[0]+F_c[1]*F_a[3]*F_a[2]+ F_c[2]*F_a[1]*F_a[3]-F_c[1]*F_a[1]*F_a[0]- F_c[0]*F_a[3]*F_a[3]-F_c[2]*F_a[0]*F_a[2])* denInv; F_b[1]={F_a[0]*F_c[1]*F_a[0]+F_a[1]*F_c[2]*F_a[2]+ F_a[2]*F_c[0]*F_a[3]-F_a[1]*F_c[0]*F_a[0]- F_a[0]*F_c[2]*F_a[3]-F_a[2]*F_c[1]*F_a[2])* denInv; F_b[2]=(F_a[0]*F_a[0]*F_c[2]+F_a[1]*F_a[3]*F_c[0]+ F_a[2]*F_a[1]*F_c[1]-F a[1]*F_a[1]*F_c[2]- F_a[0]*F_a[3]*F_c[1]-F_a[2]*F_a[0]*F_c[0])* denInv; break; } } void F_SpeSubMpe∷F_updateCrossCorr(const FloatVec& F_autoCorr, const Shortint F_pos, const Float F_gain, FloatVec& F_crossCorrUpd) { /*临时变量*/ int 1; int temp; /*修改互相关矢量*/ temp=-F_mpeTruncLen+F_pos+1; if (temp<0) temp=0; for (i=temp;i<F_pos;i++) F_crossCorrUpd[i]=F_crossCorrUpd[i] F_gain*F autoCorr[F_pos-i]; temp=F_pos+F_mpeTruncLen; if (temp>F_subframeLength) temp=F_subframeLength; for (i=F_pos;i<temp;i++) F_crossCorrUpd[i]=F_crossCorrUpd[i]- F_gain*F_autoCorr[i-F_pos]; } void F_SpeSubMpe∷F_calcImpResp(const FloatVec& F_wCoeff, FloatVec& F_impResp) { /*临时变量*/ FloatVec state(F_nrCoeff); int i,m; Float signal; /*计算脉冲响应*/ for (i=0;i<F_nrCoeff;1++) <dp n="d18"/> state[i]=0; signal=1.0; for (i=0;i<F_mpeTruncLen;i++) { for (m=F_nrCoeff-1;m>0;m--) { signal-=F_wCoeff[m]*state[m]; state[m]=state[m-1]; } signal-=F_wCoeff[0]*state[0]; state[0]=signal; F_impResp[i]=signal; signal=0; } } void F_SpeSubMpe∷F_autoCorrelate(const FloatVec& F_impResp, FloatVec& F_autoCorr) { /*临时变量*/ int i,j; /*计算自相关矢量*/ for (i=0;i<F_mpeTruncLen;i++) { F_autoCorr[i]=0.0; for(j=i;j<F_mpeTruncLen;j++) F_autoCorr[i]=F_autoCorr[i]+ F_impResp[j]*F_impResp[j-i]; }; for (i=F_mpeTruncLen;i<F_subframeLength;i++) F_autoCorr[i]=0.0; } void F_SpeSubMpe∷F_crossCorrelate{ const FloatVec& F_impResp, const FloatVec& F_wSpeechSubframe, FloatVec& F_crossCorr) { /*临时变量*/ int i,j,lastpos; /* calculate crosscorrelation vector */ for (i=0;i<F_subframeLength;i++){ F_crossCorr[i]=0.0; lastpos=i+F_mpeTruncLen; if (lastpos>F_subframeLength) lastpos=F_subframeLength; for (j=i;j<lastpos;j++) F_crossCorr[i]= F_crossCorr[i]+F_wSpeechSubframe[j]*F_impResp[j-i]; } } <dp n="d19"/> void F_SpeSubMpe∷F_searchInit(const FloatVec& F_crossCorr, const FloatVec& F_autoCorr, FloatVec& F_crossCorrUpd, ShortVec& F_mpePosition, FloatVec& F_pulseAmp, ShortVec& F_posTaken) { /*临时变量*/ int pos,i; /*搜索初始化*/ for (i=0;i<F_nMpePulses;i++) F_pulseAmp[i]=0.0; for (i=0;i<F_subframeLength;i++) F_posTaken[i]=0; /*获取第一位置*/ pos=F_maxMagIndex(F_crossCorr,F_posTaken); F_mpePosition[0]=pos; F_posTaken[pos]=pos+1; for (i=0;i<F_subframeLength;i++) F_crossCorrUpd[i]=F_crossCorr[i]; F_pulseAmp[0]=F_crossCorr[pos]/F_autoCorr[0]; F_updateCrossCorr(F_autoCorr, pos, F_pulseAmp[0], F_crossCorrUpd); } void F_SpeSubMpe∷F_searchRest(const FloatVec& F_autoCorr, const FloatVec& F_crossCorr, FloatVec& F_crossCorrUpd, ShortVec& F_mpePosVector, FloatVec& F_pulseAmp, ShortVec& F_posTaken) { /*搜索其余脉冲(方法2)*/ /*临时变量*/ FloatVec F_corrTerms(F_nMpePulses+1); FloatVec F_crossCorrTerms(F_nMpePulses); int pulse; int i,j; int pos; for (pulse=1;pulse<F_nMpePulses;pulse++) { /*获取具有最大值的位置*/ pos=F_maxMagIndex(F_crossCorrUpd,F_posTaken); F_mpePosVector[pulse]=pos; F_posTaken[pos]=pos+1; <dp n="d20"/> /*用自相关建立矢量*/ F_corrTerms[0]=F_autoCorr[0]; for (i=0;i<pulse+1;i++) for (j=0;j<i;j++) F_corrTerms[i+j]= F_autoCorr[abs(F_mpePosVector[i]- F_mpePosVector[j])]; /*用互相关建立矢量*/ for (i=0;i<pulse+1;i++) F_crossCorrTerms[i]=F_crossCorr[F_mpePosVector[i]]; /*解出新的最佳幅度*/ F_solveNewAmps(F_corrTerms, F_crossCorrTerms, pulse+1,F_pulseAmp); if (pulse!=(F_nMpePulses-1)) { for (i=0;i<F_subframeLength;i++) F_crossCorrUpd[i]=F_crossCorr[i]; for (i=0;i<=pulse;i++) F_updateCrossCorr(F_autoCorr, F_mpePosVector[i], F_pulseAmp[i], F_crossCorrUpd); } } } void F_SpeSubMpe∷F_openLoopQuantize(const Float& F_excNormFactor, FloatVec& F_pulseAmp, ShortVec& F_mpeAmpVector, ShortVec& F_mpeSignVector, Shortint& F_mpeBlockMaxCode) { /*临时变量*/ Float blockMax; Float idealBlockMax; Float blockMaxNorm; Float normPulseAmp; int pulse; Float temp; /*获取blockmax值? blockMax=0.0; for (pulse=0;pulse<F_nMpePulses,pulse++) { temp=fabs(F_pulseAmp[pulse]); if (temp>blockMax) blockMax=temp; } idealBlockMax=blockMax; /*量化blockmax*/ blockMaxNorm=blockMax/F_excNormFactor; <dp n="d21"/> if (blockMaxNorm> F_mpeBlockMaxQLimits[F_nMpeBlockMaxQLevels-2]) F_mpeBlockMaxCode=F_nMpeBlockMaxQLevels-1; else { F_mpeBlockMaxCode=0; while (blockMaxNorm> F_mpeBlockMaxQLimits[F_mpeBlockMaxCode]) F_mpeBlockMaxCode++; } blockMax=F_mpBlockMaxQLevels[F_mpeBlockMaxCode] * F_excNormFactor; /*量化脉冲幅度*/ for (pulse=0;pulse<F_nMpePulses;pulse++) { normPulseAmp=fabs(F_pulseAmp[pulse])/blockMax; if (normPulseAmp>F_mpeAmpQLimits[F_nMpeAmpQLevels-2]) F_mpeAmpVector[pulse]=F_nMpeAmpQLevels-1; else { F_mpeAmpVector[pulse]=0; while (normPulseAmp > F_mpeAmpQLimits[F_mpeAmpVector[pulse]]) F_mpeAmpVector[pulse]++; } if (F_pulseAmp[pulse]>0.0) { F_mpeSignVector[pulse]=1; F_pulseAmp[pulse]= F_mpeAmpQLevels[F_mpeAmpVector[pulse]] * blockMax; } else { F_mpeSignVector[pulse]=0; F_pulseAmp[pulse]=-1.0 * F_mpeAmpQLevels[F_mpeAmpVector[pulse]] * blockMax; } } } void F_SpeSubMpe∷F_makeInnVector(const FloatVec& F_pulseAmp, const ShortVec& F_mpePosVector, FloatVec& F_mpeInnovation) { /*临时变量*/ int i; /*创建改进矢量*/ for (i=0;i<F_subframeLength;i++) F_mpeInnovation[i]=0.0; for (i=0;i<F_nMpePulses;i++) F_mpeInnovation[F_mpePosVector[i]]=F_pulseAmp[i]; } void F_SpeSubMpe∷F_orderPositions(ShortVec& F_mpePosVector, ShortVec& F_mpeAmpVector, ShortVec& F_mpeSignVector) { <dp n="d22"/> /*临时矢量*/ ShortVec tempPosVector(F_nMpePulses); ShortVec tempAmpVector(F_nMpePulses); ShortVec tempSignVector(F_nMpePulses); int maxVal; int maxI=0; int i,j; /*创建临时矢量*/ for (i=0;i<F_nMpePulses;i++} { tempPosVector[i]=F_mpePosVector[i]; tempAmpVector[i]=F_mpeAmpVector[i]; tempSignVector[i]=F_mpeSignVector[i]; } /* 固定排序位置按降序排序*/ for (i=0;i<F_nMpePulses;i++) { maxVal=-1; for (j=0;j<F_nMpePulses;j++) { if (tempPosVector[j]>maxVal) { maxVal=tempPosVector[j]; maxI=j; } } /*从搜索中排除己找到的矢量*/ tempPosVector[maxI]=-10; /*order pulses*/ F_mpePosVector[i]=maxVal; F_mpeAmpVector[i]=tempAmpVector[maxI]; F_mpeSignVector[i]=tempSignVector[maxI]; } } void F_SpeSubMpe∷F_makeCodeWords(const ShortVec& F_mpePosVector, Shortint& F_mpePositionCode, const ShortVec& F_mpeAmpVector, Shortint& F_mpeAmpCode, const ShortVec& F_mpeSignVector, Short int& F_mpeSignCode) { /*临时变量*/ int_i; /*将位置矢量编码为14比特*/ F_mpePositionCode=0; for (i=0;i<F_nMpePulses;i++) F_mpePositionCode=F_mpePositionCode + F_mpeCombTable[(F_nMpePulses - i - 1)*F_subframeLength+ F_mpePosVector[i]]; F_mpeSignCode=0; for (i=0;i<F_nMpePulses;i++) F_mpeSignCode|=(F_mpeSignVector[i]<<i); F_mpeAmpCode=0; for (i=0;i<F_nMpePulses;1++) <dp n="d23"/> F_mpeAmpCode |=(F_mpeAmpVector[i]<< i*F_mpeAmpBits); } void F_SpeSubMpe∷F_makeMpeResidual( const FloatVec& F_mpeInnovation, const FloatVec& F_wCoeff, const FloatVec& F_wLtpResidual, FloatVec& F_wMpeResidual) { /*临时变量*/ int i,m; Float signal; FloatVec state(F_nrCoeff); /*置0*/ for (i=0;i<F_nrCoeff;i++) state[i]=0.0; /*为后续TBPE搜索计算新目标*/ s for (i=0;i<F subframeLength;i++) { signal=F_mpeInnovation[i]; for (m=F_nrCoeff-1;m>0;m--) { signal-=F_wCoeff[m]*state[m]; state[m]=state[m-1]; } signal-=F_wCoeff[0]*state[0]; state[0]=signal; F_wMpeResidual[i]=F_wLtpResidual[i]-signal; } } <dp n="d24"/> F_SpeSubTbpe.cc /* * class F_SpeSubTbpe * 变换二进制脉冲激励的码本 * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB */ #include ″F_SpeSubTbpe.hh″ #include <iostream.h> F_SpeSubTbpe∷F_SpeSubTbpe() { } void F_SpeSubTbpe∷main(const FloatVec& F_wMpeResidual, const FloatVec& F_wCoeff, const Float F_excNormFactor, FloatVec& F_tbpeInnovation, Shortint& F_tbpeGainCode, Shortint& F_tbpeIndexCode, Shortint& F_tbpeGridCode, Shortint& F_tbpeMatrixCode) { Float F_gain=F_search(F_wMpeResidual, F_wCoeff, F_tbpeInnovation, F_tbpeIndexCode, F_tbpeGridCode, F_tbpeMatrixCode); Float F_normGain=F_gain/F_excNormFactor; F tbpeGainCode=F_quantize(F_normGain); Float F_tbpeGain=F_excNormFactor * F_tbpeGainQuantTable[F_tbpeGainCode]; for(Shortint i=0;i<F_subframeLength;i++) F_tbpeInnovation[i]=F_tbpeInnovation[i] * F_tbpeGain; } void F_SpeSubTbpe∷F_crossCorr(const FloatVec& v1, const FloatVec& v2, FloatVec& F_corr) { for (Shortint i=0;i<F_subframeLangth;i++) { Float acc=0.0; for (Shortint j=i;j<F_subframeLength;j++) acc +=v1[j] *v2[j-i]; F_corr[i]=acc; } } <dp n="d25"/> void F_SpeSubTbpe∷F_crossCorrofTransfMatrix( const FloatVec& v1, const Shortint grid, const Shortint matrix, FloatVec& F_crossCorr) { for (Shortint m=0;m<F_nrTbpePulses;m++) { Float acc=0.0; for (Shortint n=0;n<F_nrTbpePulses;n++) acc += v1[grid +n * F_tbpeGridSpace] * F_tbpeTransfTable[(m+matrix * F_nrTbpePulses) * F_nrTbpePulses + n]; F_crossCorr[m] = acc; } } void F_SpeSubTbpe∷F_zeroStateFilter(const FloatVec& in, const FloatVec& F_denCoeff, FloatVec& out) { /*零状态搜索滤波器*/ FloatVec F_state(F_nrCoeff); for (int i=0;i<F_nrCoeff;i++) F_state[i]=0.0; for (i=0;i<F_subframeLength;i++) { Float signal=in[i]; for (Shortint m=F_nrCoeff-1;m>0;m--) { signal-=F_denCoeff[m] * F_state[m]; F_state[m]=F_state[m-1]; } signal-=F_denCoeff[0] * F_state[0]; F_state[0]=signal; out[i]=signal; } } void F_SpeSubTbpe∷F_construct(const Shortint index, const Shortint grid, const Shortint matrix, FloatVec& vec) { /*零结果矢量*/ for (int i=0;i<F_subframeLength;i++) vec[i]=0.0; for (Shortint j=0;j<F_nrTbpePulses;j++) { Float sum=0.0; Shortint itemp=index; for (Shortint i=0;i<F_nrTbpePulses;i++) { if (itemp & 1) sum +=F_tbpeTransfTable[(i+matrix*F_nrTbpePulses) * F_nrTbpePulses +j]; else <dp n="d26"/> sum-=F_tbpeTransfTable[(i + matrix*F_nrTbpePulses) * F_nrTbpePulses + j]; itemp >>=1; } vec[grid + j * F_tbpeGridSpace]=sum; } } Float F_SpeSubTbpe∷F_search(const FloatVec& F_wMpeResidual, const FloatVec& F_wCoeff, FloatVec& F_tbpeInnovation, Shortint& F_tbpeIndexCode, Shortint& F_tbpeGridCode, Shortint& F_tbpeMatrixCode) { FloatVec F_filtered(F_subframeLength); /*计算加权滤波器脉冲响应*/ FloatVec F_ires(F_subframeLength); F_ires[0]=1.0; for (int i=1;i<F_subframeLength;i++) F_ires[i]=0.0; F_zeroStateFilter(F_ires,F_wCoeff,F_ires); /*计算在脉冲响应和语音之间的相关性*/ and speech */ FloatVec F_corrIS(F_subframeLength); F_crossCorr(F_wMpeResidual,F_ires,F_corrIS); /*测试所有的栅格和矩阵*/ Float F_bestCorr=0.0; Float F_bestPower=1.0; F_tbpeIndexCode=0; F_tbpeGridCode=0; F_tbpeMatrixCode=0; for (int F_matrix=0;F_matrix<F_nrTbpeMatrices;F_matrix++) for (int F_grid=0;F_grid<F_nrTbpeGrids;F_grid++) { /*计算互相关*/ FloatVec F_cross(F_nrTbpePulses); F_crossCorrOfTransfMatrix(F_corrIS, F_grid, F_matrix, F_cross); /*根据互相关符号近似脉冲*/ Shortint F_lndex = 0; FloatVec F_signVector(F_nrTbpePulses); for (i=0;i<F_nrTbpePulses;i++) F_signVector[i]=-1.0; for (i=0;i<F_nrTbpePulses,i++) if (F_cross[i]>0) { F_signVector[i]=1; F_index|=(1<<i); } <dp n="d27"/> /*构造滤波后的激励矢量*/ F_construct(F_index,F_grid,F_matrix,F_tbpeInnovation); F_zeroStateFilter(F_tbpeInnovation, F_wCoeff,F_filtered); /* 计算功率和相关性*/ Float power=0; for (Shortint j=0;j<F_subframeLength;j++) power+=F_filtered[j] * F_filtered[j]; Float corr=0; for (j=0;j<F_nrTbpePulses;j++) corr+=F_cross[j] * F_signVector[j]; /*做出决定*/ if (corr*corr*F_bestPower>F_bestCorr*F_bestCorr* power) { F_bestCorr=corr; F_bestPower=power; F_tbpeIndexCode=F_index; F_tbpeGridCode=F_grid; F_tbpeMatrixCode=F_matrix; } } F_construct(F_tbpeIndexCode,F_tbpeGridCode,F_tbpeMatrixCode, F_tbpeInnovation); return F_bestCorr/F_bestPower; } Shortint F_SpeSubTbpe∷F_quantize(const Float value) { Shortint i=0; if (value>F_tbpeGainLimitTable[F_nrTbpeCbGainLevel - 2]) i=F_nrTbpeCbGainLevel - 1; else while (value > F_tbpeGainLimitTable[i]) i++; return i; } <dp n="d28"/> F_SpeMain.hh /* * class F_SpeMain * * 语音编码器的主类 * * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB * */ #ifndef F_SpeMain_h #define F_SpeMain_h #include″F_speDef.hh″ #include″F_SpeFrame.hh″ #include″F_SpeSubPre.hh″ #include″F_SpeSubLtp.hh″ #include″F_SpeSubMpe.hh″ #include″F-SpeSubTbpe.hh″ #include″F_SpeSubPost.hh″ #include″F_SpePost.hh″ class F_SpeMain { public: F_SpeMain( const FloatVec& inTemp); /* 入,第一样本*/ /* 构造函数*/ void main( const FloatVec& F_speechFrame,/* 入,16比特语音帧*/ ShortVec& F_analysisData); /* 出,分析数据帧*/ /* 主程序*/ private: F_SpeFrame F_speFrame; /*帧处理*/ F_SpeSubPre F_sPeSubPre; /*子帧预处理*/ F_SpeSubLtp F_speSubLtp; /*LTP分析*/ F_SpeSubMpe F_speSubMpe; /*MPE分析*/ F_SpeSubTbpe F_speSubTbpe; /*IBPE分析有*/ F_SpeSubPost F_speSubPost; /*子帧后处理*/ F_SpePost F_spePost; /*后处理*/ FloatVec F_hugeSpeechFrame; /*大语音帧*/ FloatVec F_lspPrev; /*以前LSP参数*/ FloatVec F_ltpHistory; /*LTP历史*/ FloatVec F_weightFilterRingState; /*加权滤波器*/ /*环状态*/ }; #endif <dp n="d29"/> F_SpeSubMpe.hh /* * class F_SpeSubMpe * * 多脉冲改进分析 * * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB * */ #ifndef F_SpeSubMpe_h #define F_SpeSubMpe_h #include ″F_speDef.hh″ class F_SpeSubMpe { public: F_SpeSubMpe(); /*构造函数*/ void main( const FloatVec& F_wCoeff, /* in */ const Float F_excNormfactor, /* in */ const FloatVec& F_wLtpResidual, /* in */ FloatVec& F_mpeInnovation, /* out */ Shortint& F_mpePositionCode, /* out */ Shortint& F_mpeAmpCode, /* out */ Shortint& F_mpeSignCode, /* out */ Shortint& F_mpeBlockMaxCode, /* out */ FloatVec& F_wMpeResidual); /* out */ /*模块F_SpeSubMpe的主程序*/ Shortint F_maxMagIndex( const FloatVec& F_corrVec, /* in */ const ShortVec& F_posTaken); /* in */ /*根据最大自相关搜索脉冲位置 */ void F_solveNewAmps( const FloatVec& F-a, /* in */ const FloatVec& F_c, /* in */ const Shortint F_nPulse, /* in */ FloatVec& F_b); /* out */ /*为最佳幅度求解(充当cholesky的替换)*/ void F_updateCrossCorr( const FloatVec& F_autoCorr /* in */ const Shortint F_pos, /* in */ const Float F_gain, /* in */ FloatVec& F_crossCorrUpd); /* out */ /*更改互相关矢量*/ void F_calcImpResp( const FloatVec& F_wCoeff, /* in */ <dp n="d30"/> FloatVec& F_impResp); /* out */ /* 计算IIR滤波器的脉冲响应*/ /* 系数wCoeff*/ void F_autoCorreate( const FloatVec& F_impResp, /* in */ FloatVec& F_autoCorr); /* out */ /*计算脉冲响应的自相差矢量*/ onse */ void F_crossCorrelate( const FloatVec& F_impResp, /* in */ const FloatVec& F_wLtpResidual, /* in */ FloatVec& F_crossCorr); /* out */ /*计算输入语音和脉冲响应间的互相关*/ */ void F_searchInit( const FloatVec& F-crossCorr, /* in */ const FloatVec& F_autoCorr, /* in */ FloatVec& F_crossCorrUpd, /* out */ ShortVec& F_mpePosVector, /* out */ FloatVec& F_pulseAmp, /* out */ ShortVec& F_posTaken), /* out */ /*初始化搜索并搜索第一脉冲*/ void F_searchRest( const FloatVec& F_autoCorr, /* in */ const FloatVec& F_crossCorr, /* in */ FloatVec& F_crossCorrUpd, /* out */ ShortVec& F_mpePosVector, /* out */ FloatVec& F_pulseAmp, /* out */ ShortVec& F_posTaken); /* out */ /*搜索其余脉冲(可选方法2)*/ void F_openLoopQuantize( const Float& F_excEnergy, /* in */ FloatVec& F_pulseAmp, /* out */ ShortVec& F_mpeAmpVector, /* out */ ShortVec& F_mpeSignVector, /* out */ Shortint& F_mpeBlockMaxCode); /* out */ /*计算blockmax和开环量化blockmax和脉冲*/ void F_makeInnVector( const FloatVec& F_pulseAmp, /* in */ const ShortVec& F_mpePosVector, /* in */ FloatVec& F_mpeInnovation) /* out */ /*构造改进矢量*/ <dp n="d31"/> void F_orderPositions( ShortVec& F_mpePosVector, /* in/out */ ShortVec& FmpeAmpVector, /* in/out */ ShortVec& F_peSignVector); /* in/out */ /*排序位置(最佳位置编码)*/ void F_makeCodeWords( const ShortVec& F_mpePosVector, /* in */ Shortint& F_mpePositionCode, /* out */ const ShortVec& F_mpeAmpVector, /* in */ Shortint& F_mpeAmpCode , /* out */ const ShortVec& F_mpeSignVector, /* in */ Shortint& F_mpeSignCode); /* out */ /*构造码字*/ void F_makeMpeResidual( const FloatVec& F_mpeInnovatlon, /* in */ const FloatVec& F_wCoeff, /* in */ const FloatVec& F_wLtpResidual, /* in */ FloatVec& F_wMpeResidual); /* out */ /*构造新的加权残余且除去MPE成分*/ }; #endif <dp n="d32"/> F_SpeSubTbpe.hh /* * class F_SpeSubTbpe * * 计算IIR滤波器的脉冲响应*/ * * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB * */ #ifndef F_SpeSubTbpe_h #define F_SpeSubTbpe_h #include″F_speDef.hh″ #include″FloatVec.hh″ class F_SpeSubTbpe { public: F_SpeSubTbpe(); /*构造函数*/ void F_SpeSubTbpe∷main( const FloatVec& F_wMpeResidual, /*入,加权MPE残余=F_wLtpResidual*/ const FloatVec& F_wCoeff, /*入,加权的直接形式系数*/ const Float F_excNormFactor, /*入,激励归一化因子*/ FloatVec& F_tbpeInnovation, /*出,TBPE改进,包括量化的增益*/ Shortint& F_tbpeGainCode, /*出,TBPE增益码*/ Shortint& F_tbpeIndexCode, /*出,TBPE脉冲符号码*/ Shortint& F_tbpeGridCode /*出,TBPE栅格码*/ Shortint& F_tbpeMatrixCode); /*出,TBPE变换矩阵码*/ /*用于TBPE码本搜索的主要子程序*/ void F_crossCorr( const FloatVec& v1, /*入,目标矢量1*/ const FloatVec& v2, /*入,目标矢量2*/ FloatVec& F_corr); /*出,互相关的矢量*/ /*计算互相关*/ void F_crossCorrOfTransfMatrix const FloatVec& v1, /*入,目标矢量*/ const Shortint grid, /*入,栅格数目*/ const Shortint matrix, /* 入,矩阵数目*/ FloatVec& F_crossCorr), /* 出,互相关矢量*/ /* <dp n="d33"/> /*计算用于变换矩阵的互相关*/ void F_zeroStateFilter( const FloatVec& in, /*入,要被滤波的矢量*/ const FloatVec& F_denCoeff,/*直接形式系数*/ FloatVec& out); /*出,滤波后的矢量*/ /*具有系数F_denCoeff的零状态滤波器*/ void F_construct( const Shortint index, /*入,索引码*/ const Shortint grid, /*入,栅格码*/ const Shortint matrix, /*入,矩阵码*/ FloatVec& vec); /*出,构造的激励*/ /*构造一个激励矢量*/ Float F_search( const FloatVec& F_wMpeResidual, /*入,加权的MPE残余=F_wLtpResidual且MPE改进被除去*/ const FloatVec& F_wCoeff, /*加权的直接形式系数*/ FloatVec& F_tbpeInnovation, /*出,TBPE改进包括量化的增益*/ Shortint& F_tbpeIndexCode, /*出,TBPE脉冲符号码*/ Shortint& F_tbpeGridCode, /*出,TBPE栅格码*/ Shortint& F_tbpeMatrixCode); /*出,TBPE变换矩阵码*/ /* 搜索最佳索引 * 根据相关符号近似索引 * 检查所有栅格和矩阵 * 返回最佳的改进,增益码,索引,栅格,矩阵 * / Shortint F_quantize( const Float value); /*入,要被量化的值*/ /*量化TBPE增益*/ }; #endif
参考文献
(1)P.Kroon,E.Deprettere用于比特率在4.6到16Kbitls之间的高质量语音编码的一类基于合成的分析的预测编码器,IEEEJour.Sel.Areas Com.,Vol.SAC-6,No.2,Feb.1988.
(2)H.Chen,W.C.Wong,C.C.Ko低延迟混合矢量激励线性预测语音编码Elecfronils letters Vol.29 no.25 1993
(3)D.Lin,使用一种混合源模型的码激励的线性预测Proc.ASSP DSP workshop,1986
(4)D.Lin,使用判定性多码本革新方法的超快CELP编码IEEEICASSP-92,San Francisco,1992.
(5)N.Moreau,P.Dymarski混合激励celp编码器。Eurospeech-89 Paris,Sep.1989.
(6)K.Ozawa,一种基于多脉冲和32kb/s CELP的混合语音编码IEEE ICASSP-90,Albuquerque,1990
(7)R.zinser,S.Koch,4800和7200bit/sel混合码本多脉冲编码,IEEE ICASSP-89,Glasgow,1989
(8)R,Zinser,混合交换的多脉冲/随机语音编码技术美国专利#5060269
(9)B.Atul,J.Remde用于在低比特率时产生自然声音语音的LPC激励的一种新模型IEEE ICASSP-82,Parls,1982.
(10)P.Vary,K.Hellwig,R.Hofman一种规律脉冲激励的线性预测编码和解码电路组合,语音通信7,North-Holland,1988
(11)R.A.Salami二进制的激励的线性预测(BCELP):没有码本的语音Celp编码的新方法,电子信件,Vol.25 no.6 march 1989.
(12)R.Salami二进制脉冲激励:低复杂度Celp编码的新方法Klwer Academic Pub.,Adanes in specch coding,1991.
(13)I.Gerson,M.Jasiuk矢量和激励的线性预测(VSELP)Kluwer Academic Pub,Advanas in speech coding(语音编码的进展)1991.
(14)R.Cox,W.B.Kleijn,P.Kroon用于含噪声背景和含噪声信道的高耐受度Celp编码器,IEEE ICASSP-89,Glasgow,1989.
(15)N.Cox用于语音编码和解码电路组合的误差控制和索引分
配Kluwer Academic Press,1993.
(16)T.B.Minde在线性预测语音编码器中的激励脉冲定位方法美国专利#5193140。
Claims (5)
1.一种基于合成的分析的线性预测语音编码器,其特征在于一个合成部分,它包括用于产生多脉冲激励(MPE)的装置(34);用于产生变换二进制脉冲激励(TBPE)的装置(36);用于组合所说的多脉冲激励和所说的变换二进制脉冲激励的装置(38)。
2.权利要求1的语音编码器,其特征在于,所说的包括用于在受限的脉冲位置产生脉冲的装置的多脉冲激励(MPE)产生装置(34)。
3.权利要求2的语音编码器,其特征在于所说的包括用于相位位置编码装置的多脉冲激励(MPE)产生装置。
4.权利要求1,2或3的语音编码器,其特征在于所说的合成部分进一步包括用于产生自适应激励的自适应码本(14)。
5.权利要求4的语音编码器,其特征在于用于组合所说的多脉冲(MPE),变换二进制脉冲(TBPE)和自适应激励的装置(18,38;gI,gM,gT)。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN 96192752 CN1179226A (zh) | 1995-03-22 | 1996-03-06 | 基于合成的分析的线性预测语音编码器 |
Applications Claiming Priority (2)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
SE95010260 | 1995-03-22 | ||
CN 96192752 CN1179226A (zh) | 1995-03-22 | 1996-03-06 | 基于合成的分析的线性预测语音编码器 |
Publications (1)
Publication Number | Publication Date |
---|---|
CN1179226A true CN1179226A (zh) | 1998-04-15 |
Family
ID=5128449
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN 96192752 Pending CN1179226A (zh) | 1995-03-22 | 1996-03-06 | 基于合成的分析的线性预测语音编码器 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN1179226A (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1886781B (zh) * | 2003-12-02 | 2011-05-04 | 汤姆森许可贸易公司 | 用于编码和解码音频信号的冲激响应的方法 |
-
1996
- 1996-03-06 CN CN 96192752 patent/CN1179226A/zh active Pending
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1886781B (zh) * | 2003-12-02 | 2011-05-04 | 汤姆森许可贸易公司 | 用于编码和解码音频信号的冲激响应的方法 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
EP0815554B1 (en) | Analysis-by-synthesis linear predictive speech coder | |
CN1121683C (zh) | 语音编码 | |
CN1954364B (zh) | 带有不同编码帧长度的音频编码 | |
CN1154086C (zh) | Celp转发 | |
JP5188990B2 (ja) | Celp技術における、デジタルオーディオ信号の改善された符号化/復号化 | |
US6385576B2 (en) | Speech encoding/decoding method using reduced subframe pulse positions having density related to pitch | |
CA2666546A1 (en) | Method and device for coding transition frames in speech signals | |
CN1737903A (zh) | 声音译码方法以及声音译码装置 | |
US6408268B1 (en) | Voice encoder, voice decoder, voice encoder/decoder, voice encoding method, voice decoding method and voice encoding/decoding method | |
CN1151492C (zh) | 综合-分析线性预测语音编码中的增益量化方法 | |
CN1192817A (zh) | 语音编码器 | |
CN1193786A (zh) | 频谱幅度的双子帧量化 | |
CN1109697A (zh) | 矢量量化器方法和设备 | |
CN1020975C (zh) | 线性预测语音编码器激励脉冲的定位方法 | |
CN1192357C (zh) | 用于语音编码的自适应规则 | |
JP3558031B2 (ja) | 音声復号化装置 | |
CN1179226A (zh) | 基于合成的分析的线性预测语音编码器 | |
CN1811917A (zh) | 语音编码器中搜寻语音讯号的编码向量的搜寻系统及方法 | |
CN1711590A (zh) | 概率式码簿的声源的编码方法 | |
CN1124590C (zh) | 改善话音信号编码器性能的方法 | |
Akamine et al. | CELP coding with an adaptive density pulse excitation model | |
US6351490B1 (en) | Voice coding apparatus, voice decoding apparatus, and voice coding and decoding system | |
JP3984048B2 (ja) | 音声/音響信号の符号化方法及び電子装置 | |
CN1159044A (zh) | 声音编码装置 | |
Akamine et al. | Efficient excitation model for low bit rate speech coding |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C01 | Deemed withdrawal of patent application (patent law 1993) | ||
WD01 | Invention patent application deemed withdrawn after publication |