CN1151492C - 综合-分析线性预测语音编码中的增益量化方法 - Google Patents

综合-分析线性预测语音编码中的增益量化方法 Download PDF

Info

Publication number
CN1151492C
CN1151492C CNB961949120A CN96194912A CN1151492C CN 1151492 C CN1151492 C CN 1151492C CN B961949120 A CNB961949120 A CN B961949120A CN 96194912 A CN96194912 A CN 96194912A CN 1151492 C CN1151492 C CN 1151492C
Authority
CN
China
Prior art keywords
gain
floatvec
const
code book
optimum
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.)
Expired - Fee Related
Application number
CNB961949120A
Other languages
English (en)
Other versions
CN1188556A (zh
Inventor
Y・蒂内尔
Y·蒂内尔
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Telefonaktiebolaget LM Ericsson AB
Original Assignee
Telefonaktiebolaget LM Ericsson AB
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Telefonaktiebolaget LM Ericsson AB filed Critical Telefonaktiebolaget LM Ericsson AB
Publication of CN1188556A publication Critical patent/CN1188556A/zh
Application granted granted Critical
Publication of CN1151492C publication Critical patent/CN1151492C/zh
Anticipated expiration legal-status Critical
Expired - Fee Related legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G10MUSICAL INSTRUMENTS; ACOUSTICS
    • G10LSPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
    • G10L19/00Speech 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/04Speech 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/08Determination or coding of the excitation function; Determination or coding of the long-term prediction parameters
    • G10L19/083Determination or coding of the excitation function; Determination or coding of the long-term prediction parameters the excitation function being an excitation gain
    • GPHYSICS
    • G10MUSICAL INSTRUMENTS; ACOUSTICS
    • G10LSPEECH ANALYSIS TECHNIQUES OR SPEECH SYNTHESIS; SPEECH RECOGNITION; SPEECH OR VOICE PROCESSING TECHNIQUES; SPEECH OR AUDIO CODING OR DECODING
    • G10L19/00Speech 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/0001Codebooks
    • G10L2019/0004Design or structure of the codebook
    • G10L2019/0005Multi-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是可使用本发明的方法的综合-分析线性预测语音编码器的一个实施例的框图;
图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示出了转换双脉冲激励的原理,这在参考文献(8)和在所附的程序列表中已有详细的描述。双脉冲码本可包含例如有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的对数。
log ( g ^ 2 ) = b + c · log ( g 1 Q )
其中 代表预测增益g2。根据本发明的一个实施例,不量化g2而根据下列公式计算在实际和预测增益g2的对数之间的差δ
δ = log ( g 2 ) - log ( g ^ 2 ) = log ( g 2 ) - ( b + c · log ( g 1 Q ) )
然后再进行量化。
图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)]2n=0..N-1      加权误差的平方和
N    =40(for example)            矢量长度
sw(n)=w(n)*s(n)                 加权语音
hw(n)=w(n)*h(n)                 综合滤波器的加权冲激响应
min E i = min Σ n = 0 N - 1 [ e w i ( n ) ] 2
                                  在自适应码本中搜索最优系数
∂ E i ∂ g i = 0 ⇒ g i = Σ n = 0 N - 1 s w ( n ) · a i ( n ) * h w ( n ) Σ n = 0 N - 1 [ a i ( n ) * h w ( n ) ] 2
                                  相对于系数i的增益
                     参考文献
[1]P.Kroon,E.Deprettere,
   "A class of Analysis-by-Synthesis predictive coders for
   high quality speech coding at rates between 4.6 and 16
   kbit/s.",
   IEEE Jour. Sel. Areas Com.,Vol. SAC-6,No. 2,Feb. 1988
[2]N.Moreau,P.Dymarski,
   "Selection of Excitation Vectors for the CELP Coders",
   IEEE transactions on speech and audio processing,Vol.
   2,No 1,Part 1,Jan.1994
[3]I.A.Gerson,M.A.Jasiuk,
   "Vector Sum Excited Linear Prediction(VSELP)",
   Advances in Speech Coding,Ch.7,Kluwer Academic
   Publishers,1991
[4]R.Salami,C.Laflamme,J. Adoul,
   "ACELP speech coding at 8 kbit/s with a 10 ms frame:A
   candidate for CCITT."
   IEEE Workshop on Speech Coding for telecommunications,
   Sainte-Adele,1993
