static void Postprocessing(struct gsm_state *S, register int16_t * s) { register int k; register int16_t msr = S->msr; register volatile int32_t ltmp; /* for GSM_ADD */ register int16_t tmp; for (k = 160; k--; s++) { tmp = GSM_MULT_R(msr, 28180); msr = GSM_ADD(*s, tmp); /* Deemphasis */ *s = GSM_ADD(msr, msr) & 0xFFF8; /* Truncation & Upscaling */ } S->msr = msr; }
static void APCM_inverse_quantization ( register word * xMc, /* [0..12] IN */ word mant, word exp, register word * 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; word temp, temp1, temp2, temp3; longword ltmp; assert( mant >= 0 && mant <= 7 ); temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ temp2 = gsm_sub( 6, exp ); /* 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 <<= 12; /* 16 bit signed */ temp = GSM_MULT_R( temp1, temp ); temp = GSM_ADD( temp, temp3 ); *xMp++ = gsm_asr( temp, temp2 ); } }
static void Short_term_synthesis_filtering(struct gsm_state *S, gsmword *rrp, int k, gsmword *wt, short *sr) { gsmword * v = S->v; gsmword sri; longword ltmp; gsmword v0=v[0], v1=v[1], v2=v[2], v3=v[3], v4=v[4], v5=v[5], v6=v[6], v7=v[7]; gsmword rrp0, rrp1, rrp2, rrp3, rrp4, rrp5, rrp6, rrp7; rrp0 = rrp[0]; rrp1 = rrp[1]; rrp2 = rrp[2]; rrp3 = rrp[3]; rrp4 = rrp[4]; rrp5 = rrp[5]; rrp6 = rrp[6]; rrp7 = rrp[7]; while(k-- != 0) { sri = *wt++; sri -= (gsmword)GSM_MULT_R(rrp7, v7); sri -= (gsmword)GSM_MULT_R(rrp6, v6); v7 = v6 + (gsmword)GSM_MULT_R(rrp6, sri); sri -= (gsmword)GSM_MULT_R(rrp5, v5); v6 = v5 + (gsmword)GSM_MULT_R(rrp5, sri); sri -= (gsmword)GSM_MULT_R(rrp4, v4); v5 = v4 + (gsmword)GSM_MULT_R(rrp4, sri); sri -= (gsmword)GSM_MULT_R(rrp3, v3); v4 = v3 + (gsmword)GSM_MULT_R(rrp3, sri); sri -= (gsmword)GSM_MULT_R(rrp2, v2); v3 = v2 + (gsmword)GSM_MULT_R(rrp2, sri); sri -= (gsmword)GSM_MULT_R(rrp1, v1); v2 = v1 + (gsmword)GSM_MULT_R(rrp1, sri); sri = (gsmword)GSM_SUB( sri, (gsmword)GSM_MULT_R(rrp0, v0) ); v1 = v0 + (gsmword)GSM_MULT_R(rrp0, sri); v0 = sri; *sr++ = (short)sri; } v[0]=GSM_ADD(v0, 0); v[1]=GSM_ADD(v1, 0); v[2]=GSM_ADD(v2, 0); v[3]=GSM_ADD(v3, 0); v[4]=GSM_ADD(v4, 0); v[5]=GSM_ADD(v5, 0); v[6]=GSM_ADD(v6, 0); v[7]=GSM_ADD(v7, 0); }
INLINE void Postprocessing(struct gsm_state *S, short *s) { int k; gsmword msr = S->msr; longword ltmp; for(k = 160; k--; s++) { msr = *s + (gsmword)GSM_MULT_R( msr, 28672 ); /* Deemphasis */ *s = (short)(GSM_ADD(msr, msr) & 0xFFF8); /* Truncation & Upscaling */ } S->msr = msr; }
/* 4.3.2 */ void Gsm_Long_Term_Synthesis_Filtering ( struct gsm_state * S, word Ncr, word bcr, register word * erp, /* [0..39] IN */ register word * drp /* [-120..-1] IN, [-120..40] OUT */ ) /* * This procedure uses the bcr and Ncr parameter to realize the * long term synthesis filtering. The decoding of bcr needs * table 4.3b. */ { register int k; word brp, drpp, Nr; /* Check the limits of Nr. */ Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; S->nrp = Nr; assert(Nr >= 40 && Nr <= 120); /* Decoding of the LTP gain bcr */ brp = gsm_QLB[ bcr ]; /* Computation of the reconstructed short term residual * signal drp[0..39] */ assert(brp != MIN_WORD); for (k = 0; k <= 39; k++) { drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); drp[k] = GSM_ADD( erp[k], drpp ); } /* * Update of the reconstructed short term residual signal * drp[ -1..-120 ] */ for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; }
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 ); } }
void Gsm_Coder ( struct gsm_state * State, int16_t * s, /* [0..159] samples IN */ /* * 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: */ int16_t * LARc, /* [0..7] LAR coefficients OUT */ /* * 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: */ int16_t *Nc, /* [0..3] LTP lag OUT */ int16_t *bc, /* [0..3] coded LTP gain OUT */ int16_t *Mc, /* [0..3] RPE grid selection OUT */ int16_t *xmaxc, /* [0..3] Coded maximum amplitude OUT */ int16_t *xMc /* [13*4] normalized RPE samples OUT */ ) { int k ; int16_t *dp = State->dp0 + 120 ; /* [-120...-1] */ int16_t *dpp = dp ; /* [0...39] */ int16_t so [160] ; Gsm_Preprocess (State, s, so) ; Gsm_LPC_Analysis (State, so, LARc) ; Gsm_Short_Term_Analysis_Filter (State, LARc, so) ; for (k = 0 ; k <= 3 ; k++, xMc += 13) { Gsm_Long_Term_Predictor (State, so+k*40, /* d [0..39] IN */ dp, /* dp [-120..-1] IN */ State->e + 5, /* e [0..39] OUT */ dpp, /* dpp [0..39] OUT */ Nc++, bc++) ; Gsm_RPE_Encoding (/*-S,-*/ State->e + 5, /* e ][0..39][IN/OUT */ xmaxc++, Mc++, xMc) ; /* * Gsm_Update_of_reconstructed_short_time_residual_signal * (dpp, State->e + 5, dp) ; */ { register int i ; for (i = 0 ; i <= 39 ; i++) dp [i] = GSM_ADD (State->e [5 + i], dpp [i]) ; } dp += 40 ; dpp += 40 ; } memcpy ((char *) State->dp0, (char *) (State->dp0 + 160), 120 * sizeof (*State->dp0)) ; }
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 ; }