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

📄 qgain795.c

📁 AMR-NB 的编码实现,纯C, VC下建立工程即可用.
💻 C
📖 第 1 页 / 共 2 页
字号:
	 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 = &qua_gain_code[index+ index+ index]; 
    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);

    return index;
}
/************************************************************************* * * FUNCTION:  MR795_gain_quant * * PURPOSE:   pitch and codebook quantization for MR795 * *************************************************************************/void MR795_gain_quant( GainAdaptState *adapt_st, Word16 res[], Word16 exc[], Word16 code[],Word16 frac_coeff[],
    Word16 exp_coeff[],    Word16 exp_code_en, Word16 frac_code_en, Word16 exp_gcode0,  Word16 frac_gcode0, 
    Word16 L_subfr,Word16 cod_gain_frac,  Word16 cod_gain_exp,Word16 gp_limit, Word16 *gain_pit, 
    Word16 *gain_cod, Word16 *qua_ener_MR122,  Word16 *qua_ener,    Word16 **anap )
{
    Word16 frac_en[4];    Word16 exp_en[4];    Word16 ltpg, alpha, gcode0;    Word16 g_pitch_cand[3];      /* pitch gain candidates   Q14 */    Word16 g_pitch_cind[3];      /* pitch gain indices      Q0  */    Word16 gain_pit_index;    Word16 gain_cod_index;    Word16 exp;    Word16 gain_cod_unq;         /* code gain (unq.) Q(10-exp_gcode0)  */    /* get list of candidate quantized pitch gain values     * and corresponding quantization indices     */    gain_pit_index = q_gain_pitch (MR795, gp_limit, gain_pit,                                   g_pitch_cand, g_pitch_cind);                         /*-------------------------------------------------------------------*     *  predicted codebook gain                                          *     *  ~~~~~~~~~~~~~~~~~~~~~~~                                          *     *  gc0     = 2^exp_gcode0 + 2^frac_gcode0                           *     *                                                                   *     *  gcode0 (Q14) = 2^14*2^frac_gcode0 = gc0 * 2^(14-exp_gcode0)      *     *-------------------------------------------------------------------*/    gcode0 = (Word16)Pow2(14, frac_gcode0);          /* Q14 */    /* pre-quantization of codebook gain     * (using three pitch gain candidates);     * result: best guess of pitch gain and code gain     */    MR795_gain_code_quant3(        exp_gcode0, gcode0, g_pitch_cand, g_pitch_cind,        frac_coeff, exp_coeff,        gain_pit, &gain_pit_index, gain_cod, &gain_cod_index,        qua_ener_MR122, qua_ener);    /* calculation of energy coefficients and LTP coding gain */    calc_unfilt_energies(res, exc, code, *gain_pit, L_subfr,                         frac_en, exp_en, &ltpg);    /* run gain adaptor, calculate alpha factor to balance LTP/CB gain     * (this includes the gain adaptor update)     * Note: ltpg = 0 if frac_en[0] == 0, so the update is OK in that case     */    gain_adapt(adapt_st, ltpg, *gain_cod, &alpha);    /* if this is a very low energy signal (threshold: see     * calc_unfilt_energies) or alpha <= 0 then don't run the modified quantizer     */       if (frac_en[0] != 0 && alpha > 0)    {        /* innovation energy <cod cod> was already computed in gc_pred() */        /* (this overwrites the LtpResEn which is no longer needed)      */        frac_en[3] = frac_code_en;                exp_en[3] = exp_code_en;                           /* store optimum codebook gain in Q(10-exp_gcode0) */        exp = cod_gain_exp -exp_gcode0 + 10;       	 gain_cod_unq = exp >0 ? cod_gain_frac<<exp: cod_gain_frac>> -exp;	                 /* run quantization with modified criterion */        gain_cod_index = MR795_gain_code_quant_mod(            *gain_pit, exp_gcode0, gcode0,            frac_en, exp_en, alpha, gain_cod_unq,            gain_cod, qua_ener_MR122, qua_ener);     }    *(*anap)++ = gain_pit_index;           *(*anap)++ = gain_cod_index;      }