[5]P.Hedelin,A.Bergstrm,
   "Amplitude Quantization for CELP Excitation Signals",
   IEEE ICASSP -91, Toronto
[6]P.Hedelin,
   "A Multi-Stage Perspective on CELP Speech Coding",IEEE
   ICASSP -92,San Francisco
[7]B.Atal,J.Remde,
   "A new model of LPC excitation for producing natural--
   sounding speech at low bit rates",
   IEEE ICASSP-82,Paris,1982.
[8]R.Salami,
   "Binary pulse excitation:A novel approach to low com-
   plexity CELP coding",
   Kluwer Academic Pub.,Advances in speech coding,1991.
                              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);
        <!-- SIPO <DP n="12"> -->
        <dp n="d12"/>
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]);
        <!-- SIPO <DP n="13"> -->
        <dp n="d13"/>
    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_avgMpeAmp,

                      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_syFilterState,

                      F_accPower);
   }
   F_spePost.main(F_energy,

                F_lspCurr,

                F_accPower,

                F_energyCode,

                F_lspVQCodes,

                F_ltpGainCodes,

                F_ltpLagCodes,

                F_mpeBlockMaxCodes,

                F_mpeAmpCodes,

                F_mpeSignCodes,

                F_mpePositionCodes,

                F_tbpeGainCodes,

                F_tbpeIndexCodes,

                F_tbpeMatrixCodes,

                F_tbpeGridCodes,

                F_ltpHistory,

                F_syFilterState,

                F_lspPrev,

                F_analysisData);
        <!-- SIPO <DP n="14"> -->
        <dp n="d14"/>
                             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);
        <!-- SIPO <DP n="15"> -->
        <dp n="d15"/>
                           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);
        <!-- SIPO <DP n="16"> -->
        <dp n="d16"/>
   /* 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_seqPosVector,

    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);
}
        <!-- SIPO <DP n="17"> -->
        <dp n="d17"/>
/*
 *  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;

          }
        <!-- SIPO <DP n="18"> -->
        <dp n="d18"/>
        }

  return maxI;
}
/*
 *  function F_SpeSubMpe∷F_calc20ptAmps
 *
 *  Compute optimal amplitudes for 2 selected pulses
 *
 */
void F_SpeSubMpe∷F_calc20ptAmps(
   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_calc30ptAmps
 *
 *  Compute optimal amplitudes for 3 selected pulses
 *
 */
void F_SpeSubMpe∷F_calc30ptAmps(
   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];
        <!-- SIPO <DP n="19"> -->
        <dp n="d19"/>
   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_calc40ptAmps
 *
 *  Compute optimal amplitudes for 4 selected pulses
 *  (Cholesky decomposition)
 *
 */
void F_SpeSubMpe∷F_calc40ptAmps(
   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];

    }
        <!-- SIPO <DP n="20"> -->
        <dp n="d20"/>
   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;
        <!-- SIPO <DP n="21"> -->
        <dp n="d21"/>
     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++){
        <!-- SIPO <DP n="22"> -->
        <dp n="d22"/>
         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=l;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
        <!-- SIPO <DP n="23"> -->
        <dp n="d23"/>
               * selected positions */

              switch (pulse+1) {

              case 2 :

                 F_calc20ptAmps(F_seqPosVector,

                                F_autoCorr,
                                 F_crossCorr,
                                F_pulseAmp);

                 break;

              case 3:

                 F_calc30ptAmps(F_seqPosVector,

                                F_autoCorr,

                                F_crossCorr,

                                F_pulseAmp);

                 break;

              case 4:

                 F_calc40ptAmps(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,
        <!-- SIPO <DP n="24"> -->
        <dp n="d24"/>
                                   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_calc20ptAmps(F_posVec,

                       F_autoCorr,

                       F_crossCorr,

                       F_pulseAmp);

           break;

        case 3:

           F_calc30ptAmps(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;
        <!-- SIPO <DP n="25"> -->
        <dp n="d25"/>
   /* 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;
        <!-- SIPO <DP n="26"> -->
        <dp n="d26"/>
   /* 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 */
        <!-- SIPO <DP n="27"> -->
        <dp n="d27"/>
      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]])

             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;

       }

   }
  }
  /*
   *  function F_SpeSubMpe∷F_makeInnVector
   *
   */
  void F_SpeSubMpe∷F_makeInnVector(
        <!-- SIPO <DP n="28"> -->
        <dp n="d28"/>
   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];
        <!-- SIPO <DP n="29"> -->
        <dp n="d29"/>
    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;
        <!-- SIPO <DP n="30"> -->
        <dp n="d30"/>
   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;
}
        <!-- SIPO <DP n="31"> -->
        <dp n="d31"/>
                          SUB_TBPE.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
        <!-- SIPO <DP n="32"> -->
        <dp n="d32"/>
 *
 */
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--) {

       signal -= F_denCoeff[m] * F_state[m];

       F_state[m] = F_state[m-1];

    }
        <!-- SIPO <DP n="33"> -->
        <dp n="d33"/>
        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 (iht 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,
        <!-- SIPO <DP n="34"> -->
        <dp n="d34"/>
                                      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)
        <!-- SIPO <DP n="35"> -->
        <dp n="d35"/>
{     
   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,
        <!-- SIPO <DP n="36"> -->
        <dp n="d36"/>
                  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_avgMpeAmp,
   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
 *
        <!-- SIPO <DP n="37"> -->
        <dp n="d37"/>
 */
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;
}
        <!-- SIPO <DP n="38"> -->
        <dp n="d38"/>
