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

📄 gsm610.c

📁 GSM6.10 算法优化及详细注释 本代码较原GSM6.10代码更容易理解 仅供学习
💻 C
📖 第 1 页 / 共 3 页
字号:
					: 0x0FFFF & ((word) (( (longword)tmp1 * (longword)tmp2
								 + 16384) >> 15))) ;

			sri  = (word) GSM_SUB( sri, tmp2 );

			/* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) );
			 */
			
			tmp1 =  ( tmp1 == MIN_WORD && sri == MIN_WORD
					? MAX_WORD
					: 0x0FFFF & ((word) (( (longword)tmp1 * (longword)sri
								 + 16384) >> 15))) ;

			v[i+1] = (word) GSM_ADD( v[i], tmp1);
		}
		*s_out++ = v[0] = sri;
	}
}


/*
 * 逆LPC滤波
 */
void Gsm_Short_Term_Analysis_Filter (struct gsm610_state * g_gsm, word * LARc, word * s)
{
	word	* LARpp_j	= g_gsm->LARpp; /* 前一帧LARp[0..7];*/

	word	LARp[8],LARpp_j_1[8];
	int		i;

	for (i = 0; i < 8; i++)
		LARpp_j_1[i] = LARpp_j[i];

	Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j );
	
	/* 分析0..12位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,0);
	LARp_to_rp( LARp );
	Short_term_analysis_filtering(g_gsm, LARp, 13, s);
	
	/* 分析13..26位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,1);
	LARp_to_rp( LARp );
	Short_term_analysis_filtering(g_gsm, LARp, 14, s+13);

	/* 分析27..39位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,2);
	LARp_to_rp( LARp );
	Short_term_analysis_filtering(g_gsm, LARp, 13, s+27);

	/* 分析40..159位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,3);
	LARp_to_rp( LARp );
	Short_term_analysis_filtering(g_gsm, LARp, 120, s+40);

}

/*
 * 输入:LARcr[0..7]8个自相关系数,wt[0..159]160个未分析值
 * 输出:s_out[0..159]根据自相关系数短期相关合成值
 * Gsm_Short_Term_Analysis_Filter()的逆过程
 */
void Gsm_Short_Term_Synthesis_Filter (struct gsm610_state * g_gsm, word * LARcr, word * wt, word * s_out)
{
	word	* LARpp_j	= g_gsm->LARpp; /* 前一帧LARp[0..7];*/
	word	LARp[8],LARpp_j_1[8];
	int		i;

	for (i = 0; i < 8; i++)
		LARpp_j_1[i] = LARpp_j[i];

	Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j );
	
	/* 合成0..12位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,0);
	LARp_to_rp( LARp );
	Short_term_synthesis_filtering(g_gsm, LARp, 13, wt, s_out );
	
	/* 合成13..26位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,1);
	LARp_to_rp( LARp );
	Short_term_synthesis_filtering(g_gsm, LARp, 14, wt + 13, s_out + 13);

	/* 合成27..39位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,2);
	LARp_to_rp( LARp );
	Short_term_synthesis_filtering(g_gsm, LARp, 13, wt + 27, s_out + 27);

	/* 合成40..159位数 */
	Coefficients(LARpp_j_1,LARpp_j,LARp,3);
	LARp_to_rp( LARp );
	Short_term_synthesis_filtering(g_gsm, LARp, 120, wt +40, s_out + 40);
}

/**************************Short Term Analysis(结束)*********************************************/
/************************************************************************************************/
/*****************************LTP分析(开始)******************************************************/

/* 
 * 输入:d[0..39]:一子帧数据值,dp[-120..-1]:前三个子帧的估计值
 * 输出:bc_out:增益值,Nc_out: 滞后值
 * 将当前子帧数据与前三帧的共120估计值从-120到-40比较81次,取相关最大的一个子帧,Nc为该子帧起止位置+120
 * bj=bj= Rj(Nj) / Sj(Nj);Rj=L_max,sj=L_power
 */
