static void postprocessing(gsm0610_state_t *s, int16_t amp[]) { int k; int16_t msr; int16_t tmp; msr = s->msr; for (k = 0; k < GSM0610_FRAME_LEN; k++) { tmp = gsm_mult_r(msr, 28180); /* De-emphasis */ msr = gsm_add(amp[k], tmp); /* Truncation & upscaling */ amp[k] = (int16_t) (gsm_add(msr, msr) & 0xFFF8); } /*endfor*/ s->msr = msr; }
/* This procedure adds the reconstructed long term residual signal * ep[0..39] to the estimated signal dpp[0..39] from the long term * analysis filter to compute the reconstructed short term residual * signal dp[-40..-1] ; also the reconstructed short term residual * array dp[-120..-41] is updated. */ #if 0 /* Has been inlined in code.c */ void Gsm_Update_of_reconstructed_short_time_residual_signal ( int16_t * dpp, /* [0...39] IN */ int16_t * ep, /* [0...39] IN */ int16_t * dp) /* [-120...-1] IN/OUT */ { int k ; for (k = 0 ; k <= 79 ; k++) dp [-120 + k] = dp [-80 + k] ; for (k = 0 ; k <= 39 ; k++) dp [-40 + k] = gsm_add (ep [k], dpp [k]) ; }
/* The RPE-LTD coder works on a frame by frame basis. The length of the frame is equal to 160 samples. Some computations are done once per frame to produce at the output of the coder the LARc[1..8] parameters which are the coded LAR coefficients and also to realize the inverse filtering operation for the entire frame (160 samples of signal d[0..159]). These parts produce at the output of the coder: Procedure 4.2.11 to 4.2.18 are to be executed four times per frame. That means once for each sub-segment RPE-LTP analysis of 40 samples. These parts produce at the output of the coder. */ static void encode_a_frame(gsm0610_state_t *s, const int16_t amp[], gsm0610_frame_t *f) { int k; int16_t *dp; int16_t *dpp; int16_t so[GSM0610_FRAME_LEN]; int i; dp = s->dp0 + 120; dpp = dp; gsm0610_preprocess(s, amp, so); gsm0610_lpc_analysis(s, so, f->LARc); gsm0610_short_term_analysis_filter(s, f->LARc, so); for (k = 0; k < 4; k++) { gsm0610_long_term_predictor(s, so + k*40, dp, s->e + 5, dpp, &f->Nc[k], &f->bc[k]); gsm0610_rpe_encoding(s, s->e + 5, &f->xmaxc[k], &f->Mc[k], f->xMc[k]); for (i = 0; i < 40; i++) dp[i] = gsm_add(s->e[5 + i], dpp[i]); /*endfor*/ dp += 40; dpp += 40; } /*endfor*/ memcpy ((char *) s->dp0, (char *) (s->dp0 + GSM0610_FRAME_LEN), 120*sizeof(*s->dp0)); }
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; }