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

📄 gsm610.c

📁 一个关于声音驱动的例子程序一个关于声音驱动的例子程序一个关于声音驱动的例子程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    // 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 + -