⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dec_util.c

📁 ffmpeg源码分析
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
 *===================================================================
 *  3GPP AMR Wideband Floating-point Speech Codec
 *===================================================================
 */
#include <math.h>
#include <memory.h>
#include "typedef.h"
#include "dec_main.h"
#include "dec_lpc.h"

#define MAX_16       (Word16)0x7FFF
#define MIN_16       (Word16)0x8000
#define L_SUBFR      64       /* Subframe size                    */
#define L_SUBFR16k   80       /* Subframe size at 16kHz           */
#define M16k         20       /* Order of LP filter               */
#define PREEMPH_FAC  22282    /* preemphasis factor (0.68 in Q15) */
#define FAC4         4
#define FAC5         5
#define UP_FAC       20480    /* 5/4 in Q14                       */
#define INV_FAC5     6554     /* 1/5 in Q15                       */
#define NB_COEF_UP   12
#define L_FIR        31
#define MODE_7k      0
#define MODE_24k     8


extern const Word16 D_ROM_pow2[];
extern const Word16 D_ROM_isqrt[];
extern const Word16 D_ROM_log2[];
extern const Word16 D_ROM_fir_up[];
extern const Word16 D_ROM_fir_6k_7k[];
extern const Word16 D_ROM_fir_7k[];
extern const Word16 D_ROM_hp_gain[];

#ifdef WIN32
#pragma warning( disable : 4310)
#endif
/*
 * D_UTIL_random
 *
 * Parameters:
 *    seed        I/O: seed for random number
 *
 * Function:
 *    Signed 16 bits random generator.
 *
 * Returns:
 *    random number
 */
Word16 D_UTIL_random(Word16 *seed)
{
   /*static Word16 seed = 21845;*/
   *seed = (Word16)(*seed * 31821L + 13849L);
   return(*seed);
}


/*
 * D_UTIL_pow2
 *
 * Parameters:
 *    exponant    I: (Q0) Integer part.      (range: 0 <= val <= 30)
 *    fraction    I: (Q15) Fractionnal part. (range: 0.0 <= val < 1.0)
 *
 * Function:
 *    L_x = pow(2.0, exponant.fraction)         (exponant = interger part)
 *        = pow(2.0, 0.fraction) << exponant
 *
 *    Algorithm:
 *
 *    The function Pow2(L_x) is approximated by a table and linear
 *    interpolation.
 *
 *    1 - i = bit10 - b15 of fraction,   0 <= i <= 31
 *    2 - a = bit0 - b9   of fraction
 *    3 - L_x = table[i] << 16 - (table[i] - table[i + 1]) * a * 2
 *    4 - L_x = L_x >> (30-exponant)     (with rounding)
 *
 * Returns:
 *    range 0 <= val <= 0x7fffffff
 */
Word32 D_UTIL_pow2(Word16 exponant, Word16 fraction)
{
	Word32 L_x, tmp, i, exp;
	Word16 a;

	L_x = fraction * 32;          /* L_x = fraction<<6             */
	i = L_x >> 15;                /* Extract b10-b16 of fraction   */
	a = (Word16)(L_x);            /* Extract b0-b9   of fraction   */
	a = (Word16)(a & (Word16)0x7fff);
	L_x = D_ROM_pow2[i] << 16;    /* table[i] << 16                */
	tmp = D_ROM_pow2[i] - D_ROM_pow2[i + 1];  /* table[i] - table[i+1] */
	tmp = L_x - ((tmp * a) << 1); /* L_x -= tmp*a*2                */
	exp = 30 - exponant;
	if (exp <= 31)
	{
		L_x = tmp >> exp;

		if ((1 << (exp - 1)) & tmp)
		{
			L_x++;
		}
	}
	else
	{
		L_x = 0;
	}

	return(L_x);
}


/*
 * D_UTIL_norm_l
 *
 * Parameters:
 *    L_var1      I: 32 bit Word32 signed integer (Word32) whose value
 *                   falls in the range 0x8000 0000 <= var1 <= 0x7fff ffff.
 *
 * Function:
 *    Produces the number of left shifts needed to normalize the 32 bit
 *    variable L_var1 for positive values on the interval with minimum of
 *    1073741824 and maximum of 2147483647, and for negative values on
 *    the interval with minimum of -2147483648 and maximum of -1073741824;
 *    in order to normalize the result, the following operation must be done :
 *    norm_L_var1 = L_shl(L_var1,norm_l(L_var1)).
 *
 * Returns:
 *    16 bit Word16 signed integer (Word16) whose value falls in the range
 *    0x0000 0000 <= var_out <= 0x0000 001f.
 */
