UTIL_LBC.C
上传用户:meifeng08
上传日期:2013-06-18
资源大小:5304k
文件大小:20k
源码类别:

语音压缩

开发平台:

C/C++

  1. /*
  2. **
  3. ** File:    util_lbc.c
  4. **
  5. ** Description: utility functions for the lbc codec
  6. **
  7. ** Functions:
  8. **
  9. **  I/O functions:
  10. **
  11. **      Read_lbc()
  12. **      Write_lbc()
  13. **
  14. **  High-pass filtering:
  15. **
  16. **      Rem_Dc()
  17. **
  18. **  Miscellaneous signal processing functions:
  19. **
  20. **      Vec_Norm()
  21. **      Mem_Shift()
  22. **      Comp_En()
  23. **      Scale()
  24. **
  25. **  Bit stream packing/unpacking:
  26. **
  27. **      Line_Pack()
  28. **      Line_Unpk()
  29. **
  30. **  Mathematical functions:
  31. **
  32. **      Sqrt_lbc()
  33. **      Rand_lbc()
  34. */
  35. /*
  36.     ITU-T G.723 Speech Coder   ANSI-C Source Code     Version 5.00
  37.     copyright (c) 1995, AudioCodes, DSP Group, France Telecom,
  38.     Universite de Sherbrooke.  All rights reserved.
  39. */
  40. #include <stdlib.h>
  41. #include <stdio.h>
  42. #include "typedef.h"
  43. #include "basop.h"
  44. #include "cst_lbc.h"
  45. #include "tab_lbc.h"
  46. #include "lbccodec.h"
  47. #include "coder.h"
  48. #include "decod.h"
  49. #include "util_lbc.h"
  50. /*
  51. **
  52. ** Function:        Read_lbc()
  53. **
  54. ** Description:     Read in a file
  55. **
  56. ** Links to text:   Sections 2.2 & 4
  57. **
  58. ** Arguments:
  59. **
  60. **  Word16 *Dpnt
  61. **  int     Len
  62. **  FILE *Fp
  63. **
  64. ** Outputs:
  65. **
  66. **  Word16 *Dpnt
  67. **
  68. ** Return value:    None
  69. **
  70. */
  71. void  Read_lbc( Word16 *Dpnt, int Len, FILE *Fp )
  72. {
  73.     int   i  ;
  74.     for ( i = 0 ; i < Len ; i ++ )
  75.         Dpnt[i] = (Word16) 0 ;
  76.     fread ( (char *)Dpnt, sizeof(Word16), Len, Fp ) ;
  77.     return;
  78. }
  79. /*
  80. **
  81. ** Function:        Write_lbc()
  82. **
  83. ** Description:     Write a file
  84. **
  85. ** Links to text:   Section
  86. **
  87. ** Arguments:
  88. **
  89. **  Word16 *Dpnt
  90. **  int     Len
  91. **  FILE *Fp
  92. **
  93. ** Outputs:         None
  94. **
  95. ** Return value:    None
  96. **
  97. */
  98. void    Write_lbc( Word16 *Dpnt, int Len, FILE *Fp )
  99. {
  100.     fwrite( (char *)Dpnt, sizeof(Word16), Len, Fp ) ;
  101. }
  102. void    Line_Wr( char *Line, FILE *Fp )
  103. {
  104.     Word16  Info ;
  105.     int     Size   ;
  106.     Info = Line[0] & (Word16)0x0003 ;
  107.     /* Check frame type and rate informations */
  108.     switch (Info) {
  109.         case 0x0002 : {   /* SID frame */
  110.             Size  = 4;
  111.             break;
  112.         }
  113.         case 0x0003 : {  /* untransmitted silence frame */
  114.             Size  = 1;
  115.             break;
  116.         }
  117.         case 0x0001 : {   /* active frame, low rate */
  118.             Size  = 20;
  119.             break;
  120.         }
  121.         default : {  /* active frame, high rate */
  122.             Size  = 24;
  123.         }
  124.     }
  125.     fwrite( Line, Size , 1, Fp ) ;
  126. }
  127. int Line_Rd( char *Line, FILE *Fp )
  128. {
  129.     Word16  Info ;
  130.     int     Size   ;
  131.     if(fread( Line, 1,1, Fp ) != 1) return(-1);
  132.     Info = Line[0] & (Word16)0x0003 ;
  133.     /* Check frame type and rate informations */
  134.     switch(Info) {
  135.         /* Active frame, high rate */
  136.         case 0 : {
  137.             Size  = 23;
  138.             break;
  139.         }
  140.         /* Active frame, low rate */
  141.         case 1 : {
  142.             Size  = 19;
  143.             break;
  144.         }
  145.         /* Sid Frame */
  146.         case 2 : {
  147.             Size  = 3;
  148.             break;
  149.         }
  150.         /* untransmitted */
  151.         default : {
  152.             return(0);
  153.         }
  154.     }
  155.     fread( &Line[1], Size , 1, Fp ) ;
  156.     return(0);
  157. }
  158. /*
  159. **
  160. ** Function:        Rem_Dc()
  161. **
  162. ** Description:     High-pass filtering
  163. **
  164. ** Links to text:   Section 2.3
  165. **
  166. ** Arguments:
  167. **
  168. **  Word16 *Dpnt
  169. **
  170. ** Inputs:
  171. **
  172. **  CodStat.HpfZdl  FIR filter memory from previous frame (1 word)
  173. **  CodStat.HpfPdl  IIR filter memory from previous frame (1 word)
  174. **
  175. ** Outputs:
  176. **
  177. **  Word16 *Dpnt
  178. **
  179. ** Return value:    None
  180. **
  181. */
  182. void  Rem_Dc( Word16 *Dpnt )
  183. {
  184.     int   i  ;
  185.     Word32   Acc0,Acc1 ;
  186.     if ( UseHp ) {
  187.         for ( i = 0 ; i < Frame ; i ++ ) {
  188.             /* Do the Fir and scale by 2 */
  189.             Acc0 = L_mult( Dpnt[i], (Word16) 0x4000 ) ;
  190.             Acc0 = L_mac ( Acc0, CodStat.HpfZdl, (Word16) 0xc000 ) ;
  191.             CodStat.HpfZdl = Dpnt[i] ;
  192.             /* Do the Iir part */
  193.             Acc1 = L_mls( CodStat.HpfPdl, (Word16) 0x7f00 ) ;
  194.             Acc0 = L_add( Acc0, Acc1 ) ;
  195.             CodStat.HpfPdl = Acc0 ;
  196.             Dpnt[i] = round(Acc0) ;
  197.         }
  198.     }
  199.     else {
  200.         for ( i = 0 ; i < Frame ; i ++ )
  201.             Dpnt[i] = shr( Dpnt[i], (Word16) 1 ) ;
  202.     }
  203.     return;
  204. }
  205. /*
  206. **
  207. ** Function:        Vec_Norm()
  208. **
  209. ** Description:     Vector normalization
  210. **
  211. ** Links to text:
  212. **
  213. ** Arguments:
  214. **
  215. **  Word16 *Vect
  216. **  Word16 Len
  217. **
  218. ** Outputs:
  219. **
  220. **  Word16 *Vect
  221. **
  222. ** Return value:  The power of 2 by which the data vector multiplyed.
  223. **
  224. */
  225. Word16  Vec_Norm( Word16 *Vect, Word16 Len )
  226. {
  227.     int   i  ;
  228.     Word16  Acc0,Acc1   ;
  229.     Word16  Exp   ;
  230.     Word16  Rez ;
  231.     Word32  Temp  ;
  232.     static   short ShiftTable[16] = {
  233.       0x0001 ,
  234.       0x0002 ,
  235.       0x0004 ,
  236.       0x0008 ,
  237.       0x0010 ,
  238.       0x0020 ,
  239.       0x0040 ,
  240.       0x0080 ,
  241.       0x0100 ,
  242.       0x0200 ,
  243.       0x0400 ,
  244.       0x0800 ,
  245.       0x1000 ,
  246.       0x2000 ,
  247.       0x4000 ,
  248.       0x7fff
  249.    } ;
  250.     /* Find absolute maximum */
  251.     Acc1 = (Word16) 0 ;
  252.     for ( i = 0 ; i < Len ; i ++ ) {
  253.         Acc0 = abs_s( Vect[i] ) ;
  254.         if ( Acc0 > Acc1 )
  255.             Acc1 = Acc0 ;
  256.     }
  257.     /* Get the shift count */
  258.     Rez = norm_s( Acc1 ) ;
  259.     Exp = ShiftTable[Rez] ;
  260.     /* Normalize all the vector */
  261.     for ( i = 0 ; i < Len ; i ++ ) {
  262.         Temp = L_mult( Exp, Vect[i] ) ;
  263.         Temp = L_shr( Temp, 4 ) ;
  264.         Vect[i] = extract_l( Temp ) ;
  265.     }
  266.     Rez = sub( Rez, (Word16) 3) ;
  267.     return Rez ;
  268. }
  269. /*
  270. **
  271. ** Function:        Mem_Shift()
  272. **
  273. ** Description:     Memory shift, update of the high-passed input speech signal
  274. **
  275. ** Links to text:
  276. **
  277. ** Arguments:
  278. **
  279. **  Word16 *PrevDat
  280. **  Word16 *DataBuff
  281. **
  282. ** Outputs:
  283. **
  284. **  Word16 *PrevDat
  285. **  Word16 *DataBuff
  286. **
  287. ** Return value:    None
  288. **
  289. */
  290. void  Mem_Shift( Word16 *PrevDat, Word16 *DataBuff )
  291. {
  292.     int   i  ;
  293.     Word16   Dpnt[Frame+LpcFrame-SubFrLen] ;
  294.     /*  Form Buffer  */
  295.     for ( i = 0 ; i < LpcFrame-SubFrLen ; i ++ )
  296.         Dpnt[i] = PrevDat[i] ;
  297.     for ( i = 0 ; i < Frame ; i ++ )
  298.         Dpnt[i+LpcFrame-SubFrLen] = DataBuff[i] ;
  299.     /* Update PrevDat */
  300.     for ( i = 0 ; i < LpcFrame-SubFrLen ; i ++ )
  301.         PrevDat[i] = Dpnt[Frame+i] ;
  302.     /* Update DataBuff */
  303.     for ( i = 0 ; i < Frame ; i ++ )
  304.         DataBuff[i] = Dpnt[(LpcFrame-SubFrLen)/2+i] ;
  305.     return;
  306. }
  307. /*
  308. **
  309. ** Function:        Line_Pack()
  310. **
  311. ** Description:     Packing coded parameters in bitstream of 16-bit words
  312. **
  313. ** Links to text:   Section 4
  314. **
  315. ** Arguments:
  316. **
  317. **  LINEDEF *Line     Coded parameters for a frame
  318. **  char    *Vout     bitstream chars
  319. **  Word16   VadBit   Voice Activity Indicator
  320. **
  321. ** Outputs:
  322. **
  323. **  Word16 *Vout
  324. **
  325. ** Return value:    None
  326. **
  327. */
  328. void    Line_Pack( LINEDEF *Line, char *Vout, Word16 Ftyp )
  329. {
  330.     int     i ;
  331.     int     BitCount ;
  332.     Word16  BitStream[192] ;
  333.     Word16 *Bsp = BitStream ;
  334.     Word32  Temp ;
  335.     /* Clear the output vector */
  336.     for ( i = 0 ; i < 24 ; i ++ )
  337.         Vout[i] = 0 ;
  338.  /*
  339.   * Add the coder rate info and frame type info to the 2 msb
  340.   * of the first word of the frame.
  341.   * The signaling is as follows:
  342.   *     Ftyp  WrkRate => X1X0
  343.   *       1     Rate63     00  :   High Rate
  344.   *       1     Rate53     01  :   Low  Rate
  345.   *       2       x        10  :   Silence Insertion Descriptor frame
  346.   *       0       x        11  :   Used only for simulation of
  347.   *                                 untransmitted silence frames
  348.   */
  349.     switch (Ftyp) {
  350.         case 0 : {
  351.             Temp = 0x00000003L;
  352.             break;
  353.         }
  354.         case 2 : {
  355.             Temp = 0x00000002L;
  356.             break;
  357.         }
  358.         default : {
  359.             if ( WrkRate == Rate63 )
  360.                 Temp = 0x00000000L ;
  361.             else
  362.                 Temp = 0x00000001L ;
  363.             break;
  364.         }
  365.     }
  366.     /* Serialize Control info */
  367.     Bsp = Par2Ser( Temp, Bsp, 2 ) ;
  368.     /* Check for Speech/NonSpeech case */
  369.     if ( Ftyp == 1 ) {
  370.     /* 24 bit LspId */
  371.     Temp = (*Line).LspId ;
  372.     Bsp = Par2Ser( Temp, Bsp, 24 ) ;
  373.  /*
  374.   * Do the part common to both rates
  375.   */
  376.         /* Adaptive code book lags */
  377.         Temp = (Word32) (*Line).Olp[0] - (Word32) PitchMin ;
  378.         Bsp = Par2Ser( Temp, Bsp, 7 ) ;
  379.         Temp = (Word32) (*Line).Sfs[1].AcLg ;
  380.         Bsp = Par2Ser( Temp, Bsp, 2 ) ;
  381.         Temp = (Word32) (*Line).Olp[1] - (Word32) PitchMin ;
  382.         Bsp = Par2Ser( Temp, Bsp, 7 ) ;
  383.         Temp = (Word32) (*Line).Sfs[3].AcLg ;
  384.         Bsp = Par2Ser( Temp, Bsp, 2 ) ;
  385.         /* Write combined 12 bit index of all the gains */
  386.         for ( i = 0 ; i < SubFrames ; i ++ ) {
  387.             Temp = (*Line).Sfs[i].AcGn*NumOfGainLev + (*Line).Sfs[i].Mamp ;
  388.             if ( WrkRate == Rate63 )
  389.                 Temp += (Word32) (*Line).Sfs[i].Tran << 11 ;
  390.             Bsp = Par2Ser( Temp, Bsp, 12 ) ;
  391.         }
  392.         /* Write all the Grid indices */
  393.         for ( i = 0 ; i < SubFrames ; i ++ )
  394.             *Bsp ++ = (*Line).Sfs[i].Grid ;
  395.         /* High rate only part */
  396.         if ( WrkRate == Rate63 ) {
  397.             /* Write the reserved bit as 0 */
  398.             *Bsp ++ = (Word16) 0 ;
  399.             /* Write 13 bit combined position index */
  400.             Temp = (*Line).Sfs[0].Ppos >> 16 ;
  401.             Temp = Temp * 9 + ( (*Line).Sfs[1].Ppos >> 14) ;
  402.             Temp *= 90 ;
  403.             Temp += ((*Line).Sfs[2].Ppos >> 16) * 9 + ( (*Line).Sfs[3].Ppos >> 14 ) ;
  404.             Bsp = Par2Ser( Temp, Bsp, 13 ) ;
  405.             /* Write all the pulse positions */
  406.             Temp = (*Line).Sfs[0].Ppos & 0x0000ffffL ;
  407.             Bsp = Par2Ser( Temp, Bsp, 16 ) ;
  408.             Temp = (*Line).Sfs[1].Ppos & 0x00003fffL ;
  409.             Bsp = Par2Ser( Temp, Bsp, 14 ) ;
  410.             Temp = (*Line).Sfs[2].Ppos & 0x0000ffffL ;
  411.             Bsp = Par2Ser( Temp, Bsp, 16 ) ;
  412.             Temp = (*Line).Sfs[3].Ppos & 0x00003fffL ;
  413.             Bsp = Par2Ser( Temp, Bsp, 14 ) ;
  414.             /* Write pulse amplitudes */
  415.             Temp = (Word32) (*Line).Sfs[0].Pamp ;
  416.             Bsp = Par2Ser( Temp, Bsp, 6 ) ;
  417.             Temp = (Word32) (*Line).Sfs[1].Pamp ;
  418.             Bsp = Par2Ser( Temp, Bsp, 5 ) ;
  419.             Temp = (Word32) (*Line).Sfs[2].Pamp ;
  420.             Bsp = Par2Ser( Temp, Bsp, 6 ) ;
  421.             Temp = (Word32) (*Line).Sfs[3].Pamp ;
  422.             Bsp = Par2Ser( Temp, Bsp, 5 ) ;
  423.         }
  424.         /* Low rate only part */
  425.         else {
  426.             /* Write 12 bits of positions */
  427.             for ( i = 0 ; i < SubFrames ; i ++ ) {
  428.                 Temp = (*Line).Sfs[i].Ppos ;
  429.                 Bsp = Par2Ser( Temp, Bsp, 12 ) ;
  430.             }
  431.             /* Write 4 bit Pamps */
  432.             for ( i = 0 ; i < SubFrames ; i ++ ) {
  433.                 Temp = (*Line).Sfs[i].Pamp ;
  434.                 Bsp = Par2Ser( Temp, Bsp, 4 ) ;
  435.             }
  436.         }
  437.     }
  438.     else if(Ftyp == 2) {   /* SID frame */
  439.         /* 24 bit LspId */
  440.         Temp = (*Line).LspId ;
  441.         Bsp = Par2Ser( Temp, Bsp, 24 ) ;
  442.         /* Do Sid frame gain */
  443.         Temp = (Word32)(*Line).Sfs[0].Mamp ;
  444.         Bsp = Par2Ser( Temp, Bsp, 6 ) ;
  445.     }
  446.     /* Write out active frames */
  447.     if ( Ftyp == 1 ) {
  448.         if ( WrkRate == Rate63 )
  449.             BitCount = 192 ;
  450.         else
  451.             BitCount = 160 ;
  452.     }
  453.     /* Non active frames */
  454.     else if ( Ftyp == 2 )
  455.         BitCount = 32 ;
  456.     else
  457.         BitCount = 2;
  458.     for ( i = 0 ; i < BitCount ; i ++ )
  459.         Vout[i>>3] ^= BitStream[i] << (i & 0x0007) ;
  460.     return;
  461. }
  462. Word16* Par2Ser( Word32 Inp, Word16 *Pnt, int BitNum )
  463. {
  464.     int i   ;
  465.     Word16  Temp ;
  466.     for ( i = 0 ; i < BitNum ; i ++ ) {
  467.         Temp = (Word16) Inp & (Word16)0x0001 ;
  468.         Inp >>= 1 ;
  469.         *Pnt ++ = Temp ;
  470.     }
  471.     return Pnt ;
  472. }
  473. /*
  474. **
  475. ** Function:        Line_Unpk()
  476. **
  477. ** Description:     unpacking of bitstream, gets coding parameters for a frame
  478. **
  479. ** Links to text:   Section 4
  480. **
  481. ** Arguments:
  482. **
  483. **  char   *Vinp        bitstream chars
  484. **  Word16 *VadType
  485. **
  486. ** Outputs:
  487. **
  488. **  Word16 *VadType
  489. **
  490. ** Return value:
  491. **
  492. **  LINEDEF             coded parameters
  493. **     Word16   Crc
  494. **     Word32   LspId
  495. **     Word16   Olp[SubFrames/2]
  496. **     SFSDEF   Sfs[SubFrames]
  497. **
  498. */
  499. LINEDEF  Line_Unpk( char *Vinp, Word16 *Ftyp, Word16 Crc )
  500. {
  501.     int   i  ;
  502.     Word16  BitStream[192] ;
  503.     Word16 *Bsp = BitStream ;
  504.     LINEDEF Line ;
  505.     Word32  Temp ;
  506.     Word16  Info;
  507.     Word16 Bound_AcGn;
  508.     Line.Crc = Crc;
  509.     if(Crc != 0) return Line;
  510.     /* Unpack the byte info to BitStream vector */
  511.     for ( i = 0 ; i < 192 ; i ++ )
  512.         BitStream[i] = ( Vinp[i>>3] >> (i & (Word16)0x0007) ) & (Word16)1 ;
  513.     /* Decode the frame type and rate info */
  514.     Info = (Word16)Ser2Par( &Bsp, 2 ) ;
  515.     if ( Info == 3 ) {
  516.         *Ftyp = 0;
  517.         Line.LspId = 0L;    /* Dummy : to avoid Borland C3.1 warning */
  518.         return Line;
  519.     }
  520.     /* Decode the LspId */
  521.     Line.LspId = Ser2Par( &Bsp, 24 ) ;
  522.     if ( Info == 2 ) {
  523.         /* Decode the Noise Gain */
  524.         Line.Sfs[0].Mamp = (Word16)Ser2Par( &Bsp, 6);
  525.         *Ftyp = 2;
  526.         return Line ;
  527.     }
  528.  /*
  529.   * Decode the common information to both rates
  530.   */
  531.     *Ftyp = 1;
  532.     /* Decode the bit-rate */
  533.     WrkRate = (Info == 0) ? Rate63 : Rate53;
  534.     /* Decode the adaptive codebook lags */
  535.     Temp = Ser2Par( &Bsp, 7 ) ;
  536.     /* Test if forbidden code */
  537.     if( Temp <= 123) {
  538.         Line.Olp[0] = (Word16) Temp + (Word16)PitchMin ;
  539.     }
  540.     else {
  541.         /* transmission error */
  542.         Line.Crc = 1;
  543.         return Line ;
  544.     }
  545.     Line.Sfs[1].AcLg = (Word16) Ser2Par( &Bsp, 2 ) ;
  546.     Temp = Ser2Par( &Bsp, 7 ) ;
  547.     /* Test if forbidden code */
  548.     if( Temp <= 123) {
  549.         Line.Olp[1] = (Word16) Temp + (Word16)PitchMin ;
  550.     }
  551.     else {
  552.         /* transmission error */
  553.         Line.Crc = 1;
  554.         return Line ;
  555.     }
  556.     Line.Sfs[3].AcLg = (Word16) Ser2Par( &Bsp, 2 ) ;
  557.     Line.Sfs[0].AcLg = 1 ;
  558.     Line.Sfs[2].AcLg = 1 ;
  559.     /* Decode the combined gains accordingly to the rate */
  560.     for ( i = 0 ; i < SubFrames ; i ++ ) {
  561.         Temp = Ser2Par( &Bsp, 12 ) ;
  562.         Line.Sfs[i].Tran = 0 ;
  563.         Bound_AcGn = NbFilt170 ;
  564.         if ( (WrkRate == Rate63) && (Line.Olp[i>>1] < (SubFrLen-2) ) ) {
  565.             Line.Sfs[i].Tran = (Word16)(Temp >> 11) ;
  566.             Temp &= 0x000007ffL ;
  567.             Bound_AcGn = NbFilt085 ;
  568.         }
  569.         Line.Sfs[i].AcGn = (Word16)(Temp / (Word16)NumOfGainLev) ;
  570.         if(Line.Sfs[i].AcGn < Bound_AcGn ) {
  571.             Line.Sfs[i].Mamp = (Word16)(Temp % (Word16)NumOfGainLev) ;
  572.         }
  573.         else {
  574.             /* error detected */
  575.             Line.Crc = 1;
  576.             return Line ;
  577.         }
  578.     }
  579.     /* Decode the grids */
  580.     for ( i = 0 ; i < SubFrames ; i ++ )
  581.         Line.Sfs[i].Grid = *Bsp ++ ;
  582.     if (Info == 0) {
  583.         /* Skip the reserved bit */
  584.         Bsp ++ ;
  585.         /* Decode 13 bit combined position index */
  586.         Temp = Ser2Par( &Bsp, 13 ) ;
  587.         Line.Sfs[0].Ppos = ( Temp/90 ) / 9 ;
  588.         Line.Sfs[1].Ppos = ( Temp/90 ) % 9 ;
  589.         Line.Sfs[2].Ppos = ( Temp%90 ) / 9 ;
  590.         Line.Sfs[3].Ppos = ( Temp%90 ) % 9 ;
  591.         /* Decode all the pulse positions */
  592.         Line.Sfs[0].Ppos = ( Line.Sfs[0].Ppos << 16 ) + Ser2Par( &Bsp, 16 ) ;
  593.         Line.Sfs[1].Ppos = ( Line.Sfs[1].Ppos << 14 ) + Ser2Par( &Bsp, 14 ) ;
  594.         Line.Sfs[2].Ppos = ( Line.Sfs[2].Ppos << 16 ) + Ser2Par( &Bsp, 16 ) ;
  595.         Line.Sfs[3].Ppos = ( Line.Sfs[3].Ppos << 14 ) + Ser2Par( &Bsp, 14 ) ;
  596.         /* Decode pulse amplitudes */
  597.         Line.Sfs[0].Pamp = (Word16)Ser2Par( &Bsp, 6 ) ;
  598.         Line.Sfs[1].Pamp = (Word16)Ser2Par( &Bsp, 5 ) ;
  599.         Line.Sfs[2].Pamp = (Word16)Ser2Par( &Bsp, 6 ) ;
  600.         Line.Sfs[3].Pamp = (Word16)Ser2Par( &Bsp, 5 ) ;
  601.     }
  602.     else {
  603.         /* Decode the positions */
  604.         for ( i = 0 ; i < SubFrames ; i ++ )
  605.             Line.Sfs[i].Ppos = Ser2Par( &Bsp, 12 ) ;
  606.         /* Decode the amplitudes */
  607.         for ( i = 0 ; i < SubFrames ; i ++ )
  608.             Line.Sfs[i].Pamp = (Word16)Ser2Par( &Bsp, 4 ) ;
  609.     }
  610.    return Line ;
  611. }
  612. Word32  Ser2Par( Word16 **Pnt, int Count )
  613. {
  614.     int     i ;
  615.     Word32  Rez = 0L ;
  616.     for ( i = 0 ; i < Count ; i ++ ) {
  617.         Rez += (Word32) **Pnt << i ;
  618.         (*Pnt) ++ ;
  619.     }
  620.     return Rez ;
  621. }
  622. /*
  623. **
  624. ** Function:        Comp_En()
  625. **
  626. ** Description:     Compute energy of a subframe vector
  627. **
  628. ** Links to text:
  629. **
  630. ** Arguments:
  631. **
  632. **  Word16 *Dpnt
  633. **
  634. ** Outputs:         None
  635. **
  636. ** Return value:
  637. **
  638. **      Word32 energy
  639. **
  640. */
  641. Word32   Comp_En( Word16 *Dpnt )
  642. {
  643.     int   i ;
  644.     Word32   Rez ;
  645.     Word16   Temp[SubFrLen] ;
  646.     for ( i = 0 ; i < SubFrLen ; i ++ )
  647.         Temp[i] = shr( Dpnt[i], (Word16) 2 ) ;
  648.     Rez = (Word32) 0 ;
  649.     for ( i = 0 ; i < SubFrLen ; i ++ )
  650.         Rez = L_mac( Rez, Temp[i], Temp[i] ) ;
  651.     return Rez ;
  652. }
  653. /*
  654. **
  655. ** Function:        Sqrt_lbc()
  656. **
  657. ** Description:     Square root computation
  658. **
  659. ** Links to text:
  660. **
  661. ** Arguments:
  662. **
  663. **  Word32 Num
  664. **
  665. ** Outputs:     None
  666. **
  667. ** Return value:
  668. **
  669. **  Word16 square root of num
  670. **
  671. */
  672. Word16   Sqrt_lbc( Word32 Num )
  673. {
  674.     int   i  ;
  675.     Word16   Rez = (Word16) 0 ;
  676.     Word16   Exp = (Word16) 0x4000 ;
  677.     Word32   Acc ;
  678.     for ( i = 0 ; i < 14 ; i ++ ) {
  679.         Acc = L_mult( add(Rez, Exp), add(Rez, Exp) ) ;
  680.         if ( Num >= Acc )
  681.             Rez = add( Rez, Exp ) ;
  682.         Exp = shr( Exp, (Word16) 1 ) ;
  683.     }
  684.     return Rez ;
  685. }
  686. /*
  687. **
  688. ** Function:        Rand_lbc()
  689. **
  690. ** Description:     Generator of random numbers
  691. **
  692. ** Links to text:   Section 3.10.2
  693. **
  694. ** Arguments:
  695. **
  696. **  Word16 *p
  697. **
  698. ** Outputs:
  699. **
  700. **  Word16 *p
  701. **
  702. ** Return value:
  703. **
  704. **  Word16 random number
  705. **
  706. */
  707. Word16   Rand_lbc( Word16 *p )
  708. {
  709.     Word32   Temp ;
  710.     Temp = L_deposit_l( *p ) ;
  711.     Temp &= (Word32) 0x0000ffff ;
  712.     Temp = Temp*(Word32)521 + (Word32) 259 ;
  713.     *p = extract_l( Temp ) ;
  714.     return extract_l( Temp ) ;
  715. }
  716. /*
  717. **
  718. ** Function:        Scale()
  719. **
  720. ** Description:     Postfilter gain scaling
  721. **
  722. ** Links to text:   Section 3.9
  723. **
  724. ** Arguments:
  725. **
  726. **  Word16 *Tv
  727. **  Word32 Sen
  728. **
  729. **  Inputs:
  730. **
  731. **  Word16 DecStat.Gain
  732. **
  733. ** Outputs:
  734. **
  735. **  Word16 *Tv
  736. **
  737. ** Return value:    None
  738. **
  739. */
  740. void  Scale( Word16 *Tv, Word32 Sen )
  741. {
  742.     int   i ;
  743.     Word32   Acc0,Acc1   ;
  744.     Word16   Exp,SfGain  ;
  745.     Acc0 = Sen ;
  746.     Acc1 = Comp_En( Tv ) ;
  747.     /* Normalize both */
  748.     if ( (Acc1 != (Word32) 0) && (Acc0 != (Word32) 0 ) ) {
  749.         Exp = norm_l( Acc1 ) ;
  750.         Acc1 = L_shl( Acc1, Exp ) ;
  751.         SfGain = norm_l( Acc0 ) ;
  752.         Acc0 = L_shl( Acc0, SfGain ) ;
  753.         Acc0 = L_shr( Acc0, (Word16) 1 ) ;
  754.         Exp = sub( Exp, SfGain ) ;
  755.         Exp = add( Exp, (Word16) 1 ) ;
  756.         Exp = sub( (Word16) 6, Exp ) ;
  757.         if ( Exp < (Word16) 0 )
  758.             Exp = (Word16) 0 ;
  759.         SfGain = extract_h( Acc1 ) ;
  760.         SfGain = div_l( Acc0, SfGain ) ;
  761.         Acc0 = L_deposit_h( SfGain ) ;
  762.         Acc0 = L_shr( Acc0, Exp ) ;
  763.         SfGain = Sqrt_lbc( Acc0 ) ;
  764.     }
  765.     else
  766.         SfGain = 0x1000 ;
  767.     /* Filter the data */
  768.     for ( i = 0 ; i < SubFrLen ; i ++ ) {
  769.         /* Update gain */
  770.         Acc0 = L_deposit_h( DecStat.Gain ) ;
  771.         Acc0 = L_msu( Acc0, DecStat.Gain, (Word16) 0x0800 ) ;
  772.         Acc0 = L_mac( Acc0, SfGain, (Word16) 0x0800 ) ;
  773.         DecStat.Gain = round( Acc0 ) ;
  774.         Exp = add( DecStat.Gain, shr( DecStat.Gain, (Word16) 4) ) ;
  775.         Acc0 = L_mult( Tv[i], Exp ) ;
  776.         Acc0 = L_shl( Acc0, (Word16) 4 ) ;
  777.         Tv[i] = round( Acc0 ) ;
  778.     }
  779.     return;
  780. }