/*
 *  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
        <!-- SIPO <DP n="39"> -->
        <dp n="d39"/>
                          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
        <!-- SIPO <DP n="40"> -->
        <dp n="d40"/>
                           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_calc20ptAmps(

    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_calc30ptAmps(

    const ShortVec& F_posVec,            /* in */
        <!-- SIPO <DP n="41"> -->
        <dp n="d41"/>
   const FloatVec& F_autoCorr,         /* in */
   const FloatVec& F_crossCorr,        /* in */
   FloatVec& F_optAmp);                /* out */
/* Solve for 3 optimal amplitudes */
void F_calc40ptAmps(
   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 regarding
 * possible positions */
Float F_calcMpePredErr(
   const ShortVec& F_posVec,           /* in */
        <!-- SIPO <DP n="42"> -->
        <dp n="d42"/>
   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_seqPosVector,     /* 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(
   const FloatVec& 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 */
        <!-- SIPO <DP n="43"> -->
        <dp n="d43"/>
   /* 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
        <!-- SIPO <DP n="44"> -->
        <dp n="d44"/>
                          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,  /* out,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 */
        <!-- SIPO <DP n="45"> -->
        <dp n="d45"/>
void F_crossCorrOfTransfMatrix(
   const FloatVec& v1,        /* 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(
   const FloatVec& 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
        <!-- SIPO <DP n="46"> -->
        <dp n="d46"/>
                                  * 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的方法,其中根据预先传送送的语音帧,对量化增益执行所述第一和第二线性预测。
CNB961949120A 1995-05-03 1996-04-12 综合-分析线性预测语音编码中的增益量化方法 Expired - Fee Related CN1151492C (zh)

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 CN1188556A (zh) 1998-07-22
CN1151492C true 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 (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2009097763A1 (zh) * 2008-01-31 2009-08-13 Huawei Technologies Co., Ltd. 一种增益量化方法及装置
CN104505097A (zh) * 2011-02-15 2015-04-08 沃伊斯亚吉公司 检索激励的固定贡献的量化增益的设备和方法
US9911425B2 (en) 2011-02-15 2018-03-06 Voiceage Corporation Device and method for quantizing the gains of the adaptive and fixed contributions of the excitation in a CELP codec

Families Citing this family (16)

* Cited by examiner, † Cited by third party
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
BRPI0409970B1 (pt) * 2003-05-01 2018-07-24 Nokia Technologies Oy “Método para codificar um sinal de som amostrado, método para decodificar um fluxo de bit representativo de um sinal de som amostrado, codificador, decodificador e fluxo de bit”
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
WO2009059632A1 (en) * 2007-11-06 2009-05-14 Nokia Corporation An encoder
BRPI0722269A2 (pt) * 2007-11-06 2014-04-22 Nokia Corp Encodificador para encodificar um sinal de áudio, método para encodificar um sinal de áudio; decodificador para decodificar um sinal de áudio; método para decodificar um sinal de áudio; aparelho; dispositivo eletrônico; produto de programa de comoputador configurado para realizar um método para encodificar e para decodificar um sinal de áudio
KR101228165B1 (ko) * 2008-06-13 2013-01-30 노키아 코포레이션 프레임 에러 은폐 방법, 장치 및 컴퓨터 판독가능한 저장 매체
WO2014007349A1 (ja) * 2012-07-05 2014-01-09 日本電信電話株式会社 符号化装置、復号装置、これらの方法、プログラム、および記録媒体

Family Cites Families (6)

* Cited by examiner, † Cited by third party
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
DE69309557T2 (de) * 1992-06-29 1997-10-09 Nippon Telegraph & Telephone Verfahren und Vorrichtung zur Sprachkodierung
US5615298A (en) * 1994-03-14 1997-03-25 Lucent Technologies Inc. Excitation signal synthesis during frame erasure or packet loss

Cited By (6)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
WO2009097763A1 (zh) * 2008-01-31 2009-08-13 Huawei Technologies Co., Ltd. 一种增益量化方法及装置
CN101499281B (zh) * 2008-01-31 2011-04-27 华为技术有限公司 一种语音编码中的增益量化方法及装置
CN104505097A (zh) * 2011-02-15 2015-04-08 沃伊斯亚吉公司 检索激励的固定贡献的量化增益的设备和方法
US9911425B2 (en) 2011-02-15 2018-03-06 Voiceage Corporation Device and method for quantizing the gains of the adaptive and fixed contributions of the excitation in a CELP codec
CN104505097B (zh) * 2011-02-15 2018-08-17 沃伊斯亚吉公司 检索激励的固定贡献的量化增益的设备和方法
US10115408B2 (en) 2011-02-15 2018-10-30 Voiceage Corporation Device and method for quantizing the gains of the adaptive and fixed contributions of the excitation in a CELP codec

Also Published As

Publication number Publication date
EP0824750A1 (en) 1998-02-25
WO1996035208A1 (en) 1996-11-07
DE69610915D1 (de) 2000-12-14
CN1188556A (zh) 1998-07-22
EP0824750B1 (en) 2000-11-08
DE69610915T2 (de) 2001-03-15
SE9501640D0 (sv) 1995-05-03
AU5519696A (en) 1996-11-21
SE9501640L (sv) 1996-11-04
US5970442A (en) 1999-10-19
SE504397C2 (sv) 1997-01-27
JPH11504438A (ja) 1999-04-20
JP4059350B2 (ja) 2008-03-12

Similar Documents

Publication Publication Date Title
CN1151492C (zh) 综合-分析线性预测语音编码中的增益量化方法
CN1121683C (zh) 语音编码
CN1150516C (zh) 语音编码方法和语音编码器
CN100350807C (zh) 在不连续传输期间产生安慰噪声的改进方法
CN1132154C (zh) 多信道信号编码和解码
US8521519B2 (en) Adaptive audio signal source vector quantization device and adaptive audio signal source vector quantization method that search for pitch period based on variable resolution
EP2301021B1 (en) Device and method for quantizing lpc filters in a super-frame
JP5188990B2 (ja) Celp技術における、デジタルオーディオ信号の改善された符号化/復号化
CN1708907A (zh) 用于快速celp参数映射的方法和装置
CN1820306A (zh) 可变比特率宽带语音编码中增益量化的方法和装置
CN101044554A (zh) 可扩展性编码装置、可扩展性解码装置以及可扩展性编码方法
CN1147833C (zh) 生成和编码线状谱平方根的方法和装置
CN1134761C (zh) 综合分析语音编码方法
CN1192357C (zh) 用于语音编码的自适应规则
US20100185442A1 (en) Adaptive sound source vector quantizing device and adaptive sound source vector quantizing method
JPH08272395A (ja) 音声符号化装置
CN1711589A (zh) 在语音编码系统中对增益信息进行编码的方法和装置
US8200483B2 (en) Adaptive sound source vector quantization device, adaptive sound source vector inverse quantization device, and method thereof
WO2004090864A2 (en) Method and apparatus for the encoding and decoding of speech
JPH1063300A (ja) 音声復号化装置及び音声符号化装置
CN1124590C (zh) 改善话音信号编码器性能的方法
JP3174779B2 (ja) 拡散音源ベクトル生成装置及び拡散音源ベクトル生成方法
JP3174781B2 (ja) 拡散音源ベクトル生成装置及び拡散音源ベクトル生成方法
JP3174783B2 (ja) Celp型音声符号化装置及びcelp型音声符号化方法
JP3174780B2 (ja) 拡散音源ベクトル生成装置及び拡散音源ベクトル生成方法

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