Word16 D_UTIL_norm_l(Word32 L_var1)
{
   Word16 var_out;

   if(L_var1 == 0)
   {
      var_out = 0;
   }
   else
   {
      if(L_var1 == (Word32)0xffffffffL)
      {
         var_out = 31;
      }
      else
      {
         if(L_var1 < 0)
         {
            L_var1 = ~L_var1;
         }

         for(var_out = 0; L_var1 < (Word32)0x40000000L; var_out++)
         {
            L_var1 <<= 1;
         }
      }
   }

   return(var_out);
}


/*
 * D_UTIL_norm_s
 *
 * Parameters:
 *    L_var1      I: 32 bit Word32 signed integer (Word32) whose value
 *                   falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
 *
 * Function:
 *    Produces the number of left shift needed to normalize the 16 bit
 *    variable var1 for positive values on the interval with minimum
 *    of 16384 and maximum of 32767, and for negative values on
 *    the interval with minimum of -32768 and maximum of -16384.
 *
 * Returns:
 *    16 bit Word16 signed integer (Word16) whose value falls in the range
 *    0x0000 0000 <= var_out <= 0x0000 000f.
 */
Word16 D_UTIL_norm_s(Word16 var1)
{
   Word16 var_out;

   if(var1 == 0)
   {
      var_out = 0;
   }
   else
   {
      if(var1 == -1)
      {
         var_out = 15;
      }
      else
      {
         if(var1 < 0)
         {
            var1 = (Word16)~var1;
         }

         for(var_out = 0; var1 < 0x4000; var_out++)
         {
            var1 <<= 1;
         }
      }
   }
   return(var_out);
}


/*
 * D_UTIL_dot_product12
 *
 * Parameters:
 *    x        I: 12bit x vector
 *    y        I: 12bit y vector
 *    lg       I: vector length
 *    exp      O: exponent of result (0..+30)
 *
 * Function:
 *    Compute scalar product of <x[],y[]> using accumulator.
 *    The result is normalized (in Q31) with exponent (0..30).
 *
 * Returns:
 *    Q31 normalised result (1 < val <= -1)
 */
Word32 D_UTIL_dot_product12(Word16 x[], Word16 y[], Word16 lg, Word16 *exp)
{
   Word32 sum, i, sft;

   sum = 0L;

   for(i = 0; i < lg; i++)
   {
      sum += x[i] * y[i];
   }
   sum = (sum << 1) + 1;

   /* Normalize acc in Q31 */
   sft = D_UTIL_norm_l(sum);
   sum = sum << sft;
   *exp = (Word16)(30 - sft);   /* exponent = 0..30 */

   return(sum);
}


/*
 * D_UTIL_normalised_inverse_sqrt
 *
 * Parameters:
 *    frac     I/O: (Q31) normalized value (1.0 < frac <= 0.5)
 *    exp      I/O: exponent (value = frac x 2^exponent)
 *
 * Function:
 *    Compute 1/sqrt(value).
 *    If value is negative or zero, result is 1 (frac=7fffffff, exp=0).
 *
 *    The function 1/sqrt(value) is approximated by a table and linear
 *    interpolation.
 *    1. If exponant is odd then shift fraction right once.
 *    2. exponant = -((exponant - 1) >> 1)
 *    3. i = bit25 - b30 of fraction, 16 <= i <= 63 ->because of normalization.
 *    4. a = bit10 - b24
 *    5. i -= 16
 *    6. fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2
 *
 * Returns:
 *    void
 */
void D_UTIL_normalised_inverse_sqrt(Word32 *frac, Word16 *exp)
{
   Word32 i, tmp;
   Word16 a;

   if(*frac <= (Word32)0)
   {
      *exp = 0;
      *frac = 0x7fffffffL;
      return;
   }

   if((*exp & 0x1) == 1)   /* If exponant odd -> shift right */
   {
      *frac = *frac >> 1;
   }
   *exp = (Word16)(-((*exp - 1) >> 1));
   *frac = *frac >> 9;
   i = *frac >>16;      /* Extract b25-b31   */
   *frac = *frac >> 1;
   a = (Word16)(*frac); /* Extract b10-b24   */
   a = (Word16)(a & (Word16)0x7fff);
   i = i - 16;
   *frac = D_ROM_isqrt[i] << 16; /* table[i] << 16    */
   tmp = D_ROM_isqrt[i] - D_ROM_isqrt[i + 1];   /* table[i] - table[i+1]) */
   *frac = *frac - ((tmp * a) << 1);   /* frac -=  tmp*a*2  */

   return;
}


