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

📄 gsm_encode.c

📁 由HawK提供的语音压缩软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		*LARp += (gsmword)SASR( *LARpp_j_1, 1);
	}
}

INLINE void Coefficients_13_26(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp)
{
	int i;

	for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
		*LARp = SASR( *LARpp_j_1, 1) + SASR( *LARpp_j, 1 );
}

INLINE void Coefficients_27_39(gsmword * LARpp_j_1, gsmword * LARpp_j, gsmword * LARp)
{
	int i;

	for(i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++)
    {
		*LARp = (gsmword)(SASR( *LARpp_j_1, 2 ) + SASR( *LARpp_j, 2 ));
		*LARp += (gsmword)SASR( *LARpp_j, 1 );
	}
}

INLINE void Coefficients_40_159(gsmword * LARpp_j, gsmword * LARp)
{
	int i;

	for(i = 1; i <= 8; i++, LARp++, LARpp_j++)
		*LARp = *LARpp_j;
}

static void LARp_to_rp(gsmword * LARp)
{
	int 		i;
	gsmword	temp;

	for(i = 1; i <= 8; i++, LARp++)
    {
		if(*LARp < 0)
        {
			temp = (gsmword)GSM_ABS( *LARp );
			*LARp = (gsmword)(- ((temp < 11059) ? SASL( temp, 1 )
				: ((temp < 20070) ? temp + 11059
				:  ( SASR( temp, 2 ) + 26112 ))));
		}
        else
        {
			temp  = *LARp;
			*LARp =    (gsmword)((temp < 11059) ? SASL( temp, 1 )
				: ((temp < 20070) ? temp + 11059
				:  ( SASR( temp, 2 ) + 26112 )));
		}
	}
}

static void Short_term_analysis_filtering(struct gsm_state *S, gsmword *rp,
                                          int k_n, gsmword *s)
{
    gsmword	    *u = S->u;
    gsmword	    di, ui, sav;
    longword 	ltmp;
    gsmword     u0=u[0], u1=u[1], u2=u[2], u3=u[3],
                u4=u[4], u5=u[5], u6=u[6], u7=u[7];
    gsmword     rp0, rp1, rp2, rp3,
                rp4, rp5, rp6, rp7;

    rp0 = rp[0]; rp1 = rp[1];
    rp2 = rp[2]; rp3 = rp[3];
    rp4 = rp[4]; rp5 = rp[5];
    rp6 = rp[6]; rp7 = rp[7];
    
    while( k_n-- != 0)
    {
        
        di = sav = *s;

        ui  = u0;
        u0  = sav;
        
        sav = ui + (gsmword)GSM_MULT_R(rp0, di);
        di  += (gsmword)GSM_MULT_R(rp0, ui);
        
        ui  = u1;
        u1  = sav;
        
        sav = ui + (gsmword)GSM_MULT_R(rp1, di);
        di  += (gsmword)GSM_MULT_R(rp1, ui);
        
        ui  = u2;
        u2  = sav;
        
        sav = ui + (gsmword)GSM_MULT_R(rp2, di);
        di  += (gsmword)GSM_MULT_R(rp2, ui);
        
        ui  = u3;
        u3  = sav;
        
        sav = ui + (gsmword)GSM_MULT_R(rp3, di);
        di  += (gsmword)GSM_MULT_R(rp3, ui);
        
        ui  = u4;
        u4  = sav;
        
        sav = ui + (gsmword)GSM_MULT_R(rp4, di);
        di  += (gsmword)GSM_MULT_R(rp4, ui);
        
        ui  = u5;
        u5  = sav;
        
        sav = ui + (gsmword)GSM_MULT_R(rp5,di);
        di  += (gsmword)GSM_MULT_R(rp5,ui);
        
        ui  = u6;
        u6  = sav;
        
        sav = ui + (gsmword)GSM_MULT_R(rp6,di);
        di  += (gsmword)GSM_MULT_R(rp6,ui);
        
        ui  = u7;
        u7  = sav;
        
        *s++ = (gsmword)GSM_ADD( di, (gsmword)GSM_MULT_R(rp7,ui) ); /* This GSM_ADD is needed for over/under flow */
    }
    u[0]=GSM_ADD(u0, 0);
    u[1]=GSM_ADD(u1, 0);
    u[2]=GSM_ADD(u2, 0);
    u[3]=GSM_ADD(u3, 0);
    u[4]=GSM_ADD(u4, 0);
    u[5]=GSM_ADD(u5, 0);
    u[6]=GSM_ADD(u6, 0);
    u[7]=GSM_ADD(u7, 0);
}