static void Calculation_of_the_LTP_parameters (register word * d, register word	* dp, word * bc_out, word * Nc_out)
{
	register int	k, lambda;
	word			Nc, bc;
	word			wt[40];

	longword		L_max, L_power;
	word			R, S, dmax, scal;
	register word	temp;
	register longword L_temp;  
  
	/* 求一子帧数据最大值 */
	dmax = 0;
	for ( k=0; k<40; k++)
	{
		temp = d[k];
		temp = GSM_ABS( temp );
		if (temp > dmax)
			dmax = temp;
	}
	
	/* 获得最大值dmax量化值temp(越大量化值越小),交计算须右移的位数保证下面计算不溢出 */
	temp = 0;
	if (0 == dmax)
		scal = 0;
	else
	{
		assert( dmax > 0);
		temp = gsm_norm((longword) dmax << 16);
	}
	
	if (temp > 6) 
		scal = 0;
	else 
		scal = 6 - temp;
	
	assert(scal >= 0);
	for (k = 0; k <= 39; k++) 
		wt[k] = SASR( d[k], scal ); /* Initialization of a working array wt,右移保证计算值不溢出 */
	
	/* 初始化默认Nc,为最近的一子帧数据相关最大
	   计算获得∑dp[k-lambda]*d[k] k=0..39,lambda=40..120的最大值;取Nc=lambda */
	L_max = 0;
	Nc	  = 40;						
	for (lambda = 40; lambda <= 120; lambda++)
	{
		L_temp = 0;
		for (k = 0; k < 40; k++)
			L_temp = L_temp + (longword)dp[k-lambda] * wt[k];
		if ( L_temp > L_max)
		{
			L_max = L_temp;
			Nc = (word)lambda;
		}
	}
	*Nc_out = Nc;
	L_max <<= 1;
	assert(scal <= 6 && scal >=  0);
	L_max >>= (6-scal);   /*L_max先左移1位再右移6位*/
	
	assert( Nc <= 120 && Nc >= 40);

	/*	 Compute the power of the reconstructed short term residual
	 *	 signal dp[..]
	 */
	L_power = 0;
	for (k = 0; k < 40; k++) 
	{
		L_temp	 = SASR( dp[k - Nc], 3 );  /* 确保值不溢出 */
		L_power += L_temp * L_temp;
	}
	L_power <<= 1;	/* from L_MULT */
	
	if (L_max <= 0)		/* Rj(Nj) / Sj(Nj) <= 0 */
	{
			*bc_out = 0;
			return;
	}
	if (L_max >= L_power)	/* Rj(Nj) / Sj(Nj) >= 1 */
	{
			*bc_out = 3;
			return;
	}

	/* L_max,L_power都左移至最高位,减少误差 */
	temp = gsm_norm( L_power );  
	R = (word) (SASR( L_max   << temp, 16 ));
	S = (word) (SASR( L_power << temp, 16 ));

	/* 根据bj的值不同情况确定bc输出的值;
	   bj<02 bc=0; 0.2<bj<0.5 bc=1; 0.5<bj<08 bc=2; 0.8<bj bc=3 */
	for (k = 0; k < 4; k++)
	{
		if (R <= gsm_mult(S, gsm_DLB[k]))
		{
			bc = (word)k;
			break;
		}
	}
	*bc_out = bc;
}


/* 
 * 输入:bc 增益,Nc 滞后,dp[-120..-1]前面三个子帧的估计值, d[0..40]当前子帧
 * 输出:dpp[0..39]根据dp,bc,Nc计算当前子帧的估计值,e[0..39]当前子帧d[k]-dpp[k]的差分值
 * 计算差分e[0..39],dpp[k]=dp[k-Nc]*gsm_QLB[bc];e[k]=d[k]-dpp[k]
 * In this part, we have to decode the bc parameter to compute
 * the samples of the estimate dpp[0..39].  The decoding of bc needs the
 * use of table 4.3b.	The long term residual signal e[0..39]
 * is then calculated to be fed to the RPE encoding section.
 */
static void Long_term_analysis_filtering (word	bc, word Nc, register word * dp, register word *d, register word * dpp, register word * e)
{
	register int	  k;
	register longword ltmp;
	
	for ( k = 0; k < 40; k++)
	{
		dpp[k] = (word) (GSM_MULT_R( gsm_QLB[bc], dp[k-Nc]));
		e[k] = (word) (GSM_SUB( d[k], dpp[k]));
	}
}