/*
 * D_UTIL_inverse_sqrt
 *
 * Parameters:
 *    L_x     I/O: (Q0) input value (range: 0<=val<=7fffffff)
 *
 * Function:
 *    Compute 1/sqrt(L_x).
 *    If value is negative or zero, result is 1 (7fffffff).
 *
 *    The function 1/sqrt(value) is approximated by a table and linear
 *    interpolation.
 *    1. Normalization of L_x
 *    2. call Normalised_Inverse_sqrt(L_x, exponant)
 *    3. L_y = L_x << exponant
 *
 * Returns:
 *    (Q31) output value (range: 0 <= val < 1)
 */
Word32 D_UTIL_inverse_sqrt(Word32 L_x)
{
   Word32 L_y;
   Word16 exp;

   exp = D_UTIL_norm_l(L_x);
   L_x = (L_x << exp);   /* L_x is normalized */
   exp = (Word16)(31 - exp);
   D_UTIL_normalised_inverse_sqrt(&L_x, &exp);

   if(exp < 0)
   {
      L_y = (L_x >> -exp);   /* denormalization   */
   }
   else
   {
      L_y = (L_x << exp);   /* denormalization   */
   }

   return(L_y);
}


/*
 * D_UTIL_normalised_log2
 *
 * Parameters:
 *    L_x      I: input value (normalized)
 *    exp      I: norm_l (L_x)
 *    exponent O: Integer part of Log2.   (range: 0<=val<=30)
 *    fraction O: Fractional part of Log2. (range: 0<=val<1)
 *
 * Function:
 *    Computes log2(L_x, exp),  where   L_x is positive and
 *    normalized, and exp is the normalisation exponent
 *    If L_x is negative or zero, the result is 0.
 *
 *    The function Log2(L_x) is approximated by a table and linear
 *    interpolation. The following steps are used to compute Log2(L_x)
 *
 *    1. exponent = 30 - norm_exponent
 *    2. i = bit25 - b31 of L_x;  32 <= i <= 63  (because of normalization).
 *    3. a = bit10 - b24
 *    4. i -= 32
 *    5. fraction = table[i] << 16 - (table[i] - table[i + 1]) * a * 2
 *
 *
 * Returns:
 *    void
 */
static void D_UTIL_normalised_log2(Word32 L_x, Word16 exp, Word16 *exponent,
                                   Word16 *fraction)
{
   Word32 i, a, tmp;
   Word32 L_y;

   if (L_x <= 0)
   {
      *exponent = 0;
      *fraction = 0;
      return;
   }

   *exponent = (Word16)(30 - exp);

   L_x = L_x >> 10;
   i = L_x >> 15;         /* Extract b25-b31               */
   a = L_x;               /* Extract b10-b24 of fraction   */
   a = a & 0x00007fff;
   i = i - 32;
   L_y = D_ROM_log2[i] << 16;               /* table[i] << 16        */
   tmp = D_ROM_log2[i] - D_ROM_log2[i + 1]; /* table[i] - table[i+1] */
   L_y = L_y - ((tmp * a) << 1);            /* L_y -= tmp*a*2        */
   *fraction = (Word16)(L_y >> 16);

   return;
}


/*
 * D_UTIL_log2
 *
 * Parameters:
 *    L_x      I: input value
 *    exponent O: Integer part of Log2.   (range: 0<=val<=30)
 *    fraction O: Fractional part of Log2. (range: 0<=val<1)
 *
 * Function:
 *    Computes log2(L_x),  where   L_x is positive.
 *    If L_x is negative or zero, the result is 0.
 *
 * Returns:
 *    void
 */
void D_UTIL_log2(Word32 L_x, Word16 *exponent, Word16 *fraction)
{
   Word16 exp;

   exp = D_UTIL_norm_l(L_x);
   D_UTIL_normalised_log2((L_x <<exp), exp, exponent, fraction);
}


/*
 * D_UTIL_l_extract
 *
 * Parameters:
 *    L_32        I: 32 bit integer.
 *    hi          O: b16 to b31 of L_32
 *    lo          O: (L_32 - hi<<16)>>1
 *
 * Function:
 *    Extract from a 32 bit integer two 16 bit DPF.
 *
 * Returns:
 *    void
 */
void D_UTIL_l_extract(Word32 L_32, Word16 *hi, Word16 *lo)
{
   *hi = (Word16)(L_32 >> 16);
   *lo = (Word16)((L_32 >> 1) - (*hi * 32768));

   return;
}


/*
 * D_UTIL_mpy_32_16
 *
 * Parameters:
 *    hi          I: hi part of 32 bit number
 *    lo          I: lo part of 32 bit number
 *    n           I: 16 bit number
 *
 * Function:
 *    Multiply a 16 bit integer by a 32 bit (DPF). The result is divided
 *    by 2^15.
 *
 *    L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -