📄 gsm610.c
字号:
// Temp buffer to hold a block (two frames) of packed stream data
BYTE abBlock[ GSM610_BYTESPERMONOBLOCK ];
#ifdef DEBUG
// ProfStart();
#endif
psi = (PSTREAMINSTANCE)padsi->dwDriver;
// If this is flagged as the first block of a conversion
// then reset the stream instance data.
if (0 != (ACM_STREAMCONVERTF_START & padsh->fdwConvert))
{
gsm610Reset(psi);
}
fBlockAlign = (0 != (ACM_STREAMCONVERTF_BLOCKALIGN & padsh->fdwConvert));
//
// -= decode GSM 6.10 to PCM =-
//
//
cb = padsh->cbSrcLength;
cBlocks = cb / GSM610_BLOCKALIGNMENT(padsi->pwfxSrc);
if (0L == cBlocks)
{
padsh->cbSrcLengthUsed = cb;
padsh->cbDstLengthUsed = 0L;
return (MMSYSERR_NOERROR);
}
//
// Compute bytes we will use in destination buffer. Carefull! Look
// out for overflow in our calculations!
//
if ((0xFFFFFFFFL / GSM610_SAMPLESPERMONOBLOCK) < cBlocks)
return (ACMERR_NOTPOSSIBLE);
dwcSamples = cBlocks * GSM610_SAMPLESPERMONOBLOCK;
if (PCM_BYTESTOSAMPLES(((LPPCMWAVEFORMAT)(padsi->pwfxDst)), 0xFFFFFFFFL) < dwcSamples)
return (ACMERR_NOTPOSSIBLE);
cb = PCM_SAMPLESTOBYTES(((LPPCMWAVEFORMAT)(padsi->pwfxDst)), dwcSamples);
if (cb > padsh->cbDstLength)
{
return (ACMERR_NOTPOSSIBLE);
}
padsh->cbDstLengthUsed = cb;
padsh->cbSrcLengthUsed = cBlocks * GSM610_BLOCKALIGNMENT(padsi->pwfxSrc);
//
//
//
cbSrcLen = padsh->cbSrcLengthUsed;
// Setup huge pointers to our src and dst buffers
hpbSrc = (HPBYTE)padsh->pbSrc;
hpbDst = (HPBYTE)padsh->pbDst;
// while at least another full block of coded data
while (cbSrcLen >= GSM610_BYTESPERMONOBLOCK)
{
// copy a block of data from stream buffer to our temp buffer
for (i=0; i<GSM610_BYTESPERMONOBLOCK; i++) abBlock[i] = *(hpbSrc++);
cbSrcLen -= GSM610_BYTESPERMONOBLOCK;
// for each of the two frames in the block
for (nFrame=0; nFrame < 2; nFrame++)
{
// Unpack data from stream
if (nFrame == 0)
UnpackFrame0(abBlock, LARcr, Ncr, bcr, Mcr, xmaxcr, xMcr);
else
UnpackFrame1(abBlock, LARcr, Ncr, bcr, Mcr, xmaxcr, xMcr);
for (i=0; i<4; i++) // for each of 4 sub-blocks
{
// reconstruct the long term residual signal erp[0..39]
// from Mcr, xmaxcr, and xMcr
decodeRPE(psi, Mcr[i], xmaxcr[i], xMcr[i], erp);
// reconstruct the short term residual signal drp[0..39]
// and also update drp[-120..-1]
decodeLTP(psi, bcr[i], Ncr[i], erp);
// accumulate the four sub-blocks of reconstructed short
// term residual signal drp[0..39] into wt[0..159]
for (j=0; j<40; j++) wt[(i*40) + j] = psi->drp[120+j];
}
// reconstruct the signal s
decodeLPC(psi, LARcr, wt, sr);
// post-process the signal s
decodePostproc(psi, sr, srop);
//
// write decoded 16-bit PCM to dst. our dst format
// may be 8- or 16-bit PCM.
//
if (padsi->pwfxDst->wBitsPerSample == 16)
{
// copy 16-bit samples from srop to hpbDst
for (j=0; j < GSM610_SAMPLESPERFRAME; j++)
{
*( ((HPWORD)hpbDst)++ ) = srop[j];
}
}
else
{
// copy 16-bit samples from srop to 8-bit samples in hpbDst
for (j=0; j < GSM610_SAMPLESPERFRAME; j++)
{
*(hpbDst++) = Convert16To8BitPCM(srop[j]);
}
}
} // for (nFrame...
}
#ifdef DEBUG
// ProfStop();
#endif
return (MMSYSERR_NOERROR);
}
//=====================================================================
//=====================================================================
//
// Encode routines
//
//=====================================================================
//=====================================================================
//---------------------------------------------------------------------
//--------------------------------------------------------------------
//
// Function protos
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
EXTERN_C void CompACF(LPSHORT s, LPLONG l_ACF);
void Compr(PSTREAMINSTANCE psi, LPLONG l_ACF, LPSHORT r);
void CompLAR(PSTREAMINSTANCE psi, LPSHORT r, LPSHORT LAR);
void CompLARc(PSTREAMINSTANCE psi, LPSHORT LAR, LPSHORT LARc);
void CompLARpp(PSTREAMINSTANCE psi, LPSHORT LARc, LPSHORT LARpp);
void CompLARp(PSTREAMINSTANCE psi, LPSHORT LARpp, LPSHORT LARp1, LPSHORT LARp2, LPSHORT LARp3, LPSHORT LARp4);
void Comprp(PSTREAMINSTANCE psi, LPSHORT LARp, LPSHORT rp);
EXTERN_C void Compd(PSTREAMINSTANCE psi, LPSHORT rp, LPSHORT s, LPSHORT d, UINT k_start, UINT k_end);
void WeightingFilter(PSTREAMINSTANCE psi, LPSHORT e, LPSHORT x);
void RPEGridSelect(PSTREAMINSTANCE psi, LPSHORT x, LPSHORT pMc, LPSHORT xM);
void APCMQuantize(PSTREAMINSTANCE psi, LPSHORT xM, LPSHORT pxmaxc, LPSHORT xMc, LPSHORT pexp, LPSHORT pmant);
void APCMInvQuantize(PSTREAMINSTANCE psi, SHORT exp, SHORT mant, LPSHORT xMc, LPSHORT xMp);
void RPEGridPosition(PSTREAMINSTANCE psi, SHORT Mc, LPSHORT xMp, LPSHORT ep);
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//
// Global constant data
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
const SHORT BCODE A[9] = {
0, // not used
20480, 20480, 20480, 20480, 13964, 15360, 8534, 9036 };
const SHORT BCODE B[9] = {
0, // not used
0, 0, 2048, -2560, 94, -1792, -341, -1144 };
const SHORT BCODE MIC[9] = {
0, // not used
-32, -32, -16, -16, -8, -8, -4, -4 };
const SHORT BCODE MAC[9] = {
0, // not used
31, 31, 15, 15, 7, 7, 3, 3 };
const SHORT BCODE INVA[9] = {
0, // unused
13107, 13107, 13107, 13107, 19223, 17476, 31454, 29708 };
EXTERN_C const SHORT BCODE DLB[4] = { 6554, 16384, 26214, 32767 };
EXTERN_C const SHORT BCODE QLB[4] = { 3277, 11469, 21299, 32767 };
const SHORT BCODE H[11] = { -134, -374, 0, 2054, 5741, 8192, 5741, 2054, 0, -374, -134 };
const SHORT BCODE NRFAC[8] = { 29128, 26215, 23832, 21846, 20165, 18725, 17476, 16384 };
const SHORT BCODE FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 };
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//
// Procedures
//
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//---------------------------------------------------------------------
//
// PackFrame0
//
//---------------------------------------------------------------------
void PackFrame0
(
BYTE FAR ab[],
SHORT FAR LAR[],
SHORT FAR N[],
SHORT FAR b[],
SHORT FAR M[],
SHORT FAR Xmax[],
XM FAR X[]
)
{
int i;
// Pack the LAR[1..8] into the first 4.5 bytes
ab[0] = ((LAR[1] ) & 0x3F) | ((LAR[2] << 6) & 0xC0);
ab[1] = ((LAR[2] >> 2) & 0x0F) | ((LAR[3] << 4) & 0xF0);
ab[2] = ((LAR[3] >> 4) & 0x01) | ((LAR[4] << 1) & 0x3E) | ((LAR[5] << 6) & 0xC0);
ab[3] = ((LAR[5] >> 2) & 0x03) | ((LAR[6] << 2) & 0x3C) | ((LAR[7] << 6) & 0xC0);
ab[4] = ((LAR[7] >> 2) & 0x01) | ((LAR[8] << 1) & 0x0E);
// Pack N, b, M, Xmax, and X for each of the 4 sub-frames
for (i=0; i<4; i++)
{
ab[4+i*7+0] |= ((N[i] << 4) & 0xF0);
ab[4+i*7+1] = ((N[i] >> 4) & 0x07) | ((b[i] << 3) & 0x18) | ((M[i] << 5) & 0x60) | ((Xmax[i] << 7) & 0x80);
ab[4+i*7+2] = ((Xmax[i] >> 1) & 0x1F) | ((X[i][0] << 5) & 0xE0);
ab[4+i*7+3] = (X[i][1] & 0x07) | ((X[i][2] << 3) & 0x38) | ((X[i][3] << 6) & 0xC0);
ab[4+i*7+4] = ((X[i][3] >> 2) & 0x01) | ((X[i][4] << 1) & 0x0E) | ((X[i][5] << 4) & 0x70) | ((X[i][6] << 7) & 0x80);
ab[4+i*7+5] = ((X[i][6] >> 1) & 0x03) | ((X[i][7] << 2) & 0x1C) | ((X[i][8] << 5) & 0xE0);
ab[4+i*7+6] = (X[i][9] & 0x07) | ((X[i][10] << 3) & 0x38) | ((X[i][11] << 6) & 0xC0);
ab[4+i*7+7] = ((X[i][11] >> 2) & 0x01) | ((X[i][12] << 1) & 0x0E);
}
return;
}
//---------------------------------------------------------------------
//
// PackFrame1
//
//---------------------------------------------------------------------
void PackFrame1
(
BYTE FAR ab[],
SHORT FAR LAR[],
SHORT FAR N[],
SHORT FAR b[],
SHORT FAR M[],
SHORT FAR Xmax[],
XM FAR X[]
)
{
int i;
// Pack the LAR[1..8] into the first 4.5 bytes, starting with the
// more significant nibble of the first byte.
ab[32] |= ((LAR[1] << 4) & 0xF0);
ab[33] = ((LAR[1] >> 4) & 0x03) | ((LAR[2] << 2) & 0xFC);
ab[34] = ((LAR[3] ) & 0x1F) | ((LAR[4] << 5) & 0xE0);
ab[35] = ((LAR[4] >> 3) & 0x03) | ((LAR[5] << 2) & 0x3C) | ((LAR[6] << 6) & 0xC0);
ab[36] = ((LAR[6] >> 2) & 0x03) | ((LAR[7] << 2) & 0x1C) | ((LAR[8] << 5) & 0xE0);
// Pack N, b, M, Xmax, and X for each of the 4 sub-frames
for (i=0; i<4; i++)
{
ab[37+i*7+0] = (N[i] & 0x7F) | ((b[i] << 7) & 0x80);
ab[37+i*7+1] = ((b[i] >> 1) & 0x01) | ((M[i] << 1) & 0x06) | ((Xmax[i] << 3) & 0xF8);
ab[37+i*7+2] = ((Xmax[i] >> 5) & 0x01) | ((X[i][0] << 1) & 0x0E) | ((X[i][1] << 4) & 0x70) | ((X[i][2] << 7) & 0x80);
ab[37+i*7+3] = ((X[i][2] >> 1) & 0x03) | ((X[i][3] << 2) & 0x1C) | ((X[i][4] << 5) & 0xE0);
ab[37+i*7+4] = ((X[i][5] ) & 0x07) | ((X[i][6] << 3) & 0x38) | ((X[i][7] << 6) & 0xC0);
ab[37+i*7+5] = ((X[i][7] >> 2) & 0x01) | ((X[i][8] << 1) & 0x0E) | ((X[i][9] << 4) & 0x70) | ((X[i][10] << 7) & 0x80);
ab[37+i*7+6] = ((X[i][10] >> 1) & 0x03) | ((X[i][11] << 2) & 0x1C) | ((X[i][12] << 5) & 0xE0);
}
return;
}
//---------------------------------------------------------------------
//
// encodePreproc()
//
//---------------------------------------------------------------------
void encodePreproc(PSTREAMINSTANCE psi, LPSHORT sop, LPSHORT s)
{
SHORT so[160];
SHORT sof[160];
UINT k;
SHORT s1;
SHORT temp;
SHORT msp, lsp;
LONG l_s2;
// downscale
for (k=0; k<160; k++)
{
so[k] = sop[k] >> 3;
so[k] = so[k] << 2;
}
// offset compensation
for (k=0; k<160; k++)
{
// Compute the non-recursive part
s1 = sub(so[k], psi->z1);
psi->z1 = so[k];
// compute the recursive part
l_s2 = s1;
l_s2 = l_s2 << 15;
// execution of 31 by 16 bits multiplication
msp = (SHORT) (psi->l_z2 >> 15);
lsp = (SHORT) l_sub(psi->l_z2, ( ((LONG)msp) << 15));
temp = mult_r(lsp, 32735);
l_s2 = l_add(l_s2, temp);
psi->l_z2 = l_add(l_mult(msp, 32735) >> 1, l_s2);
// compute sof[k] with rounding
sof[k] = (SHORT) (l_add(psi->l_z2, 16384) >> 15);
}
// preemphasis
for (k=0; k<160; k++)
{
s[k] = add(sof[k], mult_r(psi->mp, -28180));
psi->mp = sof[k];
}
return;
}
//---------------------------------------------------------------------
//
// encodeLPCAnalysis()
//
//---------------------------------------------------------------------
void encodeLPCAnalysis(PSTREAMINSTANCE psi, LPSHORT s, LPSHORT LARc)
{
LONG l_ACF[9];
SHORT r[9];
SHORT LAR[9];
CompACF(s, l_ACF);
Compr(psi, l_ACF, r);
CompLAR(psi, r, LAR);
CompLARc(psi, LAR, LARc);
return;
}
//---------------------------------------------------------------------
//
// CompACF()
//
//---------------------------------------------------------------------
void CompACF(LPSHORT s, LPLONG l_ACF)
{
SHORT smax, temp, scalauto;
UINT i, k;
//
// Dynamic scaling of array s[0..159]
//
// Search for the maximum
smax = 0;
for (k=0; k<160; k++)
{
temp = gabs(s[k]);
if (temp > smax) smax = temp;
}
// Computation of the scaling factor
if (smax == 0) scalauto = 0;
else scalauto = sub( 4, norm( ((LONG)smax)<<16 ) );
// Scaling of the array s
if (scalauto > 0)
{
temp = BITSHIFTRIGHT(16384, sub(scalauto,1));
for (k=0; k<160; k++)
{
// s[k] = mult_r(s[k], temp);
s[k] = HIWORD( ( (((LONG)s[k])<<(15-scalauto)) + 0x4000L ) << 1 );
}
}
//
// Compute the l_ACF[..]
//
for (k=0; k<9; k++)
{
l_ACF[k] = 0;
for (i=k; i<160; i++)
{
l_ACF[k] = l_add(l_ACF[k], l_mult(s[i], s[i-k]));
}
}
//
// Rescaling of array s
//
if (scalauto > 0)
{
for (k=0; k<160; k++)
{
// We don't need the BITSHIFTLEFT macro
// cuz we know scalauto>0 due to above test
s[k] = s[k] << scalauto;
}
}
//
//
//
return;
}
//---------------------------------------------------------------------
//
// Compr()
//
//---------------------------------------------------------------------
void Compr(PSTREAMINSTANCE psi, LPLONG l_ACF, LPSHORT r)
{
UINT i, k, m, n;
SHORT temp, ACF[9];
SHORT K[9], P[9]; // K[2..8], P[0..8]
//
// Schur recursion with 16 bits arithmetic
//
if (l_ACF[0] == 0)
{
for (i=1; i<=8; i++)
{
r[i] = 0;
}
return;
}
temp = norm(l_ACF[0]);
for (k=0; k<=8; k++)
{
ACF[k] = (SHORT) ((BITSHIFTLEFT(l_ACF[k], temp)) >> 16);
}
//
// Init array P and K for the recursion
//
for (i=1; i<=7; i++)
{
K[9-i] = ACF[i];
}
for (i=0; i<=8; i++)
{
P[i] = ACF[i];
}
//
// Compute reflection coefficients
//
for (n=1; n<=8; n++)
{
if (P[0] < gabs(P[1]))
{
for (i=n; i<=8; i++)
{
r[i] = 0;
}
return;
}
r[n] = gdiv(gabs(P[1]),P[0]);
if (P[1] > 0) r[n] = sub(0,r[n]);
// Here's the real exit from this for loop
if (n==8) return;
// Schur recursion
P[0] = add(P[0], mult_r(P[1], r[n]));
for (m=1; m<=8-n; m++)
{
P[m] = add( P[m+1], mult_r(K[9-m],r[n]) );
K[9-m] = add( K[9-m], mult_r(P[m+1], r[n]) );
}
}
}
//---------------------------------------------------------------------
//
// CompLAR()
//
//---------------------------------------------------------------------
void CompLAR(PSTREAMINSTANCE psi, LPSHORT r, LPSHORT LAR)
{
UINT i;
SHORT temp;
//
// Computation of LAR[1..8] from r[1..8]
//
for (i=1; i<=8; i++)
{
temp = gabs(r[i]);
if (temp < 22118)
{
temp = temp >> 1;
}
else if (temp < 31130)
{
temp = sub(temp, 11059);
}
else
{
temp = sub(temp, 26112) << 2;
}
LAR[i] = temp;
if (r[i] < 0)
{
LAR[i] = sub(0, LAR[i]);
}
}
return;
}
//---------------------------------------------------------------------
//
// CompLARc()
//
//---------------------------------------------------------------------
void CompLARc(PSTREAMINSTANCE psi, LPSHORT LAR, LPSHORT LARc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -