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 ); } }
static void APCM_quantization_xmaxc_to_exp_mant ( word xmaxc, /* IN */ word * exp_out, /* OUT */ word * mant_out ) /* OUT */ { word exp, mant; /* Compute exponent and mantissa of the decoded version of xmaxc */ exp = 0; if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; mant = xmaxc - (exp << 3); if (mant == 0) { exp = -4; mant = 7; } else { while (mant <= 7) { mant = mant << 1 | 1; exp--; } mant -= 8; } assert( exp >= -4 && exp <= 6 ); assert( mant >= 0 && mant <= 7 ); *exp_out = exp; *mant_out = mant; }
static void APCM_quantization_xmaxc_to_exp_mant(gsmword xmaxc, gsmword *exp_out, gsmword *mant_out) { gsmword exp, mant; exp = 0; if(xmaxc > 15) exp = (gsmword)(SASR(xmaxc, 3) - 1); mant = (gsmword)(xmaxc - SASL( exp, 3 )); if(mant == 0) { exp = -4; mant = 7; } else { while(mant <= 7) { mant = (gsmword)(SASL(mant, 1) | 1); exp--; } mant -= 8; } *exp_out = exp; *mant_out = mant; }
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 APCM_inverse_quantization(gsmword *xMc, gsmword mant, gsmword exp, gsmword *xMp) { int i; gsmword temp, temp1, temp2, temp3; longword ltmp; temp1 = gsm_FACd[ mant ]; /* see 4.2-15 for mant */ temp2 = (gsmword)GSM_SUB( 6, exp ); /* see 4.2-15 for exp */ temp3 = (gsmword)SASL( 1, GSM_SUB( temp2, 1 )); for(i = 13; i--;) { temp = (gsmword)(SASL(*xMc++, 1) - 7); /* restore sign */ temp = (gsmword)SASL(temp, 12); /* 16 bit signed */ temp = (gsmword)GSM_MULT_R( temp1, temp ); temp = (gsmword)GSM_ADD( temp, temp3 ); *xMp++ = (gsmword)SASR( temp, temp2 ); } }
static void Cut_Calculation_of_the_LTP_parameters ( struct gsm_state * st, register int16_t * d, /* [0..39] IN */ register int16_t * dp, /* [-120..-1] IN */ int16_t * bc_out, /* OUT */ int16_t * Nc_out /* OUT */) { register int k, lambda ; int16_t Nc, bc ; int16_t wt [40] ; int32_t L_result ; int32_t L_max, L_power ; int16_t R, S, dmax, scal, best_k ; int16_t ltp_cut ; register int16_t temp, wt_k ; /* Search of the optimum scaling of d [0..39]. */ dmax = 0 ; for (k = 0 ; k <= 39 ; k++) { temp = d [k] ; temp = GSM_ABS (temp) ; if (temp > dmax) { dmax = temp ; best_k = k ; } } temp = 0 ; if (dmax == 0) scal = 0 ; else { assert (dmax > 0) ; temp = gsm_norm ((int32_t) dmax << 16) ; } if (temp > 6) scal = 0 ; else scal = 6 - temp ; assert (scal >= 0) ; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0 ; Nc = 40 ; /* index for the maximum cross-correlation */ wt_k = SASR_W (d [best_k], scal) ; for (lambda = 40 ; lambda <= 120 ; lambda++) { L_result = (int32_t) wt_k * dp [best_k - lambda] ; if (L_result > L_max) { Nc = lambda ; L_max = L_result ; } } *Nc_out = Nc ; L_max <<= 1 ; /* Rescaling of L_max */ assert (scal <= 100 && scal >= -100) ; L_max = L_max >> (6 - scal) ; /* sub (6, scal) */ assert (Nc <= 120 && Nc >= 40) ; /* Compute the power of the reconstructed short term residual * signal dp [..] */ L_power = 0 ; for (k = 0 ; k <= 39 ; k++) { register int32_t L_temp ; L_temp = SASR_W (dp [k - Nc], 3) ; L_power += L_temp * L_temp ; } L_power <<= 1 ; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0 ; return ; } if (L_max >= L_power) { *bc_out = 3 ; return ; } temp = gsm_norm (L_power) ; R = SASR (L_max << temp, 16) ; S = SASR (L_power << temp, 16) ; /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB [i] for the * quantization of the LTP gain b to get the coded version bc. */ 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 ( struct gsm_state * st, /* IN */ register int16_t * d, /* [0..39] IN */ register int16_t * dp, /* [-120..-1] IN */ int16_t * bc_out, /* OUT */ int16_t * Nc_out /* OUT */) { register int k, lambda ; int16_t Nc, bc ; int16_t ltp_cut ; float wt_float [40] ; float dp_float_base [120], * dp_float = dp_float_base + 120 ; int32_t L_max, L_power ; int16_t R, S, dmax, scal ; register int16_t temp ; /* Search of the optimum scaling of d [0..39]. */ dmax = 0 ; for (k = 0 ; k <= 39 ; k++) { temp = d [k] ; temp = GSM_ABS (temp) ; if (temp > dmax) dmax = temp ; } temp = 0 ; if (dmax == 0) scal = 0 ; else { assert (dmax > 0) ; temp = gsm_norm ((int32_t) dmax << 16) ; } if (temp > 6) scal = 0 ; else scal = 6 - temp ; assert (scal >= 0) ; ltp_cut = (int32_t) SASR_W (dmax, scal) * st->ltp_cut / 100 ; /* Initialization of a working array wt */ for (k = 0 ; k < 40 ; k++) { register int16_t w = SASR_W (d [k], scal) ; if (w < 0 ? w > -ltp_cut : w < ltp_cut) wt_float [k] = 0.0 ; else wt_float [k] = w ; } for (k = -120 ; k < 0 ; k++) dp_float [k] = dp [k] ; /* Search for the maximum cross-correlation and coding of the LTP lag */ L_max = 0 ; Nc = 40 ; /* index for the maximum cross-correlation */ for (lambda = 40 ; lambda <= 120 ; lambda += 9) { /* Calculate L_result for l = lambda .. lambda + 9. */ register float *lp = dp_float - lambda ; register float W ; register float a = lp [-8], b = lp [-7], c = lp [-6], d = lp [-5], e = lp [-4], f = lp [-3], g = lp [-2], h = lp [-1] ; register float E ; register float S0 = 0, S1 = 0, S2 = 0, S3 = 0, S4 = 0, S5 = 0, S6 = 0, S7 = 0, S8 = 0 ; # undef STEP # define STEP(K, a, b, c, d, e, f, g, h) \ if ((W = wt_float [K]) != 0.0) { \ E = W * a ; S8 += E ; \ E = W * b ; S7 += E ; \ E = W * c ; S6 += E ; \ E = W * d ; S5 += E ; \ E = W * e ; S4 += E ; \ E = W * f ; S3 += E ; \ E = W * g ; S2 += E ; \ E = W * h ; S1 += E ; \ a = lp [K] ; \ E = W * a ; S0 += E ; } else (a = lp [K]) # define STEP_A(K) STEP (K, a, b, c, d, e, f, g, h) # define STEP_B(K) STEP (K, b, c, d, e, f, g, h, a) # define STEP_C(K) STEP (K, c, d, e, f, g, h, a, b) # define STEP_D(K) STEP (K, d, e, f, g, h, a, b, c) # define STEP_E(K) STEP (K, e, f, g, h, a, b, c, d) # define STEP_F(K) STEP (K, f, g, h, a, b, c, d, e) # define STEP_G(K) STEP (K, g, h, a, b, c, d, e, f) # define STEP_H(K) STEP (K, h, a, b, c, d, e, f, g) STEP_A (0) ; STEP_B (1) ; STEP_C (2) ; STEP_D (3) ; STEP_E (4) ; STEP_F (5) ; STEP_G (6) ; STEP_H (7) ; STEP_A (8) ; STEP_B (9) ; STEP_C (10) ; STEP_D (11) ; STEP_E (12) ; STEP_F (13) ; STEP_G (14) ; STEP_H (15) ; STEP_A (16) ; STEP_B (17) ; STEP_C (18) ; STEP_D (19) ; STEP_E (20) ; STEP_F (21) ; STEP_G (22) ; STEP_H (23) ; STEP_A (24) ; STEP_B (25) ; STEP_C (26) ; STEP_D (27) ; STEP_E (28) ; STEP_F (29) ; STEP_G (30) ; STEP_H (31) ; STEP_A (32) ; STEP_B (33) ; STEP_C (34) ; STEP_D (35) ; STEP_E (36) ; STEP_F (37) ; STEP_G (38) ; STEP_H (39) ; # undef STEP_A # undef STEP_B # undef STEP_C # undef STEP_D # undef STEP_E # undef STEP_F # undef STEP_G # undef STEP_H if (S0 > L_max) { L_max = S0 ; Nc = lambda ; } if (S1 > L_max) { L_max = S1 ; Nc = lambda + 1 ; } if (S2 > L_max) { L_max = S2 ; Nc = lambda + 2 ; } if (S3 > L_max) { L_max = S3 ; Nc = lambda + 3 ; } if (S4 > L_max) { L_max = S4 ; Nc = lambda + 4 ; } if (S5 > L_max) { L_max = S5 ; Nc = lambda + 5 ; } if (S6 > L_max) { L_max = S6 ; Nc = lambda + 6 ; } if (S7 > L_max) { L_max = S7 ; Nc = lambda + 7 ; } if (S8 > L_max) { L_max = S8 ; Nc = lambda + 8 ; } } *Nc_out = Nc ; L_max <<= 1 ; /* Rescaling of L_max */ assert (scal <= 100 && scal >= -100) ; L_max = L_max >> (6 - scal) ; /* sub (6, scal) */ assert (Nc <= 120 && Nc >= 40) ; /* Compute the power of the reconstructed short term residual * signal dp [..] */ L_power = 0 ; for (k = 0 ; k <= 39 ; k++) { register int32_t L_temp ; L_temp = SASR_W (dp [k - Nc], 3) ; L_power += L_temp * L_temp ; } L_power <<= 1 ; /* from L_MULT */ /* Normalization of L_max and L_power */ if (L_max <= 0) { *bc_out = 0 ; return ; } if (L_max >= L_power) { *bc_out = 3 ; return ; } temp = gsm_norm (L_power) ; R = SASR (L_max << temp, 16) ; S = SASR (L_power << temp, 16) ; /* Coding of the LTP gain */ /* Table 4.3a must be used to obtain the level DLB [i] for the * quantization of the LTP gain b to get the coded version bc. */ for (bc = 0 ; bc <= 2 ; bc++) if (R <= gsm_mult (S, gsm_DLB [bc])) break ; *bc_out = bc ; }
static void APCM_quantization ( word * xM, /* [0..12] IN */ word * xMc, /* [0..12] OUT */ word * mant_out, /* OUT */ word * exp_out, /* OUT */ word * xmaxc_out /* OUT */ ) { int i, itest; word xmax, xmaxc, temp, temp1, temp2; word exp, mant; /* Find the maximum absolute value xmax of xM[0..12]. */ xmax = 0; for (i = 0; i <= 12; i++) { temp = xM[i]; temp = GSM_ABS(temp); if (temp > xmax) xmax = temp; } /* Qantizing and coding of xmax to get xmaxc. */ exp = 0; temp = SASR( xmax, 9 ); itest = 0; for (i = 0; i <= 5; i++) { itest |= (temp <= 0); temp = SASR( temp, 1 ); assert(exp <= 5); if (itest == 0) exp++; /* exp = add (exp, 1) */ } assert(exp <= 6 && exp >= 0); temp = exp + 5; assert(temp <= 11 && temp >= 0); xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); /* Quantizing and coding of the xM[0..12] RPE sequence * to get the xMc[0..12] */ APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); /* This computation uses the fact that the decoded version of xmaxc * can be calculated by using the exponent and the mantissa part of * xmaxc (logarithmic table). * So, this method avoids any division and uses only a scaling * of the RPE samples by a function of the exponent. A direct * multiplication by the inverse of the mantissa (NRFAC[0..7] * found in table 4.5) gives the 3 bit coded version xMc[0..12] * of the RPE samples. */ /* Direct computation of xMc[0..12] using table 4.5 */ assert( exp <= 4096 && exp >= -4096); assert( mant >= 0 && mant <= 7 ); temp1 = 6 - exp; /* normalization by the exponent */ temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ for (i = 0; i <= 12; i++) { assert(temp1 >= 0 && temp1 < 16); temp = xM[i] << temp1; temp = GSM_MULT( temp, temp2 ); temp = SASR(temp, 12); xMc[i] = temp + 4; /* see note below */ } /* NOTE: This equation is used to make all the xMc[i] positive. */ *mant_out = mant; *exp_out = exp; *xmaxc_out = xmaxc; }
static void Weighting_filter ( register word * e, /* signal [-5..0.39.44] IN */ word * x /* signal [0..39] OUT */ ) /* * The coefficients of the weighting filter are stored in a table * (see table 4.4). The following scaling is used: * * H[0..10] = integer( real_H[ 0..10] * 8192 ); */ { /* word wt[ 50 ]; */ register longword L_result; register int k /* , i */ ; /* 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++; * for (k = 45; k <= 49; k++) wt[k] = 0; * * (e[-5..-1] and e[40..44] are allocated by the caller, * are initially zero and are not written anywhere.) */ e -= 5; /* Compute the signal x[0..39] */ for (k = 0; k <= 39; k++) { L_result = 8192 >> 1; /* for (i = 0; i <= 10; i++) { * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); * L_result = GSM_L_ADD( L_result, L_temp ); * } */ #undef STEP #define STEP( i, H ) (e[ k + i ] * (longword)H) /* Every one of these multiplications is done twice -- * but I don't see an elegant way to optimize this. * Do you? */ #ifdef STUPID_COMPILER L_result += STEP( 0, -134 ) ; L_result += STEP( 1, -374 ) ; /* + STEP( 2, 0 ) */ L_result += STEP( 3, 2054 ) ; L_result += STEP( 4, 5741 ) ; L_result += STEP( 5, 8192 ) ; L_result += STEP( 6, 5741 ) ; L_result += STEP( 7, 2054 ) ; /* + STEP( 8, 0 ) */ L_result += STEP( 9, -374 ) ; L_result += STEP( 10, -134 ) ; #else L_result += STEP( 0, -134 ) + STEP( 1, -374 ) /* + STEP( 2, 0 ) */ + STEP( 3, 2054 ) + STEP( 4, 5741 ) + STEP( 5, 8192 ) + STEP( 6, 5741 ) + STEP( 7, 2054 ) /* + STEP( 8, 0 ) */ + STEP( 9, -374 ) + STEP(10, -134 ) ; #endif /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) * * x[k] = SASR( L_result, 16 ); */ /* 2 adds vs. >>16 => 14, minus one shift to compensate for * those we lost when replacing L_MULT by '*'. */ L_result = SASR( L_result, 13 ); x[k] = ( L_result < MIN_WORD ? MIN_WORD : (L_result > MAX_WORD ? MAX_WORD : L_result )); } }
void Gsm_Preprocess ( struct gsm_state * S, word * s, word * so ) /* [0..159] IN/OUT */ { word z1 = S->z1; longword L_z2 = S->L_z2; word mp = S->mp; word s1; longword L_s2; longword L_temp; word msp, lsp; word SO; longword ltmp; /* for ADD */ ulongword utmp; /* for L_ADD */ register int k = 160; while (k--) { /* 4.2.1 Downscaling of the input signal */ SO = SASR( *s, 3 ) << 2; s++; assert (SO >= -0x4000); /* downscaled by */ assert (SO <= 0x3FFC); /* previous routine. */ /* 4.2.2 Offset compensation * * This part implements a high-pass filter and requires extended * arithmetic precision for the recursive part of this filter. * The input of this procedure is the array so[0...159] and the * output the array sof[ 0...159 ]. */ /* Compute the non-recursive part */ s1 = SO - z1; /* s1 = gsm_sub( *so, z1 ); */ z1 = SO; assert(s1 != MIN_WORD); /* Compute the recursive part */ L_s2 = s1; L_s2 <<= 15; /* Execution of a 31 bv 16 bits multiplication */ msp = SASR( L_z2, 15 ); lsp = L_z2-((longword)msp<<15); /* gsm_L_sub(L_z2,(msp<<15)); */ L_s2 += GSM_MULT_R( lsp, 32735 ); L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/ L_z2 = GSM_L_ADD( L_temp, L_s2 ); /* Compute sof[k] with rounding */ L_temp = GSM_L_ADD( L_z2, 16384 ); /* 4.2.3 Preemphasis */ msp = GSM_MULT_R( mp, -28180 ); mp = SASR( L_temp, 15 ); *so++ = GSM_ADD( mp, msp ); } S->z1 = z1; S->L_z2 = L_z2; S->mp = mp; }