dec_util.c
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:31k
源码类别:

Symbian

开发平台:

C/C++

  1. /*
  2.  *===================================================================
  3.  *  3GPP AMR Wideband Floating-point Speech Codec
  4.  *===================================================================
  5.  */
  6. #include "hlxclib/math.h"
  7. #include "hlxclib/memory.h"
  8. #include "typedef.h"
  9. #include "dec_main.h"
  10. #include "dec_lpc.h"
  11. #define MAX_16       (Word16)0x7FFF
  12. #define MIN_16       (Word16)0x8000
  13. #define L_SUBFR      64       /* Subframe size                    */
  14. #define L_SUBFR16k   80       /* Subframe size at 16kHz           */
  15. #define M16k         20       /* Order of LP filter               */
  16. #define PREEMPH_FAC  22282    /* preemphasis factor (0.68 in Q15) */
  17. #define FAC4         4
  18. #define FAC5         5
  19. #define UP_FAC       20480    /* 5/4 in Q14                       */
  20. #define INV_FAC5     6554     /* 1/5 in Q15                       */
  21. #define NB_COEF_UP   12
  22. #define L_FIR        31
  23. #define MODE_7k      0
  24. #define MODE_24k     8
  25. extern const Word16 D_ROM_pow2[];
  26. extern const Word16 D_ROM_isqrt[];
  27. extern const Word16 D_ROM_log2[];
  28. extern const Word16 D_ROM_fir_up[];
  29. extern const Word16 D_ROM_fir_6k_7k[];
  30. extern const Word16 D_ROM_fir_7k[];
  31. extern const Word16 D_ROM_hp_gain[];
  32. #ifdef WIN32
  33. #pragma warning( disable : 4310)
  34. #endif
  35. /*
  36.  * D_UTIL_random
  37.  *
  38.  * Parameters:
  39.  *    seed        I/O: seed for random number
  40.  *
  41.  * Function:
  42.  *    Signed 16 bits random generator.
  43.  *
  44.  * Returns:
  45.  *    random number
  46.  */
  47. Word16 D_UTIL_random(Word16 *seed)
  48. {
  49.    /*static Word16 seed = 21845;*/
  50.    *seed = (Word16)(*seed * 31821L + 13849L);
  51.    return(*seed);
  52. }
  53. /*
  54.  * D_UTIL_pow2
  55.  *
  56.  * Parameters:
  57.  *    exponant    I: (Q0) Integer part.      (range: 0 <= val <= 30)
  58.  *    fraction    I: (Q15) Fractionnal part. (range: 0.0 <= val < 1.0)
  59.  *
  60.  * Function:
  61.  *    L_x = pow(2.0, exponant.fraction)         (exponant = interger part)
  62.  *        = pow(2.0, 0.fraction) << exponant
  63.  *
  64.  *    Algorithm:
  65.  *
  66.  *    The function Pow2(L_x) is approximated by a table and linear
  67.  *    interpolation.
  68.  *
  69.  *    1 - i = bit10 - b15 of fraction,   0 <= i <= 31
  70.  *    2 - a = bit0 - b9   of fraction
  71.  *    3 - L_x = table[i] << 16 - (table[i] - table[i + 1]) * a * 2
  72.  *    4 - L_x = L_x >> (30-exponant)     (with rounding)
  73.  *
  74.  * Returns:
  75.  *    range 0 <= val <= 0x7fffffff
  76.  */
  77. Word32 D_UTIL_pow2(Word16 exponant, Word16 fraction)
  78. {
  79.    Word32 L_x, tmp, i, exp;
  80.    Word16 a;
  81.    L_x = fraction * 32;          /* L_x = fraction<<6             */
  82.    i = L_x >> 15;                /* Extract b10-b16 of fraction   */
  83.    a = (Word16)(L_x);            /* Extract b0-b9   of fraction   */
  84.    a = (Word16)(a & (Word16)0x7fff);
  85.    L_x = D_ROM_pow2[i] << 16;    /* table[i] << 16                */
  86.    tmp = D_ROM_pow2[i] - D_ROM_pow2[i + 1];  /* table[i] - table[i+1] */
  87.    L_x = L_x - ((tmp * a) << 1); /* L_x -= tmp*a*2                */
  88.    exp = 30 - exponant;
  89.    L_x = (L_x + (1 << (exp - 1))) >> exp;
  90.    return(L_x);
  91. }
  92. /*
  93.  * D_UTIL_norm_l
  94.  *
  95.  * Parameters:
  96.  *    L_var1      I: 32 bit Word32 signed integer (Word32) whose value
  97.  *                   falls in the range 0x8000 0000 <= var1 <= 0x7fff ffff.
  98.  *
  99.  * Function:
  100.  *    Produces the number of left shifts needed to normalize the 32 bit
  101.  *    variable L_var1 for positive values on the interval with minimum of
  102.  *    1073741824 and maximum of 2147483647, and for negative values on
  103.  *    the interval with minimum of -2147483648 and maximum of -1073741824;
  104.  *    in order to normalize the result, the following operation must be done :
  105.  *    norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).
  106.  *
  107.  * Returns:
  108.  *    16 bit Word16 signed integer (Word16) whose value falls in the range
  109.  *    0x0000 0000 <= var_out <= 0x0000 001f.
  110.  */
  111. Word16 D_UTIL_norm_l(Word32 L_var1)
  112. {
  113.    Word16 var_out;
  114.    if(L_var1 == 0)
  115.    {
  116.       var_out = 0;
  117.    }
  118.    else
  119.    {
  120.       if(L_var1 == (Word32)0xffffffffL)
  121.       {
  122.          var_out = 31;
  123.       }
  124.       else
  125.       {
  126.          if(L_var1 < 0)
  127.          {
  128.             L_var1 = ~L_var1;
  129.          }
  130.          for(var_out = 0; L_var1 < (Word32)0x40000000L; var_out++)
  131.          {
  132.             L_var1 <<= 1;
  133.          }
  134.       }
  135.    }
  136.    return(var_out);
  137. }
  138. /*
  139.  * D_UTIL_norm_s
  140.  *
  141.  * Parameters:
  142.  *    L_var1      I: 32 bit Word32 signed integer (Word32) whose value
  143.  *                   falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
  144.  *
  145.  * Function:
  146.  *    Produces the number of left shift needed to normalize the 16 bit
  147.  *    variable var1 for positive values on the interval with minimum
  148.  *    of 16384 and maximum of 32767, and for negative values on
  149.  *    the interval with minimum of -32768 and maximum of -16384.
  150.  *
  151.  * Returns:
  152.  *    16 bit Word16 signed integer (Word16) whose value falls in the range
  153.  *    0x0000 0000 <= var_out <= 0x0000 000f.
  154.  */
  155. Word16 D_UTIL_norm_s(Word16 var1)
  156. {
  157.    Word16 var_out;
  158.    if(var1 == 0)
  159.    {
  160.       var_out = 0;
  161.    }
  162.    else
  163.    {
  164.       if(var1 == -1)
  165.       {
  166.          var_out = 15;
  167.       }
  168.       else
  169.       {
  170.          if(var1 < 0)
  171.          {
  172.             var1 = (Word16)~var1;
  173.          }
  174.          for(var_out = 0; var1 < 0x4000; var_out++)
  175.          {
  176.             var1 <<= 1;
  177.          }
  178.       }
  179.    }
  180.    return(var_out);
  181. }
  182. /*
  183.  * D_UTIL_dot_product12
  184.  *
  185.  * Parameters:
  186.  *    x        I: 12bit x vector
  187.  *    y        I: 12bit y vector
  188.  *    lg       I: vector length
  189.  *    exp      O: exponent of result (0..+30)
  190.  *
  191.  * Function:
  192.  *    Compute scalar product of <x[],y[]> using accumulator.
  193.  *    The result is normalized (in Q31) with exponent (0..30).
  194.  *
  195.  * Returns:
  196.  *    Q31 normalised result (1 < val <= -1)
  197.  */
  198. Word32 D_UTIL_dot_product12(Word16 x[], Word16 y[], Word16 lg, Word16 *exp)
  199. {
  200.    Word32 sum, i, sft;
  201.    sum = 0L;
  202.    for(i = 0; i < lg; i++)
  203.    {
  204.       sum += x[i] * y[i];
  205.    }
  206.    sum = (sum << 1) + 1;
  207.    /* Normalize acc in Q31 */
  208.    sft = D_UTIL_norm_l(sum);
  209.    sum = sum << sft;
  210.    *exp = (Word16)(30 - sft);   /* exponent = 0..30 */
  211.    return(sum);
  212. }
  213. /*
  214.  * D_UTIL_normalised_inverse_sqrt
  215.  *
  216.  * Parameters:
  217.  *    frac     I/O: (Q31) normalized value (1.0 < frac <= 0.5)
  218.  *    exp      I/O: exponent (value = frac x 2^exponent)
  219.  *
  220.  * Function:
  221.  *    Compute 1/sqrt(value).
  222.  *    If value is negative or zero, result is 1 (frac=7fffffff, exp=0).
  223.  *
  224.  *    The function 1/sqrt(value) is approximated by a table and linear
  225.  *    interpolation.
  226.  *    1. If exponant is odd then shift fraction right once.
  227.  *    2. exponant = -((exponant - 1) >> 1)
  228.  *    3. i = bit25 - b30 of fraction, 16 <= i <= 63 ->because of normalization.
  229.  *    4. a = bit10 - b24
  230.  *    5. i -= 16
  231.  *    6. fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
  232.  *
  233.  * Returns:
  234.  *    void
  235.  */
  236. void D_UTIL_normalised_inverse_sqrt(Word32 *frac, Word16 *exp)
  237. {
  238.    Word32 i, tmp;
  239.    Word16 a;
  240.    if(*frac <= (Word32)0)
  241.    {
  242.       *exp = 0;
  243.       *frac = 0x7fffffffL;
  244.       return;
  245.    }
  246.    if((*exp & 0x1) == 1)   /* If exponant odd -> shift right */
  247.    {
  248.       *frac = *frac >> 1;
  249.    }
  250.    *exp = (Word16)(-((*exp - 1) >> 1));
  251.    *frac = *frac >> 9;
  252.    i = *frac >>16;      /* Extract b25-b31   */
  253.    *frac = *frac >> 1;
  254.    a = (Word16)(*frac); /* Extract b10-b24   */
  255.    a = (Word16)(a & (Word16)0x7fff);
  256.    i = i - 16;
  257.    *frac = D_ROM_isqrt[i] << 16; /* table[i] << 16    */
  258.    tmp = D_ROM_isqrt[i] - D_ROM_isqrt[i + 1];   /* table[i] - table[i+1]) */
  259.    *frac = *frac - ((tmp * a) << 1);   /* frac -=  tmp*a*2  */
  260.    return;
  261. }
  262. /*
  263.  * D_UTIL_inverse_sqrt
  264.  *
  265.  * Parameters:
  266.  *    L_x     I/O: (Q0) input value (range: 0<=val<=7fffffff)
  267.  *
  268.  * Function:
  269.  *    Compute 1/sqrt(L_x).
  270.  *    If value is negative or zero, result is 1 (7fffffff).
  271.  *
  272.  *    The function 1/sqrt(value) is approximated by a table and linear
  273.  *    interpolation.
  274.  *    1. Normalization of L_x
  275.  *    2. call Normalised_Inverse_sqrt(L_x, exponant)
  276.  *    3. L_y = L_x << exponant
  277.  *
  278.  * Returns:
  279.  *    (Q31) output value (range: 0 <= val < 1)
  280.  */
  281. Word32 D_UTIL_inverse_sqrt(Word32 L_x)
  282. {
  283.    Word32 L_y;
  284.    Word16 exp;
  285.    exp = D_UTIL_norm_l(L_x);
  286.    L_x = (L_x << exp);   /* L_x is normalized */
  287.    exp = (Word16)(31 - exp);
  288.    D_UTIL_normalised_inverse_sqrt(&L_x, &exp);
  289.    if(exp < 0)
  290.    {
  291.       L_y = (L_x >> -exp);   /* denormalization   */
  292.    }
  293.    else
  294.    {
  295.       L_y = (L_x << exp);   /* denormalization   */
  296.    }
  297.    return(L_y);
  298. }
  299. /*
  300.  * D_UTIL_normalised_log2
  301.  *
  302.  * Parameters:
  303.  *    L_x      I: input value (normalized)
  304.  *    exp      I: norm_l (L_x)
  305.  *    exponent O: Integer part of Log2.   (range: 0<=val<=30)
  306.  *    fraction O: Fractional part of Log2. (range: 0<=val<1)
  307.  *
  308.  * Function:
  309.  *    Computes log2(L_x, exp),  where   L_x is positive and
  310.  *    normalized, and exp is the normalisation exponent
  311.  *    If L_x is negative or zero, the result is 0.
  312.  *
  313.  *    The function Log2(L_x) is approximated by a table and linear
  314.  *    interpolation. The following steps are used to compute Log2(L_x)
  315.  *
  316.  *    1. exponent = 30 - norm_exponent
  317.  *    2. i = bit25 - b31 of L_x;  32 <= i <= 63  (because of normalization).
  318.  *    3. a = bit10 - b24
  319.  *    4. i -= 32
  320.  *    5. fraction = table[i] << 16 - (table[i] - table[i + 1]) * a * 2
  321.  *
  322.  *
  323.  * Returns:
  324.  *    void
  325.  */
  326. static void D_UTIL_normalised_log2(Word32 L_x, Word16 exp, Word16 *exponent,
  327.                                    Word16 *fraction)
  328. {
  329.    Word32 i, a, tmp;
  330.    Word32 L_y;
  331.    if (L_x <= 0)
  332.    {
  333.       *exponent = 0;
  334.       *fraction = 0;
  335.       return;
  336.    }
  337.    *exponent = (Word16)(30 - exp);
  338.    L_x = L_x >> 10;
  339.    i = L_x >> 15;         /* Extract b25-b31               */
  340.    a = L_x;               /* Extract b10-b24 of fraction   */
  341.    a = a & 0x00007fff;
  342.    i = i - 32;
  343.    L_y = D_ROM_log2[i] << 16;               /* table[i] << 16        */
  344.    tmp = D_ROM_log2[i] - D_ROM_log2[i + 1]; /* table[i] - table[i+1] */
  345.    L_y = L_y - ((tmp * a) << 1);            /* L_y -= tmp*a*2        */
  346.    *fraction = (Word16)(L_y >> 16);
  347.    return;
  348. }
  349. /*
  350.  * D_UTIL_log2
  351.  *
  352.  * Parameters:
  353.  *    L_x      I: input value
  354.  *    exponent O: Integer part of Log2.   (range: 0<=val<=30)
  355.  *    fraction O: Fractional part of Log2. (range: 0<=val<1)
  356.  *
  357.  * Function:
  358.  *    Computes log2(L_x),  where   L_x is positive.
  359.  *    If L_x is negative or zero, the result is 0.
  360.  *
  361.  * Returns:
  362.  *    void
  363.  */
  364. void D_UTIL_log2(Word32 L_x, Word16 *exponent, Word16 *fraction)
  365. {
  366.    Word16 exp;
  367.    exp = D_UTIL_norm_l(L_x);
  368.    D_UTIL_normalised_log2((L_x <<exp), exp, exponent, fraction);
  369. }
  370. /*
  371.  * D_UTIL_l_extract
  372.  *
  373.  * Parameters:
  374.  *    L_32        I: 32 bit integer.
  375.  *    hi          O: b16 to b31 of L_32
  376.  *    lo          O: (L_32 - hi<<16)>>1
  377.  *
  378.  * Function:
  379.  *    Extract from a 32 bit integer two 16 bit DPF.
  380.  *
  381.  * Returns:
  382.  *    void
  383.  */
  384. void D_UTIL_l_extract(Word32 L_32, Word16 *hi, Word16 *lo)
  385. {
  386.    *hi = (Word16)(L_32 >> 16);
  387.    *lo = (Word16)((L_32 >> 1) - (*hi * 32768));
  388.    return;
  389. }
  390. /*
  391.  * D_UTIL_mpy_32_16
  392.  *
  393.  * Parameters:
  394.  *    hi          I: hi part of 32 bit number
  395.  *    lo          I: lo part of 32 bit number
  396.  *    n           I: 16 bit number
  397.  *
  398.  * Function:
  399.  *    Multiply a 16 bit integer by a 32 bit (DPF). The result is divided
  400.  *    by 2^15.
  401.  *
  402.  *    L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1
  403.  *
  404.  * Returns:
  405.  *    32 bit result
  406.  */
  407. Word32 D_UTIL_mpy_32_16(Word16 hi, Word16 lo, Word16 n)
  408. {
  409.    Word32 L_32;
  410.    L_32 = hi * n;
  411.    L_32 += (lo * n) >> 15;
  412.    return(L_32 << 1);
  413. }
  414. /*
  415.  * D_UTIL_mpy_32
  416.  *
  417.  * Parameters:
  418.  *    hi1         I: hi part of first number
  419.  *    lo1         I: lo part of first number
  420.  *    hi2         I: hi part of second number
  421.  *    lo2         I: lo part of second number
  422.  *
  423.  * Function:
  424.  *    Multiply two 32 bit integers (DPF). The result is divided by 2^31
  425.  *
  426.  *    L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1
  427.  *
  428.  * Returns:
  429.  *    32 bit result
  430.  */
  431. Word32 D_UTIL_mpy_32(Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2)
  432. {
  433.    Word32 L_32;
  434.    L_32 = hi1 * hi2;
  435.    L_32 += (hi1 * lo2) >> 15;
  436.    L_32 += (lo1 * hi2) >> 15;
  437.    return(L_32 << 1);
  438. }
  439. /*
  440.  * D_UTIL_saturate
  441.  *
  442.  * Parameters:
  443.  *    inp        I: 32-bit number
  444.  *
  445.  * Function:
  446.  *    Saturation to 16-bit number
  447.  *
  448.  * Returns:
  449.  *    16-bit number
  450.  */
  451. Word16 D_UTIL_saturate(Word32 inp)
  452. {
  453.   Word16 out;
  454.   if ((inp < MAX_16) & (inp > MIN_16))
  455.   {
  456.      out = (Word16)inp;
  457.   }
  458.   else
  459.   {
  460.      if (inp > 0)
  461.      {
  462.         out = MAX_16;
  463.      }
  464.      else
  465.      {
  466.         out = MIN_16;
  467.      }
  468.   }
  469.   return(out);
  470. }
  471. /*
  472.  * D_UTIL_signal_up_scale
  473.  *
  474.  * Parameters:
  475.  *    x         I/O: signal to scale
  476.  *    lg          I: size of x[]
  477.  *    exp         I: exponent: x = round(x << exp)
  478.  *
  479.  * Function:
  480.  *    Scale signal up to get maximum of dynamic.
  481.  *
  482.  * Returns:
  483.  *    32 bit result
  484.  */
  485. void D_UTIL_signal_up_scale(Word16 x[], Word16 lg, Word16 exp)
  486. {
  487.     Word32 i, tmp;
  488.     for (i = 0; i < lg; i++)
  489.     {
  490.        tmp = x[i] << exp;
  491.        x[i] = D_UTIL_saturate(tmp);
  492.     }
  493.     return;
  494. }
  495. /*
  496.  * D_UTIL_signal_down_scale
  497.  *
  498.  * Parameters:
  499.  *    x         I/O: signal to scale
  500.  *    lg          I: size of x[]
  501.  *    exp         I: exponent: x = round(x << exp)
  502.  *
  503.  * Function:
  504.  *    Scale signal up to get maximum of dynamic.
  505.  *
  506.  * Returns:
  507.  *    32 bit result
  508.  */
  509. void D_UTIL_signal_down_scale(Word16 x[], Word16 lg, Word16 exp)
  510. {
  511.    Word32 i, tmp;
  512.    for(i = 0; i < lg; i++)
  513.    {
  514.       tmp = x[i] << 16;
  515.       tmp = tmp >> exp;
  516.       x[i] = (Word16)((tmp + 0x8000) >> 16);
  517.    }
  518.    return;
  519. }
  520. /*
  521.  * D_UTIL_deemph_32
  522.  *
  523.  * Parameters:
  524.  *    x_hi           I: input signal (bit31..16)
  525.  *    x_lo           I: input signal (bit15..4)
  526.  *    y              O: output signal (x16)
  527.  *    mu             I: (Q15) deemphasis factor
  528.  *    L              I: vector size
  529.  *    mem          I/O: memory (y[-1])
  530.  *
  531.  * Function:
  532.  *    Filtering through 1/(1-mu z^-1)
  533.  *
  534.  * Returns:
  535.  *    void
  536.  */
  537. static void D_UTIL_deemph_32(Word16 x_hi[], Word16 x_lo[], Word16 y[],
  538.                              Word16 mu, Word16 L, Word16 *mem)
  539. {
  540.    Word32 i, fac;
  541.    Word32 tmp;
  542.    fac = mu >> 1;   /* Q15 --> Q14 */
  543.    /* L_tmp = hi<<16 + lo<<4 */
  544.    tmp = (x_hi[0] << 12) + x_lo[0];
  545.    tmp = (tmp << 6) + (*mem * fac);
  546.    tmp = (tmp + 0x2000) >> 14;
  547.    y[0] = D_UTIL_saturate(tmp);
  548.    for(i = 1; i < L; i++)
  549.    {
  550.       tmp = (x_hi[i] << 12) + x_lo[i];
  551.       tmp = (tmp << 6) + (y[i - 1] * fac);
  552.       tmp = (tmp + 0x2000) >> 14;
  553.       y[i] = D_UTIL_saturate(tmp);
  554.    }
  555.    *mem = y[L - 1];
  556.    return;
  557. }
  558. /*
  559.  * D_UTIL_synthesis_32
  560.  *
  561.  * Parameters:
  562.  *    a              I: LP filter coefficients
  563.  *    m              I: order of LP filter
  564.  *    exc            I: excitation
  565.  *    Qnew           I: exc scaling = 0(min) to 8(max)
  566.  *    sig_hi         O: synthesis high
  567.  *    sig_lo         O: synthesis low
  568.  *    lg             I: size of filtering
  569.  *
  570.  * Function:
  571.  *    Perform the synthesis filtering 1/A(z).
  572.  *
  573.  * Returns:
  574.  *    void
  575.  */
  576. static void D_UTIL_synthesis_32(Word16 a[], Word16 m, Word16 exc[],
  577.                                 Word16 Qnew, Word16 sig_hi[], Word16 sig_lo[],
  578.                                 Word16 lg)
  579. {
  580.    Word32 i, j, a0;
  581.    Word32 tmp, tmp2;
  582.    a0 = a[0] >> (4 + Qnew);   /* input / 16 and >>Qnew */
  583.    /* Do the filtering. */
  584.    for(i = 0; i < lg; i++)
  585.    {
  586.       tmp = 0;
  587.       for(j = 1; j <= m; j++)
  588.       {
  589.          tmp -= sig_lo[i - j] * a[j];
  590.       }
  591.       tmp = tmp >> (15 - 4);   /* -4 : sig_lo[i] << 4 */
  592.       tmp2 = exc[i] * a0;
  593.       for(j = 1; j <= m; j++)
  594.       {
  595.          tmp2 -= sig_hi[i - j] * a[j];
  596.       }
  597.       tmp += tmp2 << 1;
  598.       /* sig_hi = bit16 to bit31 of synthesis */
  599.       sig_hi[i] = (Word16)(tmp >> 13);
  600.       /* sig_lo = bit4 to bit15 of synthesis */
  601.       sig_lo[i] = (Word16)((tmp  >> 1) - (sig_hi[i] * 4096));
  602.    }
  603.    return;
  604. }
  605. /*
  606.  * D_UTIL_hp50_12k8
  607.  *
  608.  * Parameters:
  609.  *    signal       I/O: signal
  610.  *    lg             I: lenght of signal
  611.  *    mem          I/O: filter memory [6]
  612.  *
  613.  * Function:
  614.  *    2nd order high pass filter with cut off frequency at 50 Hz.
  615.  *
  616.  *    Algorithm:
  617.  *
  618.  *    y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
  619.  *                     + a[1]*y[i-1] + a[2]*y[i-2];
  620.  *
  621.  *    b[3] = {0.989501953f, -1.979003906f, 0.989501953f};
  622.  *    a[3] = {1.000000000F,  1.978881836f,-0.966308594f};
  623.  *
  624.  *
  625.  * Returns:
  626.  *    void
  627.  */
  628. static void D_UTIL_hp50_12k8(Word16 signal[], Word16 lg, Word16 mem[])
  629. {
  630.    Word32 i, L_tmp;
  631.    Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2;
  632.    y2_hi = mem[0];
  633.    y2_lo = mem[1];
  634.    y1_hi = mem[2];
  635.    y1_lo = mem[3];
  636.    x0 = mem[4];
  637.    x1 = mem[5];
  638.    for(i = 0; i < lg; i++)
  639.    {
  640.       x2 = x1;
  641.       x1 = x0;
  642.       x0 = signal[i];
  643.       /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2]  */
  644.       /* + a[1]*y[i-1] + a[2] * y[i-2];  */
  645.       L_tmp = 8192L;   /* rounding to maximise precision */
  646.       L_tmp = L_tmp + (y1_lo * 16211);
  647.       L_tmp = L_tmp + (y2_lo * (-8021));
  648.       L_tmp = L_tmp >> 14;
  649.       L_tmp = L_tmp + (y1_hi * 32422);
  650.       L_tmp = L_tmp + (y2_hi * (-16042));
  651.       L_tmp = L_tmp + (x0 * 8106);
  652.       L_tmp = L_tmp + (x1 * (-16212));
  653.       L_tmp = L_tmp + (x2 * 8106);
  654.       L_tmp = L_tmp << 2;  /* coeff Q11 --> Q14 */
  655.       y2_hi = y1_hi;
  656.       y2_lo = y1_lo;
  657.       D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo);
  658.       L_tmp = (L_tmp + 0x4000) >> 15;   /* coeff Q14 --> Q15 with saturation */
  659.       signal[i] = D_UTIL_saturate(L_tmp);
  660.    }
  661.    mem[0] = y2_hi;
  662.    mem[1] = y2_lo;
  663.    mem[2] = y1_hi;
  664.    mem[3] = y1_lo;
  665.    mem[4] = x0;
  666.    mem[5] = x1;
  667.    return;
  668. }
  669. /*
  670.  * D_UTIL_interpol
  671.  *
  672.  * Parameters:
  673.  *    x           I: input vector
  674.  *    fir         I: filter coefficient
  675.  *    frac        I: fraction (0..resol)
  676.  *    up_samp     I: resolution
  677.  *    nb_coef     I: number of coefficients
  678.  *
  679.  * Function:
  680.  *    Fractional interpolation of signal at position (frac/up_samp)
  681.  *
  682.  * Returns:
  683.  *    result of interpolation
  684.  */
  685. Word16 D_UTIL_interpol(Word16 *x, Word16 const *fir, Word16 frac,
  686.                        Word16 resol, Word16 nb_coef)
  687. {
  688.    Word32 i, k;
  689.    Word32 sum;
  690.    x = x - nb_coef + 1;
  691.    sum = 0L;
  692.    for(i = 0, k = ((resol - 1) - frac); i < 2 * nb_coef; i++,
  693.       k = (Word16)(k + resol))
  694.    {
  695.       sum = sum + (x[i] * fir[k]);
  696.    }
  697.    if((sum < 536846336) & (sum > -536879104))
  698.    {
  699.       sum = (sum + 0x2000) >> 14;
  700.    }
  701.    else if(sum > 536846336)
  702.    {
  703.       sum = 32767;
  704.    }
  705.    else
  706.    {
  707.       sum = -32768;
  708.    }
  709.    return((Word16)sum);   /* saturation can occur here */
  710. }
  711. /*
  712.  * D_UTIL_up_samp
  713.  *
  714.  * Parameters:
  715.  *    res_d          I: signal to upsampling
  716.  *    res_u          O: upsampled output
  717.  *    L_frame        I: length of output
  718.  *
  719.  * Function:
  720.  *    Upsampling
  721.  *
  722.  * Returns:
  723.  *    void
  724.  */
  725. static void D_UTIL_up_samp(Word16 *sig_d, Word16 *sig_u, Word16 L_frame)
  726. {
  727.    Word32 pos, i, j;
  728.    Word16 frac;
  729.    pos = 0;   /* position with 1/5 resolution */
  730.    for(j = 0; j < L_frame; j++)
  731.    {
  732.       i = (pos * INV_FAC5) >> 15;   /* integer part = pos * 1/5 */
  733.       frac = (Word16)(pos - ((i << 2) + i));   /* frac = pos - (pos/5)*5   */
  734.       sig_u[j] = D_UTIL_interpol(&sig_d[i], D_ROM_fir_up, frac, FAC5, NB_COEF_UP);
  735.       pos = pos + FAC4;   /* position + 4/5 */
  736.    }
  737.    return;
  738. }
  739. /*
  740.  * D_UTIL_oversamp_16k
  741.  *
  742.  * Parameters:
  743.  *    sig12k8        I: signal to oversampling
  744.  *    lg             I: length of input
  745.  *    sig16k         O: oversampled signal
  746.  *    mem          I/O: memory (2*12)
  747.  *
  748.  * Function:
  749.  *    Oversampling from 12.8kHz to 16kHz
  750.  *
  751.  * Returns:
  752.  *    void
  753.  */
  754. static void D_UTIL_oversamp_16k(Word16 sig12k8[], Word16 lg, Word16 sig16k[],
  755.                                 Word16 mem[])
  756. {
  757.    Word16 lg_up;
  758.    Word16 signal[L_SUBFR + (2 * NB_COEF_UP)];
  759.    memcpy(signal, mem, (2 * NB_COEF_UP) * sizeof(Word16));
  760.    memcpy(signal + (2 * NB_COEF_UP), sig12k8, lg * sizeof(Word16));
  761.    lg_up = (Word16)(((lg * UP_FAC) >> 15) << 1);
  762.    D_UTIL_up_samp(signal + NB_COEF_UP, sig16k, lg_up);
  763.    memcpy(mem, signal + lg, (2 * NB_COEF_UP) * sizeof(Word16));
  764.    return;
  765. }
  766. /*
  767.  * D_UTIL_hp400_12k8
  768.  *
  769.  * Parameters:
  770.  *    signal       I/O: signal
  771.  *    lg             I: lenght of signal
  772.  *    mem          I/O: filter memory [6]
  773.  *
  774.  * Function:
  775.  *    2nd order high pass filter with cut off frequency at 400 Hz.
  776.  *
  777.  *    Algorithm:
  778.  *
  779.  *    y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2]
  780.  *                     + a[1]*y[i-1] + a[2]*y[i-2];
  781.  *
  782.  *    b[3] = {0.893554687, -1.787109375,  0.893554687};
  783.  *    a[3] = {1.000000000,  1.787109375, -0.864257812};
  784.  *
  785.  *
  786.  * Returns:
  787.  *    void
  788.  */
  789. void D_UTIL_hp400_12k8(Word16 signal[], Word16 lg, Word16 mem[])
  790. {
  791.    Word32 i, L_tmp;
  792.    Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2;
  793.    y2_hi = mem[0];
  794.    y2_lo = mem[1];
  795.    y1_hi = mem[2];
  796.    y1_lo = mem[3];
  797.    x0 = mem[4];
  798.    x1 = mem[5];
  799.    for(i = 0; i < lg; i++)
  800.    {
  801.       x2 = x1;
  802.       x1 = x0;
  803.       x0 = signal[i];
  804.       /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2]  */
  805.       /* + a[1]*y[i-1] + a[2] * y[i-2];  */
  806.       L_tmp = 8192L + (y1_lo * 29280);
  807.       L_tmp = L_tmp + (y2_lo * (-14160));
  808.       L_tmp = (L_tmp >> 14);
  809.       L_tmp = L_tmp + (y1_hi * 58560);
  810.       L_tmp = L_tmp + (y2_hi * (-28320));
  811.       L_tmp = L_tmp + (x0 * 1830);
  812.       L_tmp = L_tmp + (x1 * (-3660));
  813.       L_tmp = L_tmp + (x2 * 1830);
  814.       L_tmp = (L_tmp << 1);   /* coeff Q12 --> Q13 */
  815.       y2_hi = y1_hi;
  816.       y2_lo = y1_lo;
  817.       D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo);
  818.       /* signal is divided by 16 to avoid overflow in energy computation */
  819.       signal[i] = (Word16)((L_tmp + 0x8000) >> 16);
  820.    }
  821.    mem[0] = y2_hi;
  822.    mem[1] = y2_lo;
  823.    mem[2] = y1_hi;
  824.    mem[3] = y1_lo;
  825.    mem[4] = x0;
  826.    mem[5] = x1;
  827.    return;
  828. }
  829. /*
  830.  * D_UTIL_synthesis
  831.  *
  832.  * Parameters:
  833.  *    a              I: LP filter coefficients
  834.  *    m              I: order of LP filter
  835.  *    x              I: input signal
  836.  *    y              O: output signal
  837.  *    lg             I: size of filtering
  838.  *    mem          I/O: initial filter states
  839.  *    update_m       I: update memory flag
  840.  *
  841.  * Function:
  842.  *    Perform the synthesis filtering 1/A(z).
  843.  *
  844.  * Returns:
  845.  *    void
  846.  */
  847. static void D_UTIL_synthesis(Word16 a[], Word16 m, Word16 x[], Word16 y[],
  848.                              Word16 lg, Word16 mem[], Word16 update)
  849. {
  850.    Word32 i, j, tmp;
  851.    Word16 y_buf[L_SUBFR16k + M16k], a0;
  852.    Word16 *yy;
  853.    yy = &y_buf[m];
  854.    /* copy initial filter states into synthesis buffer */
  855.    memcpy(y_buf, mem, m * sizeof(Word16));
  856.    a0 = (Word16)(a[0] >> 1);   /* input / 2 */
  857.    /* Do the filtering. */
  858.    for(i = 0; i < lg; i++)
  859.    {
  860.       tmp = x[i] * a0;
  861.       for(j = 1; j <= m; j++)
  862.       {
  863.          tmp -= a[j] * yy[i - j];
  864.       }
  865.       y[i] = yy[i] = (Word16)((tmp + 0x800) >> 12);
  866.    }
  867.    /* Update memory if required */
  868.    if(update)
  869.    {
  870.       memcpy(mem, &yy[lg - m], m * sizeof(Word16));
  871.    }
  872.    return;
  873. }
  874. /*
  875.  * D_UTIL_bp_6k_7k
  876.  *
  877.  * Parameters:
  878.  *    signal       I/O: signal
  879.  *    lg             I: lenght of signal
  880.  *    mem          I/O: filter memory [4]
  881.  *
  882.  * Function:
  883.  *    15th order band pass 6kHz to 7kHz FIR filter.
  884.  *
  885.  * Returns:
  886.  *    void
  887.  */
  888. void D_UTIL_bp_6k_7k(Word16 signal[], Word16 lg, Word16 mem[])
  889. {
  890.    Word32 x[L_SUBFR16k + (L_FIR - 1)];
  891.    Word32 i, j, tmp;
  892.    for(i = 0; i < (L_FIR - 1); i++)
  893.    {
  894.       x[i] = (Word16)mem[i];   /* gain of filter = 4 */
  895.    }
  896.    for(i = 0; i < lg; i++)
  897.    {
  898.       x[i + L_FIR - 1] = signal[i] >> 2;   /* gain of filter = 4 */
  899.    }
  900.    for(i = 0; i < lg; i++)
  901.    {
  902.       tmp = 0;
  903.       for(j = 0; j < L_FIR; j++)
  904.       {
  905.          tmp += x[i + j] * D_ROM_fir_6k_7k[j];
  906.       }
  907.       signal[i] = (Word16)((tmp + 0x4000) >> 15);
  908.    }
  909.    for(i = 0; i < (L_FIR - 1); i++)
  910.    {
  911.       mem[i] = (Word16)x[lg + i];   /* gain of filter = 4 */
  912.    }
  913.    return;
  914. }
  915. /*
  916.  * D_UTIL_hp_7k
  917.  *
  918.  * Parameters:
  919.  *    signal          I/O: ISF vector
  920.  *    lg                I: length of signal
  921.  *    mem             I/O: memory (30)
  922.  *
  923.  * Function:
  924.  *    15th order high pass 7kHz FIR filter
  925.  *
  926.  * Returns:
  927.  *    void
  928.  */
  929. static void D_UTIL_hp_7k(Word16 signal[], Word16 lg, Word16 mem[])
  930. {
  931.    Word32 i, j, tmp;
  932.    Word16 x[L_SUBFR16k + (L_FIR - 1)];
  933.    memcpy(x, mem, (L_FIR - 1) * sizeof(Word16));
  934.    memcpy(&x[L_FIR - 1], signal, lg * sizeof(Word16));
  935.    for(i = 0; i < lg; i++)
  936.    {
  937.       tmp = 0;
  938.       for(j = 0; j < L_FIR; j++)
  939.       {
  940.          tmp += x[i + j] * D_ROM_fir_7k[j];
  941.       }
  942.       signal[i] = (Word16)((tmp + 0x4000) >> 15);
  943.    }
  944.    memcpy(mem, x + lg, (L_FIR - 1) * sizeof(Word16));
  945.    return;
  946. }
  947. /*
  948.  * D_UTIL_Dec_synthesis
  949.  *
  950.  * Parameters:
  951.  *    Aq             I: quantized Az
  952.  *    exc            I: excitation at 12kHz
  953.  *    Q_new          I: scaling performed on exc
  954.  *    synth16k       O: 16kHz synthesis signal
  955.  *    prms           I: parameters
  956.  *    HfIsf        I/O: High frequency ISF:s
  957.  *    mode           I: codec mode
  958.  *    newDTXState    I: dtx state
  959.  *    bfi            I: bad frame indicator
  960.  *    st           I/O: State structure
  961.  *
  962.  * Function:
  963.  *    Synthesis of signal at 16kHz with HF extension.
  964.  *
  965.  * Returns:
  966.  *    void
  967.  */
  968. void D_UTIL_dec_synthesis(Word16 Aq[], Word16 exc[], Word16 Q_new,
  969.                           Word16 synth16k[], Word16 prms, Word16 HfIsf[],
  970.                           Word16 mode, Word16 newDTXState, Word16 bfi,
  971.                           Decoder_State *st)
  972. {
  973.    Word32 tmp, i;
  974.    Word16 exp;
  975.    Word16 ener, exp_ener;
  976.    Word32 fac;
  977.    Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR];
  978.    Word16 synth[L_SUBFR];
  979.    Word16 HF[L_SUBFR16k];   /* High Frequency vector      */
  980.    Word16 Ap[M16k + 1];
  981.    Word16 HfA[M16k + 1];
  982.    Word16 HF_corr_gain;
  983.    Word16 HF_gain_ind;
  984.    Word32 gain1, gain2;
  985.    Word16 weight1, weight2;
  986.    /*
  987.     * Speech synthesis
  988.     *
  989.     * - Find synthesis speech corresponding to exc2[].
  990.     * - Perform fixed deemphasis and hp 50hz filtering.
  991.     * - Oversampling from 12.8kHz to 16kHz.
  992.     */
  993.    memcpy(synth_hi, st->mem_syn_hi, M * sizeof(Word16));
  994.    memcpy(synth_lo, st->mem_syn_lo, M * sizeof(Word16));
  995.    D_UTIL_synthesis_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR);
  996.    memcpy(st->mem_syn_hi, synth_hi + L_SUBFR, M * sizeof(Word16));
  997.    memcpy(st->mem_syn_lo, synth_lo + L_SUBFR, M * sizeof(Word16));
  998.    D_UTIL_deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR,
  999.       &(st->mem_deemph));
  1000.    D_UTIL_hp50_12k8(synth, L_SUBFR, st->mem_sig_out);
  1001.    D_UTIL_oversamp_16k(synth, L_SUBFR, synth16k, st->mem_oversamp);
  1002.    /*
  1003.     * HF noise synthesis
  1004.     *
  1005.     * - Generate HF noise between 5.5 and 7.5 kHz.
  1006.     * - Set energy of noise according to synthesis tilt.
  1007.     *     tilt > 0.8 ==> - 14 dB (voiced)
  1008.     *     tilt   0.5 ==> - 6 dB  (voiced or noise)
  1009.     *     tilt < 0.0 ==>   0 dB  (noise)
  1010.     */
  1011.    /* generate white noise vector */
  1012.    for(i = 0; i < L_SUBFR16k; i++)
  1013.    {
  1014.       HF[i] = (Word16)(D_UTIL_random(&(st->mem_seed2)) >> 3);
  1015.    }
  1016.    /* energy of excitation */
  1017.    D_UTIL_signal_down_scale(exc, L_SUBFR, 3);
  1018.    Q_new = (Word16)(Q_new - 3);
  1019.    ener = (Word16)(D_UTIL_dot_product12(exc, exc, L_SUBFR, &exp_ener) >> 16);
  1020.    exp_ener = (Word16)(exp_ener - (Q_new << 1));
  1021.    /* set energy of white noise to energy of excitation */
  1022.    tmp = (Word16)(D_UTIL_dot_product12(HF, HF, L_SUBFR16k, &exp) >> 16);
  1023.    if(tmp > ener)
  1024.    {
  1025.       tmp = tmp >> 1;   /* Be sure tmp < ener */
  1026.       exp = (Word16)(exp + 1);
  1027.    }
  1028.    tmp = (tmp << 15) / ener;
  1029.    if(tmp > 32767)
  1030.    {
  1031.       tmp = 32767;
  1032.    }
  1033.    tmp = tmp << 16;   /* result is normalized */
  1034.    exp = (Word16)(exp - exp_ener);
  1035.    D_UTIL_normalised_inverse_sqrt(&tmp, &exp);
  1036.    /* L_tmp x 2, L_tmp in Q31 */
  1037.    /* tmp = 2 x sqrt(ener_exc/ener_hf) */
  1038.    if(exp >= 0)
  1039.    {
  1040.       tmp = tmp >> (15 - exp);
  1041.    }
  1042.    else
  1043.    {
  1044.       tmp = tmp >> (-exp);
  1045.       tmp = tmp >> 15;
  1046.    }
  1047.    /* saturation */
  1048.    if(tmp > 0x7FFF)
  1049.    {
  1050.       tmp = 0x7FFF;
  1051.    }
  1052.    for(i = 0; i < L_SUBFR16k; i++)
  1053.    {
  1054.       HF[i] = (Word16)((HF[i] * tmp) >> 15);
  1055.    }
  1056.    /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */
  1057.    D_UTIL_hp400_12k8(synth, L_SUBFR, st->mem_hp400);
  1058.    tmp = 0L;
  1059.    for(i = 0; i < L_SUBFR; i++)
  1060.    {
  1061.       tmp = tmp + (synth[i] * synth[i]);
  1062.    }
  1063.    tmp = (tmp << 1) + 1;
  1064.    exp = D_UTIL_norm_l(tmp);
  1065.    ener = (Word16)((tmp << exp) >> 16);   /* ener = r[0] */
  1066.    tmp = 0L;
  1067.    for(i = 1; i < L_SUBFR; i++)
  1068.    {
  1069.       tmp = tmp + (synth[i] * synth[i - 1]);
  1070.    }
  1071.    tmp = (tmp << 1) + 1;
  1072.    tmp = (tmp << exp) >> 16;   /* tmp = r[1] */
  1073.    if(tmp > 0)
  1074.    {
  1075.       fac = ((tmp << 15) / ener);
  1076.       if(fac > 32767)
  1077.       {
  1078.          fac = 32767;
  1079.       }
  1080.    }
  1081.    else
  1082.    {
  1083.       fac = 0;
  1084.    }
  1085.    /* modify energy of white noise according to synthesis tilt */
  1086.    gain1 = (32767 - fac);
  1087.    gain2 = ((32767 - fac) * 20480) >> 15;
  1088.    gain2 = (gain2 << 1);
  1089.    if(gain2 > 32767)
  1090.       gain2 = 32767;
  1091.    if(st->mem_vad_hist > 0)
  1092.    {
  1093.       weight1 = 0;
  1094.       weight2 = 32767;
  1095.    }
  1096.    else
  1097.    {
  1098.       weight1 = 32767;
  1099.       weight2 = 0;
  1100.    }
  1101.    tmp = (weight1 * gain1) >> 15;
  1102.    tmp = tmp + ((weight2 * gain2) >> 15);
  1103.    if(tmp != 0)
  1104.    {
  1105.       tmp = tmp + 1;
  1106.    }
  1107.    if(tmp < 3277)
  1108.    {
  1109.       tmp = 3277;   /* 0.1 in Q15 */
  1110.    }
  1111.    if((mode == MODE_24k) & (bfi == 0))
  1112.    {
  1113.       /* HF correction gain */
  1114.       HF_gain_ind = prms;
  1115.       HF_corr_gain = D_ROM_hp_gain[HF_gain_ind];
  1116.       /* HF gain */
  1117.       for(i = 0; i < L_SUBFR16k; i++)
  1118.       {
  1119.          HF[i] = (Word16)(((HF[i] * HF_corr_gain) >> 15) << 1);
  1120.       }
  1121.    }
  1122.    else
  1123.    {
  1124.       for(i = 0; i < L_SUBFR16k; i++)
  1125.       {
  1126.          HF[i] = (Word16)((HF[i] * tmp) >> 15);
  1127.       }
  1128.    }
  1129.    if((mode <= MODE_7k) & (newDTXState == SPEECH))
  1130.    {
  1131.       D_LPC_isf_extrapolation(HfIsf);
  1132.       D_LPC_isp_a_conversion(HfIsf, HfA, M16k);
  1133.       D_LPC_a_weight(HfA, Ap, 29491, M16k);   /* fac=0.9 */
  1134.       D_UTIL_synthesis(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1);
  1135.    }
  1136.    else
  1137.    {
  1138.       /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */
  1139.       D_LPC_a_weight(Aq, Ap, 19661, M);   /* fac=0.6 */
  1140.       D_UTIL_synthesis(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf + (M16k - M), 1);
  1141.    }
  1142.    /* noise High Pass filtering (1ms of delay) */
  1143.    D_UTIL_bp_6k_7k(HF, L_SUBFR16k, st->mem_hf);
  1144.    if(mode == MODE_24k)
  1145.    {
  1146.       /* Low Pass filtering (7 kHz) */
  1147.       D_UTIL_hp_7k(HF, L_SUBFR16k, st->mem_hf3);
  1148.    }
  1149.    /* add filtered HF noise to speech synthesis */
  1150.    for(i = 0; i < L_SUBFR16k; i++)
  1151.    {
  1152.       tmp = (synth16k[i] + HF[i]);
  1153.       synth16k[i] = D_UTIL_saturate(tmp);
  1154.    }
  1155.    return;
  1156. }
  1157. /*
  1158.  * D_UTIL_preemph
  1159.  *
  1160.  * Parameters:
  1161.  *    x            I/O: signal
  1162.  *    mu             I: preemphasis factor
  1163.  *    lg             I: vector size
  1164.  *    mem          I/O: memory (x[-1])
  1165.  *
  1166.  * Function:
  1167.  *    Filtering through 1 - mu z^-1
  1168.  *
  1169.  *
  1170.  * Returns:
  1171.  *    void
  1172.  */
  1173. void D_UTIL_preemph(Word16 x[], Word16 mu, Word16 lg, Word16 *mem)
  1174. {
  1175.    Word32 i, L_tmp;
  1176.    Word16 temp;
  1177.    temp = x[lg - 1];
  1178.    for(i = lg - 1; i > 0; i--)
  1179.    {
  1180.       L_tmp = x[i] << 15;
  1181.       L_tmp = L_tmp - (x[i - 1] * mu);
  1182.       x[i] = (Word16)((L_tmp + 0x4000) >> 15);
  1183.    }
  1184.    L_tmp = x[0] << 15;
  1185.    L_tmp = L_tmp - (*mem * mu);
  1186.    x[0] = (Word16)((L_tmp + 0x4000) >> 15);
  1187.    *mem = temp;
  1188.    return;
  1189. }