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

📄 gsm610.c

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

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