static void APCM_inverse_quantization ( register int16_t * xMc, /* [0..12] IN */ int16_t mant, int16_t expon, register int16_t * xMp) /* [0..12] OUT */ /* * This part is for decoding the RPE sequence of coded xMc [0..12] * samples to obtain the xMp[0..12] array. Table 4.6 is used to get * the mantissa of xmaxc (FAC[0..7]). */ { int i ; int16_t temp, temp1, temp2, temp3 ; assert (mant >= 0 && mant <= 7) ; temp1 = gsm_FAC [mant] ; /* see 4.2-15 for mant */ temp2 = gsm_sub (6, expon) ; /* see 4.2-15 for exp */ temp3 = gsm_asl (1, gsm_sub (temp2, 1)) ; for (i = 13 ; i-- ;) { assert (*xMc <= 7 && *xMc >= 0) ; /* 3 bit unsigned */ /* temp = gsm_sub (*xMc++ << 1, 7) ; */ temp = (*xMc++ << 1) - 7 ; /* restore sign */ assert (temp <= 7 && temp >= -7) ; /* 4 bit signed */ temp = arith_shift_left (temp, 12) ; /* 16 bit signed */ temp = GSM_MULT_R (temp1, temp) ; temp = GSM_ADD (temp, temp3) ; *xMp++ = gsm_asr (temp, temp2) ; } }
void Gsm_Preprocess ( struct gsm_state * S, int16_t * s, int16_t * so) /* [0..159] IN/OUT */ { int16_t z1 = S->z1 ; int32_t L_z2 = S->L_z2 ; int16_t mp = S->mp ; int16_t s1 ; int32_t L_s2 ; int32_t L_temp ; int16_t msp, lsp ; int16_t SO ; register int k = 160 ; while (k--) { /* 4.2.1 Downscaling of the input signal */ SO = arith_shift_left (SASR_W (*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 = arith_shift_left (L_s2, 15) ; /* Execution of a 31 bv 16 bits multiplication */ msp = SASR_L (L_z2, 15) ; lsp = L_z2 - arith_shift_left ((int32_t) msp, 15) ; /* gsm_L_sub (L_z2,(msp<<15)) ; */ L_s2 += GSM_MULT_R (lsp, 32735) ; L_temp = (int32_t) 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 (L_temp, 15) ; *so++ = GSM_ADD (mp, msp) ; } S->z1 = z1 ; S->L_z2 = L_z2 ; S->mp = mp ; }
static void APCM_quantization ( int16_t * xM, /* [0..12] IN */ int16_t * xMc, /* [0..12] OUT */ int16_t * mant_out, /* OUT */ int16_t * expon_out, /* OUT */ int16_t * xmaxc_out /* OUT */ ) { int i, itest ; int16_t xmax, xmaxc, temp, temp1, temp2 ; int16_t expon, 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. */ expon = 0 ; temp = SASR_W (xmax, 9) ; itest = 0 ; for (i = 0 ; i <= 5 ; i++) { itest |= (temp <= 0) ; temp = SASR_W (temp, 1) ; assert (expon <= 5) ; if (itest == 0) expon++ ; /* expon = add (expon, 1) */ } assert (expon <= 6 && expon >= 0) ; temp = expon + 5 ; assert (temp <= 11 && temp >= 0) ; xmaxc = gsm_add (SASR_W (xmax, temp), (int16_t) (expon << 3)) ; /* Quantizing and coding of the xM [0..12] RPE sequence * to get the xMc [0..12] */ APCM_quantization_xmaxc_to_exp_mant (xmaxc, &expon, &mant) ; /* This computation uses the fact that the decoded version of xmaxc * can be calculated by using the expononent 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 expononent. 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 (expon <= 4096 && expon >= -4096) ; assert (mant >= 0 && mant <= 7) ; temp1 = 6 - expon ; /* normalization by the expononent */ temp2 = gsm_NRFAC [mant] ; /* inverse mantissa */ for (i = 0 ; i <= 12 ; i++) { assert (temp1 >= 0 && temp1 < 16) ; temp = arith_shift_left (xM [i], temp1) ; temp = GSM_MULT (temp, temp2) ; temp = SASR_W (temp, 12) ; xMc [i] = temp + 4 ; /* see note below */ } /* NOTE: This equation is used to make all the xMc [i] positive. */ *mant_out = mant ; *expon_out = expon ; *xmaxc_out = xmaxc ; }