/*
 * 输入:Ncr LTP分析滞后值,bcr LTP分析增益值,erp[0..39]一个子帧的差分值,drp[-120..-1]前三个子帧的估计值
 * 输出:drp[0..39]该子帧的估计值
 * 根据Ncr,bcr,erp[0..39]差分值,drp[-120..-1]前三个子帧的估计值,由drp[k]=drp[k-Ncr]*gsm_QLB[bcr]+erp[k]求drp[0..39]
 * This procedure uses the bcr and Ncr parameter to realize the
 * long term synthesis filtering.	The decoding of bcr needs
 */
void Gsm_Long_Term_Synthesis_Filtering (struct gsm610_state * g_gsm, word Ncr, word bcr, register word * erp, register word * drp)
{
	register longword	ltmp;			/* for ADD */
	word				Nr;				/* LTP滞后值缓存 */
	word				brp;			/* LTP增益值 */
	word				drpp;			/* 估计值 */
	register int		k;
	if ( Ncr < 40 || Ncr > 120)
		Nr = g_gsm->nrp;
	else
	{
		Nr = Ncr;
		g_gsm->nrp =Nr;
	}
	assert(Nr >= 40 && Nr <= 120);

	brp = gsm_QLB[bcr];

	/*	Computation of the reconstructed short term residual 
	 *	signal drp[0..39]
	 */
	assert(brp != MIN_WORD);

	for (k = 0; k < 40; k++) 
	{
		drpp   = (word) (GSM_MULT_R( brp, drp[ k - Nr ]));
		drp[k] = (word) (GSM_ADD( erp[k], drpp));
	}
	
	/* 更新前三个子帧估计值 */
	for (k = 0;  k < 120; k++)
		drp[ -120 + k ] = drp[ -80 + k ];
}

/*
 * d:   [0..39]	 residual signal	IN  子帧信号
 * dp:  [-120..-1] d'               IN	前3个子帧估计信号
 * e:   [0..39]						out	差分
 * dpp  [0..39]	   d''				out	
 * Nc			   correlation lag  out	滞后
 * bc			   gain factor      out 增益
 */
void Gsm_Long_Term_Predictor (  struct gsm610_state * g_gsm, word * d,  word * dp,  word * e,  word * dpp,  word * Nc,  word * bc )
{
	assert( d  ); assert( dp ); assert( e  );
    assert( dpp); assert( Nc ); assert( bc );

	Calculation_of_the_LTP_parameters( d, dp, bc, Nc );

	Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
}

/****************************LTP分析(结束)*******************************************************/
/************************************************************************************************/
/***************************RPE Code(开始)*******************************************************/

/* 
 * 输入: e[-5..44]差分值,有效值为e[0..39]
 * 输出: x[0..39]可理解为根据gsm_h[i]细化e[0..39]
 * The coefficients of the weighting filter are stored in a table
 */
static void Weighting_filter (register word * e, word * x)
{
	register longword		L_result;
	register int			k,i;

	e -= 5;

	/*	Compute the signal x[0..39]
	 */ 
	for (k = 0; k < 40; k++)
	{
		L_result = 0;
		for (i = 0; i < 11; i++)
			L_result = L_result + (e[k + i]) * ((long)gsm_H[i]);
		
		L_result = L_result + 4096; /*为下面右移13位(2^13=8192)做四舍五入*/
		L_result = SASR( L_result, 13 );
		
		if (L_result < MIN_WORD)
			x[k] = MIN_WORD;
		else if (L_result > MAX_WORD)
			x[k] = MAX_WORD;
		else 
			x[k] = (word)L_result;
	}
}

/* 
 * 输入: x[0..39]40个差分值
 * 输出: x[0..12]最接近40个差分值的的子序列数值,Mc_out子序列栅格位置
 * 将40个数据分成[0,3,..36],[1,4..37],[2,5..38],[3,6..39]四个子序列,
 * 并计算分析取最接近40个数据的子序列
 * The signal x[0..39] is used to select the RPE grid which is
 * represented by Mc.
 */
