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 ); } }
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; }
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; }
/* 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 Gsm_Long_Term_Synthesis_Filtering(struct gsm_state *S, gsmword Ncr, gsmword bcr, gsmword *erp, gsmword *drp) { int k; gsmword brp, Nr; gsmword * pdrp; Nr = (gsmword)(Ncr < 40 || Ncr > 120 ? S->nrp : Ncr); S->nrp = Nr; brp = gsm_QLB[ bcr ]; pdrp = drp; for(k = 40; k--; pdrp++) { *pdrp = (gsmword)(*erp++ + GSM_MULT_R( brp, pdrp[ -(Nr) ] )); } memcpy(&drp[-120], &drp[-80], (sizeof(drp[0]) * 120)); }
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_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 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); }