/******************************************************************** Copyright 1992 by Jutta Degener and Carsten Bormann, Technische Universitaet Berlin Any use of this software is permitted provided that this notice is not removed and that neither the authors nor the Technische Universitaet Berlin are deemed to have made any representations as to the suitability of this software for any purpose nor are held responsible for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. As a matter of courtesy, the authors request to be informed about uses this software has found, about bugs in this software, and about any improvements that may be of general interest. Berlin, 15.09.1992 Jutta Degener Carsten Bormann ********************************************************************/ #include #include /* POD optional */ #include "xa_gsm_int.h" //void XA_MSGSM_Decoder(); static void GSM_Decode(); static void Gsm_RPE_Decoding(); //static short gsm_buf[320]; static XA_GSM_STATE gsm_state; unsigned char xa_sign_2_ulaw[256]; unsigned char XA_Signed_To_uLaw(long ch) { long mask; if (ch < 0) { ch = -ch; mask = 0x7f; } else { mask = 0xff; } if (ch < 32) { ch = 0xF0 | (15 - (ch / 2)); } else if (ch < 96) { ch = 0xE0 | (15 - (ch - 32) / 4); } else if (ch < 224) { ch = 0xD0 | (15 - (ch - 96) / 8); } else if (ch < 480) { ch = 0xC0 | (15 - (ch - 224) / 16); } else if (ch < 992) { ch = 0xB0 | (15 - (ch - 480) / 32); } else if (ch < 2016) { ch = 0xA0 | (15 - (ch - 992) / 64); } else if (ch < 4064) { ch = 0x90 | (15 - (ch - 2016) / 128); } else if (ch < 8160) { ch = 0x80 | (15 - (ch - 4064) / 256); } else { ch = 0x80; } return (mask & ch); } void Gen_Signed_2_uLaw() { unsigned long i; for(i=0;i<256;i++) { unsigned char d; char ch = i; long chr = ch; d = XA_Signed_To_uLaw(chr * 16); xa_sign_2_ulaw[i] = d; } } void GSM_Init() { memset((char *)(&gsm_state), 0, sizeof(XA_GSM_STATE)); gsm_state.nrp = 40; Gen_Signed_2_uLaw(); } /* Table 4.3b Quantization levels of the LTP gain quantizer */ /* bc 0 1 2 3 */ static word gsm_QLB[4] = { 3277, 11469, 21299, 32767 }; /* Table 4.6 Normalized direct mantissa used to compute xM/xmax */ /* i 0 1 2 3 4 5 6 7 */ static word gsm_FAC[8] = { 18431, 20479, 22527, 24575, 26623, 28671, 30719, 32767 }; /****************/ #define saturate(x) \ ((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x)) /****************/ static word gsm_sub (a,b) word a; word b; { longword diff = (longword)a - (longword)b; return saturate(diff); } /****************/ static word gsm_asr (a,n) word a; int n; { if (n >= 16) return -(a < 0); if (n <= -16) return 0; if (n < 0) return a << -n; # ifdef SASR return a >> n; # else if (a >= 0) return a >> n; else return -(word)( -(uword)a >> n ); # endif } /****************/ static word gsm_asl (a,n) word a; int n; { if (n >= 16) return 0; if (n <= -16) return -(a < 0); if (n < 0) return gsm_asr(a, -n); return a << n; } /* * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. */ /**** 4.2.17 */ static void RPE_grid_positioning(Mc,xMp,ep) word Mc; /* grid position IN */ register word * xMp; /* [0..12] IN */ register word * ep; /* [0..39] OUT */ /* * This procedure computes the reconstructed long term residual signal * ep[0..39] for the LTP analysis filter. The inputs are the Mc * which is the grid position selection and the xMp[0..12] decoded * RPE samples which are upsampled by a factor of 3 by inserting zero * values. */ { int i = 13; assert(0 <= Mc && Mc <= 3); switch (Mc) { case 3: *ep++ = 0; case 2: do { *ep++ = 0; case 1: *ep++ = 0; case 0: *ep++ = *xMp++; } while (--i); } while (++Mc < 4) *ep++ = 0; /* int i, k; for (k = 0; k <= 39; k++) ep[k] = 0; for (i = 0; i <= 12; i++) { ep[ Mc + (3*i) ] = xMp[i]; } */ } /**** 4.2.16 */ static void APCM_inverse_quantization (xMc,mant,exp,xMp) 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 ); } } /**** 4.12.15 */ static void APCM_quantization_xmaxc_to_exp_mant (xmaxc,exp_out,mant_out) 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 Gsm_RPE_Decoding (S, xmaxcr, Mcr, xMcr, erp) XA_GSM_STATE * S; word xmaxcr; word Mcr; word * xMcr; /* [0..12], 3 bits IN */ word * erp; /* [0..39] OUT */ { word exp, mant; word xMp[ 13 ]; APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); APCM_inverse_quantization( xMcr, mant, exp, xMp ); RPE_grid_positioning( Mcr, xMp, erp ); } /* * 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER */ static void Postprocessing(S,s) XA_GSM_STATE * S; register word * s; { register int k; register word msr = S->msr; register longword ltmp; /* for GSM_ADD */ register word 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 (S,Ncr,bcr,erp,drp) XA_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 longword ltmp; /* for ADD */ 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 Short_term_synthesis_filtering (S,rrp,k,wt,sr) XA_GSM_STATE *S; register word *rrp; /* [0..7] IN */ register int k; /* k_end - k_start */ register word *wt; /* [0..k-1] IN */ register word *sr; /* [0..k-1] OUT */ { register word * v = S->v; register int i; register word sri, tmp1, tmp2; register longword ltmp; /* for GSM_ADD & GSM_SUB */ while (k--) { sri = *wt++; for (i = 8; i--;) { /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); */ tmp1 = rrp[i]; tmp2 = v[i]; tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 + 16384) >> 15)) ; sri = GSM_SUB( sri, tmp2 ); /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); */ tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD ? MAX_WORD : 0x0FFFF & (( (longword)tmp1 * (longword)sri + 16384) >> 15)) ; v[i+1] = GSM_ADD( v[i], tmp1); } *sr++ = v[0] = sri; } } /* 4.2.8 */ static void Decoding_of_the_coded_Log_Area_Ratios (LARc,LARpp) word * LARc; /* coded log area ratio [0..7] IN */ word * LARpp; /* out: decoded .. */ { register word temp1 /* , temp2 */; register long ltmp; /* for GSM_ADD */ /* This procedure requires for efficient implementation * two tables. * * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) * MIC[1..8] = minimum value of the LARc[1..8] */ /* Compute the LARpp[1..8] */ /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { * * temp1 = GSM_ADD( *LARc, *MIC ) << 10; * temp2 = *B << 1; * temp1 = GSM_SUB( temp1, temp2 ); * * assert(*INVA != MIN_WORD); * * temp1 = GSM_MULT_R( *INVA, temp1 ); * *LARpp = GSM_ADD( temp1, temp1 ); * } */ #undef STEP #define STEP( B, MIC, INVA ) \ temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ temp1 = GSM_SUB( temp1, B << 1 ); \ temp1 = GSM_MULT_R( INVA, temp1 ); \ *LARpp++ = GSM_ADD( temp1, temp1 ); STEP( 0, -32, 13107 ); STEP( 0, -32, 13107 ); STEP( 2048, -16, 13107 ); STEP( -2560, -16, 13107 ); STEP( 94, -8, 19223 ); STEP( -1792, -8, 17476 ); STEP( -341, -4, 31454 ); STEP( -1144, -4, 29708 ); /* NOTE: the addition of *MIC is used to restore * the sign of *LARc. */ } /* 4.2.9 */ /* Computation of the quantized reflection coefficients */ /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] */ /* * Within each frame of 160 analyzed speech samples the short term * analysis and synthesis filters operate with four different sets of * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) * and the actual set of decoded LARs (LARpp(j)) * * (Initial value: LARpp(j-1)[1..8] = 0.) */ static void Coefficients_0_12 (LARpp_j_1, LARpp_j, LARp) register word * LARpp_j_1; register word * LARpp_j; register word * LARp; { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); } } static void Coefficients_13_26 (LARpp_j_1, LARpp_j, LARp) register word * LARpp_j_1; register word * LARpp_j; register word * LARp; { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); } } static void Coefficients_27_39 (LARpp_j_1, LARpp_j, LARp) register word * LARpp_j_1; register word * LARpp_j; register word * LARp; { register int i; register longword ltmp; for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); } } static void Coefficients_40_159 (LARpp_j, LARp) register word * LARpp_j; register word * LARp; { register int i; for (i = 1; i <= 8; i++, LARp++, LARpp_j++) *LARp = *LARpp_j; } /* 4.2.9.2 */ static void LARp_to_rp (LARp) register word * LARp; /* [0..7] IN/OUT */ /* * The input of this procedure is the interpolated LARp[0..7] array. * The reflection coefficients, rp[i], are used in the analysis * filter and in the synthesis filter. */ { register int i; register word temp; register longword ltmp; for (i = 1; i <= 8; i++, LARp++) { /* temp = GSM_ABS( *LARp ); * * if (temp < 11059) temp <<= 1; * else if (temp < 20070) temp += 11059; * else temp = GSM_ADD( temp >> 2, 26112 ); * * *LARp = *LARp < 0 ? -temp : temp; */ if (*LARp < 0) { temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); *LARp = - ((temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 ))); } else { temp = *LARp; *LARp = (temp < 11059) ? temp << 1 : ((temp < 20070) ? temp + 11059 : GSM_ADD( temp >> 2, 26112 )); } } } /**** */ static void Gsm_Short_Term_Synthesis_Filter (S, LARcr, wt, s) XA_GSM_STATE * S; word * LARcr; /* received log area ratios [0..7] IN */ word * wt; /* received d [0..159] IN */ word * s; /* signal s [0..159] OUT */ { word * LARpp_j = S->LARpp[ S->j ]; word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; word LARp[8]; #undef FILTER #if defined(FAST) && defined(USE_FLOAT_MUL) # define FILTER (* (S->fast \ ? Fast_Short_term_synthesis_filtering \ : Short_term_synthesis_filtering )) #else # define FILTER Short_term_synthesis_filtering #endif Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt, s ); Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 14, wt + 13, s + 13 ); Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); LARp_to_rp( LARp ); FILTER( S, LARp, 13, wt + 27, s + 27 ); Coefficients_40_159( LARpp_j, LARp ); LARp_to_rp( LARp ); FILTER(S, LARp, 120, wt + 40, s + 40); } static void GSM_Decode(S,LARcr, Ncr,bcr,Mcr,xmaxcr,xMcr,s) XA_GSM_STATE *S; word *LARcr; /* [0..7] IN */ word *Ncr; /* [0..3] IN */ word *bcr; /* [0..3] IN */ word *Mcr; /* [0..3] IN */ word *xmaxcr; /* [0..3] IN */ word *xMcr; /* [0..13*4] IN */ word *s; /* [0..159] OUT */ { int j, k; word erp[40], wt[160]; word *drp = S->dp0 + 120; for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) { Gsm_RPE_Decoding( S, *xmaxcr, *Mcr, xMcr, erp ); Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp ); for (k = 0; k <= 39; k++) wt[ j * 40 + k ] = drp[ k ]; } Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s ); Postprocessing(S, s); } /****-------------------------------------------------------------------**** **** Podlipec: For AVI/WAV files GSM 6.10 combines two 33 bytes frames **** into one 65 byte frame. ****-------------------------------------------------------------------****/ void XA_MSGSM_Decoder(unsigned char *ibuf,unsigned short *obuf) { word sr; word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; sr = *ibuf++; LARc[0] = sr & 0x3f; sr >>= 6; sr |= (word)*ibuf++ << 2; LARc[1] = sr & 0x3f; sr >>= 6; sr |= (word)*ibuf++ << 4; LARc[2] = sr & 0x1f; sr >>= 5; LARc[3] = sr & 0x1f; sr >>= 5; sr |= (word)*ibuf++ << 2; LARc[4] = sr & 0xf; sr >>= 4; LARc[5] = sr & 0xf; sr >>= 4; sr |= (word)*ibuf++ << 2; /* 5 */ LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 4; Nc[0] = sr & 0x7f; sr >>= 7; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 1; xmaxc[0] = sr & 0x3f; sr >>= 6; xmc[0] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[1] = sr & 0x7; sr >>= 3; xmc[2] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; xmc[5] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; /* 10 */ xmc[6] = sr & 0x7; sr >>= 3; xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[9] = sr & 0x7; sr >>= 3; xmc[10] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 4; Nc[1] = sr & 0x7f; sr >>= 7; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 1; xmaxc[1] = sr & 0x3f; sr >>= 6; xmc[13] = sr & 0x7; sr >>= 3; sr = *ibuf++; /* 15 */ xmc[14] = sr & 0x7; sr >>= 3; xmc[15] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; xmc[18] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[19] = sr & 0x7; sr >>= 3; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[22] = sr & 0x7; sr >>= 3; xmc[23] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 4; /* 20 */ Nc[2] = sr & 0x7f; sr >>= 7; bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 1; xmaxc[2] = sr & 0x3f; sr >>= 6; xmc[26] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[27] = sr & 0x7; sr >>= 3; xmc[28] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; xmc[31] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[32] = sr & 0x7; sr >>= 3; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; sr = *ibuf++; /* 25 */ xmc[35] = sr & 0x7; sr >>= 3; xmc[36] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 4; Nc[3] = sr & 0x7f; sr >>= 7; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 1; xmaxc[3] = sr & 0x3f; sr >>= 6; xmc[39] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[40] = sr & 0x7; sr >>= 3; xmc[41] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; /* 30 */ xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; xmc[44] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[45] = sr & 0x7; sr >>= 3; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[48] = sr & 0x7; sr >>= 3; xmc[49] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; GSM_Decode(&gsm_state, LARc, Nc, bc, Mc, xmaxc, xmc, obuf); /* carry = sr & 0xf; sr = carry; */ /* 2nd frame */ sr &= 0xf; sr |= (word)*ibuf++ << 4; /* 1 */ LARc[0] = sr & 0x3f; sr >>= 6; LARc[1] = sr & 0x3f; sr >>= 6; sr = *ibuf++; LARc[2] = sr & 0x1f; sr >>= 5; sr |= (word)*ibuf++ << 3; LARc[3] = sr & 0x1f; sr >>= 5; LARc[4] = sr & 0xf; sr >>= 4; sr |= (word)*ibuf++ << 2; LARc[5] = sr & 0xf; sr >>= 4; LARc[6] = sr & 0x7; sr >>= 3; LARc[7] = sr & 0x7; sr >>= 3; sr = *ibuf++; /* 5 */ Nc[0] = sr & 0x7f; sr >>= 7; sr |= (word)*ibuf++ << 1; bc[0] = sr & 0x3; sr >>= 2; Mc[0] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 5; xmaxc[0] = sr & 0x3f; sr >>= 6; xmc[0] = sr & 0x7; sr >>= 3; xmc[1] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[2] = sr & 0x7; sr >>= 3; xmc[3] = sr & 0x7; sr >>= 3; xmc[4] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[5] = sr & 0x7; sr >>= 3; xmc[6] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; /* 10 */ xmc[7] = sr & 0x7; sr >>= 3; xmc[8] = sr & 0x7; sr >>= 3; xmc[9] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[10] = sr & 0x7; sr >>= 3; xmc[11] = sr & 0x7; sr >>= 3; xmc[12] = sr & 0x7; sr >>= 3; sr = *ibuf++; Nc[1] = sr & 0x7f; sr >>= 7; sr |= (word)*ibuf++ << 1; bc[1] = sr & 0x3; sr >>= 2; Mc[1] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 5; xmaxc[1] = sr & 0x3f; sr >>= 6; xmc[13] = sr & 0x7; sr >>= 3; xmc[14] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; /* 15 */ xmc[15] = sr & 0x7; sr >>= 3; xmc[16] = sr & 0x7; sr >>= 3; xmc[17] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[18] = sr & 0x7; sr >>= 3; xmc[19] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[20] = sr & 0x7; sr >>= 3; xmc[21] = sr & 0x7; sr >>= 3; xmc[22] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[23] = sr & 0x7; sr >>= 3; xmc[24] = sr & 0x7; sr >>= 3; xmc[25] = sr & 0x7; sr >>= 3; sr = *ibuf++; Nc[2] = sr & 0x7f; sr >>= 7; sr |= (word)*ibuf++ << 1; /* 20 */ bc[2] = sr & 0x3; sr >>= 2; Mc[2] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 5; xmaxc[2] = sr & 0x3f; sr >>= 6; xmc[26] = sr & 0x7; sr >>= 3; xmc[27] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[28] = sr & 0x7; sr >>= 3; xmc[29] = sr & 0x7; sr >>= 3; xmc[30] = sr & 0x7; sr >>= 3; sr = *ibuf++; xmc[31] = sr & 0x7; sr >>= 3; xmc[32] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[33] = sr & 0x7; sr >>= 3; xmc[34] = sr & 0x7; sr >>= 3; xmc[35] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; /* 25 */ xmc[36] = sr & 0x7; sr >>= 3; xmc[37] = sr & 0x7; sr >>= 3; xmc[38] = sr & 0x7; sr >>= 3; sr = *ibuf++; Nc[3] = sr & 0x7f; sr >>= 7; sr |= (word)*ibuf++ << 1; bc[3] = sr & 0x3; sr >>= 2; Mc[3] = sr & 0x3; sr >>= 2; sr |= (word)*ibuf++ << 5; xmaxc[3] = sr & 0x3f; sr >>= 6; xmc[39] = sr & 0x7; sr >>= 3; xmc[40] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[41] = sr & 0x7; sr >>= 3; xmc[42] = sr & 0x7; sr >>= 3; xmc[43] = sr & 0x7; sr >>= 3; sr = (word)*ibuf++; /* 30 */ xmc[44] = sr & 0x7; sr >>= 3; xmc[45] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 2; xmc[46] = sr & 0x7; sr >>= 3; xmc[47] = sr & 0x7; sr >>= 3; xmc[48] = sr & 0x7; sr >>= 3; sr |= (word)*ibuf++ << 1; xmc[49] = sr & 0x7; sr >>= 3; xmc[50] = sr & 0x7; sr >>= 3; xmc[51] = sr & 0x7; sr >>= 3; GSM_Decode(&gsm_state, LARc, Nc, bc, Mc, xmaxc, xmc, &obuf[160]); /* Return number of source bytes consumed and output samples produced */ // *icnt = 65; // *ocnt = 320; return; } #define GSM_MAGIC 0xd void XA_GSM_Decoder(unsigned char *ibuf,unsigned short *obuf) { word LARc[8], Nc[4], Mc[4], bc[4], xmaxc[4], xmc[13*4]; /* Sanity */ if (((*ibuf >> 4) & 0x0F) != GSM_MAGIC) { int i; for(i=0;i<160;i++) obuf[i] = 0; // *icnt = 33; // *ocnt = 160; return; } LARc[0] = (*ibuf++ & 0xF) << 2; /* 1 */ LARc[0] |= (*ibuf >> 6) & 0x3; LARc[1] = *ibuf++ & 0x3F; LARc[2] = (*ibuf >> 3) & 0x1F; LARc[3] = (*ibuf++ & 0x7) << 2; LARc[3] |= (*ibuf >> 6) & 0x3; LARc[4] = (*ibuf >> 2) & 0xF; LARc[5] = (*ibuf++ & 0x3) << 2; LARc[5] |= (*ibuf >> 6) & 0x3; LARc[6] = (*ibuf >> 3) & 0x7; LARc[7] = *ibuf++ & 0x7; Nc[0] = (*ibuf >> 1) & 0x7F; bc[0] = (*ibuf++ & 0x1) << 1; bc[0] |= (*ibuf >> 7) & 0x1; Mc[0] = (*ibuf >> 5) & 0x3; xmaxc[0] = (*ibuf++ & 0x1F) << 1; xmaxc[0] |= (*ibuf >> 7) & 0x1; xmc[0] = (*ibuf >> 4) & 0x7; xmc[1] = (*ibuf >> 1) & 0x7; xmc[2] = (*ibuf++ & 0x1) << 2; xmc[2] |= (*ibuf >> 6) & 0x3; xmc[3] = (*ibuf >> 3) & 0x7; xmc[4] = *ibuf++ & 0x7; xmc[5] = (*ibuf >> 5) & 0x7; xmc[6] = (*ibuf >> 2) & 0x7; xmc[7] = (*ibuf++ & 0x3) << 1; /* 10 */ xmc[7] |= (*ibuf >> 7) & 0x1; xmc[8] = (*ibuf >> 4) & 0x7; xmc[9] = (*ibuf >> 1) & 0x7; xmc[10] = (*ibuf++ & 0x1) << 2; xmc[10] |= (*ibuf >> 6) & 0x3; xmc[11] = (*ibuf >> 3) & 0x7; xmc[12] = *ibuf++ & 0x7; Nc[1] = (*ibuf >> 1) & 0x7F; bc[1] = (*ibuf++ & 0x1) << 1; bc[1] |= (*ibuf >> 7) & 0x1; Mc[1] = (*ibuf >> 5) & 0x3; xmaxc[1] = (*ibuf++ & 0x1F) << 1; xmaxc[1] |= (*ibuf >> 7) & 0x1; xmc[13] = (*ibuf >> 4) & 0x7; xmc[14] = (*ibuf >> 1) & 0x7; xmc[15] = (*ibuf++ & 0x1) << 2; xmc[15] |= (*ibuf >> 6) & 0x3; xmc[16] = (*ibuf >> 3) & 0x7; xmc[17] = *ibuf++ & 0x7; xmc[18] = (*ibuf >> 5) & 0x7; xmc[19] = (*ibuf >> 2) & 0x7; xmc[20] = (*ibuf++ & 0x3) << 1; xmc[20] |= (*ibuf >> 7) & 0x1; xmc[21] = (*ibuf >> 4) & 0x7; xmc[22] = (*ibuf >> 1) & 0x7; xmc[23] = (*ibuf++ & 0x1) << 2; xmc[23] |= (*ibuf >> 6) & 0x3; xmc[24] = (*ibuf >> 3) & 0x7; xmc[25] = *ibuf++ & 0x7; Nc[2] = (*ibuf >> 1) & 0x7F; bc[2] = (*ibuf++ & 0x1) << 1; /* 20 */ bc[2] |= (*ibuf >> 7) & 0x1; Mc[2] = (*ibuf >> 5) & 0x3; xmaxc[2] = (*ibuf++ & 0x1F) << 1; xmaxc[2] |= (*ibuf >> 7) & 0x1; xmc[26] = (*ibuf >> 4) & 0x7; xmc[27] = (*ibuf >> 1) & 0x7; xmc[28] = (*ibuf++ & 0x1) << 2; xmc[28] |= (*ibuf >> 6) & 0x3; xmc[29] = (*ibuf >> 3) & 0x7; xmc[30] = *ibuf++ & 0x7; xmc[31] = (*ibuf >> 5) & 0x7; xmc[32] = (*ibuf >> 2) & 0x7; xmc[33] = (*ibuf++ & 0x3) << 1; xmc[33] |= (*ibuf >> 7) & 0x1; xmc[34] = (*ibuf >> 4) & 0x7; xmc[35] = (*ibuf >> 1) & 0x7; xmc[36] = (*ibuf++ & 0x1) << 2; xmc[36] |= (*ibuf >> 6) & 0x3; xmc[37] = (*ibuf >> 3) & 0x7; xmc[38] = *ibuf++ & 0x7; Nc[3] = (*ibuf >> 1) & 0x7F; bc[3] = (*ibuf++ & 0x1) << 1; bc[3] |= (*ibuf >> 7) & 0x1; Mc[3] = (*ibuf >> 5) & 0x3; xmaxc[3] = (*ibuf++ & 0x1F) << 1; xmaxc[3] |= (*ibuf >> 7) & 0x1; xmc[39] = (*ibuf >> 4) & 0x7; xmc[40] = (*ibuf >> 1) & 0x7; xmc[41] = (*ibuf++ & 0x1) << 2; xmc[41] |= (*ibuf >> 6) & 0x3; xmc[42] = (*ibuf >> 3) & 0x7; xmc[43] = *ibuf++ & 0x7; /* 30 */ xmc[44] = (*ibuf >> 5) & 0x7; xmc[45] = (*ibuf >> 2) & 0x7; xmc[46] = (*ibuf++ & 0x3) << 1; xmc[46] |= (*ibuf >> 7) & 0x1; xmc[47] = (*ibuf >> 4) & 0x7; xmc[48] = (*ibuf >> 1) & 0x7; xmc[49] = (*ibuf++ & 0x1) << 2; xmc[49] |= (*ibuf >> 6) & 0x3; xmc[50] = (*ibuf >> 3) & 0x7; xmc[51] = *ibuf & 0x7; /* 33 */ GSM_Decode(&gsm_state, LARc, Nc, bc, Mc, xmaxc, xmc, obuf); /* Return number of source bytes consumed and output samples produced */ // *icnt = 33; // *ocnt = 160; }