CN1188556A - 综合-分析线性预测语音编码中的增益量化方法 - Google Patents
综合-分析线性预测语音编码中的增益量化方法 Download PDFInfo
- Publication number
- CN1188556A CN1188556A CN96194912A CN96194912A CN1188556A CN 1188556 A CN1188556 A CN 1188556A CN 96194912 A CN96194912 A CN 96194912A CN 96194912 A CN96194912 A CN 96194912A CN 1188556 A CN1188556 A CN 1188556A
- Authority
- CN
- China
- Prior art keywords
- gain
- floatvec
- const
- code book
- vector
- 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.)
- Granted
Links
- 238000000034 method Methods 0.000 title claims abstract description 46
- 238000013139 quantization Methods 0.000 title claims abstract description 19
- 238000003786 synthesis reaction Methods 0.000 title claims abstract description 14
- 239000013598 vector Substances 0.000 claims abstract description 113
- 230000005284 excitation Effects 0.000 claims abstract description 42
- 238000011002 quantification Methods 0.000 claims description 24
- 230000003044 adaptive effect Effects 0.000 claims description 20
- 238000006243 chemical reaction Methods 0.000 claims description 6
- 230000008569 process Effects 0.000 claims description 5
- 239000011800 void material Substances 0.000 description 50
- 241001673391 Entandrophragma candollei Species 0.000 description 35
- 239000011159 matrix material Substances 0.000 description 32
- 230000000875 corresponding effect Effects 0.000 description 11
- 230000004044 response Effects 0.000 description 8
- 238000010606 normalization Methods 0.000 description 6
- 230000015572 biosynthetic process Effects 0.000 description 5
- 238000010586 diagram Methods 0.000 description 5
- 230000002596 correlated effect Effects 0.000 description 4
- 230000008901 benefit Effects 0.000 description 3
- 230000008859 change Effects 0.000 description 3
- 238000005070 sampling Methods 0.000 description 3
- 230000009466 transformation Effects 0.000 description 3
- 244000287680 Garcinia dulcis Species 0.000 description 2
- 238000012937 correction Methods 0.000 description 2
- 238000000354 decomposition reaction Methods 0.000 description 2
- 230000007774 longterm Effects 0.000 description 2
- 238000012805 post-processing Methods 0.000 description 2
- 238000012360 testing method Methods 0.000 description 2
- -1 /* in Substances 0.000 description 1
- 239000010754 BS 2869 Class F Substances 0.000 description 1
- 238000013459 approach Methods 0.000 description 1
- 230000005540 biological transmission Effects 0.000 description 1
- 238000004364 calculation method Methods 0.000 description 1
- 230000001413 cellular effect Effects 0.000 description 1
- 239000007795 chemical reaction product Substances 0.000 description 1
- 238000001914 filtration Methods 0.000 description 1
- 230000006872 improvement Effects 0.000 description 1
- 238000010295 mobile communication Methods 0.000 description 1
- 238000005457 optimization Methods 0.000 description 1
- 238000007781 pre-processing Methods 0.000 description 1
- 238000012545 processing Methods 0.000 description 1
- 238000012549 training Methods 0.000 description 1
- 230000001131 transforming effect Effects 0.000 description 1
Images
Classifications
-
- G—PHYSICS
- G10—MUSICAL INSTRUMENTS; ACOUSTICS
- G10L—SPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
- G10L19/00—Speech or audio signals analysis-synthesis techniques for redundancy reduction, e.g. in vocoders; Coding or decoding of speech or audio signals, using source filter models or psychoacoustic analysis
- G10L19/04—Speech or audio signals analysis-synthesis techniques for redundancy reduction, e.g. in vocoders; Coding or decoding of speech or audio signals, using source filter models or psychoacoustic analysis using predictive techniques
- G10L19/08—Determination or coding of the excitation function; Determination or coding of the long-term prediction parameters
- G10L19/083—Determination or coding of the excitation function; Determination or coding of the long-term prediction parameters the excitation function being an excitation gain
-
- G—PHYSICS
- G10—MUSICAL INSTRUMENTS; ACOUSTICS
- G10L—SPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
- G10L19/00—Speech or audio signals analysis-synthesis techniques for redundancy reduction, e.g. in vocoders; Coding or decoding of speech or audio signals, using source filter models or psychoacoustic analysis
- G10L2019/0001—Codebooks
- G10L2019/0004—Design or structure of the codebook
- G10L2019/0005—Multi-stage vector quantisation
Landscapes
- Engineering & Computer Science (AREA)
- Computational Linguistics (AREA)
- Signal Processing (AREA)
- Health & Medical Sciences (AREA)
- Audiology, Speech & Language Pathology (AREA)
- Human Computer Interaction (AREA)
- Physics & Mathematics (AREA)
- Acoustics & Sound (AREA)
- Multimedia (AREA)
- Compression, Expansion, Code Conversion, And Decoders (AREA)
Abstract
在综合-分析线性预测编码中的一种增益量化方法,包括步骤:为来自第一码本的最优激励矢量确定第一增益(GAIN1);量化第一增益(GAIN1);为来自第二码本的最优激励矢量确定最优第二增益;由量化第一增益(GAIN1)确定第二增益(GAIN2)的对数的线性预测;量化在第二增益的对数与线性预测之间的误差(σ)。
Description
技术领域
本发明涉及一种在综合分析线性预测语音编码中的增益量化方法,具体说是用于移动电话上的增益量化方法。
发明背景
综合分析线性预测语音编码器通常有一个长期预测程序或自适应码本,并带有几个固定码本。例如在(1)中就描述了这种语音编码器。在这种语音编码器中总的激励矢量可用码本矢量vi的线性组合描述,即每一个码本矢量vi与对应的增益相乘。顺序地搜索码本。通常在搜寻第二个码本前从目标信号(语音信号)中减去来自第一个码本的激励。另一本方式是正交搜索,其中在后一码本中的所有矢量与所选的码本矢量正交。因而,码本都是相互独立的,并都能朝着同一目标信号被搜索。
在(2)中描述了一般的有任意数量码本的CELP编码器的搜索方式和增益量化。
通常码本的增益是分别地进行量化,但也可是与增益一起量化矢量。
在(3)中所描述的编码器中,两个固定码本和一个自适应码本一起使用。搜索固定码本并正交化。在变换到合适的域后,将固定码本增益与自适应码本增益一起进行矢量量化。并通过在新的综合-分析环中检测所有可能性发现最佳量化系数。在ACELP编码器中使用了相似的量化方式(4),但在这种情况中使用的是标准码本搜索方法。
在(5,6)中描述了一种自适应地计算量化边界的方法它使用了所选的LTP(长期预测)矢量而对于第二码本,则使用了由第一码本中选择的矢量。
在(2)中提出了一种方法,根据这种方法与正常码本矢量成比例地量化LTP码本增益。并与帧能量成比例地量化自适应码本增益。比率g2/g1,g3/g2,……是在不相同的量化器中进行量化。为使用增益的矢量量化,增益必须在激励矢量选择后进行量化。这意味着在搜索下一码本时不知道第一搜索码本的精确增益。如果使用传统的搜索方式,则不能为下一码本计算正确的目标信号,因而下一搜索不是最优的。
如果使用正交搜索方式,则码本搜索是与前一码本增益相独立的。因此在码本搜索后再量化增益,并可使用矢量量化。然而,码本的正交化通常非常复杂,而通常并不可行,除非在(3)中,对码本进行特殊专门设计以得到有效率的正交化。当使用矢量量化时,正常地是在新综合分析环中选择最佳增益。由于增益是标量量化的,因此与滤波过程不相干,这相对于在码本搜索中的综合-分析环节而言简化了计算。但这种方式仍独立量化要更复杂。另一缺点是矢量系数对于信道差错很敏感,这是由于系数中一位的错误会带来不同的一组增益。从这一方面而言独立量化是一种更好的选择。但在这种方式中要实现与其它方式相同的性能必须使用更多位。
有在(5,6)中描述的自适应量化限制的方式包含复杂的计算,因而在例如移动电话等低复杂度系统中并不实用。同样,由于最后码本的解码依赖于前面所有增益和矢量的正确传送,因此可见这种方式对于信道差错是很敏感的。
如(2)中所描述的增益比率对于信道误差是健壮的,并且不太复杂,这种方式要求对不相同的量化器要进行训练,这可能使得编码器对于未在训练中使用的其它信道较不健壮。这种方式也非常不实用。
发明概述
本发明的一个目的是在综合 分析线性预测语言编码中提出改进的增益量化方式以减少或消除大多数上述问题。具体说是,该方式应具有更低复杂度,并给出对于信道误差不敏感的量化增益和使用比独立增益量化方式更少比特数。
上述目的可由根据权利要求1的方式实现。
附图简述
通过参照下列与附图一起进行的叙述,可以更好地理解本发明和它的其它目的与优点。其中
图1是可使用本发明的方法的综合-分析线性预测语音编码器的一个实施例的框图;
图2是可使用本发明的方法综合-分析线性预测语音编码器的另一实施例的框图;
图3示出了多脉冲激励(MPE)的原理;
图4示出了转换双脉冲激励(TBPE)的原理;
图5示出了来自一个码本的最佳增益与来自下一码本的最佳增益的分布;
图6示出了在来自一个码本的量化增益与来自下一码本的最佳增益之间的分布;
图7示出了一个码本的最佳增益的动态范围;
图8示出了一个参数σ的较小的动态范围,根据本发明,用σ代替了图7的增益g2;
图9是显示本发明的方法的流程图;
图10是使用本发明的方法的语音编码器的一个实施例;
图11是使用本发明方法的语音编码器的另一实施例;
图12是使用本发明方法的语音编码器的另一实施例。
最佳实施例详述
在随后的描述中的许多例子将参照欧洲GSM(全球移动通信系统)系统。然而,应该认识到本发明的原理也可用于其它蜂窝系统。
在所有附图中对于对应的或相似的部件将使用相同的参照符号。
在描述本发明的增益量化方法前,首先描述一下可能在其中使用本发明的语音编码器的例子是很有帮助的。下面将参照图1和2进行描述。
图1显示了一个典型的综合-分析线性语音编码器的例子的框图。编码器包括了在垂直中心虚线左边的综合部件和在虚线右边的分析部件。综合部件基本上包括两个单元,分别叫作激励代码产生单元10和LPC(线性预测编码)综合滤波器12。激励代码产生单元10包含一个自适应码本14,一个固定码本16和一个加法器18。来自自适应码本14的所选矢量ar(n)与增益因子gIQ(Q表示量化值)相乘以形成信号p(n)。用同样方法将来自固定码本16的激励矢量与增益因子gJQ相乘以形成信号f(n)。信号p(n)与f(n)在加法器18中相加而形成激励矢量ex(n),它激励LPC综合滤波器12以形成预测的语音信号矢量(n)。
在分析部分中,在加法器20中由实际语音信号矢量s(n)减去预测矢量(n)以形成误差信号e(n)。把这个误差信号送至加权滤波器22以形成加权的误差矢量ew(n)。在单元24中将这个加权误差矢量的各分量平方和求和以形成这个加权误差矢量的能量测量值。
最小化单元26通过选择来自自适应码本12的增益gIQ和矢量与来自固定码本16的增益gJQ和矢量的组合来使这个加权误差矢量最小化,这一组合给出最小的能量值,即是说经过在滤波器12中的滤波后的值最接近于语音信号矢量。将最优化过程分成两步。第一步假设f(n)=0,并确定来自自适应码本14的最佳矢量和相应的gIQ。在附录中给出了确定这些参数的算法。当确定了这些参数之后,根据类似的算法再由固定码本16选取矢量与对应的gJQ。在这种情况中,自适应码本14的已确定的参数被锁定在其已确定的值上。
通过在LPC分析器28中分析语音信号帧为每一语音信号帧(160个取样)更新滤波器12的滤波器参数。这种更新已通过在分析器28与滤波器12中的虚线连接进行标记。此外,在加法器18和自适应码本14之间有一延迟部分。用这种方法最后选择的激励矢量ex(n)更新了自适应码本。这些是在子帧基础上进行实现的,其中每帧被分为四帧(40个取样)。
图2示出了可被使用本发明方法的语音编码器的另一实施例。图1中的语音编码器与图2的语音编码器的基本差异是图1的固定码本已被包括多脉冲激励发生器和转换双脉冲激励发生器36(TBPE)的固定激励发生器32代替。下面将对这两种激励进行简要描述。图2中对应块增益已被分别用gMQ,gTQ表示。来自发生器34,36的激励在加法器38中相加,而在加法器18中将混合激励加到自适应码本激励上。
图3中示出了多脉冲激励,在(7)中详述,也和在所附的C++程序列表中作了详述。图3示出了在40个取样的子帧(=5ms)内的6个脉冲。可用这些脉冲的位置(在例子中为位置7,9,14,25,37)和脉冲的幅度(例子中为AMP1-AMP6)描述激发矢量。在(7)中描述了获得这些参数的方法。通常幅度只代表激励矢量的形状。因此块增益gMQ(见图2)被用来代表这基矢形状的幅度。
图4示出了转换双脉冲激励的原理,这在(B)和在所附的程序列表中已有详细的描述。双脉冲码本可包含例如有10个分量的矢量。如图4中所示每个矢量的分量可指向上(+1)也可指向下(-1)。双脉冲码本包括这些矢量的所有可能的组合。这个码本的矢量可被认为是一系列所有指向一个十维“立方体”的各“顶角”的矢量。因而矢量顶点都均匀地分布在一个10维球体的表面。
此外,TBPE包含一个或几个交换矩阵(MATRIX1和MATRIX2)。在ROM中存储了预先计算的矩阵。用这些矩阵对存储在双脉冲码本中的矢量进行运算以产生一系列变换的矢量。最后,将这些变换矢量分布在一系列激励脉冲栅格上。结果是对于每个矩阵有4种不同类型的规则分布的“随机”码本。图4中显示了一个作为最后结果的来自其中一个码本的矢量(基于格子2)。搜索过程的目的是获得双脉冲码本的双脉冲码本系数,变换矩阵和一起给出最小加权误差的激励脉冲栅格。这些参数与增益gTQ相组合(见图2)。
在图1,2所示的语音编码器中,增益gIQ,gJQ,gMQ和gTQ已被相互完全独立地量化。然而,如图5中可见,在两个不同码本的增益之间有强的相关。图5中显示了在对应于MPE码本的增益g1的对数与对应于TBPE码本的增益g2的对数之间的分布。图6中显示了相似的分布图,但是,在此情况下增益g1已被量化。此外,图6中还显示了一条线L。这条线可通过回归分析发现,它可被用来从gIQ中预测g2,这将在下面进一步描述。图5和6中的数据总是从8000帧中获取的。
如图5和6中所示,在属于不同码本的增益之间有强的相关。通过计算来自第一码本的大量量化增益gIQ和在对应帧和确定线L中的第二码本的对应增益(未量化)g2,这条线可被用作线性预测器,它可根据下列公式由gIQ的对数预测g2的对数。
其中
代表预测增益g2。根据本发明的一个实施例,不量化g2而根据下列公式计算在实际和预测增益g2的对数之间的差σ
然后再进行量化。
图7和8示出了一个由上述方法而得到的优点。图7示出了8000帧的增益g2的动态范围。图8示出了在对应的相同帧中的σ的动态范围。由图7和8中可见,σ的动态范围比g2的动态范围小了很多。这意味着,对比g2所要求的量化级数,用于σ的量化级数可以显著减少。为在量化中实现较好性能,通常要在增益量化中用16级。采用本发明的σ量化,只需6个量化级就可获得同样的性能,这等于节约了0.3kb/s的比特率。
由于值b和c是存储于编码器与解码器中预确定和固定的值,故在解码器中可根据下列公式重构增益g2。
g2=[g1Q]c·exp(b+δQ)
其中g1Q和σQ已在解码器处被发送和接收。
在码本增益之间的相关性很依赖于在码本矢量中的能级。如果在码本中能量正在变化,则可将矢量能量包括进预测中以改善性能。在(2)中使用了归一化码本矢量,它消除了这一问题。然而,如果这个码本不是自动进行归一化并有许多非零分量则这种方法可能会很复杂,代之以可以在用于预测前修正因子g1以更好地代表前面码本的激励矢量。因此,计算σ的公式可修正为下式。
其中E代表由码本1选取的矢量的能量。激励能量被计算并被用于码本的搜索中,所以不必进行额外计算。
如果第一码本身是自适应码本,则能量变化很大,并且许多分量非零。归一化这些矢量将是一种计算复杂的过程。然而,如果没有归一化而使用码本,则量化增益可被矢量能量的平方根乘,如上所述,以便为下一码本增益的预测打下好的基础。
一个MPE码本矢量有很少幅度和符号变化的非零脉冲。通过对脉冲幅度的平方和给出矢量能量。为了预测下一码本增益,例如TBPE码本增益,可象自适应码本中情况一样,用能量的平方根修正MPE增益。然而如果使用的是平均脉冲幅度(幅度总是正的),可获得相同性能,而这种计算较不复杂。图6中的量化增益采用这种方法进行修正。
上面讨论的能量修正为在解码器处的g2给出下式
因为在解码器处也可得到激励矢量,则不必传送能量E但可在解码器处进行重算。
下面总结一个算法例子,其中第一增益为MPE增益而第二增益为TBPE增益。
LPC分析
子帧_nr=1…4
LTP分析
MPE分析
搜索最佳矢量
计算最优增益
量化增益
更新目标矢量
TBPE分析
搜索最佳矢量
最化增益
计算最优增益
根据MPE脉冲平均幅度*
MPE增益的对数来计算预测值
计算σ
量化σ
计算量化增益
状态更新
在这一算法中以帧为基础在帧上实现LPC分析,同时以子帧为基础在子帧上实现余下步骤的LTP分析,MPE激励,TBPE激励和状态更新。在此算法中展开了MPE和TBPE激励步骤以显示那些与本发明相关的步骤。
在图9中给出了一个本发明的流程图。
图10图示了一个与图1中语音编码器对应的语音编码器,但提供了用于完成本发明的装置。在块50中确定了对应于来自固定码本16的最优矢量的增益g2,而将激励矢量能量E(在块54中确定)送至块52,它计算σQ和量化增益g2Q。最好用微处理器进行以上计算。
图11图示了本发明的另一实施例,它对应于上面给出的举例算法。在此情况中,g1Q对应于来自MPE码本34的具有能量E的最优矢量,同时增益g2对应来自TBPE码本36的激励矢量。
图12图示了语音编码器的另一实施例,它综合了上述方法。由于已显示了在对应不同码本的增益之间有很强相关性,在有多于两个码本的情况下很自然通过重复这一算法来综合这一构想。在图12中,根据上述方法在块52中计算第一参数σ1。在此情况中,第一码本是一自适应码本14,第2码本是一MPE码本34。然而,为第二码本计算了g2Q后,可通过将MPE码本34认作“第一”码本而将TBPE码本认作“第二码本”而重复这一过程。因此,块52′可以根据上述相同的原理计算σ2和g3Q。差别是现在需要两个线性预测,一个为g2而一个为g3,分别有不同常数“a”和“b”。
在上面描述中已假设只在当前子帧中进行线性预测。然而,由于在当前子帧的增益与前面子帧的增益之间可能存在相关,因此也可能存储在前面子帧中已确定的增益和包括前面在线性预测中确定的增益。象在上述实施例中一样,线性预测的常数可通过经验获得并存储在编码和解码器中。这种方法将进一步提高预测的准确度,同时将进一步减少σ的动态范围。这将导致或是改进的质量(σ的可提供的量化级可用于覆盖较小的动态范围)或是进一步减少的量化级数。
因而,通过考虑到在增益间的相关性,本发明的量化方式相对于独立增益量化方式减少了增益比特率。由于在计算的复杂度上的增加是较少的,因而本发明的方法也仍是一种低复杂性方法。
此外,相对于矢量量化方式,位误码的稳定性也有改进。相对于独立量化,第一码本的增益的敏感度增加了,因为它也将影响第二码本的增益的量化。然而,参数σ的位误码敏感度低于在独立量化中第二增益g2的位误码敏感度。如果这在信道编码中被考虑,则总的稳定性相对于独立量化将确实被改善,因为σ量化的位误码敏感度更不等,当使用不等差错保护时这是较佳的。
一种用于减少增益动态范围的常用方法是在量化前用帧能量参数归一化增益。于是对每帧只发送一次帧能量参数。这种方法不是本发明所要求的,但为其它原因可以使用增益的帧能量归一。在附录的程序列表中使用于帧能量归一。
熟悉本技术领域人士可理解对本发明可做修正和改变,但这些修正与改变不背离本发明的附属权利要求中确定的精神与范围。
附录
附录概述了确定在一个彻底的搜索中的自适应码本系数;和对应增益gi的算法。图1中也显示了这些信号。ex(n)=p(n) 激励矢量(f(n)=0)p(n) =gi·ai(n) 定标的自适应矢量(n)=h(n)*p(n) 合成语音
(*=卷积)
h(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的增益
MAIN.CC /* * class F_SpeMain * main class for speech encoder * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB */ #include"F_SpeMain.hh" #include <iostream.h> F_SpeMain∷F_SpeMain(): F_speechSave(F_savedSpeechLength), F_lspPrev(F_nrCoeff), F_ltpHistory(F_historyLength), F_weightFilterRingState(F_nrCoeff), F_syFilterState(F_nrCoeff) { /* clear saved speech*/ for (int i=0;i<F_savedSpeechLength;i++) F_speechSave[i]=0.0; 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; for (i=0;i<F_nrCoeff;i++) F_syFilterState[i]=0.0; } /* * function F_SpeMain:main */ void F_SpeMain∷main(const FloatVec&F_speechFrame, ShortVec&F_analysisData) } /*local variables */ FloatVec F_lspCurr(F_nrCoeff); ShortVec F_lspVQCodes(F_nLspTables); Float F_energy; Float F_accPower; Shortint F_energyCode; FloatVec F_hpSpeech(F_frameLength); 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); <dp n="d10"/> ShortVec F_mpePositionCodes(F_nrOfSubframes); ShortVec F_tbpeGainCodes(F_nrOfSubframes); ShortVec F_tbpeGridCodes(F_nrOfSubframes); ShortVec F_tbpeMatrixCodes(F_nrOfSubframes); ShortVec F_tbpeIndexCodes(F_nrOfSubframes); F_speFrame.main(F_speechFrame, F_lspPrev, F_speechSave, F_lspCurr, F_lspVQCodes, F_energy, F_accPower, F_energyCode, F_hpSpeech); for (int F_subframeNr=0; F_subframeNr<F_nrOfSubframes; F_subframeNr++){ /* subframe local variables */ Float F_excNormFactor; FloatVec F_wCoeff(F_nrCoeff); FloatVec F_aCoeff(F_nrCoeff); FloatVec F_wSpeechSubframe(F_subframeLength); FloatVec F_impulseResponse(F_subframeLength); FloatVec F_ltpExcitation(F_subframeLength); FloatVec F_wLtpResidual(F_subframeLength); Float F_avgMpeAmp; FloatVec F_mpeInnovation(F_subframeLength); FloatVec F_wMpeResidual(F_subframeLength); FloatVec F_tbpeInnovation(F_subframeLength); F_speSubPre.main(F_hpSpeech, F_subframeNr, F_lspCurr, F_lspPrev, F_energy, F_weightFilterRingState, F_excNormFactor, F_wCoeff, F_aCoeff, F_wSpeechSubframe, F_impulseResponse); F_speSubLtp.main(F_wSpeechSubframe, F_wCoeff, F_ltpHistory, F_wLtpResidual, F_ltpExcitation, F_ltpLagCodes[F_subframeNr], F_ltpGainCodes[F_subframeNr]); <dp n="d11"/> F_speSubMpe.main(F_wCoeff, F_excNormFactor, F_wLtpResidual, F_impulseResponse, F_mpeInnovation, F_mpePositionCodes[F_subframeNr], F_mpeAmpCodes[F_subframeNr], F_mpeSignCodes[F_subframeNr], F_mpeBlockMaxCodes[F_subframeNr], F_wMpeResidual, F_avgMpeAmp); F_speSubTbpe.main(F_wMpeResidual, F_wCoeff, F_excNormFactor, F_avqMpeAmp, F_impulseResponse, F_tbpeInnovation, F_tbpeGainCodes[F_subframeNr], F_tbpeIndexCodes[F_subframeNr], F_tbpeGridCodes[F_subframeNr], F_tbpeMatrixCodes[F_subframeNr]); F_speSubPost.main(F_ltpExcitation, F_tbpeInnovation, F_mpeInnovation, F_wCoeff, F_aCoeff, F_ltpHistory, F_weightFilterRingState, F_svFilterState, F_accPower); } F_spePost.main(F_energy, F_lspCurr, F_accPower, F_enerqyCode, F_lspVQCodes, F_ltpGainCodes, F_ltpLaqCodes, F_mpeBlockMaxCodes, F_mpeAmpCodes, F_mpeSiqnCodes, F_mpePositionCodes, F_tbpeGainCodes, F_tbpeIndexCodes, F_tbpeMatrixCodes, F_ tbpeGridCodes, F_ltpHistory, F_syFilterState, F_lspPrev, F_analysisData); } <dp n="d12"/> SPE DEF.CC /* * module F_speDef * * constant definitions for speech encoder * * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB * */ #include"F_speDef.hh" #include<iostream.h> #include<math.h> const Float F_tbpeDeltaQuantInit[F_nrTbpeDeltaGainLevel] = { -2.3, -2.04286, -1.78571, -1.52857, -1.27143, -1.01429, -0.757143, -0.5, }; const FloatVec F_tbpeDeltaQuantTable(F_nrTbpeDeltaGainLevel, F_tbpeDeltaQuantInit); const Float F_tbpeDeltaLimitInit[F_nrTbpeDeltaGainLevel-1] = { -2.17143, -1.91429, -1.65714, -1.4, -1.14286, -0.885714, -0.628571 }; const FloatVec F_tbpeDeltaLimitTable(F_nrTbpeDeltaGainLevel-1, F_tbpeDeltaLimitInit); <dp n="d13"/> SUB_MPE.CC /* * class F_SpeSubMpe * * Multipulse innovation analysis * * 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() { } /* * function F_SpeSubMpe∷main * */ void F_SpeSubMpe∷main( const FloatVec& F_wCoeff, Float F_excNormFactor, const FloatVec& F_wLtpResidual, const FloatVec& F_impulseResponse, FloatVec& F_mpeInnovation, Shortint& F_mpePositionCode, Shortint& F_mpeAmpCode, Shortint& F_mpeSignCode, Shortint& F_mpeBlockMaxCode, FloatVec& F_wMpeResidual, Float& F_avgMpeAmp) { /* temporary variables */ FloatVec F_autoCorr(F_subframeLength); FloatVec F_crossCorr(F_subframeLength); ShortVec F_seqPosVector(F_nMpeSeqPulses); FloatVec F_pulseAmp(F_nMpePulses); ShortVec F_mpePosVector(F_nMpePulses); ShortVec F_mpeAmpVector(F_nMpePulses); ShortVec F_mpeSignVector(F_nMpePulses); /* calculate autocorrelation */ F_autoCorrelate( F_impulseResponse, F_autoCorr); /* calculate cross correlation */ F_crossCorrelate( F_impulseResponse, F_wLtpResidual, F_crossCorr); <dp n="d14"/> /* do sequential search (5 pulses) with no restrictions */ F searchUnRestricted( F_autoCorr, F_crossCorr, F_seqPosVector); /* do reoptimization with respect to possible positions */ F_reoptSearch( F_autoCorr, F_crossCorr, F_impulseResponse, F_wLtpResidual, F_segPosVector, F_mpePosVector, F_pulseAmp); /* quantize blockmax and pulse amplitudes */ F_openLoopQuantize( F_excNormFactor, F_pulseAmp, F_mpeAmpVector, F_mpeSignVector, F_mpeBlockMaxCode); /* make innovation vector */ F_makeInnVector( F_pulseAmp, F_mpePosVector, F_mpeInnovation); /* order pulse position */ F_orderPositions( F_mpePosVector, F_mpeAmpVector, F_mpeSignVector); /* make codewords position */ F_makeCodeWords( F_mpePosVector, F_mpePositionCode, F_mpeAmpVector, F_mpeAmpCode, F_mpeSignVector, F_mpeSignCode); /* make new weigthed residual */ F_makeMpeResidual( F_mpeInnovation, F_wCoeff, F_wLtpResidual, F_wMpeResidual); /* compute average pulse amplitude */ F_avgMpeAmp=F_computeAvgAmp( F_excNormFactor,F_pulseAmp); } <dp n="d15"/> /* * function F_SpeSubMpe∷F_maxMagIndex */ Shortint F_SpeSubMpe∷F maxMagIndex( const FloatVec& F_corrVec, const ShortVec& F_posTaken) { /* temporary variables */ Float max: Float temp; int i; Shortint maxI = 0; /* init variables */ max = -1; /* find position with greatest correlation * excluding used positions */ for (i=0;i<F_subframeLength;i++){ temp = fabs(F.corrVec[i]); if(!F_posTaken[i] && temp>max){ max=temp; maxI=i; } } return maxI; } /* * function F_SpeSubMpe∷F_maxMagIndexRestr */ Shortint F_SpeSubMpe∷F_maxMagIndexRestr( const FloatVec& F_corrVec, const ShortVec& F_phaseTaken) { /* temporary variables */ Float max; Float temp; int i,j; Shortint maxI=0; /* init variables */ max=-1; /* find position with greatest correlation * excluding used phases */ for(i=0;i<F_nMpePhases;i++) if(!F_phaseTaken[i]) for (j=i;j<F_subframeLength;j+=F_nMpePhases) { temp=fabs(F_corrVec[j]); if(temp>max) { max=temp; maxI=j; } <dp n="d16"/> } return maxI; } /* * function F_SpeSubMpe∷F_calc2OptAmps * Compute optimal amplitudes for 2 selected pulses */ void F_SpeSubMpe∷F_calc2OptAmps( const ShortVec& F_posVec, const FloatVec& F_autoCorr, const FloatVec& F_crossCorr, FloatVec& F_optAmp) { /* temporary variables */ FloatVec a(2); FloatVec c(2); Float den,denInv; /* init vectors */ a[0]=F_autoCorr[0]; a[1]=F_autoCorr[abs(F_posVec[0]-F_posVec[1])]; c[0]=F_crossCorr[F_posVec[0]]; c[1]=F_crossCorr[F_posVec[1]]; den=a[0]*a[0]-a[1]*a[1]; if (den==0.0) { cerr<<"MPE singular 2*2 matrix"<<endl; return; } denInv=1.0/den; F_optAmp[0]=(c[0]*a[0]-c[1]*a[1]) * denInv; F_optAmp[1]=(c[1]*a[0]-c[0]*a[1]) * denInv; } /* * function F_SpeSubMpe∷F_calc3OptAmps * Compute optimal amplitudes for 3 selected pulses */ void F_SpeSubMpe∷F_calc3OptAmps( const ShortVec& F_posVec, const FloatVec& F_autoCorr, const FloatVec& F_crossCorr, FloatVec& F_optAmp) { /* temporary variables */ FloatVec a(4); FloatVec c(3); Float den,denInv; /* init vectors */ a[0]=F_autoCorr[0]; <dp n="d17"/> a[1]=F_autoCorr[abs(F_posVec[0]-F_posVec[1])]; a[2]=F_autoCorr[abs(F_posVec[0]-F_posVec[2])]; a[3]=F_autoCorr[abs(F_posVec[1]-F_posVec[2])]; c[0]=F_crossCorr[F_posVec[0]]; c[1]=F_crossCorr[F_posVec[1]]; c[2]=F_crossCorr[F_posVec[2]]; /* Kramers rule */ den=a[0]*a[0]*a[0]+a[1]*a[3]*a[2]+a[2]*a[1]*a[3]- a[1]*a[1]*a[0]-a[0]*a[3]*a[3]-a[2]*a[0]*a[2]; if (den==0.0){ cerr<<"MPE singular 3*3 matrix"<<endl; return: } denInv=1.0/den; F_optAmp[0]=(c[0]*a[0]*a[0]+c[1]*a[3]*a[2] +c[2]*a[1]*a[3]-c[1]*a[1]*a[0] -c[0]*a[3]*a[3]-c[2]*a[0]*a[2])*denInv; F_optAmp[1]=(a[0]*c[1]*a[0]+a[1]*c[2]*a[2] +a[2]*c[0]*a[3]-a[1]*c[0]*a[0] -a[0]*c[2]*a[3]-a[2]*c[1]*a[2])*denInv; F_optAmp[2]=(a[0]*a[0]*c[2]+a[1]*a[3]*c[0] +a[2]*a[1]*c[1]-a[1]*a[1]*c[2] -a[0]*a[3]*c[1]-a[2]*a[0]*c[0])*denInv; } /* * function F_SpeSubMpe∷F_calc4OptAmps * Compute optimal amplitudes for 4 selected pulses * (Cholesky decomposition) */ void F_SpeSubMpe∷F_calc4OptAmps( const ShortVec& F_posVec, const FloatVec& F_autoCorr, const FloatVec& F_crossCorr, FloatVec& F_optAmp) { /* temporary variables */ Shortint i,j,k; Float sum,tmp; FloatVec v(4*4); FloatVec w(4*4); FloatVec d(4); FloatVec y(4); FloatVec c(4); FloatVec a(4*4); /* init vectors */ for (i=0;i<4;i++) for (j=0;j<=i;j++){ a[i*4+j]= F_autoCorr[abs(F_posVec[i]-F_posVec[j])]; a[j*4+i]=a[i*4+j]; } <dp n="d18"/> for (i=0;i<4;i++) c[i]=F_crossCorr[F_posVec[i]]; /* triangular decomposition */ for (j=0;j<4;j++){ sum=a[j*4+j]; for (k=0;k<j;k++){ tmp=v[j*4+k]; sum=sum-tmp*tmp*d[k]; } if (fabs(sum)<1.0e-14){ cerr<<"MPE singular 4*4 matrix"<<endl; for (k=0;k<4;k++) F_optAmp[k]=0; break; } d[j]=sum; for (i=j+1;i<4;i++){ sum=a[i*4+j]; for (k=0;k<j;k++) sum=sum-v[i*4+k]*w[j*4+k]; w[i*4+j]=sum; v[i*4+j]=sum/d[j]; } } /* invert the matrix,and get the solution recursively */ for (i=0;i<4;i++){ sum=c[i]; for (j=0;j<i;j++) sum=sum-v[i*4+j]*y[j]; y[i]=sum; } /* finally,collect the results */ for (i=4-1;i>=0;i--){ sum=y[i]/d[i]; for (j=i+1;j<4;j++) sum=sum-v[j*4+i] *F_optAmp[j]; F_optAmp[i]=sum; } } /* * function F_SpeSubMpe∷F_updateCrossCorr * */ void F_SpeSubMpe∷F_updateCrossCorr( const FloatVec& F_autoCorr, const Shortint F_pos, const Float F_gain, FloatVec& F_crossCorrUpd) { /* temporary variables */ int i; <dp n="d19"/> int temp; /* update crosscorrelation vector */ 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]; } /* * function F_SpeSubMpe∷F_autoCorrelate * */ void F_SpeSubMpe∷F_autoCorrelate( const FloatVec& F_impulseResponse, FloatVec& F_autoCorr) { /*temporary variables */ int i,j; /* calculate autocorrelation vector */ 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_impulseResponse[j]*F_impulseResponse[j-i]; }; for (i=F_mpeTruncLen;i<F_subframeLength;i++) F_autoCorr[i]=0.0; } /* * function F_SpeSubMpe∷F_crossCorrelate * */ void F_SpeSubMpe∷F_crossCorrelate( const FloatVec& F_impulseResponse, const FloatVec& F_wSpeechSubframe, FloatVec& F_crossCorr) { /* temporary variables */ int i,j,lastpos; /* calculate crosscorrelation vector */ for (i=0;i<F_subframeLength;i++){ <dp n="d20"/> 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_impulseResponse[j-i]; } } /* * function F_SpeSubMpe∷F_searchUnRestricted * Search 5 pulses with no respect to possible positions */ void F_SpeSubMpe∷F_searchUnRestricted( const FloatVec& F_autoCorr, const FloatVec& F_crossCorr, ShortVec& F_seqPosVector) { /* temporary variables */ FloatVec F_crossCorrUpd(F_subframeLength); FloatVec F_pulseAmp(F_nMpeSeqPulses-1); ShortVec F_posTaken(F_subframeLength); int pulse; int i; int pos; /* search init */ for (i=0;i<F_subframeLength;i++) F_posTaken[i]=0; for (i=0;i<F_subframeLength;i++) F_crossCorrUpd[i]=F_crossCorr[i]; /* get first position */ pos=F_maxMagIndex(F_crossCorr,F_posTaken); F_seqPosVector[0]=pos; F_posTaken[pos]=1; /* update crosscorrelation vector */ F_updateCrossCorr(F_autoCorr, pos, F_crossCorr[pos]/F_autoCorr[0], F_crossCorrUpd); /* get positions 2 through 5 */ for(pulse=1;pulse<F_nMpeSeqPulses;pulse++){ /* get position with maximum value */ pos=F_maxMagIndex(F_crossCorrUpd,F_posTaken); F_seqPosVector[pulse]=pos; F_posTaken[pos]=1; if (pulse!=(F_nMpeSeqPulses-1)){ /* calculate optimal amplitudes for <dp n="d21"/> * selected positions */ switch(pulse+1){ case 2: F_calc2OptAmps(F_seqPosVector, F_autoCorr, F_crossCorr, F_pulseAmp); break; case 3: F_calc3OptAmps(F_seqPosVector, F_autoCorr, F_crossCorr, F_pulseAmp); break; case 4: F_calc4OptAmps(F_seqPosVector, F_autoCorr, F_crossCorr, F_pulseAmp); break; }; /* update crosscorrelation vector */ for (i=0;i<F_subframeLength;i++) F_crossCorrUpd[i]=F_crossCorr[i]; for (i=0;i<pulse+1;i++) F_updateCrossCorr(F_autoCorr, F_seqPosVector[i], F_pulseAmp[i], F_crossCorrUpd); } } } /* * function F_SpeSubMpe∷F_searchRestricted * search 3 pulses with restriction to possible positions */ void F_SpeSubMpe∷F_searchRestricted( const FloatVec& F_autoCorr, const FloatVec& F_crossCorr, ShortVec& F_posVec, ShortVec& F_phaseTaken, FloatVec& F_pulseAmp) { /* temporary variables */ FloatVec F_crossCorrUpd(F_subframeLength); Shortint pos; int i,pulse; /* update crosscorrelation vector*/ for (i=0;i<F_subframeLength;i++) F_crossCorrUpd[i]=F_crossCorr[i]; F_updateCrossCorr(F_autoCorr, <dp n="d22"/> F_posVec[0], F_pulseAmp[0], F_crossCorrUpd); /* search pulse 2 and 3 */ for(pulse=1;pulse<F_nMpePulses;pulse++){ pos=F_maxMagIndexRestr(F_crossCorrUpd,F_phaseTaken); F_phaseTaken[pos % F_nMpePhases]=1; F_posVec[pulse]=pos; /* calculate optimal amplitudes for selected positions*/ switch (pulse+1){ case 2: F_calc2OptAmps(F_posVec, F_autoCorr, F_crossCorr, F_pulseAmp); break; case 3: F_calc3OptAmps(F_posVec, F_autoCorr, F_crossCorr, F_pulseAmp); break; } if (pulse !=(F_nMpePulses-1)){ /* update crosscorrelation vector */ for(i=0;i<F_subframeLength;i++) F_crossCorrUpd[i]=F_crossCorr[i]; for (i=0;i<pulse+1;i++) F_updateCrossCorr(F_autoCorr, F_posVec[i], F_pulseAmp[i], F_crossCorrUpd); } } } /* * function F_SpeSubMpe∷F_calcMpePredErr * * Calculate prediction error of candidate mpe pulse vector * */ Float F_SpeSubMpe∷F_calcMpePredErr( const ShortVec& F_posVec, const FloatVec& F_pulseAmp, const FloatVec& F_impulseResponse, const FloatVec& F_wTarget) { /* temporary variables */ int pos,start,stop,i; FloatVec error(F_subframeLength); Float errorEnergy; <dp n="d23"/> /* init error vector */ for (i=0;i<F_subframeLength;i++) error[i]=F_wTarget[i]; /* subtract from target a linear combination of * shifted impulse responses */ for(pos=0;pos<F_nMpePulses;pos++){ start=F_posVec[pos]; stop=start+F_mpeTruncLen; if (stop>F_subframeLength) stop=F_subframeLength; for (i=start;i<stop;i++) error[i]=error[i]- F_pulseAmp[pos]*F_impulseResponse[i-start]; } /* compute energy in resulting errorvector */ errorEnergy=0; for (i=0;i<F_subframeLength;i++) errorEnergy=errorEnergy+error[i]*error[i]; return errorEnergy; } /* * function F_SpeSubMpe∷F_reoptSearch * * Do new search with start positions equal to * the previous found 5 positions * */ void F_SpeSubMpe∷F_reoptSearch( const FloatVec& F_autoCorr, const FloatVec& F_crossCorr, const FloatVec& F_impulseResponse, const FloatVec& F_wTarget, const ShortVec& F_seqPosVector, ShortVec& F_mpePosVector, FloatVec& F_mpePulseAmp) { /* updates posEnc and fpulseGain with the best * encodable alternative uses idealPos and * idealPulseGains as starting points * for several sequential searches */ /* temporary variables */ int start,i; Float error,minError; ShortVec F_phaseTaken(F_nMpePhases); ShortVec F_tempPosVec(F_nMpePulses); FloatVec F_tempPulseAmp(F_nMpePulses); /* init variables */ minError=1.0e30; <dp n="d24"/> /* search for the best out of 5 pulse position * combinations */ for(start=0;start<F_nMpeSeqPulses;start++){ /* compute first amplitude */ F_tempPulseAmp[0]= F_crossCorr[F_seqPosVector[start]]/F_autoCorr[0]; /* reset taken-position vector */ for (i=0;i<F_nMpePhases;i++) F_phaseTaken[i]=0; /* reserve the phase corresponding to * seqPosVector[start] */ F_phaseTaken[F_seqPosVector[start]% F_nMpePhases]=1; F_tempPosVec[0]=F_seqPosVector[start]; F_searchRestricted( F_autoCorr, F_crossCorr, F_tempPosVec, F_phaseTaken, F_tempPulseAmp); error=F_calcMpePredErr(F_tempPosVec, F_tempPulseAmp, F_impulseResponse, F_wTarget); if(minError>error){ minError=error: for (i=0;i<F_nMpePulses;i++){ F_mpePulseAmp[i]=F_tempPulseAmp[i]; F_mpePosVector[i]=F_tempPosVec[i]; } } } } /* * function F_SpeSubMpe∷openLoopQuantize */ void F_SpeSubMpe∷F_openLoopQuantize( const Float& F_excNormFactor, FloatVec& F_pulseAmp, ShortVec& F_mpeAmpVector, ShortVec& F_mpeSignVector, Shortint& F_mpeBlockMaxCode) { /* temporary variables */ Float blockMax; Float idealBlockMax; Float blockMaxNorm; Float normPulseAmp; int pulse; Float temp; /* get blockmax value */ <dp n="d25"/> blockMax=0.0; for (pulse=0;pulse<F_nMpePulses;pulse++){ temp=fabs(F_pulseAmp[pulse]); if (temp>blockMax) blockMax=temp; } idealBlockMax=blockMax; /* quantize blockmax */ blockMaxNorm=blockMax/F_excNormFactor; 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_mpeBlockMaxQLevels[F_mpeBlockMaxCode] * F_excNormFactor; /* quantize pulse amplitudes */ 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]]} FmpeAmpVector[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; } } } /* * function F_SpeSubMpe∷F_makeInnVector */ void F_SpeSubMpe∷F_makeInnVector( <dp n="d26"/> const FloatVec& F_pulseAmp, const ShortVec& F_mpePosVector, FloatVec& F_mpeInnovation) { /* temporary variables */ int i; /* create innovation vector */ 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]; } /* * function F_SpeSubMpe∷F_orderPositions */ void F_SpeSubMpe∷F_orderPositions( ShortVec& F_mpePosVector, ShortVec& F_mpeAmpVector, ShortVec& F_mpeSignVector) { /* temporary variables */ ShortVec tempPosVector(F_nMpePulses); ShortVec tempAmpVector(F_nMpePulses); ShortVec tempSignVector(F_nMpePulses); int maxVal,maxPhase; int maxI=0; int i,j; /* Create temporary vectors */ for (i=0;i<F_nMpePulses;i++){ tempPosVector[i]=F_mpePosVector[i]; tempAmpVector[i]=F_mpeAmpVector[i]; tempSignVector[i]=F_mpeSignVector[i]; } /* fix ordering,the position phases are ordered * decreasingly */ for (i=0;i<F_nMpePulses;i++){ maxVal=-1; maxPhase=-1; for (j=0;j<F_nMpePulses;j++){ if ((tempPosVector[j]%F_nMpePhases)>maxPhase && tempPosVector[j]!=-10){ maxPhase=tempPosVector[j]%F_nMpePhases; maxVal=tempPosVector[j]; maxI=j; } } /* exclude found vector from search */ tempPosVector[maxI]=-10; /* order pulses */ F_mpePosVector[i]=maxVal; F_mpeAmpVector[i]=tempAmpVector[maxI]; <dp n="d27"/> F_mpeSignVector[i]=tempSignVector[maxI]; } } /* * function F_SpeSubMpe:F_makeCodeWords * */ void F_SpeSubMpe∷F_makeCodeWords( const ShortVec& F_mpePosVector, Shortint& F_mpePositionCode, const ShortVec& F_mpeAmpVector, Shortint& F_mpeAmpCode, const ShortVec& F_mpeSignVector, Shortint& F_mpeSignCode) { /* temporary variables */ int i,phaseIndex; /* code position vector into 13 bits */ /* put phase indices into codeword */ phaseIndex=0; for (i=0;i<F_nMpePulses;i++) phaseIndex+=(1<< (F_mpePosVector[i]% F_nMpePhases)); F_mpePositionCode=F_mpePhaseCodeTable[phaseIndex]; /* put group indices */ for (i=F_nMpePulses-1;i>=0;i--){ F_mpePositionCode<<=F_nMpeGroupBits; F_mpePositionCode=F_mpePosVector[i]/F_nMpePhases; } /* code Mpe signs */ F_mpeSignCode=0; for (i=0;i<F_nMpePulses;i++) F_mpeSignCode=(F_mpeSignVector[i]<<i); /* code Mpe amps */ F_mpeAmpCode=0; for (i=0;i<F_nMpePulses;i++) F_mpeAmpCode=(F_mpeAmpVector[i]<<i*F_mpeAmpBits); } /* * function F_SpeSubMpe∷F_makeMpeResidual * */ void F_SpeSubMpe∷F_makeMpeResidual( const FloatVec& F_mpeInnovation, const FloatVec& F_wCoeff, const FloatVec& F_wLtpResidual, FloatVec& F_wMpeResidual) { /* temporary variables */ int i,m; <dp n="d28"/> Float signal; FloatVec state(F_nrCoeff); /* set zero state */ for (i=0;i<F_nrCoeff;i++) state[i]=0.0; /* calculate new target for subsequent TBPE search */ 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; } } /* * function F_SpeSubMpe∷F_computeAvgAmp * */ Float F_SpeSubMpe∷F_computeAvgAmp( Float F_excNormFactor, const FloatVec& F_pulseAmp) { /* temporary variables */ Float temp; int i; /* compute average pulse amplitude */ temp=0; for (i=0;i<F_nMpePulses;i++) temp=temp+fabs(F_pulseAmp[i]]; temp=temp/(F_nMpePulses*F_excNormFactor); return temp; } <dp n="d29"/> SUB_IBPE.CC /* * class F_SpeSubTbpe * Transformed Binary Pulse Excited codebook * COPYRIGHT (C) 1995 ERICSSON RADIO SYSTEMS AB */ #include"F_SpeSubTbpe.hh" #include<iostream.h> #include<math.h> F_SpeSubTbpe∷F_SpeSubTbpe() { } /* * function F_SpeSubTbpe∷main */ void F_SpeSubTbpe∷main(const FloatVec& F_wMpeResidual, const FloatVec& F_wCoeff, const Float& F_excNormFactor, const Float& F_avgMpeAmp, const FloatVec& F_impulseResponse, FloatVec& F_tbpeInnovation, Shortint& F_tbpeGainCode, Shortint& F_tbpeIndexCode, Shortint& F_tbpeGridCode, Shortint& F_tbpeMatrixCode) { Float F_optGain=F_search(F_wMpeResidual, F_wCoeff, F_impulseResponse, F_tbpeInnovation, F_tbpeIndexCode, F_tbpeGridCode, F_tbpeMatrixCode); Float F_tbpeGain; F_gainQuant(F_excNormFactor, F_avgMpeAmp, F_optGain, F_tbpeGainCode, F_tbpeGain); for(Shortint i=0;i<F_subframeLength;i++) F_tbpeInnovation[i]=F_tbpeInnovation[i] * F_tbpeGain; } /* * function F_SpeSubTbpe∷F_crossCorr <dp n="d30"/> * */ void F_SpeSubTbpe∷F_crossCorr(const FloatVec& v1, const FloatVec& v2, FloatVec& F_corr) { for (Shortint i=0;i<F_subframeLength;i++){ Float acc=0.0; for (Shortint j=i;j<F_subframeLength;j++) acc+=v1[j]*v2[j-i]; F_corr[i]=acc; } } /* * function F_SpeSubTbpe∷F_crossCorrOfTransfMatrix */ 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; } } /* * function F_SpeSubTbpe∷F_zeroStateFilter * */ void F_speSubTbpe∷F_zeroStateFilter(const FloatVec& in, const FloatVec& F_denCoeff, FloatVec& out) { /* zero state search filter */ 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--){ sigmal-=F_denCoeff[m] * F_state[m]; F_state[m]=F_state[m-1]; } <dp n="d31"/> signal-=F_denCoeff[0] * F_state[0]; F_state[0]=signal; out[i]=signal; } } /* * function F_SpeSubTbpe∷F_construct * */ void F_SpeSubTbpe∷F_construct(const Shortint index, const Shortint grid, const Shortint matrix, FloatVec& vec) { /* zero result vector */ 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 sum-= F_tbpeTransfTable[(i+matrix*F_nrTbpePulses)*F_nrTbpePulses+j]; itemp>>=1; } vec[grid+j*F_tbpeGridSpace]=sum; } } /* * function F_SpeSubTbpe∷F_calcPower * */ void F_SpeSubTbpe∷F_calcPower(const FloatVec& F_in, Float& F_power) { F_power=0.0; for (int i=0;i<F_subframeLength;i++) F_power+=F_in[i]*F_in[i]; } /* * function F_SpeSubTbpe∷F_calcCorr * */ void F_SpeSubTbpe∷F_calcCorr(const FloatVec& F_cross, const FloatVec& F_signVector, <dp n="d32"/> Float& F_corr) { F_corr=0.0; for (int i=0;i<F_nrTbpePulses;i++) F_corr+=F_cross[i]*F_signVector[i]; } /* * function F_SpeSubTbpe∷F_decision * */ void F_SpeSubTbpe∷F_decision(const Float F_corr, const Float F_power, const Shortint F_index, const Shortint F_grid, const Shortint F_matrix, Float& F_bestCorr, Float& F_bestPower, Shortint& F_bestIndex, Shortint& F_bestGrid, Shortint& F_bestMatrix, Shortint& F_updated) { F_updated=0; if (F_corr*F_corr*F_bestPower>F_bestCorr*F_bestCorr* F_power) { F_bestCorr =F_corr; F_bestPower =F_power; F_bestIndex =F_index; F_bestGrid =F_grid; F_bestMatrix=F_matrix; F_updated=1; } } /* * function F_SpeSubTbpe∷F_search * * F_zeroStateFilter : 8 * F_calcPower : 8 * F_calcCorr : 8 * F_decision : 8 * F_crossCorr : 1 * F_crossCorrOfTransfMatrix : 8 * F_construct : 9 */ Float F_SpeSubTbpe∷F_search(const FloatVec& F_wMpeResidual, const FloatVec& F_wCoeff, const FloatVec& F_impulseResponse, FloatVec& F_tbpeInnovation, Shortint& F_tbpeIndexCode, Shortint& F_tbpeGridCode, Shortint& F_tbpeMatrixCode) <dp n="d33"/> { FloatVec F_filtered(F_subframeLength); /* compute correlation between impulse response and speech */ FloatVec F_corrIS(F_subframeLength); F_crossCorr(F_wMpeResidual,F_impulseResponse,F_corrIS); /* test for all grids and all matrices */ Float F_bestCorr=0.0; Float F_bestPower=1.0; F_tbpeIndexCode=0; F_tbpeGridCode=0; F_tbpeMatrixCode=0; for (Shortint F_matrix=0;F_matrix<F_nrTbpeMatrices; F_matrix++) for (Shortint F_grid=0;F_grid<F_nrTbpeGrids;F_grid++) { /* calculate cross correlations */ FloatVec F_cross(F_nrTbpePulses); F_crossCorrOfTransfMatrix(F_corrIS, F_grid, F_matrix, F_cross); /* approximate the pulses with sign of cross correlation */ Shortint F_index=0; FloatVec F_signVector(F_nrTbpePulses); for (int 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); } /* construct filtered excitation vector */ F_construct(F_index,F_grid,F_matrix,F_tbpeInnovation); F_zeroStateFilter(F_tbpeInnovation,F_wCoeff,F_filtered); /* compute power and correlations */ Float F_power; Float F_corr; F_calcPower(F_filtered, F_power); F_calcCorr(F_cross, F_signVector, F_corr); /* make decision */ Shortint F_updated; F_decision(F_corr, <dp n="d34"/> F_power, F_index, F_grid, F_matrix, F_bestCorr, F_bestPower, F_tbpeIndexCode, F_tbpeGridCode, F_tbpeMatrixCode, F_updated); } F_construct(F_tbpeIndexCode,F_tbpeGridCode,F_tbpeMatrixCode, F_tbpeInnovation); return F_bestCorr/F_bestPower; } /* * function F_SpeSubTbpe∷F_gainQuant * */ void F_SpeSubTbpe∷F_gainQuant( const Float& F_excNormFactor, const Float& F_avgMpeAmpmp, const Float& F_optGain, Shortint& F_tbpeGainCode, Float& F_tbpeGain) { Float F_logGain; if (F_optGain>0) /* sanity check*/ F_logGain=log(F_optGain); else { F_logGain=F_tbpeDeltaQuantTable[0]; cerr<<"ERROR:F_SpeSubTbpe∷F_gainQuant:F_optGain<=0" <<endl; } Float F_predGain; if ((F_excNormFactor>0)&&(F_avgMpeAmp>0))/* sanity check */ F_predGain=log(F_excNormFactor)+ F_tbpeDeltaPredCoeff*log(F_avgMpeAmp); else { F_predGain=F_tbpeDeltaQuantTable[0]; cerr<<"ERROR:F_SpeSubTbpe∷F_gainQuant:F_excNormFactor <=0 or F_avgMpeAmp<=0"<<endl; } Float F_delta=F_logGain-F_predGain; F_tbpeGainCode=F_quantize(F_delta); F_tbpeGain=exp(F_predGain+ F_tbpeDeltaQuantTable[F_tbpeGainCode]); } /* * function F_SpeSubTbpe∷F_quantize * <dp n="d35"/> Shortint F_SpeSubTbpe∷F_quantize(const Float value) { Shortint i=0; if (value>F_tbpeDeltaLimitTable[F_nrTbpeDeltaGainLevel-2]) i=F_nrTbpeDeltaGainLevel-1; else while (value>F_tbpeDeltaLimitTable[i]) i++; return i; } <dp n="d36"/> MAIN.HH /* * class F_SpeMain * * main class for speech encoder * * 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(); /* in,first samples */ /* constructor */ void main( const FloatVec& F_speechFrame, /* in,16 bit speech frame */ ShortVec& F_analysisData); /* out,analysis data frame */ /* main routine */ private: F_SpeFrame F_speFrame; /* frame processing */ F_SpeSubPre F_speSubPre; /* subframe pre processing */ F_SpeSubLtp F_speSubLtp; /* LTP analysis */ F_SpeSubMpe F_speSubMpe; /* MPE analysis */ F_SpeSubTbpe F_speSubTbpe; /*"TBPE analysis */ F_SpeSubPost F_speSubPost; /* subframe post processing */ F_SpePost F_spePost; /* post processing */ FloatVec F_speechSave; /* speech saved between * * frames */ FloatVec F_lspPrev; /* previous LSP parameters */ FloatVec F_ltpHistory; /* LTP history */ FloatVec F_weightFilterRingState; /* Weighting filter * ringing states */ FloatVec F_syFilterState; /* Synthesis filter states */ }; #endif <dp n="d37"/> SPE_DEF.HH /* * module F_speDef * * constant definitions for speech encoder * */ #ifndef F_speDef_h #define F_speDef_h #include"typedefs.h" #include"FloatVec.hh" #include"ShortVec.hh" #include"LongVec.hh″ const Float F_tbpeDeltaPredCoeff=1.03; /*Delta prediction coefficient */ extern const FloatVec F_tbpeDeltaQuantTable; /* Quantizer table for TBPE delta gain */ extern const FloatVec F_tbpeDeltaLimitTable; /* Limits for gain delta quantizer */ #endif <dp n="d38"/> SUB_MPE.HH /* * class F_SpeSubMpe * * Multipulse innovation analysis * * 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(); /* constructor */ void main( const FloatVec& F_wCoeff, /* in */ Float F_excNormfactor, /* in */ const FloatVec& F_wLtpResidual, /* in */ const FloatVec& F_impulseResponse, /* 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 */ Float& F_avgMpeAmp); /* out */ /* Main routine for module F_SpeSubMpe */ Shortint F_maxMagIndex( const FloatVec& F_corrVec, /* in */ const ShortVec& F_posTaken); /* in */ /* Search for pulse position with max correlation so far */ Shortint F_maxMagIndexRestr( const FloatVec& F_corrVec, /* in */ const ShortVec& F_phaseTaken); /* in */ /* Search for pulse position with max correlation so far*/ void F_calc2OptAmps( const ShortVec& F_posVec, /* in */ const FloatVec& F_autoCorr, /* in */ const FloatVec& F_crossCorr, /* in */ FloatVec& F_optAmp); /* out */ /* Solve for 2 optimal amplitudes */ void F_calc3OptAmps( const ShortVec& F_posVec, /* in */ <dp n="d39"/> const FloatVec& F_autoCorr, /* in */ const FloatVec& F_crossCorr, /* in */ FloatVec& F_optAmp); /* out */ /* Solve for 3 optimal amplitudes */ void F_calc4OptAmps( const ShortVec& F_posVec, /* in */ const FloatVec& F_autoCorr, /* in */ const FloatVec& F_crossCorr, /* in */ FloatVec& F_optAmp); /* out */ /* Solve for 4 optimal amplitudes */ void F_updateCrossCorr( const FloatVec& F_autoCorr, /* in */ const Shortint F_pos, /* in */ const Float F_gain, /* in */ FloatVec& F_crossCorrUpd); /* out */ /* Update crosscorrelation vector */ void F_autoCorrelate( const FloatVec& F_impulseResponse, /* in */ FloatVec& F_autoCorr); /* out */ /* Compute autocorrelation vector of impulse response */ void F_crossCorrelate( const FloatVec& F_impulseResponse, /* in */ const FloatVec& F_wLtpResidual, /* in */ FloatVec& F_crossCorr); /* out */ /* Compute crosscorrelation between input speech * and impulse response */ void F_searchUnRestricted( const FloatVec& F_autoCorr, /* in */ const FloatVec& F_crossCorr, /* in */ ShortVec& F_seqPosVector); /* out */ /* Search for 5 pulses with no restrictions regarding * possible positions */ void F_searchRestricted( const FloatVec& F_autoCorr, /* in */ const FloatVec& F_crossCorr, /* in */ ShortVec& F_posVec, /* in */ ShortVec& F_phaseTaken, /* in */ FloatVec& F_pulseAmp); /* in */ /* Search for 3 pulses with restrictions regardnig * possible positions */ Float F_calcMpePredErr( const ShortVec& F_posVec, /* in */ <dp n="d40"/> const FloatVec& F_pulseAmp, /* in */ const FloatVec& F_impulseResponse, /* in */ const FloatVec& F_wTarget); /* in */ /* Calculate the prediction gain of the candidate * mpe vector */ void F_reoptSearch( const FloatVec& F_autoCorr, /* in */ const FloatVec& F_crossCorr, /* in */ const FloatVec& F_impulseResponse, /* in */ const FloatVec& F_wTarget, /* in */ const ShortVec& F_segPosVector, /* in */ ShortVec& F_mpePosVector, /* out */ FloatVec& F_mpePulseAmp); /* out */ /* Find the position combination that gives * the best prediction gain */ void F_openLoopQuantize( const Float& F_excEnergy, /* in */ FloatVec& F_pulseAmp, /* out */ ShortVec& F_mpeAmpVector, /* out */ ShortVec& F_mpeSignVector, /* out */ Shortint& F_mpeBlockMaxCode); /* out */ /* Calculate blockMax and openloop quantize * blockmax and pulses */ void F_makeInnVector( constFloatVec& F_pulseAmp, /* in */ const ShortVec& F_mpePosVector, /* in */ FloatVec& F_mpeInnovation); /* out */ /* Make innovation vector */ void F_orderPositions( ShortVec& F_mpePosVector, /* in/out */ ShortVec& F_mpeAmpVector, /* in/out */ ShortVec& F_mpeSignVector); /* in/out */ /* Order positions(optimum position encoding) */ 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 */ /* Construct codewords */ void F_makeMpeResidual( const FloatVec& F_mpeInnovation, /* in */ const FloatVec& F_wCoeff, /* in */ const FloatVec& F_wLtpResidual, /* in */ FloatVec& F_wMpeResidual); /* out */ <dp n="d41"/> /* Make new weigthed residual with MPE contribution * removed */ Float F_computeAvgAmp( Float F_excNormFactor, /* in */ const FloatVec& F_pulseAmp); /* in */ /* Compute average multipulse amplitude */ }; #endif <dp n="d42"/> SUB TBPE.HH /* * class F SpeSubTbpe * * Transformed Binary Pulse Excited codebook * * 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(); /* constructor */ void F_SpeSubTbpe::main( const FloatVec& F_wMpeResidual, /* in,Weighted MPE * residual = */ * F_wLtpResidual with MPE*/ const FloatVec& F_wCoeff, /* in,weighted direct form * coeff */ const Float& F_excNormFactor, /* in,Excitation * normalization factor */ const Float& F_avgMpeAmp, /* in,average Mp * amplitude */ const FloatVec& F_impulseResponse, /* in,impulse response for * the search filter */ FloatVec& F_tbpeInnovation,/* out,TBPE innovation, * quanTized gain included*/ Shortint& F_tbpeGainCode, /* our,TBPE gain code */ Shortint& F_tbpeIndexcode, /* out,TBPE pulse * sign code */ Shortint& F_tbpeGridCode, /* out,TBPE grid code */ Shortint& F_tbpeMatrixCode);/* out,TBPE transform * matrix code */ /* Main routin for TBPE codebook search */ void F crossCorr( const FloatVec& v1, /* in,Target Vector 1 */ const FloatVec& v2, /* in,Target Vector 2 */ FloatVec& F_corr); /* out,Cross correlated * vector */ /* Calculate cross correlation */ <dp n="d43"/> void F_crossCorrOfTransfMatrix( const FloatVec& vl, /* in,Target vector */ const Shortint grid, /* in,The grid number */ const Shortint matrix, /* in,The matrix number */ FloatVec& F_crossCorr); /* out,Cross correlated * vector */ /* Calculate cross correlation for the * transformation matrix */ void F_zeroStateFilter( constFloatVec& in, /* in,Vector to be * filtered */ const FloatVec& F_denCoeff, /* in,Direct form * coefficient */ FloatVec& out); /* out,Filtered vector */ /* Zero state filter with coefficients F_denCoeff */ void F_construct( const Shortint index, /* in,Index code */ const Shortint grid, /* in,Grid code */ const Shortint matrix, /* in,Matrix code */ FloatVec& vec); /* out,Constructed * excitation */ /* Construct a excitation vector */ void F_calcPower( const FloatVec& F_in, /* in,input vector */ Float& F_power); /* out,power of input * vector */ /* Calculate power of input vector */ void F_calcCorr( const FloatVec& F_cross, /* in,cross corr of * transf matrix */ const FloatVec& F_signVector, /* in,vector of signs */ Float&F_corr); /* out,correlation of * input vectors */ /* Calculate power of input vector */ void F_decision( const Float F_corr, /* in,tested correlation*/ const Float F_power, /* in,tested power */ const Shortint F_index, /* in,tested index */ const Shortint F_grid, /* in,tested grid */ const Shortint F_matrix, /* in,tested matrix */ Float& F_bestCorr, /* in/out,saved best * correlation */ Float& F_bestPower, /* in/out,saved best * power */ Shortint& F_tbpeIndexCode, /* in/out,saved best <dp n="d44"/> * index */ Shortint& F_tbpeGridCode, /* in/out,saved best grid */ Shortint& F_tbpeMatrixCode, /* in/out,saved best * matrix */ Shortint& F_updated); /* out,TRUE if parameters * has been updated. * used for testing only */ /* Make decision */ Float F_search( const FloatVec& F_wMpeResidual, /* in,Weighted MPE residual=F_wLtpResidual * with MPE innovation removed */ const FloatVec& F_wCoeff, /* in,Weighted direct form coeffs */ const FloatVec& F_impulseResponse, /* in,impulse response for the search filter */ FloatVec& F_tbpeInnovation, /* out,TBPE innovation,quantized gain included */ Shortint& F_tbpeIndexCode, /* out,TBPE pulse sign code */ Shortint& F_tbpeGridCode, /* out,TBPE grid code */ Shortint& F_tbpeMatrixCode); /* out,TBPE transform matrix code */ /* search for best index, * approximate index with sign of correlation, * examine all grids and matrices * return optimal innovation,gainCode,index,grid,matrix */ void F_gainQuant( const Float& F_excNormFactor, /* in,Excitation normalization factor */ const Float& F_avgMpeAmp, /* in,average MP amplitude */ const Float& F_optGain, /* in,optimal TBPE gain */ Shortint& F_tbpeGainCode, /* out,TBPE gain code */ Float& F_tbpeGain); /* out,TBPE gain */ /* Predict and quantize TBPE gain */ Shortint F_quantize( const Float value); /* in,value to be quantized */ /* Quantize TBPE gain */ }; #endif
Claims (10)
1.一种在综合分析线性预测编码中用于激励的增益量化方法:
为来自第一码本的最优第一矢量确定最优第一增益;
量化所说的最优第一增益;
为来自第二码本的最优第二矢量确定最优第二增益;
由至少是所说的量化最优第一增益确定所说的最优第二增益的对数的第一线性预测;
量化所说的最优第二增益的对数与所说的第一线性预测之间的第一误差。
2.根据权利要求1的一种方法,其中所说的第一线性预测包括所说的量化最优第一增益与所说的最优第一矢量的能量的平方根测量值的乘积的对数。
3.根据权利要求2的一种方法,其中所说的第一码本是自适应码本,而所说的第二码本是一固定码本。
4.根据权利要求2的一种方法,其中所说的第一码本是多脉冲激励码本,而所说的第二码本是转换双脉冲激励码本。
5.根据权利要求3或4的一种方法,其中所说的测量值包括所说最优第一矢量的分量的平方和的平方根。
6.根据权利要求4的一种方法,其中所说测量值包括所说的最优第一矢量的平均脉冲幅度。
7.根据权利要求1的一种方法,包括更多的步骤:
由所说的量化第一差值确定和量化所说的最优第二增益;
由第三码本最优第三矢量确定最优第三增益;
由至少是所说的量化最优第二增益确定所说的最优第三增益的对数的第二线性预测;
量化在所说的最优第三增益的对数与所说的第二线性预测之间的第二差值。
8.根据权利要求7的方法,其中所说的第一码本是自适应码本,所说的第二码本是多脉冲激励码本,而所说的第三码本是转换双脉冲激励码本。
9.根据权利要求1的方法,其中所说的第一线性预测也包括来自前面所确定的激励的量化增益。
10.根据权利要求7的方法,其中所说的第一和第二线性预测也包括来自前面所确定的激励的量化增益。
Applications Claiming Priority (3)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
SE9501640A SE504397C2 (sv) | 1995-05-03 | 1995-05-03 | Metod för förstärkningskvantisering vid linjärprediktiv talkodning med kodboksexcitering |
SE95016408 | 1995-05-03 | ||
SE9501640-8 | 1995-05-03 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN1188556A true CN1188556A (zh) | 1998-07-22 |
CN1151492C CN1151492C (zh) | 2004-05-26 |
Family
ID=20398181
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CNB961949120A Expired - Fee Related CN1151492C (zh) | 1995-05-03 | 1996-04-12 | 综合-分析线性预测语音编码中的增益量化方法 |
Country Status (8)
Country | Link |
---|---|
US (1) | US5970442A (zh) |
EP (1) | EP0824750B1 (zh) |
JP (1) | JP4059350B2 (zh) |
CN (1) | CN1151492C (zh) |
AU (1) | AU5519696A (zh) |
DE (1) | DE69610915T2 (zh) |
SE (1) | SE504397C2 (zh) |
WO (1) | WO1996035208A1 (zh) |
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1820306B (zh) * | 2003-05-01 | 2010-05-05 | 诺基亚有限公司 | 可变比特率宽带语音编码中增益量化的方法和装置 |
Families Citing this family (18)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US6266419B1 (en) * | 1997-07-03 | 2001-07-24 | At&T Corp. | Custom character-coding compression for encoding and watermarking media content |
JP3998330B2 (ja) * | 1998-06-08 | 2007-10-24 | 沖電気工業株式会社 | 符号化装置 |
US7072832B1 (en) | 1998-08-24 | 2006-07-04 | Mindspeed Technologies, Inc. | System for speech encoding having an adaptive encoding arrangement |
US6330531B1 (en) * | 1998-08-24 | 2001-12-11 | Conexant Systems, Inc. | Comb codebook structure |
SE519563C2 (sv) * | 1998-09-16 | 2003-03-11 | Ericsson Telefon Ab L M | Förfarande och kodare för linjär prediktiv analys-genom- synteskodning |
US6397178B1 (en) | 1998-09-18 | 2002-05-28 | Conexant Systems, Inc. | Data organizational scheme for enhanced selection of gain parameters for speech coding |
US6581032B1 (en) * | 1999-09-22 | 2003-06-17 | Conexant Systems, Inc. | Bitstream protocol for transmission of encoded voice signals |
CA2327041A1 (en) * | 2000-11-22 | 2002-05-22 | Voiceage Corporation | A method for indexing pulse positions and signs in algebraic codebooks for efficient coding of wideband signals |
DE10124420C1 (de) * | 2001-05-18 | 2002-11-28 | Siemens Ag | Verfahren zur Codierung und zur Übertragung von Sprachsignalen |
DE102004036154B3 (de) * | 2004-07-26 | 2005-12-22 | Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. | Vorrichtung und Verfahren zur robusten Klassifizierung von Audiosignalen sowie Verfahren zu Einrichtung und Betrieb einer Audiosignal-Datenbank sowie Computer-Programm |
US20070174054A1 (en) * | 2006-01-25 | 2007-07-26 | Mediatek Inc. | Communication apparatus with signal mode and voice mode |
EP2227682A1 (en) * | 2007-11-06 | 2010-09-15 | Nokia Corporation | An encoder |
CA2704812C (en) * | 2007-11-06 | 2016-05-17 | Nokia Corporation | An encoder for encoding an audio signal |
CN101499281B (zh) * | 2008-01-31 | 2011-04-27 | 华为技术有限公司 | 一种语音编码中的增益量化方法及装置 |
CN102057424B (zh) * | 2008-06-13 | 2015-06-17 | 诺基亚公司 | 用于经编码的音频数据的错误隐藏的方法和装置 |
US9626982B2 (en) | 2011-02-15 | 2017-04-18 | Voiceage Corporation | Device and method for quantizing the gains of the adaptive and fixed contributions of the excitation in a CELP codec |
WO2012109734A1 (en) * | 2011-02-15 | 2012-08-23 | Voiceage Corporation | Device and method for quantizing the gains of the adaptive and fixed contributions of the excitation in a celp codec |
WO2014007349A1 (ja) * | 2012-07-05 | 2014-01-09 | 日本電信電話株式会社 | 符号化装置、復号装置、これらの方法、プログラム、および記録媒体 |
Family Cites Families (6)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
JP2776050B2 (ja) * | 1991-02-26 | 1998-07-16 | 日本電気株式会社 | 音声符号化方式 |
GB9118217D0 (en) * | 1991-08-23 | 1991-10-09 | British Telecomm | Speech processing apparatus |
US5327520A (en) * | 1992-06-04 | 1994-07-05 | At&T Bell Laboratories | Method of use of voice message coder/decoder |
US5313554A (en) * | 1992-06-16 | 1994-05-17 | At&T Bell Laboratories | Backward gain adaptation method in code excited linear prediction coders |
EP0751496B1 (en) * | 1992-06-29 | 2000-04-19 | Nippon Telegraph And Telephone Corporation | Speech coding method and apparatus for the same |
US5615298A (en) * | 1994-03-14 | 1997-03-25 | Lucent Technologies Inc. | Excitation signal synthesis during frame erasure or packet loss |
-
1995
- 1995-05-03 SE SE9501640A patent/SE504397C2/sv not_active IP Right Cessation
-
1996
- 1996-04-12 JP JP53322296A patent/JP4059350B2/ja not_active Expired - Lifetime
- 1996-04-12 EP EP96912361A patent/EP0824750B1/en not_active Expired - Lifetime
- 1996-04-12 AU AU55196/96A patent/AU5519696A/en not_active Abandoned
- 1996-04-12 WO PCT/SE1996/000481 patent/WO1996035208A1/en active IP Right Grant
- 1996-04-12 CN CNB961949120A patent/CN1151492C/zh not_active Expired - Fee Related
- 1996-04-12 DE DE69610915T patent/DE69610915T2/de not_active Expired - Lifetime
-
1997
- 1997-10-31 US US08/961,867 patent/US5970442A/en not_active Expired - Lifetime
Cited By (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN1820306B (zh) * | 2003-05-01 | 2010-05-05 | 诺基亚有限公司 | 可变比特率宽带语音编码中增益量化的方法和装置 |
Also Published As
Publication number | Publication date |
---|---|
JPH11504438A (ja) | 1999-04-20 |
WO1996035208A1 (en) | 1996-11-07 |
DE69610915D1 (de) | 2000-12-14 |
US5970442A (en) | 1999-10-19 |
EP0824750B1 (en) | 2000-11-08 |
CN1151492C (zh) | 2004-05-26 |
DE69610915T2 (de) | 2001-03-15 |
SE9501640L (sv) | 1996-11-04 |
EP0824750A1 (en) | 1998-02-25 |
AU5519696A (en) | 1996-11-21 |
SE504397C2 (sv) | 1997-01-27 |
SE9501640D0 (sv) | 1995-05-03 |
JP4059350B2 (ja) | 2008-03-12 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN1188556A (zh) | 综合-分析线性预测语音编码中的增益量化方法 | |
CN1121683C (zh) | 语音编码 | |
EP2301021B1 (en) | Device and method for quantizing lpc filters in a super-frame | |
JP5188990B2 (ja) | Celp技術における、デジタルオーディオ信号の改善された符号化/復号化 | |
EP0422232A1 (en) | Voice encoder | |
CN101911185B (zh) | 矢量量化装置、矢量反量化装置及其方法 | |
AU6397094A (en) | Vector quantizer method and apparatus | |
CN102682778B (zh) | 编码装置以及编码方法 | |
SE506379C3 (sv) | Lpc-talkodare med kombinerad excitation | |
CN1134764C (zh) | 语音编码的方法和装置 | |
CN1173939A (zh) | 综合分析的语音编码方法 | |
US20100185442A1 (en) | Adaptive sound source vector quantizing device and adaptive sound source vector quantizing method | |
US20050114123A1 (en) | Speech processing system and method | |
US8200483B2 (en) | Adaptive sound source vector quantization device, adaptive sound source vector inverse quantization device, and method thereof | |
CN1325529A (zh) | 用于语音编码的自适应规则 | |
CN103081007A (zh) | 量化装置及量化方法 | |
JP3147807B2 (ja) | 信号符号化装置 | |
JPH1063300A (ja) | 音声復号化装置及び音声符号化装置 | |
CN1235335A (zh) | 改善话音信号编码器性能的方法 | |
CN1159044A (zh) | 声音编码装置 | |
JP3174779B2 (ja) | 拡散音源ベクトル生成装置及び拡散音源ベクトル生成方法 | |
Delprat et al. | Fractional excitation and other efficient transformed codebooks for CELP coding of speech | |
JP3174781B2 (ja) | 拡散音源ベクトル生成装置及び拡散音源ベクトル生成方法 | |
JP3174780B2 (ja) | 拡散音源ベクトル生成装置及び拡散音源ベクトル生成方法 | |
Choi et al. | On Reducing the Complexity of the VSELP Coder |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
C14 | Grant of patent or utility model | ||
GR01 | Patent grant | ||
CF01 | Termination of patent right due to non-payment of annual fee |
Granted publication date: 20040526 Termination date: 20150412 |
|
EXPY | Termination of patent right or utility model |