/************************************************************************* * *  Function:   gain_adapt() *  Purpose:    calculate pitch/codebook gain adaptation factor alpha *              (and update the adaptor state) * ***************************************************************************/
void gain_adapt(GainAdaptState *st, Word16 ltpg,    Word16 gain_cod,  Word16 *alpha )
{
	Word16 adapt;      /* adaptdation status; 0, 1, or 2       */
	Word16 result;      /* alpha factor, Q13                    */
	Word16 filt;           /* median-filtered LTP coding gain, Q13 */
	Word16 tmp, i,temp[5];

	GainAdaptState *pst = st;

	adapt = (ltpg <= LTP_GAIN_THR1) ? 0 : ((ltpg <= LTP_GAIN_THR2 ) ? 1 : 2);
	tmp = (gain_cod>>1)+(gain_cod&0x1);
	pst->onset = ((tmp > pst->prev_gc ) &&(gain_cod> 200) ) ? 8 : pst->onset - (pst->onset != 0);


	/**  // if onset, increase adaptor state
	*  if (onset && (gainAdapt < 2)) gainAdapt++;*/
	adapt = adapt + ((pst->onset != 0) && (adapt < 2));

	pst->ltpg_mem[0] = ltpg;   

	temp[0] = pst->ltpg_mem[0];temp[1] = pst->ltpg_mem[1];temp[2] = pst->ltpg_mem[2];
	temp[3] = pst->ltpg_mem[3];temp[4] = pst->ltpg_mem[4];

	if(temp[0] < temp[1]) { i = temp[0]; temp[0] = temp[1]; temp[1] = i; };
	if(temp[0] < temp[2]) { i = temp[0]; temp[0] = temp[2]; temp[2] = i; };
	if(temp[0] < temp[3]) { i = temp[0]; temp[0] = temp[3]; temp[3] = i; };
	if(temp[0] < temp[4]) { i = temp[0]; temp[0] = temp[4]; temp[4] = i; };

	if(temp[1] < temp[2]) { i = temp[1]; temp[1] = temp[2]; temp[2] = i; };
	if(temp[1] < temp[3]) { i = temp[1]; temp[1] = temp[3]; temp[3] = i; };
	if(temp[1] < temp[4]) { i = temp[1]; temp[1] = temp[4]; temp[4] = i; };

	if(temp[2] < temp[3]) { i = temp[2]; temp[2] = temp[3]; temp[3] = i; };
	if(temp[2] < temp[4]) { i = temp[2]; temp[2] = temp[4]; temp[4] = i; };

	filt = temp[2];
        if (adapt == 0)
     {
               if ( filt >5443) /* 5443 Q13 = 0.66443... */        {            result = 0;         }        else        {            result = filt < 0 ? 16384 :16384-(24660*(filt<<2)>>15 );

        }    }    else    {        result = 0;    }    /*     *  if (prevAlpha == 0.0) result = 0.5 * (result + prevAlpha);     */   result >>= (pst->prev_alpha == 0);
	
    /* store the result */    *alpha = result;                                  /* update adapter state memory */	pst->prev_alpha = result;                  
	pst->prev_gc = gain_cod;                   
	pst->ltpg_mem[4] = pst->ltpg_mem[3];   
	pst->ltpg_mem[3] = pst->ltpg_mem[2];   
	pst->ltpg_mem[2] = pst->ltpg_mem[1];   
	pst->ltpg_mem[1] = pst->ltpg_mem[0];   


}


Word16 q_gain_pitch ( Mode mode, Word16 gp_limit,  Word16 *gain,Word16 gain_cand[], Word16 gain_cind[]  )
{

	Word16 i, index, err, err_min;
	Word16  *pgain = gain, *pgain_cind = gain_cind, *pgain_cand = gain_cand;
	const Word16 *pqua_gain_pitch = qua_gain_pitch;

	err_min = abs(*pgain -  pqua_gain_pitch[0]);
	index = 0;                                           
    for (i = 1; i < NB_QUA_PITCH; i++)    {               if ( pqua_gain_pitch[i] <= gp_limit)
        {            err = abs (*pgain- pqua_gain_pitch[i]);
                        index     = err < err_min ? i :index;
	     err_min = err<err_min ? err : err_min; 
        }
    }    if (mode == MR795)    {		/* in MR795 mode, compute three gain_pit candidates around the index
		* found in the quantization loop: the index found and the two direct
		* neighbours, except for the extreme cases (i=0 or i=NB_QUA_PITCH-1),
		* where the direct neighbour and the neighbour to that is used.
		*/
		Word16 ii;

		ii = index == 0 ? index : ((index == NB_QUA_PITCH-1)||  (pqua_gain_pitch[index+1]> gp_limit) ? index-2 : index-1);

		/* store candidate indices and values */

		pgain_cind[0] = ii;                             
		pgain_cand[0] = pqua_gain_pitch[ii];            
		ii ++;

		pgain_cind[1] = ii;                             
		pgain_cand[1] = pqua_gain_pitch[ii];            
		ii ++;

		pgain_cind[2] = ii;                             
		pgain_cand[2] = pqua_gain_pitch[ii];            
		ii ++;

		*pgain = pqua_gain_pitch[index];                     
    }    else    {
      *pgain = ( mode == MR122) ? pqua_gain_pitch[index] & 0xFFFC : pqua_gain_pitch[index];

    }    return index;
	
}