static void RPE_grid_selection (word * x, word * xM, word * Mc_out)
{
	register int			i,k;
	register longword		L_result, L_temp ,L_max;
	word					Mc;

	Mc = 0;
	L_max = 0;

	/* 计算四个子序列最接近原数据的序列栅格位置(序号0..3) */
	for (i = 0; i < 4; i++)
	{
		L_result = 0;
		
		for (k = 0; k <= 36; k += 3)
		{
			L_temp = SASR( x[k + i], 2 ); /* 确保计算结果不溢出 */
			L_result = L_result + L_temp * L_temp; 
		}
		
		if (L_result > L_max)
		{
			L_max = L_result;
			Mc = (word)i;     /* 栅格位置 */
		}
	}

	/* 将计算确定的子序列数据输出 */
	for (i = 0; i < 13; i++)
		 xM[i] = x[Mc + 3*i];
	
	*Mc_out = Mc;
}

/*
 * 输入:xmaxc 子序列最大值的量化值
 * 输出:exp_out 计算xmaxc的指数,mant_out 尾数
 * 计算指数与尾数的作用为下面量化xM[0..12]输出xMc[0..12],xMc值为0-7;
 */
	
static void APCM_quantization_xmaxc_to_exp_mant (word xmaxc, word * exp_out, word * mant_out)
{
	word	exp, mant;

	/* Compute exponent and mantissa of the decoded version of xmaxc
	 */
	exp = 0;
	if (xmaxc > 15)
		exp = SASR(xmaxc, 3) - 1;
	mant = xmaxc - (exp << 3);
	
	if (mant == 0) 
	{
		exp  = -4;
		mant = 7;
	}
	else 
	{
		while (mant <= 7)
		{
			mant = mant << 1 | 1;;
			exp--;
		}
		mant -= 8;
	}

	assert( exp  >= -4 && exp <= 6 );
	assert( mant >= 0 && mant <= 7 );

	*exp_out  = exp;
	*mant_out = mant;
}


/*
 * 输入:xM[0..12]13个子序列值
 * 输出:xMc[0..12]13个子序列的量化值,mant_out尾数,exp_out指数,xmaxc_out子序列最大值量化值
 * 首先比较取得13个子序列数据的最大值xmax,将xmax量化为xmaxc 0-63;并将xM/xmax量化为0-7,0-3为负,4-7为正
 * 输出自适应量化值xMc[0..12]为xm[0..12]/xmax的量化值
 */
static void APCM_quantization (word * xM, word * xMc, word * mant_out, word * exp_out, word * xmaxc_out)
{
	word	xmax;  /* 最大值 */
	word	xmaxc; /* 最大值量化值 */
	word	exp;   /* 量化指数 */
	word	mant;  /* 量化尾数 */
	word	temp, temp1, temp2;
	int		i;

	xmax = 0;
	for (i = 0; i < 13; i++)
	{
		temp = xM[i];
		temp = GSM_ABS(temp);
		if ( temp > xmax)
			xmax = temp;
	}
	
	exp = 0;
	temp = SASR( xmax, 9);
	
	while (temp > 0)
	{
		assert(exp < 6); /* 最大值为32767 */
		exp ++;
		temp = SASR(temp, 1);
	}

	assert(exp <= 6 && exp >= 0);
	temp = exp + 5;
	xmaxc = gsm_add( (word) SASR(xmax, temp), (word) (exp << 3) ); /* 计算xmax量化值 */
	
	APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );

	/*	This computation uses the fact that the decoded version of xmaxc
	 *	can be calculated by using the exponent and the mantissa part of
	 *	xmaxc (logarithmic table).
	 *	So, this method avoids any division and uses only a scaling
	 *	of the RPE samples by a function of the exponent.  A direct 
	 *	multiplication by the inverse of the mantissa (NRFAC[0..7]
	 *	found in table 4.5) gives the 3 bit coded version xMc[0..12]
	 *	of the RPE samples.
	 */

	assert( exp <= 6 && exp >= -4);
	assert( mant >= 0 && mant <= 7 ); 

	temp1 = 6 - exp;				/* normalization by the exponent */
	temp2 = gsm_NRFAC[ mant ];		/* inverse mantissa 			 */

	for (i = 0; i <= 12; i++) 
	{
		assert(temp1 >= 0 && temp1 < 16);

⌨️ 快捷键说明

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