static void Gsm_Short_Term_Analysis_Filter( struct gsm_state *S, gsmword *LARc, gsmword *s)
{
	gsmword		* LARpp_j	= S->LARpp[ S->j      ];
	gsmword		* LARpp_j_1	= S->LARpp[ S->j ^= 1 ];

	gsmword		LARp[8];

	Decoding_of_the_coded_Log_Area_Ratios(LARc, LARpp_j);

	Coefficients_0_12(LARpp_j_1, LARpp_j, LARp);
	LARp_to_rp(LARp);
	Short_term_analysis_filtering(S, LARp, 13, s);

	Coefficients_13_26(LARpp_j_1, LARpp_j, LARp);
	LARp_to_rp(LARp);
	Short_term_analysis_filtering(S, LARp, 14, s + 13);

	Coefficients_27_39(LARpp_j_1, LARpp_j, LARp);
	LARp_to_rp(LARp);
	Short_term_analysis_filtering(S, LARp, 13, s + 27);

	Coefficients_40_159(LARpp_j, LARp);
	LARp_to_rp(LARp);
	Short_term_analysis_filtering(S, LARp, 120, s + 40);
}

static void Calculation_of_the_LTP_parameters(gsmword *d, gsmword *dp,
                                              gsmword *bc_out, gsmword *Nc_out)
{
	int  	    k, lambda;
	gsmword		Nc, bc;
	gsmword		wt[40];
    gsmword     * pwt = wt;
	longword	L_max, L_power;
	gsmword		R, S, dmax, scal;
	gsmword	    temp;
    gsmword     * pd = d;

	dmax = 0;

	for (k = 0; k < 40; k+=8)
    {
# undef STEP
# define STEP temp = (gsmword)GSM_ABS( *pd );\
		if (temp > dmax) dmax = temp;\
        pd++;

        STEP;STEP;STEP;STEP;
        STEP;STEP;STEP;STEP;
    }

	temp = 0;
	if(dmax == 0)
       scal = 0;
	else
		temp = gsm_norm( SASL( (longword)dmax, 16 ) );

	if(temp > 6)
        scal = 0;
	else
        scal = (gsmword)(6 - temp);

    pd = d;
    for (k = 0; k < 40; k+=8)
    {
# undef STEP
# define STEP        *pwt = (gsmword)SASR( *pd, scal ); pd++; pwt++;

        STEP;STEP;STEP;STEP;
        STEP;STEP;STEP;STEP;
    }
 
	L_max = 0;
	Nc    = 40;	/* index for the maximum cross-correlation */

	for (lambda = 40; lambda <= 120; lambda++)
    {

# undef STEP
#		define STEP(k) 	(longword)wt[k] * dp[k - lambda];

		register longword L_result;

		L_result  = STEP(0)  ; L_result += STEP(1) ;
		L_result += STEP(2)  ; L_result += STEP(3) ;
		L_result += STEP(4)  ; L_result += STEP(5)  ;
		L_result += STEP(6)  ; L_result += STEP(7)  ;
		L_result += STEP(8)  ; L_result += STEP(9)  ;
		L_result += STEP(10) ; L_result += STEP(11) ;
		L_result += STEP(12) ; L_result += STEP(13) ;
		L_result += STEP(14) ; L_result += STEP(15) ;
		L_result += STEP(16) ; L_result += STEP(17) ;
		L_result += STEP(18) ; L_result += STEP(19) ;
		L_result += STEP(20) ; L_result += STEP(21) ;
		L_result += STEP(22) ; L_result += STEP(23) ;
		L_result += STEP(24) ; L_result += STEP(25) ;
		L_result += STEP(26) ; L_result += STEP(27) ;
		L_result += STEP(28) ; L_result += STEP(29) ;
		L_result += STEP(30) ; L_result += STEP(31) ;
		L_result += STEP(32) ; L_result += STEP(33) ;
		L_result += STEP(34) ; L_result += STEP(35) ;
		L_result += STEP(36) ; L_result += STEP(37) ;
		L_result += STEP(38) ; L_result += STEP(39) ;

		if (L_result > L_max)
        {

			Nc    = (gsmword)lambda;
			L_max = L_result;
		}
	}

	*Nc_out = Nc;

	L_max = SASL(L_max, 1 );

	L_max = SASR( L_max, (6 - scal) );	/* sub(6, scal) */

	L_power = 0;
	for (k = 0; k < 40; k+=4)
    {

		register longword L_temp;

		L_temp   = SASR( dp[k - Nc], 3 );
		L_power += L_temp * L_temp;

		L_temp   = SASR( dp[k + 1 - Nc], 3 );
		L_power += L_temp * L_temp;

		L_temp   = SASR( dp[k + 2 - Nc], 3 );
		L_power += L_temp * L_temp;

		L_temp   = SASR( dp[k + 3 - Nc], 3 );
		L_power += L_temp * L_temp;

    }
	L_power = SASL( L_power, 1 );

	if (L_max <= 0)
    {
		*bc_out = 0;
		return;
	}
	if (L_max >= L_power)
    {
		*bc_out = 3;
		return;
	}

	temp = gsm_norm( L_power );

	R = (gsmword)SASR( SASL( L_max, temp ), 16 );
	S = (gsmword)SASR( SASL( L_power, temp ), 16 );

	for(bc = 0; bc <= 2; bc++)
    {
        if(R <= GSM_MULT(S, gsm_DLB[bc]))
            break;
    }
	*bc_out = bc;
}

