📄 gsm610.c
字号:
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//
// Function protos
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
EXTERN_C void Compsr(PSTREAMINSTANCE psi, LPSHORT wt, LPSHORT rrp, UINT k_start, UINT k_end, LPSHORT sr);
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//
// Procedures
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//
// UnpackFrame0
//
//---------------------------------------------------------------------
void UnpackFrame0
(
BYTE FAR ab[],
SHORT FAR LAR[],
SHORT FAR N[],
SHORT FAR b[],
SHORT FAR M[],
SHORT FAR Xmax[],
XM FAR X[]
)
{
UINT i;
// Unpack the LAR[1..8] from the first 4.5 bytes
LAR[1] = (ab[0] & 0x3F);
LAR[2] = ((ab[0] & 0xC0) >> 6) | ((ab[1] & 0x0F) << 2);
LAR[3] = ((ab[1] & 0xF0) >> 4) | ((ab[2] & 0x01) << 4);
LAR[4] = ((ab[2] & 0x3E) >> 1);
LAR[5] = ((ab[2] & 0xC0) >> 6) | ((ab[3] & 0x03) << 2);
LAR[6] = ((ab[3] & 0x3C) >> 2);
LAR[7] = ((ab[3] & 0xC0) >> 6) | ((ab[4] & 0x01) << 2);
LAR[8] = ((ab[4] & 0x0E) >> 1);
// Unpack N, b, M, Xmax, and X for each of the four sub-frames
for (i=0; i<4; i++)
{
// A convenient macro for getting bytes out of the array for
// construction of the subframe parameters
#define sfb(x) (ab[4+i*7+x])
N[i] = ((sfb(0) & 0xF0) >> 4) | ((sfb(1) & 0x07) << 4);
b[i] = ((sfb(1) & 0x18) >> 3);
M[i] = ((sfb(1) & 0x60) >> 5);
Xmax[i] = ((sfb(1) & 0x80) >> 7) | ((sfb(2) & 0x1F) << 1);
X[i][0] = ((sfb(2) & 0xE0) >> 5);
X[i][1] = (sfb(3) & 0x07);
X[i][2] = ((sfb(3) & 0x3C) >> 3);
X[i][3] = ((sfb(3) & 0xC0) >> 6) | ((sfb(4) & 0x01) << 2);
X[i][4] = ((sfb(4) & 0x0E) >> 1);
X[i][5] = ((sfb(4) & 0x70) >> 4);
X[i][6] = ((sfb(4) & 0x80) >> 7) | ((sfb(5) & 0x03) << 1);
X[i][7] = ((sfb(5) & 0x1C) >> 2);
X[i][8] = ((sfb(5) & 0xE0) >> 5);
X[i][9] = (sfb(6) & 0x07);
X[i][10] = ((sfb(6) & 0x38) >> 3);
X[i][11] = ((sfb(6) & 0xC0) >> 6) | ((sfb(7) & 0x01) << 2);
X[i][12] = ((sfb(7) & 0x0E) >> 1);
#undef sfb
}
return;
}
//---------------------------------------------------------------------
//
// UnpackFrame1
//
//---------------------------------------------------------------------
void UnpackFrame1
(
BYTE FAR ab[],
SHORT FAR LAR[],
SHORT FAR N[],
SHORT FAR b[],
SHORT FAR M[],
SHORT FAR Xmax[],
XM FAR X[]
)
{
UINT i;
// Unpack the LAR[1..8] from the first 4.5 bytes
LAR[1] = ((ab[32] & 0xF0) >> 4) | ((ab[33] & 0x03) << 4);
LAR[2] = ((ab[33] & 0xFC) >> 2);
LAR[3] = ((ab[34] & 0x1F) );
LAR[4] = ((ab[34] & 0xE0) >> 5) | ((ab[35] & 0x03) << 3);
LAR[5] = ((ab[35] & 0x3C) >> 2);
LAR[6] = ((ab[35] & 0xC0) >> 6) | ((ab[36] & 0x03) << 2);
LAR[7] = ((ab[36] & 0x1C) >> 2);
LAR[8] = ((ab[36] & 0xE0) >> 5);
// Unpack N, b, M, Xmax, and X for each of the four sub-frames
for (i=0; i<4; i++)
{
// A convenient macro for getting bytes out of the array for
// construction of the subframe parameters
#define sfb(x) (ab[37+i*7+x])
N[i] = sfb(0) & 0x7F;
b[i] = ((sfb(0) & 0x80) >> 7) | ((sfb(1) & 0x01) << 1);
M[i] = ((sfb(1) & 0x06) >> 1);
Xmax[i] = ((sfb(1) & 0xF8) >> 3) | ((sfb(2) & 0x01) << 5);
X[i][0] = ((sfb(2) & 0x0E) >> 1);
X[i][1] = ((sfb(2) & 0x70) >> 4);
X[i][2] = ((sfb(2) & 0x80) >> 7) | ((sfb(3) & 0x03) << 1);
X[i][3] = ((sfb(3) & 0x1C) >> 2);
X[i][4] = ((sfb(3) & 0xE0) >> 5);
X[i][5] = ((sfb(4) & 0x07) );
X[i][6] = ((sfb(4) & 0x38) >> 3);
X[i][7] = ((sfb(4) & 0xC0) >> 6) | ((sfb(5) & 0x01) << 2);
X[i][8] = ((sfb(5) & 0x0E) >> 1);
X[i][9] = ((sfb(5) & 0x70) >> 4);
X[i][10] = ((sfb(5) & 0x80) >> 7) | ((sfb(6) & 0x03) << 1);
X[i][11] = ((sfb(6) & 0x1C) >> 2);
X[i][12] = ((sfb(6) & 0xE0) >> 5);
#undef sfb
}
return;
}
//---------------------------------------------------------------------
//
// decodeRPE()
//
//---------------------------------------------------------------------
void decodeRPE(PSTREAMINSTANCE psi, SHORT Mcr, SHORT xmaxcr, LPSHORT xMcr, LPSHORT erp)
{
SHORT exp, mant;
SHORT itest;
UINT i;
SHORT temp1, temp2, temp3, temp;
SHORT xMrp[13];
UINT k;
// compute the exponent and mantissa of the decoded
// version of xmaxcr
exp = 0;
if (xmaxcr > 15) exp = sub( (SHORT)(xmaxcr >> 3), 1 );
mant = sub( xmaxcr, (SHORT)(exp << 3) );
// normalize the mantissa 0 <= mant <= 7
if (mant == 0)
{
exp = -4;
mant = 15;
}
else
{
itest = 0;
for (i=0; i<=2; i++)
{
if (mant > 7) itest = 1;
if (itest == 0) mant = add((SHORT)(mant << 1),1);
if (itest == 0) exp = sub(exp,1);
}
}
mant = sub(mant, 8);
// APCM inverse quantization
temp1 = FAC[mant];
temp2 = sub(6,exp);
temp3 = BITSHIFTLEFT(1, sub(temp2, 1));
for (i=0; i<=12; i++)
{
temp = sub( (SHORT)(xMcr[i] << 1), 7 );
temp = temp << 12;
temp = mult_r(temp1, temp);
temp = add(temp, temp3);
xMrp[i] = BITSHIFTRIGHT(temp, temp2);
}
// RPE grid positioning
for (k=0; k<=39; k++) erp[k] = 0;
for (i=0; i<=12; i++) erp[Mcr + (3*i)] = xMrp[i];
//
return;
}
//---------------------------------------------------------------------
//
// decodeLTP()
//
//---------------------------------------------------------------------
void decodeLTP(PSTREAMINSTANCE psi, SHORT bcr, SHORT Ncr, LPSHORT erp)
{
SHORT Nr;
SHORT brp;
UINT k;
SHORT drpp;
// check limits of Nr
Nr = Ncr;
if (Ncr < 40) Nr = psi->nrp;
if (Ncr > 120) Nr = psi->nrp;
psi->nrp = Nr;
// decoding of the LTP gain bcr
brp = QLB[bcr];
// computation of the reconstructed short term residual
// signal drp[0..39]
for (k=0; k<=39; k++)
{
drpp = mult_r( brp, psi->drp[120+k-Nr] );
psi->drp[120+k] = add( erp[k], drpp );
}
// update of the reconstructed short term residual
// signal drp[-1..-120]
for (k=0; k<=119; k++)
{
psi->drp[120-120+k] = psi->drp[120-80+k];
}
return;
}
//---------------------------------------------------------------------
//
// decodeLPC
//
//---------------------------------------------------------------------
void decodeLPC
(
PSTREAMINSTANCE psi, // instance data
LPSHORT LARcr, // received coded Log.-Area Ratios [1..8]
LPSHORT wt, // accumulated drp signal [0..159]
LPSHORT sr // reconstructed s [0..159]
)
{
UINT i;
SHORT LARrpp[9]; // LARrpp[1..8], decoded LARcr
SHORT LARrp[9]; // LARrp[1..9], interpolated LARrpp
SHORT rrp[9]; // rrp[1..8], reflection coefficients
SHORT temp1, temp2;
//
// decoding of the coded log area ratios to get LARrpp[1..8]
//
// compute LARrpp[1..8]
for (i=1; i<=8; i++)
{
temp1 = add( LARcr[i], MIC[i] ) << 10;
temp2 = B[i] << 1;
temp1 = sub( temp1, temp2);
temp1 = mult_r( INVA[i], temp1 );
LARrpp[i] = add( temp1, temp1 );
}
//
// for k_start=0 to k_end=12
//
// interpolation of LARrpp[1..8] to get LARrp[1..8]
for (i=1; i<=8; i++)
{
// for k_start=0 to k_end=12
LARrp[i] = add( (SHORT)(psi->OldLARrpp[i] >> 2), (SHORT)(LARrpp[i] >> 2) );
LARrp[i] = add( LARrp[i], (SHORT)(psi->OldLARrpp[i] >> 1) );
}
// computation of reflection coefficients rrp[1..8]
Comprp(psi, LARrp, rrp);
// short term synthesis filtering
Compsr(psi, wt, rrp, 0, 12, sr);
//
// for k_start=13 to k_end=26
//
// interpolation of LARrpp[1..8] to get LARrp[1..8]
for (i=1; i<=8; i++)
{
// for k_start=13 to k_end=26
LARrp[i] = add( (SHORT)(psi->OldLARrpp[i] >> 1), (SHORT)(LARrpp[i] >> 1) );
}
// computation of reflection coefficients rrp[1..8]
Comprp(psi, LARrp, rrp);
// short term synthesis filtering
Compsr(psi, wt, rrp, 13, 26, sr);
//
// for k_start=27 to k_end=39
//
// interpolation of LARrpp[1..8] to get LARrp[1..8]
for (i=1; i<=8; i++)
{
// for k_start=27 to k_end=39
LARrp[i] = add( (SHORT)(psi->OldLARrpp[i] >> 2), (SHORT)(LARrpp[i] >> 2) );
LARrp[i] = add( LARrp[i], (SHORT)(LARrpp[i] >> 1) );
}
// computation of reflection coefficients rrp[1..8]
Comprp(psi, LARrp, rrp);
// short term synthesis filtering
Compsr(psi, wt, rrp, 27, 39, sr);
//
// for k_start=40 to k_end=159
//
// interpolation of LARrpp[1..8] to get LARrp[1..8]
for (i=1; i<=8; i++)
{
// for k_start=40 to k_end=159
LARrp[i] = LARrpp[i];
}
// computation of reflection coefficients rrp[1..8]
Comprp(psi, LARrp, rrp);
// short term synthesis filtering
Compsr(psi, wt, rrp, 40, 159, sr);
//
// update oldLARrpp[1..8]
//
for (i=1; i<=8; i++)
{
psi->OldLARrpp[i] = LARrpp[i];
}
return;
}
//---------------------------------------------------------------------
//
// decodePostproc()
//
//---------------------------------------------------------------------
void decodePostproc(PSTREAMINSTANCE psi, LPSHORT sr, LPSHORT srop)
{
UINT k;
// deemphasis filtering
for (k=0; k<=159; k++)
{
srop[k] = psi->msr = add(sr[k], mult_r(psi->msr, 28180));
// upscaling and truncation of the output signal
srop[k] = (add(srop[k], srop[k])) & 0xFFF8;
}
return;
}
//---------------------------------------------------------------------
//
// Compsr()
//
//---------------------------------------------------------------------
void Compsr(PSTREAMINSTANCE psi, LPSHORT wt, LPSHORT rrp, UINT k_start, UINT k_end, LPSHORT sr)
{
UINT i, k;
SHORT sri;
for (k=k_start; k<=k_end; k++)
{
sri = wt[k];
for (i=1; i<=8; i++)
{
sri = sub( sri, mult_r(rrp[9-i], psi->v[8-i]) );
psi->v[9-i] = add( psi->v[8-i], mult_r( rrp[9-i], sri ) );
}
sr[k] = sri;
psi->v[0] = sri;
}
return;
}
//=====================================================================
//=====================================================================
//
// Math and helper routines
//
//=====================================================================
//=====================================================================
//
// The 8-/16-bit PCM conversion routines are implemented as seperate
// functions to allow easy modification if we someday wish to do
// something more sophisticated that simple truncation... They are
// prototyped as inline so there should be no performance penalty.
//
//
SHORT Convert8To16BitPCM(BYTE bPCM8)
{
return ( ((SHORT)bPCM8) - 0x80 ) << 8;
}
BYTE Convert16To8BitPCM(SHORT iPCM16)
{
return (BYTE)((iPCM16 >> 8) + 0x80);
}
SHORT add(SHORT var1, SHORT var2)
{
LONG sum;
sum = (LONG) var1 + (LONG) var2;
if (sum < -32768L) return -32768;
if (sum > 32767L) return 32767;
return (SHORT) sum;
}
SHORT sub(SHORT var1, SHORT var2)
{
LONG diff;
diff = (LONG) var1 - (LONG) var2;
if (diff < -32768L) return -32768;
if (diff > 32767L) return 32767;
return (SHORT) diff;
}
SHORT mult(SHORT var1, SHORT var2)
{
LONG product;
product = (LONG) var1 * (LONG) var2;
if (product >= 0x40000000) product=0x3FFFFFFF;
return ( (SHORT) HIWORD((DWORD)(product<<1)) );
}
SHORT mult_r(SHORT var1, SHORT var2)
{
LONG product;
product = ((LONG) var1 * (LONG) var2) + 16384L;
if (product >= 0x40000000) product=0x3FFFFFFF;
return ( (SHORT) HIWORD((DWORD)(product<<1)) );
}
SHORT gabs(SHORT var1)
{
if (var1 >= 0) return var1;
if (var1 == -32768) return 32767;
return -var1;
}
SHORT gdiv(SHORT num, SHORT denum)
{
UINT k;
LONG l_num, l_denum;
SHORT div;
l_num = num;
l_denum = denum;
div = 0;
for (k=0; k<15; k++)
{
div = div << 1;
l_num = l_num << 1;
if (l_num >= l_denum)
{
l_num = l_sub(l_num, l_denum);
div = add(div,1);
}
}
return div;
}
LONG l_mult(SHORT var1, SHORT var2)
{
LONG product;
product = (LONG) var1 * (LONG) var2;
return product << 1;
}
LONG l_add(LONG l_var1, LONG l_var2)
{
LONG l_sum;
// perform long addition
l_sum = l_var1 + l_var2;
// check for under or overflow
if (IsNeg(l_var1))
{
if (IsNeg(l_var2) && !IsNeg(l_sum))
{
return 0x80000000;
}
}
else
{
if (!IsNeg(l_var2) && IsNeg(l_sum))
{
return 0x7FFFFFFF;
}
}
return l_sum;
}
LONG l_sub(LONG l_var1, LONG l_var2)
{
LONG l_diff;
// perform subtraction
l_diff = l_var1 - l_var2;
// check for underflow
if ( (l_var1<0) && (l_var2>0) && (l_diff>0) ) l_diff=0x80000000;
// check for overflow
if ( (l_var1>0) && (l_var2<0) && (l_diff<0) ) l_diff=0x7FFFFFFF;
return l_diff;
}
SHORT norm(LONG l_var)
{
UINT i;
i=0;
if (l_var > 0)
{
while (l_var < 1073741824)
{
i++;
l_var = l_var << 1;
}
}
else if (l_var < 0)
{
while (l_var > -1073741824)
{
i++;
l_var = l_var << 1;
}
}
return (SHORT)i;
}
LONG IsNeg(LONG x)
{
return(x & 0x80000000);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -