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

📄 qgain795.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 2 页
字号:
 
#include "qgain795.h"
#include "basic_op.h"
#include "bitno_tab.h"


 
#define LTP_GAIN_THR1 2721 /* 2721 Q13 = 0.3322 ~= 1.0 / (10*log10(2)) */#define LTP_GAIN_THR2 5443 /* 5443 Q13 = 0.6644 ~= 2.0 / (10*log10(2)) */

#define NMAX 9  /* largest N used in median calculation */

/************************************************************************* * * FUNCTION:  MR795_gain_code_quant3 * * PURPOSE: Pre-quantization of codebook gains, given three possible *          LTP gains (using predicted codebook gain) * *************************************************************************/static void MR795_gain_code_quant3(Word16 exp_gcode0,  Word16 gcode0, Word16 g_pitch_cand[],  Word16 g_pitch_cind[], 
    Word16 frac_coeff[],Word16 exp_coeff[],Word16 *gain_pit,  Word16 *gain_pit_ind,  Word16 *gain_cod, 
    Word16 *gain_cod_ind,  Word16 *qua_ener_MR122, Word16 *qua_ener  )
{    const Word16 *p ,*pqua_gain_code = qua_gain_code;
    Word16 i, j, cod_ind, pit_ind;    Word16 e_max, exp_code;    Word16 g_pitch, g2_pitch, g_code, g2_code_h, g2_code_l;    Word16 g_pit_cod_h, g_pit_cod_l;    Word16 coeff[5], coeff_lo[5];    Word16 exp_max[5];    Word32 L_tmp, L_tmp0, dist_min;
    Word16 t1,t2;
    Word16 *pexp_coeff = exp_coeff, *pfrac_coeff = frac_coeff , *pg_pitch_cand = g_pitch_cand;
   
    /*     * The error energy (sum) to be minimized consists of five terms, t[0..4].     *     *                      t[0] =    gp^2  * <y1 y1>     *                      t[1] = -2*gp    * <xn y1>     *                      t[2] =    gc^2  * <y2 y2>     *                      t[3] = -2*gc    * <xn y2>     *                      t[4] =  2*gp*gc * <y1 y2>     *     */    /* determine the scaling exponent for g_code: ec = ec0 - 10 */    exp_code = exp_gcode0-10;    /* calculate exp_max[i] = s[i]-1 */    exp_max[0] = pexp_coeff[0]-13;                      
    exp_max[1] = pexp_coeff[1]-14;                       
    exp_max[2] = pexp_coeff[2] + 15 + (exp_code<<1); 
    exp_max[3] = pexp_coeff[3] + exp_code;                  
    exp_max[4] = pexp_coeff[4] + exp_code + 1 ;        
    /*-------------------------------------------------------------------*     *  Find maximum exponent:                                           *     *  ~~~~~~~~~~~~~~~~~~~~~~                                           *     *                                                                   *     *  For the sum operation, all terms must have the same scaling;     *     *  that scaling should be low enough to prevent overflow. There-    *     *  fore, the maximum scale is determined and all coefficients are   *     *  re-scaled:                                                       *     *                                                                   *     *    e_max = max(exp_max[i]) + 1;                                   *     *    e = exp_max[i]-e_max;         e <= 0!                          *     *    c[i] = c[i]*2^e                                                *     *-------------------------------------------------------------------*/    e_max = exp_max[0];   
    t1 = exp_max[1] > exp_max[2] ? exp_max[1]  : exp_max[2];
    t2 = exp_max[3] > exp_max[4] ? exp_max[3]  : exp_max[4];
    t1 = t1 > t2 ? t1: t2;
    e_max = e_max < t1 ? t1 : e_max;
	
    e_max ++;      /* To avoid overflow */    for (i = 0; i < 5; i++)     {        j = e_max- exp_max[i];        L_tmp = pfrac_coeff[i]<<16 ;

        if(j>= 31)
	 {
	 	 L_tmp = L_tmp < 0 ? -1 : 0;		 
	 }
	 else
	 {
		j = j< -32 ? -32 :j;	 
		L_tmp =  j>=0 ? L_tmp>>j :( L_tmp>( MAX_32>> -j) ? MAX_32 : ( L_tmp < (MIN_32 >> -j) ? MIN_32 : L_tmp << - j));
	 }   
	 coeff[i] = (Word16)(L_tmp>>16);	 coeff_lo[i]  =(L_tmp - (coeff[i]<<16))>>1;	     }    /*-------------------------------------------------------------------*     *  Codebook search:                                                 *     *  ~~~~~~~~~~~~~~~~                                                 *     *                                                                   *     *  For each of the candiates LTP gains in g_pitch_cand[], the terms *     *  t[0..4] are calculated from the values in the table (and the     *     *  pitch gain candidate) and summed up; the result is the mean      *     *  squared error for the LPT/CB gain pair. The index for the mini-  *     *  mum MSE is stored and finally used to retrieve the quantized CB  *     *  gain                                                             *     *-------------------------------------------------------------------*/    /* start with "infinite" MSE */    dist_min = MAX_32;           cod_ind = 0;                 pit_ind = 0;                /* loop through LTP gain candidates */    for (j = 0; j < 3; j++)    {        /* pre-calculate terms only dependent on pitch gain */        g_pitch = pg_pitch_cand[j];  
		        g2_pitch = (g_pitch* g_pitch>>15);
	 L_tmp0  = (coeff[0]*g2_pitch<<1) + ((coeff_lo[0]*g2_pitch>>15)<<1);
	 L_tmp0 += (coeff[1]*g_pitch<<1) + ((coeff_lo[1]*g_pitch>>15)<<1);        p = &pqua_gain_code[0];
        for (i = 0; i < NB_QUA_CODE; i++)        {            g_code = *p++;                 p++;                             /* skip log2(g_fac)         */            p++;                             /* skip 20*log10(g_fac)     */            g_code = (g_code* gcode0>>15);            L_tmp = (g_code* g_code<<1);
	    g2_code_h = (Word16)(L_tmp>>16);	    g2_code_l  = (L_tmp -(g2_code_h<<16))>>1;		            L_tmp = (g_code*g_pitch <<1 );
	     g_pit_cod_h = (Word16)(L_tmp>>16);	     g_pit_cod_l = (L_tmp - (g_pit_cod_h<<16))>>1;
			            L_tmp = L_tmp0 +  (coeff[2]*g2_code_h<<1) +(((coeff[2]*g2_code_l>>15) + (coeff_lo[2]*g2_code_h>>15))<<1);
				     L_tmp += (coeff[3]*g_code<<1) +((coeff_lo[3]*g_code>>15)<<1);
	     L_tmp += (coeff[4]*g_pit_cod_h<<1) + (((coeff[4]*g_pit_cod_l>>15) + (coeff_lo[4]*g_pit_cod_h>>15))<<1);            /* store table index if MSE for this index is lower               than the minimum MSE seen so far; also store the               pitch gain for this (so far) lowest MSE          */                      if (L_tmp < dist_min)            {                dist_min = L_tmp;                            cod_ind  = i;                    
                pit_ind    = j;                   
            }        }    }    /*------------------------------------------------------------------*     *  read quantized gains and new values for MA predictor memories   *     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *     *------------------------------------------------------------------*/    /* Read the quantized gains */    p = &pqua_gain_code[cod_ind+ cod_ind+cod_ind]; 
    g_code = *p++;               *qua_ener_MR122 = *p++;      *qua_ener = *p;            /*------------------------------------------------------------------*     *  calculate final fixed codebook gain:                            *     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                            *     *                                                                  *     *   gc = gc0 * g                                                   *     *------------------------------------------------------------------*/    L_tmp = (g_code* gcode0<<1);
       L_tmp = 9 > exp_gcode0 ? L_tmp>> (9-exp_gcode0) : L_tmp << (exp_gcode0-9);	    *gain_cod = (Word16)(L_tmp>>16);    *gain_cod_ind = cod_ind;                   *gain_pit = g_pitch_cand[pit_ind];         *gain_pit_ind = g_pitch_cind[pit_ind]; 
}/************************************************************************* * * FUNCTION:  MR795_gain_code_quant_mod * * PURPOSE: Modified quantization of the MR795 codebook gain * * Uses pre-computed energy coefficients in frac_en[]/exp_en[] * *       frac_en[0]*2^exp_en[0] = <res res>   // LP residual energy *       frac_en[1]*2^exp_en[1] = <exc exc>   // LTP residual energy *       frac_en[2]*2^exp_en[2] = <exc code>  // LTP/CB innovation dot product *       frac_en[3]*2^exp_en[3] = <code code> // CB innovation energy * *************************************************************************/static Word16  MR795_gain_code_quant_mod(Word16 gain_pit,  Word16 exp_gcode0,  Word16 gcode0, Word16 frac_en[],  Word16 exp_en[],  
    Word16 alpha, Word16 gain_cod_unq,  Word16 *gain_cod,  Word16 *qua_ener_MR122,  Word16 *qua_ener     )
{
    const Word16 *p;
    Word16 i, index, tmp,tmp1,tmp2;
    Word16 one_alpha;
    Word16 exp, e_max;
    Word16 g2_pitch, g_code;
    Word16 g2_code_h, g2_code_l;
    Word16 d2_code_h, d2_code_l;
    Word16 coeff[5], coeff_lo[5], exp_coeff[5];
    Word32 L_tmp,L_tmp1,L_tmp2, L_t0, L_t1, dist_min;
    Word16 gain_code,t1,t2;
    
    /* calculate scalings of the constant terms*/
    gain_code = 10 - exp_gcode0 < 0 ? *gain_cod >> (exp_gcode0-10) : (*gain_cod >=  (MAX_16>> (10 - exp_gcode0)) ?  MAX_16 : *gain_cod << (10 - exp_gcode0) );
	
    g2_pitch = gain_pit*gain_pit >>15 ;           
	
    one_alpha = 32767-alpha+1; /* 32768 - alpha */


    /*  alpha <= 0.5 -> mult. by 2 to keep precision; compensate in exponent */
    tmp = alpha*frac_en[1]>>14;
	
    /* directly store in 32 bit variable because no further mult. required */
    L_t1 =   tmp*g2_pitch<<1;               
    exp_coeff[1] = exp_en[1]-15;     
    tmp = alpha*frac_en[2] >>14;
	
    coeff[2] = tmp*gain_pit >> 15;        
	
    exp = exp_gcode0 -10;
    exp_coeff[2] = exp_en[2] + exp;           
     coeff[3] = alpha*frac_en[3] >>14;
	
    exp =  (exp_gcode0<<1) - 7;
    exp_coeff[3] = exp_en[3] + exp;           


    coeff[4] =  (one_alpha* frac_en[3] >> 15);          
    exp_coeff[4] = (exp_coeff[3]+1);            


    L_tmp = alpha*frac_en[0] << 1;
    L_t0 = sqrt_l_exp (L_tmp, &exp); /* normalization included in sqrt_l_exp */
                                   
    exp += 47;
    exp_coeff[0] = exp_en[0] - exp;           

    /*
     * Determine the maximum exponent occuring in the distance calculation
     * and adjust all fractions accordingly (including a safety margin)
     *
     */

	/* find max(e[1..4],e[0]+31) */
	e_max = exp_coeff[0] + 31;
	t1 = exp_coeff[1] > exp_coeff[2] ? exp_coeff[1] : exp_coeff[2];
	t2 = exp_coeff[3] > exp_coeff[4] ? exp_coeff[3] : exp_coeff[4];
	t1 = t1 > t2 ? t1 : t2;
	e_max = e_max > t1 ? e_max : t1;
	/*

	/* scale c[1]         (requires no further multiplication) */
	tmp = e_max -exp_coeff[1];

	L_t1 = tmp>0 ? L_t1>>tmp : L_t1 << -tmp;


	/* scale c[2..4] (used in Mpy_32_16 in the quantizer loop) */

	tmp =  e_max -exp_coeff[2];
	tmp1 =  e_max -exp_coeff[3];
	tmp2 =  e_max -exp_coeff[4];

	L_tmp = (coeff[2] << 16);     
	L_tmp = tmp>0 ? L_tmp >> tmp : L_tmp << -tmp;
	L_tmp1 = (coeff[3] << 16);     
	L_tmp1 = tmp1>0 ? L_tmp1 >> tmp1 : L_tmp1 << -tmp1;
	L_tmp2 = (coeff[4] << 16);     
	L_tmp2 = tmp2>0 ? L_tmp2 >> tmp2 : L_tmp2 << -tmp2;

	coeff[2] = (Word16)(L_tmp >> 16);
	coeff_lo[2] = (L_tmp - (coeff[2] <<16))>>1;      
	coeff[3] = (Word16)(L_tmp1 >> 16);
	coeff_lo[3] = (L_tmp1 - (coeff[3] <<16))>>1;       
	coeff[4] = (Word16)(L_tmp2 >> 16);
	coeff_lo[4] = (L_tmp2 - (coeff[4] <<16))>>1;


    /* scale c[0]         (requires no further multiplication) */
    exp = e_max- 31;             /* new exponent */
    tmp = exp-exp_coeff[0] ;
	
   
    L_t0 = tmp >= 0? L_t0 >>(tmp>>1) : L_t0 << -(tmp>>1);
	
    /* perform correction by 1/sqrt(2) if exponent difference is odd */
 
    if ((tmp & 0x1) != 0)
    {
      
	 coeff[0]     = (Word16)(L_t0 >> 16);
	 coeff_lo[0] = (L_t0 - (coeff[0]<<16 ))>>1;       
        L_t0 = coeff[0]*46340 + ((coeff_lo[0]*23170>>15)<<1);

	}

    /* search the quantizer table for the lowest value
       of the search criterion                           */
    dist_min = MAX_32; 
    index = 0;      
    p = &qua_gain_code[0]; 

    for (i = 0; i < NB_QUA_CODE; i++)
    {
        g_code = *p++;            /* this is g_fac (Q11)  */
        p++;                             /* skip log2(g_fac)     */
        p++;                             /* skip 20*log10(g_fac) */
        g_code = (g_code*gcode0 >> 15);

        /* only continue if    gc[i]            < 2.0*gc
           which is equiv. to  g_code (Q10-ec0) < gain_code (Q11-ec0) */
      
        if ( g_code >= gain_code)
            break;

        L_tmp = g_code* g_code << 1;
       
	 g2_code_h = (Word16)(L_tmp >> 16);
	 g2_code_l  = (L_tmp - (g2_code_h<<16))>>1;
	 

        tmp = g_code- gain_cod_unq;
        L_tmp = tmp* tmp << 1;
     
	 d2_code_h = (Word16)(L_tmp>>16);
	 d2_code_l  = (L_tmp -(d2_code_h<<16))>>1;
	 

        /* t2, t3, t4 */
      
	 L_tmp = L_t1 + (coeff[2]*g_code<<1) + ((coeff_lo[2]*g_code>>15)<<1);
	 L_tmp += (coeff[3]*g2_code_h <<1) + (((coeff[3]*g2_code_l>>15)  + (coeff_lo[3]*g2_code_h>>15))<<1);
        L_tmp = sqrt_l_exp (L_tmp, &exp);
        L_tmp = (exp>>1) >= 0 ? L_tmp >> (exp>>1) : L_tmp << -(exp>>1);
		

        /* d2 */
	 tmp = (L_tmp - L_t0 + 0x00008000)>>16;
        L_tmp = tmp*tmp << 1;

        /* dist */
	 L_tmp += (coeff[4]*d2_code_h<<1) + (((coeff_lo[4]*d2_code_h>>15) +(coeff[4]*d2_code_l>>15))<<1);

        /* store table index if distance measure for this
            index is lower than the minimum seen so far   */
        index     = L_tmp < dist_min ? i : index;

⌨️ 快捷键说明

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