static void Cut_Calculation_of_the_LTP_parameters(gsmword *d, gsmword *dp,
                                                  gsmword *bc_out, gsmword *Nc_out)
{
	int  	    k, lambda;
	gsmword		Nc, bc;

	longword	L_result;
	longword	L_max, L_power;
	gsmword		R, S, dmax, scal, best_k;

	gsmword	    temp, wt_k;

	dmax = best_k = 0;
	for (k = 0; k <= 39; k++)
    {
		temp = (gsmword)GSM_ABS( d[k] );
		if (temp > dmax)
        {
			dmax = temp;
			best_k = (gsmword)k;
		}
	}
	temp = 0;
	if (dmax == 0)
    {
        scal = 0;
    }
	else
    {
		temp = gsm_norm( (longword)dmax << 16 );
	}
	if (temp > 6) scal = 0;
	else scal = (gsmword)(6 - temp);

	L_max = 0;
	Nc    = 40;	/* index for the maximum cross-correlation */
	wt_k  = (gsmword)SASR(d[best_k], scal);

	for (lambda = 40; lambda <= 120; lambda++)
    {
		L_result = (longword)wt_k * dp[best_k - lambda];
		if (L_result > L_max)
        {
			Nc    = (gsmword)lambda;
			L_max = L_result;
		}
	}
	*Nc_out = Nc;
	L_max <<= 1;

	L_max = L_max >> (6 - scal);	/* sub(6, scal) */

	L_power = 0;
	for (k = 0; k <= 39; k++)
    {
		longword L_temp;

		L_temp   = SASR( dp[k - Nc], 3 );
		L_power += L_temp * L_temp;
	}
	L_power <<= 1;

	if (L_max <= 0)
    {
		*bc_out = 0;
		return;
	}
	if (L_max >= L_power)
    {
		*bc_out = 3;
		return;
	}

	temp = gsm_norm(L_power);

	R = (gsmword)SASR( SASL(L_max, temp), 16 );
	S = (gsmword)SASR( SASL(L_power, temp), 16 );

	for (bc = 0; bc <= 2; bc++)
    {
        if (R <= GSM_MULT(S, gsm_DLB[bc]))
            break;
    }
	*bc_out = bc;
}

