📄 gsm610.c
字号:
: 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 + -