EXC_LBC.C
Upload User: meifeng08
Upload Date: 2013-06-18
Package Size: 5304k
Code Size: 73k
Category:

Voice Compress

Development Platform:

C/C++

  1. /*
  2. **
  3. ** File:    exc_lbc.c
  4. **
  5. ** Description: Functions that implement adaptive and fixed codebook
  6. **       operations.
  7. **
  8. ** Functions:
  9. **
  10. **  Computing Open loop Pitch lag:
  11. **
  12. **      Estim_Pitch()
  13. **
  14. **  Harmonic noise weighting:
  15. **
  16. **      Comp_Pw()
  17. **      Filt_Pw()
  18. **
  19. **  Fixed Cobebook computation:
  20. **
  21. **      Find_Fcbk()
  22. **      Gen_Trn()
  23. **      Find_Best()
  24. **      Find_Pack()
  25. **      Find_Unpk()
  26. **      ACELP_LBC_code()
  27. **      Cor_h()
  28. **      Cor_h_X()
  29. **      reset_max_time()
  30. **      D4i64_LBC()
  31. **      G_code()
  32. **      search_T0()
  33. **
  34. **  Adaptive Cobebook computation:
  35. **
  36. **      Find_Acbk()
  37. **      Get_Rez()
  38. **      Decod_Acbk()
  39. **
  40. **  Pitch postfilter:
  41. **      Comp_Lpf()
  42. **      Find_B()
  43. **      Find_F()
  44. **      Filt_Lpf()
  45. **
  46. **  Residual interpolation:
  47. **
  48. **      Comp_Info()
  49. **      Regen()
  50. **
  51. */
  52. /*
  53.     ITU-T G.723 Speech Coder   ANSI-C Source Code     Version 5.00
  54.     copyright (c) 1995, AudioCodes, DSP Group, France Telecom,
  55.     Universite de Sherbrooke.  All rights reserved.
  56. */
  57. #include <stdlib.h>
  58. #include <stdio.h>
  59. #include "typedef.h"
  60. #include "basop.h"
  61. #include "cst_lbc.h"
  62. #include "tab_lbc.h"
  63. #include "lbccodec.h"
  64. #include "util_lbc.h"
  65. #include "exc_lbc.h"
  66. #include "tame.h"
  67. #include "util_cng.h"
  68. /*
  69. **
  70. ** Function:        Estim_Pitch()
  71. **
  72. ** Description: Open loop pitch estimation made twice per frame (one for
  73. **              the first two subframes and one for the last two).
  74. **              The method is based on the maximization of the
  75. **              crosscorrelation of the speech.
  76. **
  77. ** Links to text:   Section 2.9
  78. **
  79. ** Arguments:
  80. **
  81. **  Word16 *Dpnt    Perceptually weighted speech
  82. **  Word16 Start    Starting index defining the subframes under study
  83. **
  84. ** Outputs:
  85. **
  86. ** Return value:
  87. **
  88. **  Word16      Open loop pitch period
  89. **
  90. */
  91. Word16   Estim_Pitch( Word16 *Dpnt, Word16 Start )
  92. {
  93.     int   i,j   ;
  94.     Word32   Acc0,Acc1   ;
  95.     Word16   Exp,Tmp  ;
  96.     Word16   Ccr,Enr  ;
  97.     Word16   Indx = (Word16) PitchMin ;
  98.     Word16   Mxp = (Word16) 30 ;
  99.     Word16   Mcr = (Word16) 0x4000 ;
  100.     Word16   Mnr = (Word16) 0x7fff ;
  101.     Word16   Pr ;
  102.     /* Init the energy estimate */
  103.     Pr = Start - (Word16)PitchMin + (Word16)1 ;
  104.     Acc1 = (Word32) 0 ;
  105.     for ( j = 0 ; j < 2*SubFrLen ; j ++ )
  106.         Acc1 = L_mac( Acc1, Dpnt[Pr+j], Dpnt[Pr+j] ) ;
  107.     /* Main Olp search loop */
  108.     for ( i = PitchMin ; i <= PitchMax-3 ; i ++ ) {
  109.         Pr = sub( Pr, (Word16) 1 ) ;
  110.         /* Energy update */
  111.         Acc1 = L_msu( Acc1, Dpnt[Pr+2*SubFrLen], Dpnt[Pr+2*SubFrLen] ) ;
  112.         Acc1 = L_mac( Acc1, Dpnt[Pr], Dpnt[Pr] ) ;
  113.         /*  Compute the cross */
  114.         Acc0 = (Word32) 0 ;
  115.         for ( j = 0 ; j < 2*SubFrLen ; j ++ )
  116.             Acc0 = L_mac( Acc0, Dpnt[Start+j], Dpnt[Pr+j] ) ;
  117.         if ( Acc0 > (Word32) 0 ) {
  118.             /* Compute Exp and mant of the cross */
  119.             Exp = norm_l( Acc0 ) ;
  120.             Acc0 = L_shl( Acc0, Exp ) ;
  121.             Exp = shl( Exp, (Word16) 1 ) ;
  122.             Ccr = round( Acc0 ) ;
  123.             Acc0 = L_mult( Ccr, Ccr ) ;
  124.             Ccr = norm_l( Acc0 ) ;
  125.             Acc0 = L_shl( Acc0, Ccr ) ;
  126.             Exp = add( Exp, Ccr ) ;
  127.             Ccr = extract_h( Acc0 ) ;
  128.             /* Do the same with energy */
  129.             Acc0 = Acc1 ;
  130.             Enr = norm_l( Acc0 ) ;
  131.             Acc0 = L_shl( Acc0, Enr ) ;
  132.             Exp = sub( Exp, Enr ) ;
  133.             Enr = round( Acc0 ) ;
  134.             if ( Ccr >= Enr ) {
  135.                 Exp = sub( Exp, (Word16) 1 ) ;
  136.                 Ccr = shr( Ccr, (Word16) 1 ) ;
  137.             }
  138.             if ( Exp <= Mxp ) {
  139.                 if ( (Exp+1) < Mxp ) {
  140.                     Indx = (Word16) i ;
  141.                     Mxp = Exp ;
  142.                     Mcr = Ccr ;
  143.                     Mnr = Enr ;
  144.                     continue ;
  145.                 }
  146.                 if ( (Exp+1) == Mxp )
  147.                     Tmp = shr( Mcr, (Word16) 1 ) ;
  148.                 else
  149.                     Tmp = Mcr ;
  150.                 /* Compare with equal exponents */
  151.                 Acc0 = L_mult( Ccr, Mnr ) ;
  152.                 Acc0 = L_msu( Acc0, Enr, Tmp ) ;
  153.                 if ( Acc0 > (Word32) 0 ) {
  154.                     if ( ((Word16)i - Indx) < (Word16) PitchMin ) {
  155.                         Indx = (Word16) i ;
  156.                         Mxp = Exp ;
  157.                         Mcr = Ccr ;
  158.                         Mnr = Enr ;
  159.                     }
  160.                     else {
  161.                         Acc0 = L_mult( Ccr, Mnr ) ;
  162.                         Acc0 = L_negate(L_shr( Acc0, (Word16) 2 ) ) ;
  163.                         Acc0 = L_mac( Acc0, Ccr, Mnr ) ;
  164.                         Acc0 = L_msu( Acc0, Enr, Tmp ) ;
  165.                         if ( Acc0 > (Word32) 0 ) {
  166.                             Indx = (Word16) i ;
  167.                             Mxp = Exp ;
  168.                             Mcr = Ccr ;
  169.                             Mnr = Enr ;
  170.                         }
  171.                     }
  172.                 }
  173.             }
  174.         }
  175.     }
  176.     return Indx ;
  177. }
  178. /*
  179. **
  180. ** Function:        Comp_Pw()
  181. **
  182. ** Description:     Computes harmonic noise filter coefficients.
  183. **                  For each subframe, the optimal lag is searched around the
  184. **                  open loop pitch lag based on only positive correlation
  185. **                  maximization.
  186. **
  187. ** Links to text:   Section 2.11
  188. **
  189. ** Arguments:
  190. **
  191. **  Word16 *Dpnt    Formant perceptually weighted speech
  192. **  Word16 Start
  193. **  Word16 Olp      Open loop pitch lag
  194. **
  195. ** Outputs:         None
  196. **
  197. ** Return value:
  198. **
  199. **  PWDEF   Word16  Indx  lag of the harmonic noise shaping filter
  200. **          Word16  Gain  gain of the harmonic noise shaping filter
  201. **
  202. */
  203. PWDEF Comp_Pw( Word16 *Dpnt, Word16 Start, Word16 Olp )
  204. {
  205.     int   i,j   ;
  206.     Word32   Lcr[15] ;
  207.     Word16   Scr[15] ;
  208.     PWDEF    Pw ;
  209.     Word32   Acc0,Acc1   ;
  210.     Word16   Exp   ;
  211.     Word16   Ccr,Enr  ;
  212.     Word16   Mcr,Mnr  ;
  213.     /* Compute and save target energy */
  214.     Lcr[0] = (Word32) 0 ;
  215.     for ( i = 0 ; i < SubFrLen ; i ++ )
  216.         Lcr[0] = L_mac( Lcr[0], Dpnt[Start+i], Dpnt[Start+i] ) ;
  217.     /* Compute all Crosses and energys */
  218.     for ( i = 0 ; i <= 2*PwRange ; i ++ ) {
  219.         Acc1 = Acc0 = (Word32) 0 ;
  220.         for ( j = 0 ; j < SubFrLen ; j ++ ) {
  221.             Acc0 = L_mac( Acc0, Dpnt[Start+j],
  222.                                             Dpnt[Start-(Olp-PwRange+i)+j]) ;
  223.             Acc1 = L_mac( Acc1, Dpnt[Start-(Olp-PwRange+i)+j],
  224.                                             Dpnt[Start-(Olp-PwRange+i)+j] ) ;
  225.         }
  226.         /* Save both */
  227.         Lcr[2*i+1] = Acc1 ;
  228.         Lcr[2*i+2] = Acc0 ;
  229.     }
  230.     /* Normalize to maximum */
  231.     Acc1 = (Word32) 0 ;
  232.     for ( i = 0 ; i < 15 ; i ++ ) {
  233.         Acc0 = Lcr[i] ;
  234.         Acc0 = L_abs( Acc0 ) ;
  235.         if ( Acc0 > Acc1 )
  236.             Acc1 = Acc0 ;
  237.     }
  238.     Exp = norm_l( Acc1 ) ;
  239.     for ( i = 0 ; i < 15 ; i ++ ) {
  240.         Acc0 = L_shl( Lcr[i], Exp ) ;
  241.         Scr[i] = round( Acc0 ) ;
  242.     }
  243.     /* Find the best pair */
  244.     Pw.Indx = (Word16) -1 ;
  245.     Pw.Gain = (Word16) 0  ;
  246.     Mcr = (Word16) 1 ;
  247.     Mnr = (Word16) 0x7fff ;
  248.     for ( i = 0 ; i <= 2*PwRange ; i ++ ) {
  249.         Enr = Scr[2*i+1] ;
  250.         Ccr = Scr[2*i+2] ;
  251.         if ( Ccr <= (Word16) 0 )
  252.             continue ;
  253.         Exp = mult_r( Ccr, Ccr ) ;
  254.         /* Compute the cross */
  255.         Acc0 = L_mult( Exp, Mnr ) ;
  256.         Acc0 = L_msu ( Acc0, Enr, Mcr ) ;
  257.         if ( Acc0 > (Word32) 0 ) {
  258.             Mcr = Exp ;
  259.             Mnr = Enr ;
  260.             Pw.Indx = (Word16)i ;
  261.         }
  262.     }
  263.     if ( Pw.Indx == -1 ) {
  264.         Pw.Indx = Olp ;
  265.         return Pw ;
  266.     }
  267.     /* Check the db limit */
  268.     Acc0 = L_mult( Scr[0], Mnr ) ;
  269.     Acc1 = Acc0 ;
  270.     Acc0 = L_shr( Acc0, (Word16) 2 ) ;
  271.     Acc1 = L_shr( Acc1, (Word16) 3 ) ;
  272.     Acc0 = L_add( Acc0, Acc1 ) ;
  273.     Acc1 = L_mult( Scr[2*Pw.Indx+2], Scr[2*Pw.Indx+2] ) ;
  274.     Acc0 = L_sub( Acc0, Acc1 ) ;
  275.     if ( Acc0 < (Word32) 0 ) {
  276.         Exp = Scr[2*Pw.Indx + 2] ;
  277.         if ( Exp >= Mnr )
  278.             Pw.Gain = PwConst ;
  279.         else {
  280.             Pw.Gain = div_s( Exp, Mnr ) ;
  281.             Pw.Gain = mult_r( Pw.Gain, PwConst ) ;
  282.         }
  283.     }
  284.     Pw.Indx = Olp - PwRange + Pw.Indx ;
  285.     return Pw ;
  286. }
  287. /*
  288. **
  289. ** Function:        Filt_Pw()
  290. **
  291. ** Description:     Applies harmonic noise shaping filter.
  292. **                  Lth order FIR filter on each subframe (L: lag of the filter).
  293. **
  294. ** Links to text:   Section 2.11
  295. **
  296. ** Arguments:
  297. **
  298. **  Word16 *DataBuff    Target vector
  299. **  Word16 *Dpnt        Formant perceptually weighted speech
  300. **  Word16 Start
  301. **  PWDEF   Pw          Parameters of the harmonic noise shaping filter
  302. **
  303. ** Outputs:
  304. **
  305. **  Word16 *DataBuff    Target vector
  306. **
  307. ** Return value:        None
  308. **
  309. */
  310. void  Filt_Pw( Word16 *DataBuff, Word16 *Dpnt, Word16 Start, PWDEF Pw )
  311. {
  312.     int   i  ;
  313.     Word32   Acc0 ;
  314.     /* Perform the harmonic weighting */
  315.     for ( i = 0 ; i < SubFrLen ; i ++ ) {
  316.         Acc0 = L_deposit_h( Dpnt[PitchMax+Start+i] ) ;
  317.         Acc0 = L_msu( Acc0, Pw.Gain, Dpnt[PitchMax+Start-Pw.Indx+i] ) ;
  318.         DataBuff[Start+(Word16)i] = round( Acc0 ) ;
  319.     }
  320.     return;
  321. }
  322. /*
  323. **
  324. ** Function:        Find_Fcbk()
  325. **
  326. ** Description:     Fixed codebook excitation computation.
  327. **
  328. **
  329. ** Links to text:   Sections 2.15 & 2.16
  330. **
  331. ** Arguments:
  332. **
  333. **  Word16 *Dpnt    Target vector
  334. **  Word16 *ImpResp Impulse response of the synthesis filter
  335. **  LineDef *Line   Excitation parameters for one subframe
  336. **  Word16 Sfc      Subframe index
  337. **
  338. ** Outputs:
  339. **
  340. **  Word16 *Dpnt    Excitation vector
  341. **  LINEDEF *Line   Fixed codebook parameters for one subframe
  342. **
  343. ** Return value:        None
  344. **
  345. */
  346. void  Find_Fcbk( Word16 *Dpnt, Word16 *ImpResp, LINEDEF *Line, Word16 Sfc )
  347. {
  348.     int   i  ;
  349.     Word16 T0_acelp, gain_T0;
  350.     Word16   Srate ;
  351.     BESTDEF  Best ;
  352.     switch(WrkRate)  {
  353.         case Rate63: {
  354.             Srate = Nb_puls[(int)Sfc] ;
  355.             Best.MaxErr = (Word32) 0xc0000000L ;
  356.             Find_Best( &Best, Dpnt, ImpResp, Srate, (Word16) SubFrLen ) ;
  357.             if ( (*Line).Olp[Sfc>>1] < (Word16) (SubFrLen-2) ) {
  358.                 Find_Best( &Best, Dpnt, ImpResp, Srate, (*Line).Olp[Sfc>>1]);
  359.             }
  360.             /* Reconstruct the excitation */
  361.             for ( i = 0 ; i <  SubFrLen ; i ++ )
  362.                 Dpnt[i] = (Word16) 0 ;
  363.             for ( i = 0 ; i < Srate ; i ++ )
  364.                 Dpnt[Best.Ploc[i]] = Best.Pamp[i] ;
  365.             /* Code the excitation */
  366.             Fcbk_Pack( Dpnt, &((*Line).Sfs[Sfc]), &Best, Srate ) ;
  367.             if ( Best.UseTrn == (Word16) 1 )
  368.                 Gen_Trn( Dpnt, Dpnt, (*Line).Olp[Sfc>>1] ) ;
  369.             break;
  370.         }
  371.         case Rate53: {
  372.             T0_acelp = search_T0(
  373.                     (Word16) ((*Line).Olp[Sfc>>1]-1+(*Line).Sfs[Sfc].AcLg),
  374.                     (*Line).Sfs[Sfc].AcGn, &gain_T0 );
  375.             (*Line).Sfs[Sfc].Ppos = ACELP_LBC_code(
  376.                     Dpnt, ImpResp, T0_acelp, Dpnt, &(*Line).Sfs[Sfc].Mamp,
  377.                     &(*Line).Sfs[Sfc].Grid, &(*Line).Sfs[Sfc].Pamp, gain_T0 );
  378.             (*Line).Sfs[Sfc].Tran = 0;
  379.             break;
  380.         }
  381.     }
  382.     return;
  383. }
  384. /*
  385. **
  386. ** Function:        Gen_Trn()
  387. **
  388. ** Description:     Generation of a train of Dirac functions with the period
  389. **                  Olp.
  390. **
  391. ** Links to text:   Section 2.15
  392. **
  393. ** Arguments:
  394. **
  395. **  Word16 *Dst     Fixed codebook excitation vector with  train of Dirac
  396. **  Word16 *Src     Fixed codebook excitation vector without train of Dirac
  397. **  Word16 Olp      Closed-loop pitch lag of subframe 0 (for subframes 0 & 1)
  398. **                  Closed-loop pitch lag of subframe 2 (for subframes 2 & 3)
  399. **
  400. ** Outputs:
  401. **
  402. **  Word16 *Dst     excitation vector
  403. **
  404. ** Return value:    None
  405. **
  406. */
  407. void  Gen_Trn( Word16 *Dst, Word16 *Src, Word16 Olp )
  408. {
  409.     int   i  ;
  410.     Word16   Tmp0,Tmp1   ;
  411.     Word16   Tmp[SubFrLen] ;
  412.     Tmp0 = Olp ;
  413.     for ( i = 0 ; i < SubFrLen ; i ++ ) {
  414.         Tmp[i] = Src[i] ;
  415.         Dst[i] = Src[i] ;
  416.     }
  417.     while ( Tmp0 < SubFrLen ) {
  418.         for ( i = (int) Tmp0 ; i < SubFrLen ; i ++ ) {
  419.             Tmp1 = add( Dst[i], Tmp[i-(int)Tmp0] ) ;
  420.             Dst[i] = Tmp1 ;
  421.         }
  422.         Tmp0 = add( Tmp0, Olp ) ;
  423.     }
  424.     return;
  425. }
  426. /*
  427. **
  428. ** Function:        Find_Best()
  429. **
  430. ** Description:     Fixed codebook search for the high rate encoder.
  431. **                  It performs the quantization of the residual signal.
  432. **                  The excitation made of Np positive or negative pulses
  433. **                  multiplied by a gain and whose positions on the grid are
  434. **                  either all odd or all even, should approximate as best as
  435. **                  possible the residual signal (perceptual criterion).
  436. **
  437. ** Links to text:   Section 2.15
  438. **
  439. ** Arguments:
  440. **
  441. **  BESTDEF *Best   Parameters of the best excitation model
  442. **  Word16 *Tv      Target vector
  443. **  Word16 *ImpResp Impulse response of the combined filter
  444. **  Word16 Np       Number of pulses (6 for even subframes; 5 for odd subframes)
  445. **  Word16 Olp      Closed-loop pitch lag of subframe 0 (for subframes 0 & 1)
  446. **                  Closed-loop pitch lag of subframe 2 (for subframes 2 & 3)
  447. **
  448. ** Outputs:
  449. **
  450. **  BESTDEF *Best
  451. **
  452. ** Return value:    None
  453. **
  454. */
  455. void  Find_Best( BESTDEF *Best, Word16 *Tv, Word16 *ImpResp, Word16 Np,
  456. Word16 Olp )
  457. {
  458.     int   i,j,k,l  ;
  459.     BESTDEF  Temp  ;
  460.     Word16   Exp   ;
  461.     Word16   MaxAmpId ;
  462.     Word16   MaxAmp   ;
  463.     Word32   Acc0,Acc1,Acc2 ;
  464.     Word16   Imr[SubFrLen]  ;
  465.     Word16   OccPos[SubFrLen] ;
  466.     Word16   ImrCorr[SubFrLen] ;
  467.     Word32   ErrBlk[SubFrLen] ;
  468.     Word32   WrkBlk[SubFrLen] ;
  469.     /* Update Impulse response */
  470.     if ( Olp < (Word16) (SubFrLen-2) ) {
  471.         Temp.UseTrn = (Word16) 1 ;
  472.         Gen_Trn( Imr, ImpResp, Olp ) ;
  473.     }
  474.     else {
  475.         Temp.UseTrn = (Word16) 0 ;
  476.         for ( i = 0 ; i < SubFrLen ; i ++ )
  477.             Imr[i] = ImpResp[i] ;
  478.     }
  479.     /* Scale Imr to avoid overflow */
  480.     for ( i = 0 ; i < SubFrLen ; i ++ )
  481.         OccPos[i] = shr( Imr[i], (Word16) 1 ) ;
  482.     /* Compute Imr AutoCorr function */
  483.     Acc0 = (Word32) 0 ;
  484.     for ( i = 0 ; i < SubFrLen ; i ++ )
  485.         Acc0 = L_mac( Acc0, OccPos[i], OccPos[i] ) ;
  486.     Exp = norm_l( Acc0 ) ;
  487.     Acc0 = L_shl( Acc0, Exp ) ;
  488.     ImrCorr[0] = round( Acc0 ) ;
  489.     /* Compute all the other */
  490.     for ( i = 1 ; i < SubFrLen ; i ++ ) {
  491.         Acc0 = (Word32) 0 ;
  492.         for ( j = i ; j < SubFrLen ; j ++ )
  493.             Acc0 = L_mac( Acc0, OccPos[j], OccPos[j-i] ) ;
  494.         Acc0 = L_shl( Acc0, Exp ) ;
  495.         ImrCorr[i] = round( Acc0 ) ;
  496.     }
  497.     /* Cross correlation with the signal */
  498.     Exp = sub( Exp, 4 ) ;
  499.     for ( i = 0 ; i < SubFrLen ; i ++ ) {
  500.         Acc0 = (Word32) 0 ;
  501.         for ( j = i ; j < SubFrLen ; j ++ )
  502.             Acc0 = L_mac( Acc0, Tv[j], Imr[j-i] ) ;
  503.         ErrBlk[i] = L_shl( Acc0, Exp ) ;
  504.     }
  505.     /* Search for the best sequence */
  506.     for ( k = 0 ; k < Sgrid ; k ++ ) {
  507.         Temp.GridId = (Word16) k ;
  508.         /* Find maximum amplitude */
  509.         Acc1 = (Word32) 0 ;
  510.         for ( i = k ; i < SubFrLen ; i += Sgrid ) {
  511.             Acc0 = L_abs( ErrBlk[i] ) ;
  512.             if ( Acc0 >= Acc1 ) {
  513.                 Acc1 = Acc0 ;
  514.                 Temp.Ploc[0] = (Word16) i ;
  515.             }
  516.         }
  517.         /* Quantize the maximum amplitude */
  518.         Acc2 = Acc1 ;
  519.         Acc1 = (Word32) 0x40000000L ;
  520.         MaxAmpId = (Word16) (NumOfGainLev - MlqSteps) ;
  521.         for ( i = MaxAmpId ; i >= MlqSteps ; i -- ) {
  522.             Acc0 = L_mult( FcbkGainTable[i], ImrCorr[0] ) ;
  523.             Acc0 = L_sub( Acc0, Acc2 ) ;
  524.             Acc0 = L_abs( Acc0 ) ;
  525.             if ( Acc0 < Acc1 ) {
  526.                 Acc1 = Acc0 ;
  527.                 MaxAmpId = (Word16) i ;
  528.             }
  529.         }
  530.         MaxAmpId -- ;
  531.         for ( i = 1 ; i <=2*MlqSteps ; i ++ ) {
  532.             for ( j = k ; j < SubFrLen ; j += Sgrid ) {
  533.                 WrkBlk[j] = ErrBlk[j] ;
  534.                 OccPos[j] = (Word16) 0 ;
  535.             }
  536.             Temp.MampId = MaxAmpId - (Word16) MlqSteps + (Word16) i ;
  537.             MaxAmp = FcbkGainTable[Temp.MampId] ;
  538.             if ( WrkBlk[Temp.Ploc[0]] >= (Word32) 0 )
  539.                 Temp.Pamp[0] = MaxAmp ;
  540.             else
  541.                 Temp.Pamp[0] = negate(MaxAmp) ;
  542.             OccPos[Temp.Ploc[0]] = (Word16) 1 ;
  543.             for ( j = 1 ; j < Np ; j ++ ) {
  544.                 Acc1 = (Word32) 0xc0000000L ;
  545.                 for ( l = k ; l < SubFrLen ; l += Sgrid ) {
  546.                     if ( OccPos[l] != (Word16) 0 )
  547.                         continue ;
  548.                     Acc0 = WrkBlk[l] ;
  549.                     Acc0 = L_msu( Acc0, Temp.Pamp[j-1],
  550.                             ImrCorr[abs_s((Word16)(l-Temp.Ploc[j-1]))] ) ;
  551.                     WrkBlk[l] = Acc0 ;
  552.                     Acc0 = L_abs( Acc0 ) ;
  553.                     if ( Acc0 > Acc1 ) {
  554.                         Acc1 = Acc0 ;
  555.                         Temp.Ploc[j] = (Word16) l ;
  556.                     }
  557.                 }
  558.                 if ( WrkBlk[Temp.Ploc[j]] >= (Word32) 0 )
  559.                     Temp.Pamp[j] = MaxAmp ;
  560.                 else
  561.                     Temp.Pamp[j] = negate(MaxAmp) ;
  562.                 OccPos[Temp.Ploc[j]] = (Word16) 1 ;
  563.             }
  564.             /* Compute error vector */
  565.             for ( j = 0 ; j < SubFrLen ; j ++ )
  566.                 OccPos[j] = (Word16) 0 ;
  567.             for ( j = 0 ; j < Np ; j ++ )
  568.                 OccPos[Temp.Ploc[j]] = Temp.Pamp[j] ;
  569.             for ( l = SubFrLen-1 ; l >= 0 ; l -- ) {
  570.                 Acc0 = (Word32) 0 ;
  571.                 for ( j = 0 ; j <= l ; j ++ )
  572.                     Acc0 = L_mac( Acc0, OccPos[j], Imr[l-j] ) ;
  573.                 Acc0 = L_shl( Acc0, (Word16) 2 ) ;
  574.                 OccPos[l] = extract_h( Acc0 ) ;
  575.             }
  576.             /* Evaluate error */
  577.             Acc1 = (Word32) 0 ;
  578.             for ( j = 0 ; j < SubFrLen ; j ++ ) {
  579.                 Acc1 = L_mac( Acc1, Tv[j], OccPos[j] ) ;
  580.                 Acc0 = L_mult( OccPos[j], OccPos[j] ) ;
  581.                 Acc1 = L_sub( Acc1, L_shr( Acc0, (Word16) 1 ) ) ;
  582.             }
  583.             if ( Acc1 > (*Best).MaxErr ) {
  584.                 (*Best).MaxErr = Acc1 ;
  585.                 (*Best).GridId = Temp.GridId ;
  586.                 (*Best).MampId = Temp.MampId ;
  587.                 (*Best).UseTrn = Temp.UseTrn ;
  588.                 for ( j = 0 ; j < Np ; j ++ ) {
  589.                     (*Best).Pamp[j] = Temp.Pamp[j] ;
  590.                     (*Best).Ploc[j] = Temp.Ploc[j] ;
  591.                 }
  592.             }
  593.         }
  594.     }
  595.     return;
  596. }
  597. /*
  598. **
  599. ** Function:        Fcbk_Pack()
  600. **
  601. ** Description:     Encoding of the pulse positions and gains for the high
  602. **                  rate case.
  603. **                  Combinatorial encoding is used to transmit the optimal
  604. **                  combination of pulse locations.
  605. **
  606. ** Links to text:   Section 2.15
  607. **
  608. ** Arguments:
  609. **
  610. **  Word16 *Dpnt    Excitation vector
  611. **  SFSDEF *Sfs     Encoded parameters of the excitation model
  612. **  BESTDEF *Best   Parameters of the best excitation model
  613. **  Word16 Np       Number of pulses (6 for even subframes; 5 for odd subframes)
  614. **
  615. ** Outputs:
  616. **
  617. **  SFSDEF *Sfs     Encoded parameters of the excitation model
  618. **
  619. ** Return value:    None
  620. **
  621. */
  622. void  Fcbk_Pack( Word16 *Dpnt, SFSDEF *Sfs, BESTDEF *Best, Word16 Np )
  623. {
  624.     int   i,j   ;
  625.     /* Code the amplitudes and positions */
  626.     j = MaxPulseNum - (int) Np ;
  627.     (*Sfs).Pamp = (Word16) 0 ;
  628.     (*Sfs).Ppos = (Word32) 0 ;
  629.     for ( i = 0 ; i < SubFrLen/Sgrid ; i ++ ) {
  630.         if ( Dpnt[(int)(*Best).GridId + Sgrid*i] == (Word16) 0 )
  631.             (*Sfs).Ppos = L_add( (*Sfs).Ppos, CombinatorialTable[j][i] ) ;
  632.         else {
  633.             (*Sfs).Pamp = shl( (*Sfs).Pamp, (Word16) 1 ) ;
  634.             if ( Dpnt[(int)(*Best).GridId + Sgrid*i] < (Word16) 0 )
  635.                 (*Sfs).Pamp = add( (*Sfs).Pamp, (Word16) 1 ) ;
  636.             j ++ ;
  637.             /* Check for end */
  638.             if ( j == MaxPulseNum )
  639.                 break ;
  640.         }
  641.     }
  642.     (*Sfs).Mamp = (*Best).MampId ;
  643.     (*Sfs).Grid = (*Best).GridId ;
  644.     (*Sfs).Tran = (*Best).UseTrn ;
  645.     return;
  646. }
  647. /*
  648. **
  649. ** Function:        Fcbk_Unpk()
  650. **
  651. ** Description:     Decoding of the fixed codebook excitation for both rates.
  652. **                  Gains, pulse positions, grid position (odd or even), signs
  653. **                  are decoded and used to reconstruct the excitation.
  654. **
  655. ** Links to text:   Section 2.17 & 3.5
  656. **
  657. ** Arguments:
  658. **
  659. **  Word16 *Tv      Decoded excitation vector
  660. **  SFSDEF Sfs      Encoded parameters of the excitation (for one subframe)
  661. **  Word16 Olp      Closed loop adaptive pitch lag
  662. **  Word16 Sfc      Subframe index
  663. **
  664. ** Outputs:
  665. **
  666. **  Word16 *Tv      Decoded excitation vector
  667. **
  668. ** Return value:    None
  669. **
  670. */
  671. void  Fcbk_Unpk( Word16 *Tv, SFSDEF Sfs, Word16 Olp, Word16 Sfc )
  672. {
  673.     int   i,j   ;
  674.     Word32   Acc0  ;
  675.     Word16   Np ;
  676.     Word16 Tv_tmp[SubFrLen+4];
  677.     Word16 acelp_gain, acelp_sign, acelp_shift, acelp_pos;
  678.     Word16 offset, ipos, T0_acelp, gain_T0;
  679.     switch(WrkRate)  {
  680.         case Rate63: {
  681.             Np = Nb_puls[(int)Sfc] ;
  682.             for ( i = 0 ; i < SubFrLen ; i ++ )
  683.                 Tv[i] = (Word16) 0 ;
  684.             if ( Sfs.Ppos >= MaxPosTable[Sfc] )
  685.                 return ;
  686.             /* Decode the amplitudes and positions */
  687.             j = MaxPulseNum - (int) Np ;
  688.             Acc0 = Sfs.Ppos ;
  689.             for ( i = 0 ; i < SubFrLen/Sgrid ; i ++ )  {
  690.                 Acc0 = L_sub( Acc0, CombinatorialTable[j][i] ) ;
  691.                 if ( Acc0 < (Word32) 0 ) {
  692.                     Acc0 = L_add( Acc0, CombinatorialTable[j][i] ) ;
  693.                     j ++ ;
  694.                     if ( (Sfs.Pamp & (1 << (MaxPulseNum-j) )) != (Word16) 0 )
  695.                         Tv[(int)Sfs.Grid + Sgrid*i] = -FcbkGainTable[Sfs.Mamp] ;
  696.                     else
  697.                         Tv[(int)Sfs.Grid + Sgrid*i] =  FcbkGainTable[Sfs.Mamp] ;
  698.                     if ( j == MaxPulseNum )
  699.                         break ;
  700.                 }
  701.             }
  702.             if ( Sfs.Tran == (Word16) 1 )
  703.                 Gen_Trn( Tv, Tv, Olp ) ;
  704.             break;
  705.         }
  706.         case Rate53: {
  707.             for ( i = 0 ; i < SubFrLen+4 ; i ++ )
  708.                 Tv_tmp[i] = (Word16) 0 ;
  709.             /* decoding gain */
  710.             acelp_gain = FcbkGainTable[Sfs.Mamp];
  711.             /* decoding grid */
  712.             acelp_shift = Sfs.Grid;
  713.             /* decoding Sign */
  714.             acelp_sign = Sfs.Pamp;
  715.             /* decoding Pos */
  716.             acelp_pos = (short) Sfs.Ppos;
  717.             offset  = 0;
  718.             for(i=0; i<4; i++) {
  719.                 ipos = (acelp_pos & (Word16)0x0007) ;
  720.                 ipos = shl(ipos,3) + acelp_shift + offset;
  721.                 if( (acelp_sign & 1 )== 1) {
  722.                     Tv_tmp[ipos] = acelp_gain;
  723.                 }
  724.                 else {
  725.                     Tv_tmp[ipos] = -acelp_gain;
  726.                 }
  727.                 offset = add(offset,2);
  728.                 acelp_pos = shr(acelp_pos, 3);
  729.                 acelp_sign = shr(acelp_sign,1);
  730.             }
  731.             for (i = 0; i < SubFrLen; i++) Tv[i] = Tv_tmp[i];
  732.             T0_acelp = search_T0( (Word16) (Olp-1+Sfs.AcLg), Sfs.AcGn,
  733.                                                             &gain_T0);
  734.             if(T0_acelp <SubFrLen-2) {
  735.                 /* code[i] += 0.8 * code[i-Olp] */
  736.                 for (i = T0_acelp ; i < SubFrLen; i++)
  737.                     Tv[i] = add(Tv[i], mult(Tv[i-T0_acelp ], gain_T0));
  738.             }
  739.             break;
  740.         }
  741.     }
  742.     return;
  743. }
  744. /*
  745. **
  746. ** Function:        Find_Acbk()
  747. **
  748. ** Description:     Computation of adaptive codebook contribution in
  749. **                  closed-loop around the open-loop pitch lag (subframes 0 & 2)
  750. **                  around the previous subframe closed-loop pitch lag
  751. **                  (subframes 1 & 3).  For subframes 0 & 2, the pitch lag is
  752. **                  encoded whereas for subframes 1 & 3, only the difference
  753. **                  with the previous value is encoded (-1, 0, +1 or +2).
  754. **                  The pitch predictor gains are quantized using one of the two
  755. **                  codebooks (85 entries or 170 entries) depending on the
  756. **                  rate and on the pitch lag value.
  757. **                  Finally, the contribution of the pitch predictor is decoded
  758. **                  and subtracted to obtain the residual signal.
  759. **
  760. ** Links to text:   Section 2.14
  761. **
  762. ** Arguments:
  763. **
  764. **  Word16 *Tv      Target vector
  765. **  Word16 *ImpResp Impulse response of the combined filter
  766. **  Word16 *PrevExc Previous excitation vector
  767. **  LINEDEF *Line   Contains pitch related parameters (open/closed loop lag, gain)
  768. **  Word16 Sfc      Subframe index
  769. **
  770. ** Outputs:
  771. **
  772. **  Word16 *Tv     Residual vector
  773. **  LINEDEF *Line  Contains pitch related parameters (closed loop lag, gain)
  774. **
  775. ** Return value:    None
  776. **
  777. */
  778. void  Find_Acbk( Word16 *Tv, Word16 *ImpResp, Word16 *PrevExc, LINEDEF
  779. *Line, Word16 Sfc )
  780. {
  781.     int   i,j,k,l  ;
  782.     Word32   Acc0,Acc1 ;
  783.     Word16   RezBuf[SubFrLen+ClPitchOrd-1] ;
  784.     Word16   FltBuf[ClPitchOrd][SubFrLen] ;
  785.     Word32   CorBuf[4*(2*ClPitchOrd + ClPitchOrd*(ClPitchOrd-1)/2)] ;
  786.     Word32   *lPnt ;
  787.     Word16   CorVct[4*(2*ClPitchOrd + ClPitchOrd*(ClPitchOrd-1)/2)] ;
  788.     Word16   *sPnt ;
  789.     Word16   Olp ;
  790.     Word16   Lid ;
  791.     Word16   Gid ;
  792.     Word16   Hb  ;
  793.     Word16   Exp ;
  794.     Word16   Bound[2] ;
  795.     Word16   Lag1, Lag2;
  796.     Word16   off_filt;
  797.     /* Init constants */
  798.     Olp = (*Line).Olp[shr(Sfc, (Word16) 1)] ;
  799.     Lid = (Word16) Pstep ;
  800.     Gid = (Word16) 0 ;
  801.     Hb  = (Word16) 3 + (Sfc & (Word16) 1 ) ;
  802.     /* For even frames only */
  803.     if ( (Sfc & (Word16)1) == (Word16) 0 ) {
  804.         if ( Olp == (Word16) PitchMin )
  805.             Olp = add( Olp, (Word16) 1 ) ;
  806.         if ( Olp > (Word16) (PitchMax-5) )
  807.             Olp = (Word16)(PitchMax-5) ;
  808.     }
  809.     lPnt = CorBuf ;
  810.     for ( k = 0 ; k < (int) Hb ; k ++ ) {
  811.         /* Get residual from the excitation buffer */
  812.         Get_Rez( RezBuf, PrevExc, (Word16)(Olp-(Word16)Pstep+k) ) ;
  813.         /* Filter the last one using the impulse response */
  814.         for ( i = 0 ; i < SubFrLen ; i ++ ) {
  815.             Acc0 = (Word32) 0 ;
  816.             for ( j = 0 ; j <= i ; j ++ )
  817.                 Acc0 = L_mac( Acc0, RezBuf[ClPitchOrd-1+j], ImpResp[i-j] ) ;
  818.             FltBuf[ClPitchOrd-1][i] = round( Acc0 ) ;
  819.         }
  820.         /* Update all the others */
  821.         for ( i = ClPitchOrd-2 ; i >= 0 ; i -- ) {
  822.             FltBuf[i][0] = mult_r( RezBuf[i], (Word16) 0x2000 ) ;
  823.             for ( j = 1 ; j < SubFrLen ; j ++ ) {
  824.                 Acc0 = L_deposit_h( FltBuf[i+1][j-1] ) ;
  825.                 Acc0 = L_mac( Acc0, RezBuf[i], ImpResp[j] ) ;
  826.                 FltBuf[i][j] = round( Acc0 ) ;
  827.             }
  828.         }
  829.         /* Compute the cross with the signal */
  830.         for ( i = 0 ; i < ClPitchOrd ; i ++ ) {
  831.             Acc1 = (Word32) 0 ;
  832.             for ( j = 0 ; j < SubFrLen ; j ++ ) {
  833.                 Acc0 = L_mult( Tv[j], FltBuf[i][j] ) ;
  834.                 Acc1 = L_add( Acc1, L_shr( Acc0, (Word16) 1 ) ) ;
  835.             }
  836.             *lPnt ++ = L_shl( Acc1, (Word16) 1 ) ;
  837.         }
  838.         /* Compute the energies */
  839.         for ( i = 0 ; i < ClPitchOrd ; i ++ ) {
  840.             Acc1 = (Word32) 0 ;
  841.             for ( j = 0 ; j < SubFrLen ; j ++ )
  842.                 Acc1 = L_mac( Acc1, FltBuf[i][j], FltBuf[i][j] ) ;
  843.             *lPnt ++ = Acc1 ;
  844.         }
  845.         /* Compute the between crosses */
  846.         for ( i = 1 ; i < ClPitchOrd ; i ++ ) {
  847.             for ( j = 0 ; j < i ; j ++ ) {
  848.                 Acc1 = (Word32) 0 ;
  849.                 for ( l = 0 ; l < SubFrLen ; l ++ ) {
  850.                     Acc0 = L_mult( FltBuf[i][l], FltBuf[j][l] ) ;
  851.                     Acc1 = L_add( Acc1, L_shr( Acc0, (Word16) 1 ) ) ;
  852.                 }
  853.                 *lPnt ++ = L_shl( Acc1, (Word16) 2 ) ;
  854.             }
  855.         }
  856.     }
  857.     /* Find Max and normalize */
  858.     Acc1 = (Word32) 0 ;
  859.     for ( i = 0 ; i < Hb*20 ; i ++ ) {
  860.         Acc0 = L_abs(CorBuf[i]) ;
  861.         if ( Acc0 > Acc1 )
  862.             Acc1 = Acc0 ;
  863.     }
  864.     Exp = norm_l( Acc1 ) ;
  865.     /* Convert to shorts */
  866.     for ( i = 0 ; i < Hb*20 ; i ++ ) {
  867.         Acc0 = L_shl( CorBuf[i], Exp ) ;
  868.         CorVct[i] = round( Acc0 ) ;
  869.     }
  870.     /* Test potential error */
  871.     Lag1 = Olp-(Word16)Pstep;
  872.     Lag2 = Olp-(Word16)Pstep+ Hb -(Word16)1;
  873.     off_filt = Test_Err(Lag1, Lag2);
  874.     Bound[0] =  NbFilt085_min + shl(off_filt,2);
  875.     if(Bound[0] > NbFilt085) Bound[0] = NbFilt085;
  876.     Bound[1] =  NbFilt170_min + shl(off_filt,3);
  877.     if(Bound[1] > NbFilt170) Bound[1] = NbFilt170;
  878.     /* Init the search loop */
  879.     Acc1 = (Word32) 0 ;
  880.     for ( k = 0 ; k < (int) Hb ; k ++ ) {
  881.         /* Select Quantization tables */
  882.         l = 0 ;
  883.         if ( WrkRate == Rate63 ){
  884.             if ( (Sfc & (Word16) 1) == (Word16) 0 ) {
  885.                 if ( (int)Olp-Pstep+k >= SubFrLen-2 )l ++ ;
  886.             }
  887.             else {
  888.                 if ( (int)Olp >= SubFrLen-2 ) l ++ ;
  889.             }
  890.         }
  891.         else {
  892.             l = 1;
  893.         }
  894.         sPnt = AcbkGainTablePtr[l] ;
  895.         for ( i = 0 ; i < (int) Bound[l] ; i ++ ) {
  896.             Acc0 = (Word32) 0 ;
  897.             for ( j = 0 ; j < 20 ; j ++ )
  898.                 Acc0 = L_add( Acc0, L_shr( L_mult(CorVct[k*20+j], *sPnt ++),
  899. (Word16) 1 ) ) ;
  900.             if ( Acc0 > Acc1 ) {
  901.                 Acc1 = Acc0 ;
  902.                 Gid = (Word16) i ;
  903.                 Lid = (Word16) k ;
  904.             }
  905.         }
  906.     }
  907.     /* Modify Olp for even sub frames */
  908.     if ( (Sfc & (Word16) 1 ) == (Word16) 0 ) {
  909.         Olp = Olp - (Word16) Pstep + Lid ;
  910.         Lid = (Word16) Pstep ;
  911.     }
  912.     /* Save Gains and Olp */
  913.     (*Line).Sfs[Sfc].AcLg = Lid ;
  914.     (*Line).Sfs[Sfc].AcGn = Gid ;
  915.     (*Line).Olp[shr(Sfc, (Word16) 1)] = Olp ;
  916.     /* Decode the Acbk contribution and subtract it */
  917.     Decod_Acbk( RezBuf, PrevExc, Olp, Lid, Gid ) ;
  918.     for ( i = 0 ; i < SubFrLen ; i ++ ) {
  919.         Acc0 = L_deposit_h( Tv[i] ) ;
  920.         Acc0 = L_shr( Acc0, (Word16) 1 ) ;
  921.         for ( j = 0 ; j <= i ; j ++ )
  922.             Acc0 = L_msu( Acc0, RezBuf[j], ImpResp[i-j] ) ;
  923.         Acc0 = L_shl( Acc0, (Word16) 1 ) ;
  924.         Tv[i] = round( Acc0 ) ;
  925.     }
  926.     return;
  927. }
  928. /*
  929. **
  930. ** Function:        Get_Rez()
  931. **
  932. ** Description:     Gets delayed contribution from the previous excitation
  933. **                  vector.
  934. **
  935. ** Links to text:   Sections 2.14, 2.18 & 3.4
  936. **
  937. ** Arguments:
  938. **
  939. **  Word16 *Tv      delayed excitation
  940. **  Word16 *PrevExc Previous excitation vector
  941. **  Word16 Lag      Closed loop pitch lag
  942. **
  943. ** Outputs:
  944. **
  945. **  Word16 *Tv      delayed excitation
  946. **
  947. ** Return value:    None
  948. **
  949. */
  950. void  Get_Rez( Word16 *Tv, Word16 *PrevExc, Word16 Lag )
  951. {
  952.     int   i  ;
  953.     for ( i = 0 ; i < ClPitchOrd/2 ; i ++ )
  954.         Tv[i] = PrevExc[PitchMax - (int) Lag - ClPitchOrd/2 + i] ;
  955.     for ( i = 0 ; i < SubFrLen+ClPitchOrd/2 ; i ++ )
  956.         Tv[ClPitchOrd/2+i] = PrevExc[PitchMax - (int)Lag + i%(int)Lag] ;
  957.     return;
  958. }
  959. /*
  960. **
  961. ** Function:        Decod_Acbk()
  962. **
  963. ** Description:     Computes the adaptive codebook contribution from the previous
  964. **                  excitation vector.
  965. **                  With the gain index, the closed loop pitch lag, the jitter
  966. **                  which when added to this pitch lag gives the actual closed
  967. **                  loop value, and after having selected the proper codebook,
  968. **                  the pitch contribution is reconstructed using the previous
  969. **                  excitation buffer.
  970. **
  971. ** Links to text:   Sections 2.14, 2.18 & 3.4
  972. **
  973. ** Arguments:
  974. **
  975. **  Word16 *Tv      Reconstructed excitation vector
  976. **  Word16 *PrevExc Previous excitation vector
  977. **  Word16 Olp      closed-loop pitch period
  978. **  Word16 Lid      Jitter around pitch period
  979. **  Word16 Gid      Gain vector index in 5- dimensional
  980. **                      adaptive gain vector codebook
  981. **
  982. ** Outputs:
  983. **
  984. **  Word16 *Tv      Reconstructed excitation vector
  985. **
  986. ** Return value:    None
  987. **
  988. */
  989. void  Decod_Acbk( Word16 *Tv, Word16 *PrevExc, Word16 Olp, Word16 Lid,
  990. Word16 Gid )
  991. {
  992.     int   i,j   ;
  993.     Word32   Acc0  ;
  994.     Word16   RezBuf[SubFrLen+ClPitchOrd-1] ;
  995.     Word16  *sPnt ;
  996.     Get_Rez( RezBuf, PrevExc, (Word16)(Olp - (Word16)Pstep + Lid) ) ;
  997.     /* Select Quantization tables */
  998.     i = 0 ;
  999.     if ( WrkRate == Rate63 ) {
  1000.         if ( Olp >= (Word16) (SubFrLen-2) ) i ++ ;
  1001.     }
  1002.     else {
  1003.         i = 1;
  1004.     }
  1005.     sPnt = AcbkGainTablePtr[i] ;
  1006.     sPnt += (int)Gid*20 ;
  1007.     for ( i = 0 ; i < SubFrLen ; i ++ ) {
  1008.         Acc0 = (Word32) 0 ;
  1009.         for ( j = 0 ; j < ClPitchOrd ; j ++ )
  1010.             Acc0 = L_mac( Acc0, RezBuf[i+j], sPnt[j] ) ;
  1011.         Acc0 = L_shl( Acc0, (Word16) 1 ) ;
  1012.         Tv[i] = round( Acc0 ) ;
  1013.     }
  1014.     return;
  1015. }
  1016. /*
  1017. **
  1018. ** Function:        Comp_Info()
  1019. **
  1020. ** Description:     Voiced/unvoiced classifier.
  1021. **                  It is based on a cross correlation maximization over the
  1022. **                  last 120 samples of the frame and with an index varying
  1023. **                  around the decoded pitch lag (from L-3 to L+3). Then the
  1024. **                  prediction gain is tested to declare the frame voiced or
  1025. **                  unvoiced.
  1026. **
  1027. ** Links to text:   Section 3.10.2
  1028. **
  1029. ** Arguments:
  1030. **
  1031. **  Word16 *Buff  decoded excitation
  1032. **  Word16 Olp    Decoded pitch lag
  1033. **
  1034. ** Outputs: None
  1035. **
  1036. ** Return value:
  1037. **
  1038. **      Word16   Estimated pitch value
  1039. */
  1040. Word16   Comp_Info( Word16 *Buff, Word16 Olp, Word16 *Gain, Word16 *ShGain)
  1041. {
  1042.     int   i,j   ;
  1043.     Word32   Acc0,Acc1 ;
  1044.     Word16   Tenr ;
  1045.     Word16   Ccr,Enr ;
  1046.     Word16   Indx ;
  1047.     /* Normalize the excitation */
  1048.     *ShGain = Vec_Norm( Buff, (Word16) (PitchMax+Frame) ) ;
  1049.     if ( Olp > (Word16) (PitchMax-3) )
  1050.         Olp = (Word16) (PitchMax-3) ;
  1051.     Indx = Olp ;
  1052.     Acc1 = (Word32) 0 ;
  1053.     for ( i = (int)Olp-3 ; i <= (int)Olp+3 ; i ++ ) {
  1054.         Acc0 = (Word32) 0 ;
  1055.         for ( j = 0 ; j < 2*SubFrLen ; j ++ )
  1056.             Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen+j],
  1057.                                     Buff[PitchMax+Frame-2*SubFrLen-i+j] ) ;
  1058.         if ( Acc0 > Acc1 ) {
  1059.             Acc1 = Acc0 ;
  1060.             Indx = (Word16) i ;
  1061.         }
  1062.     }
  1063.     /* Compute target energy */
  1064.     Acc0 = (Word32) 0 ;
  1065.     for ( j = 0 ; j < 2*SubFrLen ; j ++ )
  1066.         Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen+j],
  1067.                                     Buff[PitchMax+Frame-2*SubFrLen+j] ) ;
  1068.     Tenr = round( Acc0 ) ;
  1069.     *Gain = Tenr;
  1070.     /* Compute best energy */
  1071.     Acc0 = (Word32) 0 ;
  1072.     for ( j = 0 ; j < 2*SubFrLen ; j ++ )
  1073.         Acc0 = L_mac( Acc0, Buff[PitchMax+Frame-2*SubFrLen-(int)Indx+j],
  1074.                             Buff[PitchMax+Frame-2*SubFrLen-(int)Indx+j] ) ;
  1075.     Ccr = round( Acc1 ) ;
  1076.     if ( Ccr <= (Word16) 0 )
  1077.         return (Word16) 0 ;
  1078.     Enr = round( Acc0 ) ;
  1079.     Acc0 = L_mult( Enr, Tenr ) ;
  1080.     Acc0 = L_shr( Acc0, (Word16) 3 ) ;
  1081.     Acc0 = L_msu( Acc0, Ccr, Ccr ) ;
  1082.     if ( Acc0 < (Word32) 0 )
  1083.         return Indx ;
  1084.     else
  1085.         return (Word16) 0 ;
  1086. }
  1087. /*
  1088. **
  1089. ** Function:        Regen()
  1090. **
  1091. ** Description:     Performs residual interpolation depending of the frame
  1092. **                  classification.
  1093. **                  If the frame is previously declared unvoiced, the excitation
  1094. **                  is regenerated using a random number generator. Otherwise
  1095. **                  a periodic excitation is generated with the period
  1096. **                  previously found.
  1097. **
  1098. ** Links to text:   Section 3.10.2
  1099. **
  1100. ** Arguments:
  1101. **
  1102. **  Word16 *DataBuff  current subframe decoded excitation
  1103. **  Word16 *Buff     past decoded excitation
  1104. **  Word16 Lag       Decoded pitch lag from previous frame
  1105. **  Word16 Gain      Interpolated gain from previous frames
  1106. **  Word16 Ecount    Number of erased frames
  1107. **  Word16 *Sd       Random number used in unvoiced cases
  1108. **
  1109. ** Outputs:
  1110. **
  1111. **  Word16 *DataBuff current subframe decoded excitation
  1112. **  Word16 *Buff     updated past excitation
  1113. **
  1114. ** Return value:    None
  1115. **
  1116. */
  1117. void     Regen( Word16 *DataBuff, Word16 *Buff, Word16 Lag, Word16 Gain,
  1118. Word16 Ecount, Word16 *Sd )
  1119. {
  1120.     int   i  ;
  1121.     /* Test for clearing */
  1122.     if ( Ecount >= (Word16) ErrMaxNum ) {
  1123.         for ( i = 0 ; i < Frame ; i ++ )
  1124.             DataBuff[i] = (Word16) 0 ;
  1125.         for ( i = 0 ; i < Frame+PitchMax ; i ++ )
  1126.             Buff[i] = (Word16) 0 ;
  1127.     }
  1128.     else {
  1129.         /* Interpolate accordingly to the voicing estimation */
  1130.         if ( Lag != (Word16) 0 ) {
  1131.             /* Voiced case */
  1132.             for ( i = 0 ; i < Frame ; i ++ )
  1133.                 Buff[PitchMax+i] = Buff[PitchMax-(int)Lag+i] ;
  1134.             for ( i = 0 ; i < Frame ; i ++ )
  1135.                 DataBuff[i] = Buff[PitchMax+i] = mult( Buff[PitchMax+i],
  1136.                             (Word16) 0x6000 ) ;
  1137.         }
  1138.         else {
  1139.             /* Unvoiced case */
  1140.             for ( i = 0 ; i < Frame ; i ++ )
  1141.                 DataBuff[i] = mult( Gain, Rand_lbc( Sd ) ) ;
  1142.             /* Clear buffer to reset memory */
  1143.             for ( i = 0 ; i < Frame+PitchMax ; i ++ )
  1144.                 Buff[i] = (Word16) 0 ;
  1145.         }
  1146.     }
  1147.     return;
  1148. }
  1149. /*
  1150. **
  1151. ** Function:        Comp_Lpf()
  1152. **
  1153. ** Description:     Computes pitch postfilter parameters.
  1154. **                  The pitch postfilter lag is first derived (Find_B
  1155. **                  and Find_F). Then, the one that gives the largest
  1156. **                  contribution is used to calculate the gains (Get_Ind).
  1157. **
  1158. **
  1159. ** Links to text:   Section 3.6
  1160. **
  1161. ** Arguments:
  1162. **
  1163. **  Word16 *Buff    decoded excitation
  1164. **  Word16 Olp      Decoded pitch lag
  1165. **  Word16 Sfc      Subframe index
  1166. **
  1167. ** Outputs:
  1168. **
  1169. **
  1170. ** Return value:
  1171. **
  1172. **  PFDEF       Pitch postfilter parameters: PF.Gain    Pitch Postfilter gain
  1173. **                                           PF.ScGn    Pitch Postfilter scaling gain
  1174. **                                           PF.Indx    Pitch postfilter lag
  1175. */
  1176. PFDEF Comp_Lpf( Word16 *Buff, Word16 Olp, Word16 Sfc )
  1177. {
  1178.     int   i,j   ;
  1179.     PFDEF Pf    ;
  1180.     Word32   Lcr[5] ;
  1181.     Word16   Scr[5] ;
  1182.     Word16   Bindx, Findx ;
  1183.     Word16   Exp ;
  1184.     Word32   Acc0,Acc1 ;
  1185.     /* Initialize */
  1186.     Pf.Indx = (Word16) 0 ;
  1187.     Pf.Gain = (Word16) 0 ;
  1188.     Pf.ScGn = (Word16) 0x7fff ;
  1189.     /* Find both indices */
  1190.     Bindx = Find_B( Buff, Olp, Sfc ) ;
  1191.     Findx = Find_F( Buff, Olp, Sfc ) ;
  1192.     /* Combine the results */
  1193.     if ( (Bindx == (Word16) 0) && (Findx == (Word16) 0) )
  1194.         return Pf ;
  1195.     /* Compute target energy */
  1196.     Acc0 = (Word32) 0 ;
  1197.     for ( j = 0 ; j < SubFrLen ; j ++ )
  1198.         Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j],
  1199.                                     Buff[PitchMax+(int)Sfc*SubFrLen+j] ) ;
  1200.     Lcr[0] = Acc0 ;
  1201.     if ( Bindx != (Word16) 0 ) {
  1202.         Acc0 = (Word32) 0 ;
  1203.         Acc1 = (Word32) 0 ;
  1204.         for ( j = 0 ; j < SubFrLen ; j ++ ) {
  1205.             Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j],
  1206.                         Buff[PitchMax+(int)Sfc*SubFrLen+(int)Bindx+j] ) ;
  1207.             Acc1 = L_mac( Acc1, Buff[PitchMax+(int)Sfc*SubFrLen+(int)Bindx+j],
  1208.                         Buff[PitchMax+(int)Sfc*SubFrLen+(int)Bindx+j] ) ;
  1209.         }
  1210.         Lcr[1] = Acc0 ;
  1211.         Lcr[2] = Acc1 ;
  1212.     }
  1213.     else {
  1214.         Lcr[1] = (Word32) 0 ;
  1215.         Lcr[2] = (Word32) 0 ;
  1216.     }
  1217.     if ( Findx != (Word16) 0 ) {
  1218.         Acc0 = (Word32) 0 ;
  1219.         Acc1 = (Word32) 0 ;
  1220.         for ( j = 0 ; j < SubFrLen ; j ++ ) {
  1221.             Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j],
  1222.                         Buff[PitchMax+(int)Sfc*SubFrLen+(int)Findx+j] ) ;
  1223.             Acc1 = L_mac( Acc1, Buff[PitchMax+(int)Sfc*SubFrLen+(int)Findx+j],
  1224.                         Buff[PitchMax+(int)Sfc*SubFrLen+(int)Findx+j] ) ;
  1225.         }
  1226.         Lcr[3] = Acc0 ;
  1227.         Lcr[4] = Acc1 ;
  1228.     }
  1229.     else {
  1230.         Lcr[3] = (Word32) 0 ;
  1231.         Lcr[4] = (Word32) 0 ;
  1232.     }
  1233.     /* Normalize and convert to shorts */
  1234.     Acc1 = 0L ;
  1235.     for ( i = 0 ; i < 5 ; i ++ ) {
  1236.         Acc0 = Lcr[i] ;
  1237.         if ( Acc0 > Acc1 )
  1238.             Acc1 = Acc0 ;
  1239.     }
  1240.     Exp = norm_l( Acc1 ) ;
  1241.     for ( i = 0 ; i < 5 ; i ++ ) {
  1242.         Acc0 = L_shl( Lcr[i], Exp ) ;
  1243.         Scr[i] = extract_h( Acc0 ) ;
  1244.     }
  1245.     /* Select the best pair */
  1246.     if ( (Bindx != (Word16) 0) && ( Findx == (Word16) 0) )
  1247.         Pf = Get_Ind( Bindx, Scr[0], Scr[1], Scr[2] ) ;
  1248.     if ( (Bindx == (Word16) 0) && ( Findx != (Word16) 0) )
  1249.         Pf = Get_Ind( Findx, Scr[0], Scr[3], Scr[4] ) ;
  1250.     if ( (Bindx != (Word16) 0) && ( Findx != (Word16) 0) ) {
  1251.         Exp = mult_r( Scr[1], Scr[1] ) ;
  1252.         Acc0 = L_mult( Exp, Scr[4] ) ;
  1253.         Exp = mult_r( Scr[3], Scr[3] ) ;
  1254.         Acc1 = L_mult( Exp, Scr[2] ) ;
  1255.         if ( Acc0 > Acc1 )
  1256.             Pf = Get_Ind( Bindx, Scr[0], Scr[1], Scr[2] ) ;
  1257.         else
  1258.             Pf = Get_Ind( Findx, Scr[0], Scr[3], Scr[4] ) ;
  1259.     }
  1260.     return Pf ;
  1261. }
  1262. /*
  1263. **
  1264. ** Function:        Find_B()
  1265. **
  1266. ** Description:     Computes best pitch postfilter backward lag by
  1267. **                  backward cross correlation maximization around the
  1268. **                  decoded pitch lag
  1269. **                  of the subframe 0 (for subframes 0 & 1)
  1270. **                  of the subframe 2 (for subframes 2 & 3)
  1271. **
  1272. ** Links to text:   Section 3.6
  1273. **
  1274. ** Arguments:
  1275. **
  1276. **  Word16 *Buff    decoded excitation
  1277. **  Word16 Olp      Decoded pitch lag
  1278. **  Word16 Sfc      Subframe index
  1279. **
  1280. ** Outputs:     None
  1281. **
  1282. ** Return value:
  1283. **
  1284. **  Word16   Pitch postfilter backward lag
  1285. */
  1286. Word16   Find_B( Word16 *Buff, Word16 Olp, Word16 Sfc )
  1287. {
  1288.     int   i,j   ;
  1289.     Word16   Indx = 0 ;
  1290.     Word32   Acc0,Acc1 ;
  1291.     if ( Olp > (Word16) (PitchMax-3) )
  1292.         Olp = (Word16) (PitchMax-3) ;
  1293.     Acc1 = (Word32) 0 ;
  1294.     for ( i = (int)Olp-3 ; i <= (int)Olp+3 ; i ++ ) {
  1295.         Acc0 = (Word32) 0 ;
  1296.         for ( j = 0 ; j < SubFrLen ; j ++ )
  1297.             Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j],
  1298.                                     Buff[PitchMax+(int)Sfc*SubFrLen-i+j] ) ;
  1299.         if ( Acc0 > Acc1 ) {
  1300.             Acc1 = Acc0 ;
  1301.             Indx = -(Word16) i ;
  1302.         }
  1303.     }
  1304.     return Indx ;
  1305. }
  1306. /*
  1307. **
  1308. ** Function:        Find_F()
  1309. **
  1310. ** Description:     Computes best pitch postfilter forward lag by
  1311. **                  forward cross correlation maximization around the
  1312. **                  decoded pitch lag
  1313. **                  of the subframe 0 (for subframes 0 & 1)
  1314. **                  of the subframe 2 (for subframes 2 & 3)
  1315. **
  1316. ** Links to text:   Section 3.6
  1317. **
  1318. ** Arguments:
  1319. **
  1320. **  Word16 *Buff    decoded excitation
  1321. **  Word16 Olp      Decoded pitch lag
  1322. **  Word16 Sfc      Subframe index
  1323. **
  1324. ** Outputs:     None
  1325. **
  1326. ** Return value:
  1327. **
  1328. **  Word16    Pitch postfilter forward lag
  1329. */
  1330. Word16   Find_F( Word16 *Buff, Word16 Olp, Word16 Sfc )
  1331. {
  1332.     int   i,j   ;
  1333.     Word16   Indx = 0 ;
  1334.     Word32   Acc0,Acc1 ;
  1335.     if ( Olp > (Word16) (PitchMax-3) )
  1336.         Olp = (Word16) (PitchMax-3) ;
  1337.     Acc1 = (Word32) 0 ;
  1338.     for ( i = Olp-3 ; i <= Olp+3 ; i ++ ) {
  1339.         Acc0 = (Word32) 0 ;
  1340.         if ( ((int)Sfc*SubFrLen+SubFrLen+i) <= Frame ) {
  1341.             for ( j = 0 ; j < SubFrLen ; j ++ )
  1342.                 Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+j],
  1343.                             Buff[PitchMax+(int)Sfc*SubFrLen+i+j] ) ;
  1344.         }
  1345.         if ( Acc0 > Acc1 ) {
  1346.             Acc1 = Acc0 ;
  1347.             Indx = (Word16) i ;
  1348.         }
  1349.     }
  1350.     return Indx ;
  1351. }
  1352. /*
  1353. **
  1354. ** Function:        Get_Ind()
  1355. **
  1356. ** Description:     Computes gains of the pitch postfilter.
  1357. **                  The gains are calculated using the cross correlation
  1358. **                  (forward or backward, the one with the greatest contribution)
  1359. **                  and the energy of the signal. Also, a test is performed on
  1360. **                  the prediction gain to see whether the pitch postfilter
  1361. **                  should be used or not.
  1362. **
  1363. **
  1364. **
  1365. ** Links to text:   Section 3.6
  1366. **
  1367. ** Arguments:
  1368. **
  1369. **  Word16 Ind      Pitch postfilter lag
  1370. **  Word16 Ten      energy of the current subframe excitation vector
  1371. **  Word16 Ccr      Crosscorrelation of the excitation
  1372. **  Word16 Enr      Energy of the (backward or forward) "delayed" excitation
  1373. **
  1374. ** Outputs:     None
  1375. **
  1376. ** Return value:
  1377. **
  1378. **  PFDEF
  1379. **         Word16   Indx    Pitch postfilter lag
  1380. **         Word16   Gain    Pitch postfilter gain
  1381. **         Word16   ScGn    Pitch postfilter scaling gain
  1382. **
  1383. */
  1384. PFDEF Get_Ind( Word16 Ind, Word16 Ten, Word16 Ccr, Word16 Enr )
  1385. {
  1386.     Word32   Acc0,Acc1 ;
  1387.     Word16   Exp   ;
  1388.     PFDEF Pf ;
  1389.     Pf.Indx = Ind ;
  1390.     /* Check valid gain */
  1391.     Acc0 = L_mult( Ten, Enr ) ;
  1392.     Acc0 = L_shr( Acc0, (Word16) 2 ) ;
  1393.     Acc1 = L_mult( Ccr, Ccr ) ;
  1394.     if ( Acc1 > Acc0 ) {
  1395.         if ( Ccr >= Enr )
  1396.             Pf.Gain = LpfConstTable[(int)WrkRate] ;
  1397.         else {
  1398.             Pf.Gain = div_s( Ccr, Enr ) ;
  1399.             Pf.Gain = mult( Pf.Gain, LpfConstTable[(int)WrkRate] ) ;
  1400.         }
  1401.         /* Compute scaling gain */
  1402.         Acc0 = L_deposit_h( Ten ) ;
  1403.         Acc0 = L_shr( Acc0, (Word16) 1 ) ;
  1404.         Acc0 = L_mac( Acc0, Ccr, Pf.Gain ) ;
  1405.         Exp  = mult( Pf.Gain, Pf.Gain ) ;
  1406.         Acc1 = L_mult( Enr, Exp ) ;
  1407.         Acc1 = L_shr( Acc1, (Word16) 1 ) ;
  1408.         Acc0 = L_add( Acc0, Acc1 ) ;
  1409.         Exp = round( Acc0 ) ;
  1410.         Acc1 = L_deposit_h( Ten ) ;
  1411.         Acc0 = L_deposit_h( Exp ) ;
  1412.         Acc1 = L_shr( Acc1, (Word16) 1 ) ;
  1413.         if ( Acc1 >= Acc0 )
  1414.             Exp = (Word16) 0x7fff ;
  1415.         else
  1416.             Exp = div_l( Acc1, Exp ) ;
  1417.         Acc0 = L_deposit_h( Exp ) ;
  1418.         Pf.ScGn = Sqrt_lbc( Acc0 ) ;
  1419.     }
  1420.     else {
  1421.         Pf.Gain = (Word16) 0 ;
  1422.         Pf.ScGn = (Word16) 0x7fff ;
  1423.     }
  1424.     Pf.Gain = mult( Pf.Gain, Pf.ScGn ) ;
  1425.     return Pf ;
  1426. }
  1427. /*
  1428. **
  1429. ** Function:        Filt_Lpf()
  1430. **
  1431. ** Description:     Applies the pitch postfilter for each subframe.
  1432. **
  1433. ** Links to text:   Section 3.6
  1434. **
  1435. ** Arguments:
  1436. **
  1437. **  Word16 *Tv      Pitch postfiltered excitation
  1438. **  Word16 *Buff    decoded excitation
  1439. **  PFDEF Pf        Pitch postfilter parameters
  1440. **  Word16 Sfc      Subframe index
  1441. **
  1442. ** Outputs:
  1443. **
  1444. **  Word16 *Tv      Pitch postfiltered excitation
  1445. **
  1446. ** Return value: None
  1447. **
  1448. */
  1449. void  Filt_Lpf( Word16 *Tv, Word16 *Buff, PFDEF Pf, Word16 Sfc )
  1450. {
  1451.     int   i  ;
  1452.     Word32   Acc0 ;
  1453.     for ( i = 0 ; i < SubFrLen ; i ++ ) {
  1454.         Acc0 = L_mult( Buff[PitchMax+(int)Sfc*SubFrLen+i], Pf.ScGn ) ;
  1455.         Acc0 = L_mac( Acc0, Buff[PitchMax+(int)Sfc*SubFrLen+(int)Pf.Indx+i],
  1456.                                                                 Pf.Gain ) ;
  1457.         Tv[(int)Sfc*SubFrLen+i] = round( Acc0 ) ;
  1458.     }
  1459.     return;
  1460. }
  1461. /*
  1462. **
  1463. ** Function:        ACELP_LBC_code()
  1464. **
  1465. ** Description:     Find Algebraic codebook for low bit rate LBC encoder
  1466. **
  1467. ** Links to text:   Section 2.16
  1468. **
  1469. ** Arguments:
  1470. **
  1471. **   Word16 X[]              Target vector.     (in Q0)
  1472. **   Word16 h[]              Impulse response.  (in Q12)
  1473. **   Word16 T0               Pitch period.
  1474. **   Word16 code[]           Innovative vector.        (in Q12)
  1475. **   Word16 gain             Innovative vector gain.   (in Q0)
  1476. **   Word16 sign             Signs of the 4 pulses.
  1477. **   Word16 shift            Shift of the innovative vector
  1478. **   Word16 gain_T0          Gain for pitch synchronous fiter
  1479. **
  1480. ** Inputs :
  1481. **
  1482. **   Word16 X[]              Target vector.     (in Q0)
  1483. **   Word16 h[]              Impulse response.  (in Q12)
  1484. **   Word16 T0               Pitch period.
  1485. **   Word16 gain_T0          Gain for pitch synchronous fiter
  1486. **
  1487. ** Outputs:
  1488. **
  1489. **   Word16 code[]           Innovative vector.        (in Q12)
  1490. **   Word16 gain             Innovative vector gain.   (in Q0)
  1491. **   Word16 sign             Signs of the 4 pulses.
  1492. **   Word16 shift            Shift of the innovative vector.
  1493. **
  1494. ** Return value:
  1495. **
  1496. **   Word16 index            Innovative codebook index
  1497. **
  1498. */
  1499. Word16  ACELP_LBC_code(Word16 X[], Word16 h[], Word16 T0, Word16 code[],
  1500.         Word16 *ind_gain, Word16 *shift, Word16 *sign, Word16 gain_T0)
  1501. {
  1502.     Word16 i, index, gain_q;
  1503.     Word16 Dn[SubFrLen2], tmp_code[SubFrLen2];
  1504.     Word16 rr[DIM_RR];
  1505.  /*
  1506.   * Include fixed-gain pitch contribution into impulse resp. h[]
  1507.   * Find correlations of h[] needed for the codebook search.
  1508.  */
  1509.     for (i = 0; i < SubFrLen; i++)    /* Q13 -->  Q12*/
  1510.         h[i] = shr(h[i], 1);
  1511.     if (T0 < SubFrLen-2) {
  1512.         for (i = T0; i < SubFrLen; i++)    /* h[i] += gain_T0*h[i-T0] */
  1513.         h[i] = add(h[i], mult(h[i-T0], gain_T0));
  1514.     }
  1515.     Cor_h(h, rr);
  1516.  /*
  1517.   * Compute correlation of target vector with impulse response.
  1518.   */
  1519.     Cor_h_X(h, X, Dn);
  1520.  /*
  1521.   * Find innovative codebook.
  1522.   * rr input matrix autocorrelation
  1523.   *    output filtered codeword
  1524.   */
  1525.     index = D4i64_LBC(Dn, rr, h, tmp_code, rr, shift, sign);
  1526.  /*
  1527.   * Compute innovation vector gain.
  1528.   * Include fixed-gain pitch contribution into code[].
  1529.   */
  1530.     *ind_gain = G_code(X, rr, &gain_q);
  1531.     for (i = 0; i < SubFrLen; i++)   {
  1532.         code[i] = i_mult(tmp_code[i], gain_q);
  1533.     }
  1534.     if(T0 < SubFrLen-2)
  1535.         for (i = T0; i < SubFrLen; i++)    /* code[i] += gain_T0*code[i-T0] */
  1536.             code[i] = add(code[i], mult(code[i-T0], gain_T0));
  1537.     return index;
  1538. }
  1539. /*
  1540. **
  1541. ** Function:        Cor_h()
  1542. **
  1543. ** Description:     Compute correlations of h[] needed for the codebook search.
  1544. **
  1545. ** Links to text:   Section 2.16
  1546. **
  1547. ** Arguments:
  1548. **
  1549. **  Word16 h[]              Impulse response.
  1550. **  Word16 rr[]             Correlations.
  1551. **
  1552. **  Outputs:
  1553. **
  1554. **  Word16 rr[]             Correlations.
  1555. **
  1556. **  Return value :          None
  1557. */
  1558. void Cor_h(Word16 *H, Word16 *rr)
  1559. {
  1560.     Word16 *rri0i0, *rri1i1, *rri2i2, *rri3i3;
  1561.     Word16 *rri0i1, *rri0i2, *rri0i3;
  1562.     Word16 *rri1i2, *rri1i3, *rri2i3;
  1563.     Word16 *p0, *p1, *p2, *p3;
  1564.     Word16 *ptr_hd, *ptr_hf, *ptr_h1, *ptr_h2;
  1565.     Word32 cor;
  1566.     Word16 i, k, ldec, l_fin_sup, l_fin_inf;
  1567.     Word16 h[SubFrLen2];
  1568.     /* Scaling for maximum precision */
  1569.     cor = 0;
  1570.     for(i=0; i<SubFrLen; i++)
  1571.         cor = L_mac(cor, H[i], H[i]);
  1572.     if(extract_h(cor) > 32000 ) {
  1573.         for(i=0; i<SubFrLen; i++) h[i+4] = shr(H[i], 1);
  1574.     }
  1575.     else {
  1576.         k = norm_l(cor);
  1577.         k = shr(k, 1);
  1578.         for(i=0; i<SubFrLen; i++) h[i+4] = shl(H[i], k);
  1579.     }
  1580.     for(i=0; i<4; i++) h[i] = 0;
  1581.     /* Init pointers */
  1582.     rri0i0 = rr;
  1583.     rri1i1 = rri0i0 + NB_POS;
  1584.     rri2i2 = rri1i1 + NB_POS;
  1585.     rri3i3 = rri2i2 + NB_POS;
  1586.     rri0i1 = rri3i3 + NB_POS;
  1587.     rri0i2 = rri0i1 + MSIZE;
  1588.     rri0i3 = rri0i2 + MSIZE;
  1589.     rri1i2 = rri0i3 + MSIZE;
  1590.     rri1i3 = rri1i2 + MSIZE;
  1591.     rri2i3 = rri1i3 + MSIZE;
  1592.  /*
  1593.   * Compute rri0i0[], rri1i1[], rri2i2[] and rri3i3[]
  1594.   */
  1595.     p0 = rri0i0 + NB_POS-1;   /* Init pointers to last position of rrixix[] */
  1596.     p1 = rri1i1 + NB_POS-1;
  1597.     p2 = rri2i2 + NB_POS-1;
  1598.     p3 = rri3i3 + NB_POS-1;
  1599.     ptr_h1 = h;
  1600.     cor    = 0;
  1601.     for(i=0;  i<NB_POS; i++) {
  1602.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1603.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1604.         *p3-- = extract_h(cor);
  1605.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1606.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1607.         *p2-- = extract_h(cor);
  1608.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1609.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1610.         *p1-- = extract_h(cor);
  1611.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1612.         cor = L_mac(cor, *ptr_h1, *ptr_h1); ptr_h1++;
  1613.         *p0-- = extract_h(cor);
  1614.     }
  1615.  /*
  1616.   * Compute elements of: rri0i1[], rri0i3[], rri1i2[] and rri2i3[]
  1617.   */
  1618.     l_fin_sup = MSIZE-1;
  1619.     l_fin_inf = l_fin_sup-(Word16)1;
  1620.     ldec = NB_POS+1;
  1621.     ptr_hd = h;
  1622.     ptr_hf = ptr_hd + 2;
  1623.     for(k=0; k<NB_POS; k++) {
  1624.         p3 = rri2i3 + l_fin_sup;
  1625.         p2 = rri1i2 + l_fin_sup;
  1626.         p1 = rri0i1 + l_fin_sup;
  1627.         p0 = rri0i3 + l_fin_inf;
  1628.         cor = 0;
  1629.         ptr_h1 = ptr_hd;
  1630.         ptr_h2 =  ptr_hf;
  1631.         for(i=k+(Word16)1; i<NB_POS; i++ ) {
  1632.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1633.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1634.             *p3 = extract_h(cor);
  1635.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1636.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1637.             *p2 = extract_h(cor);
  1638.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1639.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1640.             *p1 = extract_h(cor);
  1641.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1642.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1643.             *p0 = extract_h(cor);
  1644.             p3 -= ldec;
  1645.             p2 -= ldec;
  1646.             p1 -= ldec;
  1647.             p0 -= ldec;
  1648.         }
  1649.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1650.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1651.         *p3 = extract_h(cor);
  1652.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1653.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1654.         *p2 = extract_h(cor);
  1655.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1656.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1657.         *p1 = extract_h(cor);
  1658.         l_fin_sup -= NB_POS;
  1659.         l_fin_inf--;
  1660.         ptr_hf += STEP;
  1661.     }
  1662.  /*
  1663.   * Compute elements of: rri0i2[], rri1i3[]
  1664.   */
  1665.     ptr_hd = h;
  1666.     ptr_hf = ptr_hd + 4;
  1667.     l_fin_sup = MSIZE-1;
  1668.     l_fin_inf = l_fin_sup-(Word16)1;
  1669.     for(k=0; k<NB_POS; k++) {
  1670.         p3 = rri1i3 + l_fin_sup;
  1671.         p2 = rri0i2 + l_fin_sup;
  1672.         p1 = rri1i3 + l_fin_inf;
  1673.         p0 = rri0i2 + l_fin_inf;
  1674.         cor = 0;
  1675.         ptr_h1 = ptr_hd;
  1676.         ptr_h2 =  ptr_hf;
  1677.         for(i=k+(Word16)1; i<NB_POS; i++ ) {
  1678.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1679.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1680.             *p3 = extract_h(cor);
  1681.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1682.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1683.             *p2 = extract_h(cor);
  1684.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1685.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1686.             *p1 = extract_h(cor);
  1687.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1688.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1689.             *p0 = extract_h(cor);
  1690.             p3 -= ldec;
  1691.             p2 -= ldec;
  1692.             p1 -= ldec;
  1693.             p0 -= ldec;
  1694.         }
  1695.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1696.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1697.         *p3 = extract_h(cor);
  1698.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1699.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1700.         *p2 = extract_h(cor);
  1701.         l_fin_sup -= NB_POS;
  1702.         l_fin_inf--;
  1703.         ptr_hf += STEP;
  1704.     }
  1705.  /*
  1706.   * Compute elements of: rri0i1[], rri0i3[], rri1i2[] and rri2i3[]
  1707.   */
  1708.     ptr_hd = h;
  1709.     ptr_hf = ptr_hd + 6;
  1710.     l_fin_sup = MSIZE-1;
  1711.     l_fin_inf = l_fin_sup-(Word16)1;
  1712.     for(k=0; k<NB_POS; k++) {
  1713.         p3 = rri0i3 + l_fin_sup;
  1714.         p2 = rri2i3 + l_fin_inf;
  1715.         p1 = rri1i2 + l_fin_inf;
  1716.         p0 = rri0i1 + l_fin_inf;
  1717.         ptr_h1 = ptr_hd;
  1718.         ptr_h2 =  ptr_hf;
  1719.         cor = 0;
  1720.         for(i=k+(Word16)1; i<NB_POS; i++ ) {
  1721.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1722.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1723.             *p3 = extract_h(cor);
  1724.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1725.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1726.             *p2 = extract_h(cor);
  1727.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1728.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1729.             *p1 = extract_h(cor);
  1730.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1731.             cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1732.             *p0 = extract_h(cor);
  1733.             p3 -= ldec;
  1734.             p2 -= ldec;
  1735.             p1 -= ldec;
  1736.             p0 -= ldec;
  1737.         }
  1738.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1739.         cor = L_mac(cor, *ptr_h1, *ptr_h2); ptr_h1++; ptr_h2++;
  1740.         *p3 = extract_h(cor);
  1741.         l_fin_sup -= NB_POS;
  1742.         l_fin_inf--;
  1743.         ptr_hf += STEP;
  1744.     }
  1745.     return;
  1746. }
  1747. /*
  1748. **
  1749. **  Function:     Corr_h_X()
  1750. **
  1751. **  Description:    Compute  correlations of input response h[] with
  1752. **                  the target vector X[].
  1753. **
  1754. **  Links to the text: Section 2.16
  1755. **
  1756. ** Arguments:
  1757. **
  1758. **      Word16 h[]              Impulse response.
  1759. **      Word16 X[]              Target vector.
  1760. **      Word16 D[]              Correlations.
  1761. **
  1762. **  Outputs:
  1763. **
  1764. **      Word16 D[]              Correlations.
  1765. **
  1766. **  Return value:           None
  1767. */
  1768. void Cor_h_X(Word16 h[], Word16 X[], Word16 D[])
  1769. {
  1770.     Word16 i, j;
  1771.     Word32 s, max;
  1772.     Word32 y32[SubFrLen];
  1773.     /* first keep the result on 32 bits and find absolute maximum */
  1774.     max = 0;
  1775.     for (i = 0; i < SubFrLen; i++) {
  1776.         s = 0;
  1777.         for (j = i; j <  SubFrLen; j++)
  1778.             s = L_mac(s, X[j], h[j-i]);
  1779.         y32[i] = s;
  1780.         s = L_abs(s);
  1781.         if(s > max) max = s;
  1782.     }
  1783.     /*
  1784.      * Find the number of right shifts to do on y32[]
  1785.      * so that maximum is on 13 bits
  1786.      */
  1787.     j = norm_l(max);
  1788.     if( sub(j,16) > 0) j = 16;
  1789.     j = sub(18, j);
  1790.     for(i=0; i<SubFrLen; i++)
  1791.         D[i] = extract_l( L_shr(y32[i], j) );
  1792.     return;
  1793. }
  1794. /*
  1795. ** Function:            Reset_max_time()
  1796. **
  1797. **  Description:        This function should be called at the beginning
  1798. **                      of each frame.
  1799. **
  1800. **  Links to the text:  Section 2.16
  1801. **
  1802. **  Arguments:          None
  1803. **
  1804. **  Inputs:             None
  1805. **
  1806. **  Outputs:
  1807. **
  1808. **      Word16          extra
  1809. **
  1810. **  Return value:           None
  1811. **
  1812. */
  1813. static Word16 extra;
  1814. void reset_max_time(void)
  1815. {
  1816.     extra = 120;
  1817.     return;
  1818. }
  1819. /*
  1820. **
  1821. **  Function:       D4i64_LBC
  1822. **
  1823. **  Description:       Algebraic codebook for LBC.
  1824. **                     -> 17 bits; 4 pulses in a frame of 60 samples
  1825. **
  1826. **                     The code length is 60, containing 4 nonzero pulses
  1827. **                     i0, i1, i2, i3. Each pulse can have 8 possible
  1828. **                     positions (positive or negative):
  1829. **
  1830. **                     i0 (+-1) : 0, 8,  16, 24, 32, 40, 48, 56
  1831. **                     i1 (+-1) : 2, 10, 18, 26, 34, 42, 50, 58
  1832. **                     i2 (+-1) : 4, 12, 20, 28, 36, 44, 52, (60)
  1833. **                     i3 (+-1) : 6, 14, 22, 30, 38, 46, 54, (62)
  1834. **
  1835. **                     All the pulse can be shifted by one.
  1836. **                     The last position of the last 2 pulses falls outside the
  1837. **                     frame and signifies that the pulse is not present.
  1838. **                     The threshold controls if a section of the innovative
  1839. **                     codebook should be searched or not.
  1840. **
  1841. **  Links to the text: Section 2.16
  1842. **
  1843. **  Input arguments:
  1844. **
  1845. **      Word16 Dn[]       Correlation between target vector and impulse response h[]
  1846. **      Word16 rr[]       Correlations of impulse response h[]
  1847. **      Word16 h[]        Impulse response of filters
  1848. **
  1849. **  Output arguments:
  1850. **
  1851. **      Word16 cod[]      Selected algebraic codeword
  1852. **      Word16 y[]        Filtered codeword
  1853. **      Word16 code_shift Shift of the codeword
  1854. **      Word16 sign       Signs of the 4 pulses.
  1855. **
  1856. **  Return value:
  1857. **
  1858. **      Word16   Index of selected codevector
  1859. **
  1860. */
  1861. Word16 D4i64_LBC(Word16 Dn[], Word16 rr[], Word16 h[], Word16 cod[],
  1862.                  Word16 y[], Word16 *code_shift, Word16 *sign)
  1863. {
  1864.     Word16  i0, i1, i2, i3, ip0, ip1, ip2, ip3;
  1865.     Word16  i, j, time;
  1866.     Word16  shif, shift;
  1867.     Word16  ps0, ps1, ps2, ps3, alp, alp0;
  1868.     Word32  alp1, alp2, alp3, L32;
  1869.     Word16  ps0a, ps1a, ps2a;
  1870.     Word16  ps3c, psc, alpha;
  1871.     Word16  means, max0, max1, max2, thres;
  1872.     Word16  *rri0i0, *rri1i1, *rri2i2, *rri3i3;
  1873.     Word16  *rri0i1, *rri0i2, *rri0i3;
  1874.     Word16  *rri1i2, *rri1i3, *rri2i3;
  1875.     Word16  *ptr_ri0i0, *ptr_ri1i1, *ptr_ri2i2, *ptr_ri3i3;
  1876.     Word16  *ptr_ri0i1, *ptr_ri0i2, *ptr_ri0i3;
  1877.     Word16  *ptr_ri1i2, *ptr_ri1i3, *ptr_ri2i3;
  1878.     Word16  *ptr1_ri0i1, *ptr1_ri0i2, *ptr1_ri0i3;
  1879.     Word16  *ptr1_ri1i2, *ptr1_ri1i3, *ptr1_ri2i3;
  1880.     Word16  p_sign[SubFrLen2/2];
  1881.     /* Init pointers */
  1882.     rri0i0 = rr;
  1883.     rri1i1 = rri0i0 + NB_POS;
  1884.     rri2i2 = rri1i1 + NB_POS;
  1885.     rri3i3 = rri2i2 + NB_POS;
  1886.     rri0i1 = rri3i3 + NB_POS;
  1887.     rri0i2 = rri0i1 + MSIZE;
  1888.     rri0i3 = rri0i2 + MSIZE;
  1889.     rri1i2 = rri0i3 + MSIZE;
  1890.     rri1i3 = rri1i2 + MSIZE;
  1891.     rri2i3 = rri1i3 + MSIZE;
  1892.  /*
  1893.   * Extend the backward filtered target vector by zeros
  1894.   */
  1895.     for (i = SubFrLen; i < SubFrLen2; i++) Dn[i] = 0;
  1896.  /*
  1897.   * Chose the sign of the impulse.
  1898.   */
  1899.     for (i=0; i<SubFrLen; i+=2) {
  1900.         if( add(Dn[i],Dn[i+1]) >= 0) {
  1901.             p_sign[i/2] = 1;
  1902.         }
  1903.         else {
  1904.             p_sign[i/2] = -1;
  1905.             Dn[i] = -Dn[i];
  1906.             Dn[i+1] = -Dn[i+1];
  1907.         }
  1908.     }
  1909.     p_sign[30] = p_sign[31] = 1;
  1910.  /*
  1911.   *   Compute the search threshold after three pulses
  1912.   */
  1913.     /* odd positions */
  1914.     /* Find maximum of Dn[i0]+Dn[i1]+Dn[i2] */
  1915.     max0 = Dn[0];
  1916.     max1 = Dn[2];
  1917.     max2 = Dn[4];
  1918.     for (i = 8; i < SubFrLen; i+=STEP) {
  1919.         if (Dn[i]   > max0) max0 = Dn[i];
  1920.         if (Dn[i+2] > max1) max1 = Dn[i+2];
  1921.         if (Dn[i+4] > max2) max2 = Dn[i+4];
  1922.     }
  1923.     max0 = add(max0, max1);
  1924.     max0 = add(max0, max2);
  1925.     /* Find means of Dn[i0]+Dn[i1]+Dn[i2] */
  1926.     L32 = 0;
  1927.     for (i = 0; i < SubFrLen; i+=STEP) {
  1928.         L32 = L_mac(L32, Dn[i], 1);
  1929.         L32 = L_mac(L32, Dn[i+2], 1);
  1930.         L32 = L_mac(L32, Dn[i+4], 1);
  1931.     }
  1932.     means =extract_l( L_shr(L32, 4));
  1933.     /* thres = means + (max0-means)*threshold; */
  1934.     thres = sub(max0, means);
  1935.     thres = mult(thres, threshold);
  1936.     thres = add(thres, means);
  1937.     /* even positions */
  1938.     /* Find maximum of Dn[i0]+Dn[i1]+Dn[i2] */
  1939.     max0 = Dn[1];
  1940.     max1 = Dn[3];
  1941.     max2 = Dn[5];
  1942.     for (i = 9; i < SubFrLen; i+=STEP) {
  1943.         if (Dn[i]   > max0) max0 = Dn[i];
  1944.         if (Dn[i+2] > max1) max1 = Dn[i+2];
  1945.         if (Dn[i+4] > max2) max2 = Dn[i+4];
  1946.     }
  1947.     max0 = add(max0, max1);
  1948.     max0 = add(max0, max2);
  1949.     /* Find means of Dn[i0]+Dn[i1]+Dn[i2] */
  1950.     L32 = 0;
  1951.     for (i = 1; i < SubFrLen; i+=STEP) {
  1952.         L32 = L_mac(L32, Dn[i], 1);
  1953.         L32 = L_mac(L32, Dn[i+2], 1);
  1954.         L32 = L_mac(L32, Dn[i+4], 1);
  1955.     }
  1956.     means =extract_l( L_shr(L32, 4));
  1957.     /* max1 = means + (max0-means)*threshold */
  1958.     max1 = sub(max0, means);
  1959.     max1 = mult(max1, threshold);
  1960.     max1 = add(max1, means);
  1961.     /* Keep maximum threshold between odd and even position */
  1962.     if(max1 > thres) thres = max1;
  1963.  /*
  1964.   * Modification of rrixiy[] to take signs into account.
  1965.   */
  1966.     ptr_ri0i1 = rri0i1;
  1967.     ptr_ri0i2 = rri0i2;
  1968.     ptr_ri0i3 = rri0i3;
  1969.     ptr1_ri0i1 = rri0i1;
  1970.     ptr1_ri0i2 = rri0i2;
  1971.     ptr1_ri0i3 = rri0i3;
  1972.     for(i0=0; i0<SubFrLen/2; i0+=STEP/2) {
  1973.         for(i1=2/2; i1<SubFrLen/2; i1+=STEP/2) {
  1974.             *ptr_ri0i1++ = i_mult(*ptr1_ri0i1++,
  1975.                                     i_mult(p_sign[i0], p_sign[i1]));
  1976.             *ptr_ri0i2++ = i_mult(*ptr1_ri0i2++,
  1977.                                     i_mult(p_sign[i0], p_sign[i1+1]));
  1978.             *ptr_ri0i3++ = i_mult(*ptr1_ri0i3++,
  1979.                                     i_mult(p_sign[i0], p_sign[i1+2]));
  1980.         }
  1981.     }
  1982.     ptr_ri1i2 = rri1i2;
  1983.     ptr_ri1i3 = rri1i3;
  1984.     ptr1_ri1i2 = rri1i2;
  1985.     ptr1_ri1i3 = rri1i3;
  1986.     for(i1=2/2; i1<SubFrLen/2; i1+=STEP/2) {
  1987.         for(i2=4/2; i2<SubFrLen2/2; i2+=STEP/2) {
  1988.             *ptr_ri1i2++ = i_mult(*ptr1_ri1i2++,
  1989.                                     i_mult(p_sign[i1], p_sign[i2]));
  1990.             *ptr_ri1i3++ = i_mult(*ptr1_ri1i3++,
  1991.                                     i_mult(p_sign[i1], p_sign[i2+1]));
  1992.         }
  1993.     }
  1994.     ptr_ri2i3 = rri2i3;
  1995.     ptr1_ri2i3 = rri2i3;
  1996.     for(i2=4/2; i2<SubFrLen2/2; i2+=STEP/2) {
  1997.         for(i3=6/2; i3<SubFrLen2/2; i3+=STEP/2)
  1998.         *ptr_ri2i3++ = i_mult(*ptr1_ri2i3++, i_mult(p_sign[i2], p_sign[i3]));
  1999.     }
  2000.  /*
  2001.   * Search the optimum positions of the four  pulses which maximize
  2002.   *     square(correlation) / energy
  2003.   * The search is performed in four  nested loops. At each loop, one
  2004.   * pulse contribution is added to the correlation and energy.
  2005.   *
  2006.   * The fourth loop is entered only if the correlation due to the
  2007.   *  contribution of the first three pulses exceeds the preset
  2008.   *  threshold.
  2009.   */
  2010.     /* Default values */
  2011.     ip0    = 0;
  2012.     ip1    = 2;
  2013.     ip2    = 4;
  2014.     ip3    = 6;
  2015.     shif   = 0;
  2016.     psc    = 0;
  2017.     alpha  = 32767;
  2018.     time   = add(max_time, extra);
  2019.     /* Four loops to search innovation code. */
  2020.     /* Init. pointers that depend on first loop */
  2021.     ptr_ri0i0 = rri0i0;
  2022.     ptr_ri0i1 = rri0i1;
  2023.     ptr_ri0i2 = rri0i2;
  2024.     ptr_ri0i3 = rri0i3;
  2025.     /* first pulse loop  */
  2026.     for (i0 = 0; i0 < SubFrLen; i0 += STEP) {
  2027.         ps0  = Dn[i0];
  2028.         ps0a = Dn[i0+1];
  2029.         alp0 = *ptr_ri0i0++;
  2030.         /* Init. pointers that depend on second loop */
  2031.         ptr_ri1i1 = rri1i1;
  2032.         ptr_ri1i2 = rri1i2;
  2033.         ptr_ri1i3 = rri1i3;
  2034.         /* second pulse loop */
  2035.         for (i1 = 2; i1 < SubFrLen; i1 += STEP) {
  2036.             ps1  = add(ps0, Dn[i1]);
  2037.             ps1a = add(ps0a, Dn[i1+1]);
  2038.             /* alp1 = alp0 + *ptr_ri1i1++ + 2.0 * ( *ptr_ri0i1++); */
  2039.             alp1 = L_mult(alp0, 1);
  2040.             alp1 = L_mac(alp1, *ptr_ri1i1++, 1);
  2041.             alp1 = L_mac(alp1, *ptr_ri0i1++, 2);
  2042.             /* Init. pointers that depend on third loop */
  2043.             ptr_ri2i2 = rri2i2;
  2044.             ptr_ri2i3 = rri2i3;
  2045.             /* third pulse loop */
  2046.             for (i2 = 4; i2 < SubFrLen2; i2 += STEP) {
  2047.                 ps2  = add(ps1, Dn[i2]);
  2048.                 ps2a = add(ps1a, Dn[i2+1]);
  2049.                 /* alp2 = alp1 + *ptr_ri2i2++
  2050.                                + 2.0 * (*ptr_ri0i2++ + *ptr_ri1i2++); */
  2051.                 alp2 = L_mac(alp1, *ptr_ri2i2++, 1);
  2052.                 alp2 = L_mac(alp2, *ptr_ri0i2++, 2);
  2053.                 alp2 = L_mac(alp2, *ptr_ri1i2++, 2);
  2054.                 /* Decide the shift */
  2055.                 shift = 0;
  2056.                 if(ps2a > ps2) {
  2057.                     shift = 1;
  2058.                     ps2   = ps2a;
  2059.                 }
  2060.                 /* Test threshold */
  2061.                 if ( ps2 > thres) {
  2062.                     /* Init. pointers that depend on 4th loop */
  2063.                     ptr_ri3i3 = rri3i3;
  2064.                     /* 4th pulse loop */
  2065.                     for (i3 = 6; i3 < SubFrLen2; i3 += STEP) {
  2066.                         ps3 = add(ps2, Dn[i3+shift]);
  2067.                         /* alp3 = alp2 + (*ptr_ri3i3++) +
  2068.                                          2 x ( (*ptr_ri0i3++) +
  2069.                                                (*ptr_ri1i3++) +
  2070.                                                (*ptr_ri2i3++) ) */
  2071.                         alp3 = L_mac(alp2, *ptr_ri3i3++, 1);
  2072.                         alp3 = L_mac(alp3, *ptr_ri0i3++, 2);
  2073.                         alp3 = L_mac(alp3, *ptr_ri1i3++, 2);
  2074.                         alp3 = L_mac(alp3, *ptr_ri2i3++, 2);
  2075.                         alp  = extract_l(L_shr(alp3, 5));
  2076.                         ps3c = mult(ps3, ps3);
  2077.                         if( L_mult(ps3c, alpha) > L_mult(psc, alp) ) {
  2078.                             psc = ps3c;
  2079.                             alpha = alp;
  2080.                             ip0 = i0;
  2081.                             ip1 = i1;
  2082.                             ip2 = i2;
  2083.                             ip3 = i3;
  2084.                             shif = shift;
  2085.                         }
  2086.                     }  /*  end of for i3 = */
  2087.                     time --;
  2088.                     if(time <= 0 ) goto end_search;   /* Max time finish */
  2089.                     ptr_ri0i3 -= NB_POS;
  2090.                     ptr_ri1i3 -= NB_POS;
  2091.                 }  /* end of if >thres */
  2092.                 else {
  2093.                     ptr_ri2i3 += NB_POS;
  2094.                 }
  2095.             } /* end of for i2 = */
  2096.             ptr_ri0i2 -= NB_POS;
  2097.             ptr_ri1i3 += NB_POS;
  2098.         } /* end of for i1 = */
  2099.         ptr_ri0i2 += NB_POS;
  2100.         ptr_ri0i3 += NB_POS;
  2101.     } /* end of for i0 = */
  2102. end_search:
  2103.     extra = time;
  2104.     /* Set the sign of impulses */
  2105.     i0 = p_sign[shr(ip0, 1)];
  2106.     i1 = p_sign[shr(ip1, 1)];
  2107.     i2 = p_sign[shr(ip2, 1)];
  2108.     i3 = p_sign[shr(ip3, 1)];
  2109.     /* Find the codeword corresponding to the selected positions */
  2110.     for(i=0; i<SubFrLen; i++) cod[i] = 0;
  2111.     if(shif > 0) {
  2112.         ip0 = add(ip0 ,1);
  2113.         ip1 = add(ip1 ,1);
  2114.         ip2 = add(ip2 ,1);
  2115.         ip3 = add(ip3 ,1);
  2116.     }
  2117.     cod[ip0] =  i0;
  2118.     cod[ip1] =  i1;
  2119.     if(ip2<SubFrLen) cod[ip2] = i2;
  2120.     if(ip3<SubFrLen) cod[ip3] = i3;
  2121.     /* find the filtered codeword */
  2122.     for (i = 0; i < SubFrLen; i++) y[i] = 0;
  2123.     if(i0 > 0)
  2124.         for(i=ip0, j=0; i<SubFrLen; i++, j++)
  2125.             y[i] = add(y[i], h[j]);
  2126.     else
  2127.         for(i=ip0, j=0; i<SubFrLen; i++, j++)
  2128.             y[i] = sub(y[i], h[j]);
  2129.     if(i1 > 0)
  2130.         for(i=ip1, j=0; i<SubFrLen; i++, j++)
  2131.             y[i] = add(y[i], h[j]);
  2132.     else
  2133.         for(i=ip1, j=0; i<SubFrLen; i++, j++)
  2134.             y[i] = sub(y[i], h[j]);
  2135.     if(ip2 < SubFrLen) {
  2136.         if(i2 > 0)
  2137.             for(i=ip2, j=0; i<SubFrLen; i++, j++)
  2138.                 y[i] = add(y[i], h[j]);
  2139.         else
  2140.             for(i=ip2, j=0; i<SubFrLen; i++, j++)
  2141.                 y[i] = sub(y[i], h[j]);
  2142.     }
  2143.     if(ip3 < SubFrLen) {
  2144.         if(i3 > 0)
  2145.             for(i=ip3, j=0; i<SubFrLen; i++, j++)
  2146.                 y[i] = add(y[i], h[j]);
  2147.         else
  2148.             for(i=ip3, j=0; i<SubFrLen; i++, j++)
  2149.                 y[i] = sub(y[i], h[j]);
  2150.     }
  2151.     /* find codebook index;  17-bit address */
  2152.     *code_shift = shif;
  2153.     *sign = 0;
  2154.     if(i0 > 0) *sign = add(*sign, 1);
  2155.     if(i1 > 0) *sign = add(*sign, 2);
  2156.     if(i2 > 0) *sign = add(*sign, 4);
  2157.     if(i3 > 0) *sign = add(*sign, 8);
  2158.     i = shr(ip0, 3);
  2159.     i = add(i, shl(shr(ip1, 3), 3));
  2160.     i = add(i, shl(shr(ip2, 3), 6));
  2161.     i = add(i, shl(shr(ip3, 3), 9));
  2162.     return i;
  2163. }
  2164. /*
  2165. **
  2166. **  Function:  G_code()
  2167. **
  2168. **  Description: Compute the gain of innovative code.
  2169. **
  2170. **
  2171. **  Links to the text: Section 2.16
  2172. **
  2173. ** Input arguments:
  2174. **
  2175. **      Word16 X[]        Code target.  (in Q0)
  2176. **      Word16 Y[]        Filtered innovation code. (in Q12)
  2177. **
  2178. ** Output:
  2179. **
  2180. **      Word16 *gain_q    Gain of innovation code.  (in Q0)
  2181. **
  2182. **  Return value:
  2183. **
  2184. **      Word16  index of innovation code gain
  2185. **
  2186. */
  2187. Word16 G_code(Word16 X[], Word16 Y[], Word16 *gain_q)
  2188. {
  2189.     Word16 i;
  2190.     Word16 xy, yy, exp_xy, exp_yy, gain, gain_nq;
  2191.     Word32 L_xy, L_yy;
  2192.     Word16 dist, dist_min;
  2193.     /* Scale down Y[] by 8 to avoid overflow */
  2194.     for(i=0; i<SubFrLen; i++)
  2195.         Y[i] = shr(Y[i], 3);
  2196.     /* Compute scalar product <X[],Y[]> */
  2197.     L_xy = 0L;
  2198.     for(i=0; i<SubFrLen; i++)
  2199.         L_xy = L_mac(L_xy, X[i], Y[i]);
  2200.     exp_xy = norm_l(L_xy);
  2201.     xy = extract_h( L_shl(L_xy, exp_xy) );
  2202.     if(xy <= 0) {
  2203.         gain = 0;
  2204.         *gain_q =FcbkGainTable[gain];
  2205.         return(gain);
  2206.     }
  2207.     /* Compute scalar product <Y[],Y[]> */
  2208.     L_yy = 0L;
  2209.     for(i=0; i<SubFrLen; i++)
  2210.         L_yy = L_mac(L_yy, Y[i], Y[i]);
  2211.     exp_yy = norm_l(L_yy);
  2212.     yy     = extract_h( L_shl(L_yy, exp_yy) );
  2213.     /* compute gain = xy/yy */
  2214.     xy = shr(xy, 1);             /* Be sure xy < yy */
  2215.     gain_nq = div_s( xy, yy);
  2216.     i = add(exp_xy, 5);          /* Denormalization of division */
  2217.     i = sub(i, exp_yy);
  2218.     gain_nq = shr(gain_nq, i);
  2219.     gain = (Word16) 0;
  2220.     dist_min = sub(gain_nq, FcbkGainTable[0]);
  2221.     dist_min = abs_s(dist_min);
  2222.     for ( i =  1; i <NumOfGainLev ; i ++ ) {
  2223.         dist = sub(gain_nq, FcbkGainTable[i]);
  2224.         dist =abs_s(dist);
  2225.         if ( dist< dist_min) {
  2226.             dist_min = dist;
  2227.             gain = (Word16) i ;
  2228.         }
  2229.     }
  2230.     *gain_q = FcbkGainTable[gain];
  2231.     return(gain);
  2232. }
  2233. /*
  2234. **
  2235. **  Function:       search_T0()
  2236. **
  2237. **  Description:          Gets parameters of pitch synchronous filter
  2238. **
  2239. **  Links to the text:    Section 2.16
  2240. **
  2241. **  Arguments:
  2242. **
  2243. **      Word16 T0         Decoded pitch lag
  2244. **      Word16 Gid        Gain vector index in the adaptive gain vector codebook
  2245. **      Word16 *gain_T0   Pitch synchronous gain
  2246. **
  2247. **  Outputs:
  2248. **
  2249. **      Word16 *gain_T0   Pitch synchronous filter gain
  2250. **
  2251. **  Return Value:
  2252. **
  2253. **      Word16 T0_mod     Pitch synchronous filter lag
  2254. */
  2255. Word16 search_T0 ( Word16 T0, Word16 Gid, Word16 *gain_T0)
  2256. {
  2257.     Word16 T0_mod;
  2258.     T0_mod = T0+epsi170[Gid];
  2259.     *gain_T0 = gain170[Gid];
  2260.     return(T0_mod);
  2261. }