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

📄 gsm610.c

📁 一个关于声音驱动的例子程序一个关于声音驱动的例子程序一个关于声音驱动的例子程序
💻 C
📖 第 1 页 / 共 4 页
字号:


//---------------------------------------------------------------------
//---------------------------------------------------------------------
//
// 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 + -