📄 gsm_encode.c
字号:
*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 + -