📄 gsm610.c
字号:
{
UINT i;
SHORT temp;
for (i=1; i<=8; i++)
{
temp = mult(A[i], LAR[i]);
temp = add(temp, B[i]);
temp = add(temp, 256);
LARc[i] = temp >> 9;
// Check if LARc[i] between MIN and MAX
if (LARc[i] > MAC[i]) LARc[i] = MAC[i];
if (LARc[i] < MIC[i]) LARc[i] = MIC[i];
// This is used to make all LARc positive
LARc[i] = sub(LARc[i], MIC[i]);
}
return;
}
//---------------------------------------------------------------------
//
// encodeLPCFilter()
//
//---------------------------------------------------------------------
void encodeLPCFilter(PSTREAMINSTANCE psi, LPSHORT LARc, LPSHORT s, LPSHORT d)
{
SHORT LARpp[9]; // array [1..8]
SHORT LARp1[9], LARp2[9], LARp3[9], LARp4[9]; // array [1..8]
SHORT rp[9]; // array [1..8]
CompLARpp(psi, LARc, LARpp);
CompLARp(psi, LARpp, LARp1, LARp2, LARp3, LARp4);
Comprp(psi, LARp1, rp);
Compd(psi, (LPSHORT)rp, s, d, 0, 12);
Comprp(psi, LARp2, rp);
Compd(psi, (LPSHORT)rp, s, d, 13, 26);
Comprp(psi, LARp3, rp);
Compd(psi, (LPSHORT)rp, s, d, 27, 39);
Comprp(psi, LARp4, rp);
Compd(psi, (LPSHORT)rp, s, d, 40, 159);
return;
}
//---------------------------------------------------------------------
//
// CompLARpp()
//
//---------------------------------------------------------------------
void CompLARpp(PSTREAMINSTANCE psi, LPSHORT LARc, LPSHORT LARpp)
{
UINT i;
SHORT temp1, temp2;
for (i=1; i<=8; i++)
{
temp1 = add(LARc[i], MIC[i]) << 10;
temp2 = B[i] << 1;
temp1 = sub(temp1,temp2);
temp1 = mult_r(INVA[i], temp1);
LARpp[i] = add(temp1, temp1);
}
return;
}
//---------------------------------------------------------------------
//
// CompLARp()
//
//---------------------------------------------------------------------
void CompLARp(PSTREAMINSTANCE psi, LPSHORT LARpp, LPSHORT LARp1, LPSHORT LARp2, LPSHORT LARp3, LPSHORT LARp4)
{
UINT i;
for (i=1; i<=8; i++)
{
LARp1[i] = add( (SHORT)(psi->OldLARpp[i] >> 2), (SHORT)(LARpp[i] >> 2) );
LARp1[i] = add( LARp1[i], (SHORT)(psi->OldLARpp[i] >> 1) );
LARp2[i] = add( (SHORT)(psi->OldLARpp[i] >> 1), (SHORT)(LARpp[i] >> 1) );
LARp3[i] = add( (SHORT)(psi->OldLARpp[i] >> 2), (SHORT)(LARpp[i] >> 2) );
LARp3[i] = add( LARp3[i], (SHORT)(LARpp[i] >> 1) );
LARp4[i] = LARpp[i];
}
for (i=1; i<=8; i++)
{
psi->OldLARpp[i] = LARpp[i];
}
return;
}
//---------------------------------------------------------------------
//
// Comprp()
//
//---------------------------------------------------------------------
void Comprp(PSTREAMINSTANCE psi, LPSHORT LARp, LPSHORT rp)
{
UINT i;
SHORT temp;
for (i=1; i<=8; i++)
{
temp = gabs(LARp[i]);
if (temp < 11059)
{
temp = temp << 1;
}
else if (temp < 20070)
{
temp = add(temp, 11059);
}
else
{
temp = add((SHORT)(temp>>2), 26112);
}
rp[i] = temp;
if (LARp[i] < 0)
{
rp[i] = sub(0,rp[i]);
}
}
return;
}
//---------------------------------------------------------------------
//
// Compd()
//
//---------------------------------------------------------------------
void Compd(PSTREAMINSTANCE psi, LPSHORT rp, LPSHORT s, LPSHORT d, UINT k_start, UINT k_end)
{
UINT k, i;
SHORT sav;
SHORT di;
SHORT temp;
for (k=k_start; k<=k_end; k++)
{
di = s[k];
sav = di;
for (i=1; i<=8; i++)
{
temp = add( psi->u[i-1], mult_r(rp[i],di) );
di = add( di, mult_r(rp[i], psi->u[i-1]) );
psi->u[i-1] = sav;
sav = temp;
}
d[k] = di;
}
return;
}
//---------------------------------------------------------------------
//
// encodeLTPAnalysis()
//
//---------------------------------------------------------------------
void encodeLTPAnalysis(PSTREAMINSTANCE psi, LPSHORT d, LPSHORT pNc, LPSHORT pbc)
{
SHORT dmax;
SHORT temp;
SHORT scal;
SHORT wt[40];
SHORT lambda;
LONG l_max, l_power;
SHORT R, S;
SHORT Nc;
int k; // k must be int, not UINT!
Nc = *pNc;
// Search of the optimum scaling of d[0..39]
dmax = 0;
for (k=39; k>=0; k--)
{
temp = gabs( d[k] );
if (temp > dmax) dmax = temp;
}
temp = 0;
if (dmax == 0) scal = 0;
else temp = norm( ((LONG)dmax) << 16);
if (temp > 6) scal = 0;
else scal = sub(6,temp);
// Init of working array wt[0..39]
ASSERT( scal >= 0 );
for (k=39; k>=0; k--)
{
wt[k] = d[k] >> scal;
}
// Search for max cross-correlation and coding of LTP lag
l_max = 0;
Nc = 40;
for (lambda=40; lambda<=120; lambda++)
{
register LONG l_result = 0;
for (k=39; k>=0; k--)
{
l_result += (LONG)(wt[k]) * (LONG)(psi->dp[120-lambda+k]);
}
if (l_result > l_max)
{
Nc = lambda;
l_max = l_result;
}
}
l_max <<= 1; // This operation should be on l_result as part of the
// multiply/add, but for efficiency we shift it all
// the way out of the loops.
// Rescaling of l_max
ASSERT( sub(6,scal) >= 0 );
l_max = l_max >> sub(6,scal);
// Compute the power of the reconstructed short term residual
// signal dp[..].
l_power = 0;
{
SHORT s;
for (k=39; k>=0; k--)
{
s = psi->dp[120-Nc+k] >> 3;
l_power += s*s; // This sum can never overflow!!!
}
ASSERT( l_power >= 0 );
if( l_power >= 1073741824 ) { // 2**30
l_power = 2147483647; // 2**31 - 1
} else {
l_power <<= 1; // This shift is normally part of l_mult().
}
}
*pNc = Nc;
// Normalization of l_max and l_power
if (l_max <= 0)
{
*pbc = 0;
return;
}
if (l_max >= l_power)
{
*pbc = 3;
return;
}
temp = norm(l_power);
ASSERT( temp >= 0 );
R = (SHORT) ((l_max<<temp) >> 16);
S = (SHORT) ((l_power<<temp) >> 16);
// Codeing of the LTP gain
for ( *pbc=0; *pbc<=2; (*pbc)++ )
{
if (R <= mult(S, DLB[*pbc]))
{
return;
}
}
*pbc = 3;
return;
}
//---------------------------------------------------------------------
//
// encodeLTPFilter()
//
//---------------------------------------------------------------------
void encodeLTPFilter(PSTREAMINSTANCE psi, SHORT bc, SHORT Nc, LPSHORT d, LPSHORT e, LPSHORT dpp)
{
SHORT bp;
UINT k;
// Decoding of the coded LTP gain
bp = QLB[bc];
// Calculating the array e[0..39] and the array dpp[0..39]
for (k=0; k<=39; k++)
{
dpp[k] = mult_r(bp, psi->dp[120+k-Nc]);
e[k] = sub(d[k], dpp[k]);
}
return;
}
//---------------------------------------------------------------------
//
// encodeRPE()
//
//---------------------------------------------------------------------
void encodeRPE(PSTREAMINSTANCE psi, LPSHORT e, LPSHORT pMc, LPSHORT pxmaxc, LPSHORT xMc, LPSHORT ep)
{
SHORT x[40];
SHORT xM[13];
SHORT exp, mant;
SHORT xMp[13];
WeightingFilter(psi, e, x);
RPEGridSelect(psi, x, pMc, xM);
APCMQuantize(psi, xM, pxmaxc, xMc, &exp, &mant);
APCMInvQuantize(psi, exp, mant, xMc, xMp);
RPEGridPosition(psi, *pMc, xMp, ep);
return;
}
//---------------------------------------------------------------------
//
// WeightingFilter()
//
//---------------------------------------------------------------------
void WeightingFilter(PSTREAMINSTANCE psi, LPSHORT e, LPSHORT x)
{
UINT i, k;
LONG l_result, l_temp;
SHORT wt[50];
// Initialization of a temporary working array wt[0..49]
for (k= 0; k<= 4; k++) wt[k] = 0;
for (k= 5; k<=44; k++) wt[k] = e[k-5];
for (k=45; k<=49; k++) wt[k] = 0;
// Compute the signal x[0..39]
for (k=0; k<=39; k++)
{
l_result = 8192; // rounding of the output of the filter
for (i=0; i<=10; i++)
{
l_temp = l_mult(wt[k+i], H[i]);
l_result = l_add(l_result, l_temp);
}
l_result = l_add(l_result, l_result); // scaling x2
l_result = l_add(l_result, l_result); // scaling x4
x[k] = (SHORT) (l_result >> 16);
}
return;
}
//---------------------------------------------------------------------
//
// RPEGridSelect()
//
//---------------------------------------------------------------------
void RPEGridSelect(PSTREAMINSTANCE psi, LPSHORT x, LPSHORT pMc, LPSHORT xM)
{
UINT m, i;
LONG l_EM;
SHORT temp1;
LONG l_result, l_temp;
// the signal x[0..39] is used to select the RPE grid which is
// represented by Mc
l_EM = 0;
*pMc = 0;
for (m=0; m<=3; m++)
{
l_result = 0;
for (i=0; i<=12; i++)
{
temp1 = x[m+(3*i)] >> 2;
l_temp = l_mult(temp1, temp1);
l_result = l_add(l_temp, l_result);
}
if (l_result > l_EM)
{
*pMc = (SHORT)m;
l_EM = l_result;
}
}
// down-sampling by a factor of 3 to get the selected xM[0..12]
// RPE sequence
for (i=0; i<=12; i++)
{
xM[i] = x[*pMc + (3*i)];
}
return;
}
//---------------------------------------------------------------------
//
// APCMQuantize()
//
//---------------------------------------------------------------------
void APCMQuantize(PSTREAMINSTANCE psi, LPSHORT xM, LPSHORT pxmaxc, LPSHORT xMc, LPSHORT pexp, LPSHORT pmant)
{
UINT i;
SHORT xmax;
SHORT temp;
SHORT itest;
SHORT temp1, temp2;
// find the maximum absolute value xmax or xM[0..12]
xmax = 0;
for (i=0; i<=12; i++)
{
temp = gabs(xM[i]);
if (temp > xmax) xmax = temp;
}
// quantizing and coding of xmax to get xmaxc
*pexp = 0;
temp = xmax >> 9;
itest = 0;
for (i=0; i<=5; i++)
{
if (temp <=0) itest = 1;
temp = temp >> 1;
if (itest == 0) *pexp = add(*pexp,1);
}
temp = add(*pexp,5);
*pxmaxc = add( (SHORT)BITSHIFTRIGHT(xmax,temp), (SHORT)(*pexp << 3) );
//
// quantizing and coding of the xM[0..12] RPE sequence to get
// the xMc[0..12]
//
// compute exponent and mantissa of the decoded version of xmaxc
*pexp = 0;
if (*pxmaxc > 15) *pexp = sub((SHORT)(*pxmaxc >> 3),1);
*pmant = sub(*pxmaxc,(SHORT)(*pexp<<3));
// normalize mantissa 0 <= mant <= 7
if (*pmant==0)
{
*pexp = -4;
*pmant = 15;
}
else
{
itest = 0;
for (i=0; i<=2; i++)
{
if (*pmant > 7) itest = 1;
if (itest == 0) *pmant = add((SHORT)(*pmant << 1),1);
if (itest == 0) *pexp = sub(*pexp,1);
}
}
*pmant = sub(*pmant,8);
// direct computation of xMc[0..12] using table
temp1 = sub(6,*pexp); // normalization by the exponent
temp2 = NRFAC[*pmant]; // see table (inverse mantissa)
for (i=0; i<=12; i++)
{
temp = BITSHIFTLEFT(xM[i], temp1);
temp = mult( temp, temp2 );
xMc[i] = add( (SHORT)(temp >> 12), 4 ); // makes all xMc[i] positive
}
return;
}
//---------------------------------------------------------------------
//
// APCMInvQuantize()
//
//---------------------------------------------------------------------
void APCMInvQuantize(PSTREAMINSTANCE psi, SHORT exp, SHORT mant, LPSHORT xMc, LPSHORT xMp)
{
SHORT temp1, temp2, temp3, temp;
UINT i;
temp1 = FAC[mant];
temp2 = sub(6,exp);
temp3 = BITSHIFTLEFT(1, sub(temp2,1));
for (i=0; i<=12; i++)
{
temp = sub( (SHORT)(xMc[i] << 1), 7); // restores sign of xMc[i]
temp = temp << 12;
temp = mult_r(temp1, temp);
temp = add(temp, temp3);
xMp[i] = BITSHIFTRIGHT(temp,temp2);
}
return;
}
//---------------------------------------------------------------------
//
// RPEGridPosition(SHORT Mc, LPSHORT xMp, LPSHORT ep)
//
//---------------------------------------------------------------------
void RPEGridPosition(PSTREAMINSTANCE psi, SHORT Mc, LPSHORT xMp, LPSHORT ep)
{
UINT k, i;
for (k=0; k<=39; k++)
{
ep[k] = 0;
}
for (i=0; i<=12; i++)
{
ep[Mc + (3*i)] = xMp[i];
}
return;
}
//---------------------------------------------------------------------
//
// encodeUpdate()
//
//---------------------------------------------------------------------
void encodeUpdate(PSTREAMINSTANCE psi, LPSHORT ep, LPSHORT dpp)
{
UINT k;
for (k=0; k<=79; k++)
psi->dp[120-120+k] = psi->dp[120-80+k];
for (k=0; k<=39; k++)
psi->dp[120-40+k] = add(ep[k], dpp[k]);
return;
}
//=====================================================================
//=====================================================================
//
// Decode routines
//
//=====================================================================
//=====================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -