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

📄 gain_q.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 4 页
字号:

    /* determine the scaling exponent for g_code: ec = ec0 - 11 */
    exp_code = exp_gcode0 - 11;

    /* 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] + 1 + exp_code;        


    /*-------------------------------------------------------------------*
     *  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 ? e_max : t1;

    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 < 0)
	{ 
	  j = j<-32 ? -32 : j;
	  L_tmp = (L_tmp >= (MAX_32>>(-j) )) ? MAX_32 : ((L_tmp <= (MIN_32>>(-j) ) )? MIN_32 : L_tmp << -j );
	  	
	}
	else
	{
	   L_tmp = j>= 31 ? (L_tmp > 0 ? 0:  -1) : L_tmp >> j;

	}        
	 coeff[i]    = (Word16)(L_tmp >> 16);
	 coeff_lo[i] = (L_tmp - (coeff[i]<<16))>>1;
	 
    }


    /*-------------------------------------------------------------------*
     *  Codebook search:                                                 *
     *  ~~~~~~~~~~~~~~~~                                                 *
     *                                                                   *
     *  For each pair (g_pitch, g_fac) in the table calculate the        *
     *  terms t[0..4] and sum them up; the result is the mean squared    *
     *  error for the quantized gains from the table. The index for the  *
     *  minimum MSE is stored and finally used to retrieve the quantized *
     *  gains                                                            *
     *-------------------------------------------------------------------*/

    /* start with "infinite" MSE */
    dist_min = MAX_32;      

    p = &table_gain[0];     

    for (i = 0; i < table_len; i++)
    {
        g_pitch = *p++;       
        g_code = *p++;     
        p++;                             /* skip log2(g_fac)     */
        p++;                             /* skip 20*log10(g_fac) */
            
   
        if ( g_pitch <= gp_limit)
        {
       
            g_code    = (g_code*gcode0 >>15);
            g2_pitch  = (g_pitch*g_pitch >>15);
            g2_code  = (g_code*g_code >>15);
            g_pit_cod =(g_code*g_pitch >>15);

            L_tmp = (coeff[0]*g2_pitch<<1)+(( coeff_lo[0]* g2_pitch>>15)<<1);
			
            L_tmp += (coeff[1]*g_pitch<<1) + ((coeff_lo[1]*g_pitch>>15)<<1);
			
            L_tmp += (coeff[2]*g2_code<<1) +((coeff_lo[2]*g2_code>>15)<<1);
            L_tmp += (coeff[3]*g_code<<1) +((coeff_lo[3]*g_code>>15 )<<1);
            L_tmp += (coeff[4]*g_pit_cod<<1)+((coeff_lo[4]*g_pit_cod>>15)<<1);


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

    /*------------------------------------------------------------------*
     *  read quantized gains and new values for MA predictor memories   *
     *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~   *
     *------------------------------------------------------------------*/

    /* Read the quantized gains */
    p = &table_gain[index<<2]; 
    *gain_pit = *p++;        
    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 = (10 > exp_gcode0) ? L_tmp >> (10 - exp_gcode0): L_tmp <<(exp_gcode0 -10);
    *gain_cod = (Word16)(L_tmp>>16);

    return index;
	

}


/****************************************************
Function: q_gain_code
Description:
Input         :

mode: AMR mode                        
	exp_gcode0   : predicted CB gain (exponent),  Q0  
	frac_gcode0  : predicted CB gain (fraction),  Q15 
	gain                : quantized fixed codebook gain, Q1 

Output       :
	gain                        : quantized fixed codebook gain, Q1  
	qua_ener_MR122 : quantized energy error,        Q10 	       
	qua_ener               : quantized energy error,        Q10 
Return       :
         Quantizaiotn index

*******************************************************/

Word16 q_gain_code (Mode mode, Word16 exp_gcode0, Word16 frac_gcode0, Word16 *gain, Word16 *qua_ener_MR122,  Word16 *qua_ener  )
{
    const Word16 *p,*pqua_gain_code = qua_gain_code;    Word16 i, index;    Word16 gcode0, err, err_min;    Word16 g_q0,temp;
    Word16 *pgain = gain, *pqua_ener_MR122 = qua_ener_MR122, *pqua_ener = qua_ener;
     
    g_q0 = *gain >>1 ;
    /*-------------------------------------------------------------------*     *  predicted codebook gain                                          *     *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *     *  gc0     = Pow2(int(d)+frac(d))                                   *     *          = 2^exp + 2^frac                                         *     *                                                                   *     *-------------------------------------------------------------------*/    gcode0 = (Word16)(Pow2 (exp_gcode0, frac_gcode0));  /* predicted gain */
    gcode0 = gcode0>= 0x07ff ? MAX_16 : gcode0<<4;

    /*-------------------------------------------------------------------*     *                   Search for best quantizer                        *     *-------------------------------------------------------------------*/    p = &pqua_gain_code[0];
    temp = g_q0 - (gcode0*( *p++)>>15);
    err_min = temp > 0 ? temp : -temp ;
   
    p += 2;                                  /* skip quantized energy errors */    index = 0;                for (i = 1; i < NB_QUA_CODE; i++)    {
	temp =  g_q0 - (gcode0*(*p++)>>15);
	err =  temp>0 ? temp: -temp;
       p += 2;                              /* skip quantized energy error */
	index  = err<err_min? i : index;
       err_min = err < err_min ? err : err_min;
	
    }    p = &pqua_gain_code[index+index+ index]; 
    *gain = ( (gcode0*(*p++)>>15) <<1); 
	
    /* quantized error energies (for MA predictor update) */    *pqua_ener_MR122 = *p++;                
    *pqua_ener = *p;                      
    return index;
}

/************************************************************************* 
  Function : calc_filt_energies

  Purpose:  calculation of several energy coefficients for filteredexcitation signals
 
      Compute coefficients need for the quantization and the optimum
      codebook gain gcu (for MR475 only).
 
       coeff[0] =    y1 y1
       coeff[1] = -2 xn y1
       coeff[2] =    y2 y2
       coeff[3] = -2 xn y2
       coeff[4] =  2 y1 y2
 
 
       gcu = <xn2, y2> / <y2, y2> (0 if <xn2, y2> <= 0)
 
      Product <y1 y1> and <xn y1> have been computed in G_pitch() and
      are in vector g_coeff[].

    Input:

		mode        : coder mode                                 
		xn[]          : LTP target vector,                       Q0  
		xn2[]        : CB target vector,                        Q0  
		y1[]          : Adaptive codebook,                       Q0  
		Y2[]          : Filtered innovative vector,              Q12
		g_coeff[]  : Correlations <xn y1> <y1 y1>                
    Output:
		frac_coeff[]        : energy coefficients (5), fraction part,  Q15 
		exp_coeff[]        : energy coefficients (5), exponent part,  Q0
		cod_gain_frac    : optimum codebook gain (fraction part),   Q15
		cod_gain_exp    : optimum codebook gain (exponent part),   Q0 
		
    Return: void
    
 *************************************************************************/void calc_filt_energies( Mode mode,  Word16 xn[], Word16 xn2[], Word16 y1[], Word16 Y2[], Word16 g_coeff[], 
    Word16 frac_coeff[], Word16 exp_coeff[], Word16 *cod_gain_frac, Word16 *cod_gain_exp )
{
	Word32 s,s1,s2,s3, ener_init;
	Word16 i, exp,exp1,exp2,exp3, frac;
	Word16 y2[L_SUBFR];

	Word16*pY2 = Y2, *pfrac_coeff = frac_coeff, *pexp_coeff = exp_coeff, *pg_coeff = g_coeff, *pcod_gain_frac = cod_gain_frac, *pcod_gain_exp = cod_gain_exp;
	Word16 *pxn = xn, *pxn2 = xn2, *py1 = y1;

	ener_init = ((mode == MR795)||(mode == MR475)) ? 0 : 1 ;

	for (i = 0; i < L_SUBFR; i+=8) 
	{
		y2[i] = pY2[i] >> 3;            y2[i+1] = pY2[i+1] >> 3;y2[i+2] = pY2[i+2] >> 3;y2[i+3] = pY2[i+3] >> 3; 
		y2[i+4] = pY2[i+4] >> 3;    y2[i+5] = pY2[i+5] >> 3;y2[i+6] = pY2[i+6] >> 3;y2[i+7] = pY2[i+7] >> 3;  
	}

	pfrac_coeff[0]  =  pg_coeff[0];       
	pexp_coeff[0]  =  pg_coeff[1];         
	pfrac_coeff[1]  = (pg_coeff[2] == MIN_16 ? MAX_16 : -pg_coeff[2]); 
	pexp_coeff[1]  = (pg_coeff[3] + 1);   
    /* Compute scalar product <y2[],y2[]> */	s   = ener_init;
	s1 = ener_init;
	s2 = ener_init;
       s3 = ener_init;
		for (i = 0; i < L_SUBFR; i+=4 )
	{ 
		s   += (y2[i]*y2[i]  +    y2[i+1]*y2[i+1] +   y2[i+2]*y2[i+2] +   y2[i+3]*y2[i+3]) <<1;
		s1 += (pxn[i]*y2[i] +  pxn[i+1]*y2[i+1] + pxn[i+2]*y2[i+2] + pxn[i+3]*y2[i+3]) <<1;
		s2 += (py1[i]*y2[i] +  py1[i+1]*y2[i+1] + py1[i+2]*y2[i+2] + py1[i+3]*y2[i+3]) <<1;

	}
	exp   = norm_l(s);
	exp1 = norm_l(s1);
	exp2 = norm_l(s2);

	pfrac_coeff[2] = (Word16)((s<< exp)>>16); 	
	pexp_coeff[2] = (-3 - exp);    	
	pfrac_coeff[3] = (Word16)(( (s1 << exp1)>>16) == MIN_16 ? MAX_16 : -( (s1 << exp1)>>16)) ;
	pexp_coeff[3] = 7 - exp1;       
	pfrac_coeff[4] = (Word16)((s2 << exp2)>>16 ); 	
	pexp_coeff[4] = 7 - exp2 ;  
    if ((mode == MR475) ||(mode == MR795) )    {        /* Compute scalar product <xn2[],y2[]> */
	 for (i = 0; i < L_SUBFR; i+=4 )
	{ 
              s3 += (pxn2[i]*y2[i] +pxn2[i+1]*y2[i+1] +pxn2[i+2]*y2[i+2]+pxn2[i+3]*y2[i+3])<<1;
	}
        exp3 = norm_l(s3);
        frac = (Word16)((s3<<exp3)>>16);
        exp3 = 6 - exp3;
                if ( frac <= 0)        {            *pcod_gain_frac = 0; 
            *pcod_gain_exp = 0;  
        }        else        {            *pcod_gain_frac  = div_s ((frac>>1), pfrac_coeff[2]); 
            *pcod_gain_exp   = exp3 - pexp_coeff[2] - 14;   
        }    }
}


⌨️ 快捷键说明

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