/************************************************************************* * * FUNCTION: calc_unfilt_energies * * PURPOSE:  calculation of several energy coefficients for unfiltered *           excitation signals and the LTP coding gain * *       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] = <lres lres> // LTP residual energy *                                            // (lres = res - gain_pit*exc) *       ltpg = log2(LP_res_en / LTP_res_en) * *************************************************************************/void  calc_unfilt_energies(Word16 res[],  Word16 exc[], Word16 code[],  Word16 gain_pit,Word16 L_subfr,  Word16 frac_en[],Word16 exp_en[],  Word16 *ltpg )
{	Word32 s, s1,s2, L_temp;
	Word16 i, exp,exp1,exp2,  tmp,tmp1,tmp2,tmp3;
	Word16 ltp_res_en, pred_gain;
	Word16 ltpg_exp, ltpg_frac;

	Word16 *pres = res,*pfrac_en = frac_en, *pexp_en = exp_en,*pexc = exc,*pcode = code ;

	/* Compute residual energy */
	s =0;

	for (i = 0; i < L_subfr; i++)
	{
		s += pres[i]*pres[i]<<1;

		if(s<0)
		{
		 s = MAX_32; break;
		}

	}

	/* ResEn := 0 if ResEn < 200.0 (= 400 Q1) */
	tmp = s<400L;
	exp = tmp ?  0 : norm_l(s);
	pfrac_en[0] =  (Word16)(tmp ? 0 : ((s<<exp)>>16));
	pexp_en[0] =  tmp ? -15 :  (15 - exp); 

	/* Compute ltp excitation energy */
	s = 0;
	s1 = s2 = 0;
	
	for (i = 0; i < L_subfr; i+=4 )
	{
		s   +=  (pexc[i]*pexc[i] + pexc[i+1]*pexc[i+1]+ pexc[i+2]*pexc[i+2] + pexc[i+3]*pexc[i+3]) <<1;
		s1 +=  (pexc[i]*pcode[i] + pexc[i+1]*pcode[i+1] + pexc[i+2]*pcode[i+2] +pexc[i+3]*pcode[i+3])<<1;

		tmp   =  pres[i] -(((pexc[i]*gain_pit<<2) +0x00008000)>>16);           /* LTP residual, Q0 */
		tmp1 =  pres[i+1] -(((pexc[i+1]*gain_pit<<2) +0x00008000)>>16); 
		tmp2 =  pres[i+2] -(((pexc[i+2]*gain_pit<<2) +0x00008000)>>16); 
		tmp3 =  pres[i+3] -(((pexc[i+3]*gain_pit<<2) +0x00008000)>>16); 

		
		s2 +=  (tmp*tmp + tmp1*tmp1 + tmp2*tmp2 + tmp3*tmp3) <<1;

	}

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

	pfrac_en[1] =  (Word16)((s<< exp)>>16);   
	pexp_en[1] = 15- exp;  
	pfrac_en[2] = (Word16)((s1<<exp1)>>16);  
	pexp_en[2] = 2- exp1; 

	ltp_res_en =(Word16)((s2<<exp2)>>16);
	exp2 = 15 -exp2;
	pfrac_en[3] = ltp_res_en;                
	pexp_en[3] = exp2;                       
    	/* calculate LTP coding gain, i.e. energy reduction LP res -> LTP res */

	if (ltp_res_en > 0 && pfrac_en[0] != 0)
	{
		/* gain = ResEn / LTPResEn */
		pred_gain = div_s ((pfrac_en[0]>>1), ltp_res_en);
		exp2 -= pexp_en[0];

		/* L_temp = ltpGain * 2^(30 + exp) */
		L_temp = (pred_gain<<16);
		L_temp = (exp2 + 3) > 0 ? L_temp>>(exp2+3):(L_temp > (MAX_32 >> (-exp2-3)) ? MAX_32:  L_temp << -(exp2+3) );

		/* Log2 = log2() + 27 */
		Log2(L_temp, &ltpg_exp, &ltpg_frac);
		L_temp = ((ltpg_exp -27)<<16) + (ltpg_frac<<1);

		L_temp = L_temp << 13;
		*ltpg   =  (L_temp > 0)&&(L_temp+0x00008000)<0 ? MAX_16: (L_temp+0x00008000)>>16;
	}
	else
	{
		*ltpg = 0;                        
	}
	
}

⌨️ 快捷键说明

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