static void Long_term_analysis_filtering(gsmword bc, gsmword Nc, gsmword *dp, gsmword *d,
                                         gsmword *dpp, gsmword *e)
{
	int k;

    dp -= Nc;

#	undef STEP
#	define STEP(BP)					\
	for (k = 40; k--; e++, dpp++, d++, *dp++) {			\
		*dpp = (gsmword)GSM_MULT_R( BP, *dp);	\
		*e = (gsmword)( *d - *dpp );	\
	}

	switch (bc) {
	case 0:	STEP(  3277 ); break;
	case 1:	STEP( 11469 ); break;
	case 2: STEP( 21299 ); break;
	case 3: STEP( 32767 ); break; 
	}
}

static void Gsm_Long_Term_Predictor(struct gsm_state *S, gsmword *d, gsmword *dp, gsmword *e,
                              gsmword *dpp, gsmword *Nc, gsmword *bc)
{
    if(S->ltp_cut != 0)
    {
	    Cut_Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
    }
    else
    {
	    Calculation_of_the_LTP_parameters(d, dp, bc, Nc);
    }

	Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e );
}

static void Gsm_Coder(struct gsm_state *S, short *s, gsmword *LARc, gsmword *Nc,
            gsmword *bc, gsmword *Mc, gsmword *xmaxc, gsmword *xMc)
{
	int	k;
	gsmword	*dp  = S->dp0 + 120;	/* [ -120...-1 ] */
	gsmword e[50];
    gsmword *pe = &e[5];
	gsmword	so[160];

    memset(e, 0, sizeof(e));
	Gsm_Preprocess(S, s, so);
	Gsm_LPC_Analysis(so, LARc);
	Gsm_Short_Term_Analysis_Filter	(S, LARc, so);

	for (k = 0; k <= 3; k++, xMc += 13)
    {
        int i;

		Gsm_Long_Term_Predictor(S, so+k*40, dp, pe, dp, Nc++, bc++);

		Gsm_RPE_Encoding(pe, xmaxc++, Mc++, xMc );

		for (i = 0; i <= 39; i++, dp++)
			*dp +=  (gsmword)pe[i];
	}
	(void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160), 120 * sizeof(*S->dp0) );
}

int gsm_encode(struct gsm_state * s, short * source, unsigned char * c)
{
    gsmword	 	LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4];
    
    Gsm_Coder(s, source, LARc, Nc, bc, Mc, xmaxc, xmc);

    *c++ =	 (unsigned char)(((GSM_MAGIC & 0xF) << 4)				/* 1 */
        | ((LARc[0] >> 2) & 0xF));
    *c++ =	 (unsigned char)(((LARc[0] & 0x3) << 6)
        | (LARc[1] & 0x3F));
    *c++ =	 (unsigned char)(((LARc[2] & 0x1F) << 3)
        | ((LARc[3] >> 2) & 0x7));
    *c++ =	 (unsigned char)(((LARc[3] & 0x3) << 6)
        | ((LARc[4] & 0xF) << 2)
        | ((LARc[5] >> 2) & 0x3));
    *c++ =	 (unsigned char)(((LARc[5] & 0x3) << 6)
        | ((LARc[6] & 0x7) << 3)
        | (LARc[7] & 0x7));
    *c++ =	 (unsigned char)(((Nc[0] & 0x7F) << 1)
        | ((bc[0] >> 1) & 0x1));
    *c++ =	 (unsigned char)(((bc[0] & 0x1) << 7)
        | ((Mc[0] & 0x3) << 5)
        | ((xmaxc[0] >> 1) & 0x1F));
    *c++ =	 (unsigned char)(((xmaxc[0] & 0x1) << 7)
        | ((xmc[0] & 0x7) << 4)
        | ((xmc[1] & 0x7) << 1)
        | ((xmc[2] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[2] & 0x3) << 6)
        | ((xmc[3] & 0x7) << 3)
        | (xmc[4] & 0x7));
    *c++ =	 (unsigned char)(((xmc[5] & 0x7) << 5)					/* 10 */
        | ((xmc[6] & 0x7) << 2)
        | ((xmc[7] >> 1) & 0x3));
    *c++ =	 (unsigned char)(((xmc[7] & 0x1) << 7)
        | ((xmc[8] & 0x7) << 4)
        | ((xmc[9] & 0x7) << 1)
        | ((xmc[10] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[10] & 0x3) << 6)
        | ((xmc[11] & 0x7) << 3)
        | (xmc[12] & 0x7));
    *c++ =	 (unsigned char)(((Nc[1] & 0x7F) << 1)
        | ((bc[1] >> 1) & 0x1));
    *c++ =	 (unsigned char)(((bc[1] & 0x1) << 7)
        | ((Mc[1] & 0x3) << 5)
        | ((xmaxc[1] >> 1) & 0x1F));
    *c++ =	 (unsigned char)(((xmaxc[1] & 0x1) << 7)
        | ((xmc[13] & 0x7) << 4)
        | ((xmc[14] & 0x7) << 1)
        | ((xmc[15] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[15] & 0x3) << 6)
        | ((xmc[16] & 0x7) << 3)
        | (xmc[17] & 0x7));
    *c++ =	 (unsigned char)(((xmc[18] & 0x7) << 5)
        | ((xmc[19] & 0x7) << 2)
        | ((xmc[20] >> 1) & 0x3));
    *c++ =	 (unsigned char)(((xmc[20] & 0x1) << 7)
        | ((xmc[21] & 0x7) << 4)
        | ((xmc[22] & 0x7) << 1)
        | ((xmc[23] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[23] & 0x3) << 6)
        | ((xmc[24] & 0x7) << 3)
        | (xmc[25] & 0x7));
    *c++ =	 (unsigned char)(((Nc[2] & 0x7F) << 1)					/* 20 */
        | ((bc[2] >> 1) & 0x1));
    *c++ =	 (unsigned char)(((bc[2] & 0x1) << 7)
        | ((Mc[2] & 0x3) << 5)
        | ((xmaxc[2] >> 1) & 0x1F));
    *c++ =	 (unsigned char)(((xmaxc[2] & 0x1) << 7)
        | ((xmc[26] & 0x7) << 4)
        | ((xmc[27] & 0x7) << 1)
        | ((xmc[28] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[28] & 0x3) << 6)
        | ((xmc[29] & 0x7) << 3)
        | (xmc[30] & 0x7));
    *c++ =	 (unsigned char)(((xmc[31] & 0x7) << 5)
        | ((xmc[32] & 0x7) << 2)
        | ((xmc[33] >> 1) & 0x3));
    *c++ =	 (unsigned char)(((xmc[33] & 0x1) << 7)
        | ((xmc[34] & 0x7) << 4)
        | ((xmc[35] & 0x7) << 1)
        | ((xmc[36] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[36] & 0x3) << 6)
        | ((xmc[37] & 0x7) << 3)
        | (xmc[38] & 0x7));
    *c++ =	 (unsigned char)(((Nc[3] & 0x7F) << 1)
        | ((bc[3] >> 1) & 0x1));
    *c++ =	 (unsigned char)(((bc[3] & 0x1) << 7)
        | ((Mc[3] & 0x3) << 5)
        | ((xmaxc[3] >> 1) & 0x1F));
    *c++ =	 (unsigned char)(((xmaxc[3] & 0x1) << 7)
        | ((xmc[39] & 0x7) << 4)
        | ((xmc[40] & 0x7) << 1)
        | ((xmc[41] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[41] & 0x3) << 6) 				/* 30 */
        | ((xmc[42] & 0x7) << 3)
        | (xmc[43] & 0x7));
    *c++ =	 (unsigned char)(((xmc[44] & 0x7) << 5)
        | ((xmc[45] & 0x7) << 2)
        | ((xmc[46] >> 1) & 0x3));
    *c++ =	 (unsigned char)(((xmc[46] & 0x1) << 7)
        | ((xmc[47] & 0x7) << 4)
        | ((xmc[48] & 0x7) << 1)
        | ((xmc[49] >> 2) & 0x1));
    *c++ =	 (unsigned char)(((xmc[49] & 0x3) << 6)
        | ((xmc[50] & 0x7) << 3)
        | (xmc[51] & 0x7));
    
    return GSM_ENCODED_FRAME_SIZE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -