From 463845e0db4d8ed2a1e0902b1af35cdd891e2535 Mon Sep 17 00:00:00 2001 From: arpi Date: Sat, 13 Apr 2002 18:04:24 +0000 Subject: native codecs files moved to libmpcodecs/native/ git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@5604 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpcodecs/native/xa_gsm.c | 997 ++++++++++++++++++++++++++++++++++++++++ libmpcodecs/native/xa_gsm.h | 6 + libmpcodecs/native/xa_gsm_int.h | 114 +++++ 3 files changed, 1117 insertions(+) create mode 100644 libmpcodecs/native/xa_gsm.c create mode 100644 libmpcodecs/native/xa_gsm.h create mode 100644 libmpcodecs/native/xa_gsm_int.h (limited to 'libmpcodecs/native') diff --git a/libmpcodecs/native/xa_gsm.c b/libmpcodecs/native/xa_gsm.c new file mode 100644 index 0000000000..d014eaabbc --- /dev/null +++ b/libmpcodecs/native/xa_gsm.c @@ -0,0 +1,997 @@ + +/* + Written by Mark Podlipec . + + Most of this code comes from a GSM 06.10 library by + Jutta Degener and Carsten Bormann, available via + . + + That library is distributed with the following copyright: + + 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 +#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; +} diff --git a/libmpcodecs/native/xa_gsm.h b/libmpcodecs/native/xa_gsm.h new file mode 100644 index 0000000000..212fbe0e97 --- /dev/null +++ b/libmpcodecs/native/xa_gsm.h @@ -0,0 +1,6 @@ + +void XA_MSGSM_Decoder(unsigned char *ibuf,unsigned short *obuf); +void XA_GSM_Decoder(unsigned char *ibuf,unsigned short *obuf); +void GSM_Init(); + + diff --git a/libmpcodecs/native/xa_gsm_int.h b/libmpcodecs/native/xa_gsm_int.h new file mode 100644 index 0000000000..3bc0f051fc --- /dev/null +++ b/libmpcodecs/native/xa_gsm_int.h @@ -0,0 +1,114 @@ +/******************************************************************** + * + * 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. + * + ********************************************************************/ + +#include "xa_gsm.h" + + +typedef short word; /* 16 bit signed int */ +typedef int longword; /* 32 bit signed int */ + +typedef unsigned short uword; /* unsigned word */ +typedef unsigned int ulongword; /* unsigned longword */ + +typedef struct { + + word dp0[ 280 ]; + + word z1; /* preprocessing.c, Offset_com. */ + longword L_z2; /* Offset_com. */ + int mp; /* Preemphasis */ + + word u[8]; /* short_term_aly_filter.c */ + word LARpp[2][8]; /* */ + word j; /* */ + + word ltp_cut; /* long_term.c, LTP crosscorr. */ + word nrp; /* 40 */ /* long_term.c, synthesis */ + word v[9]; /* short_term.c, synthesis */ + word msr; /* decoder.c, Postprocessing */ + + char verbose; /* only used if !NDEBUG */ + char fast; /* only used if FAST */ + + char wav_fmt; /* only used if WAV49 defined */ + unsigned char frame_index; /* odd/even chaining */ + unsigned char frame_chain; /* half-byte to carry forward */ +} XA_GSM_STATE; + + +#define MIN_WORD (-32767 - 1) +#define MAX_WORD 32767 + +#define MIN_LONGWORD (-2147483647 - 1) +#define MAX_LONGWORD 2147483647 + +#ifdef SASR /* flag: >> is a signed arithmetic shift right */ +#undef SASR +#define SASR(x, by) ((x) >> (by)) +#else +#define SASR(x, by) ((x) >= 0 ? (x) >> (by) : (~(-((x) + 1) >> (by)))) +#endif /* SASR */ + + + +/* + * Inlined functions from add.h + */ + +/* + * #define GSM_MULT_R(a, b) (* word a, word b, !(a == b == MIN_WORD) *) \ + * (0x0FFFF & SASR(((longword)(a) * (longword)(b) + 16384), 15)) + */ +#define GSM_MULT_R(a, b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b) + 16384), 15 )) + +# define GSM_MULT(a,b) /* word a, word b, !(a == b == MIN_WORD) */ \ + (SASR( ((longword)(a) * (longword)(b)), 15 )) + +# define GSM_L_MULT(a, b) /* word a, word b */ \ + (((longword)(a) * (longword)(b)) << 1) + +# define GSM_L_ADD(a, b) \ + ( (a) < 0 ? ( (b) >= 0 ? (a) + (b) \ + : (utmp = (ulongword)-((a) + 1) + (ulongword)-((b) + 1)) \ + >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)utmp-2 ) \ + : ((b) <= 0 ? (a) + (b) \ + : (utmp = (ulongword)(a) + (ulongword)(b)) >= MAX_LONGWORD \ + ? MAX_LONGWORD : utmp)) + +/* + * # define GSM_ADD(a, b) \ + * ((ltmp = (longword)(a) + (longword)(b)) >= MAX_WORD \ + * ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + */ +/* Nonportable, but faster: */ + +#define GSM_ADD(a, b) \ + ((ulongword)((ltmp = (longword)(a) + (longword)(b)) - MIN_WORD) > \ + MAX_WORD - MIN_WORD ? (ltmp > 0 ? MAX_WORD : MIN_WORD) : ltmp) + +# define GSM_SUB(a, b) \ + ((ltmp = (longword)(a) - (longword)(b)) >= MAX_WORD \ + ? MAX_WORD : ltmp <= MIN_WORD ? MIN_WORD : ltmp) + +# define GSM_ABS(a) ((a) < 0 ? ((a) == MIN_WORD ? MAX_WORD : -(a)) : (a)) + +/* Use these if necessary: + +# define GSM_MULT_R(a, b) gsm_mult_r(a, b) +# define GSM_MULT(a, b) gsm_mult(a, b) +# define GSM_L_MULT(a, b) gsm_L_mult(a, b) + +# define GSM_L_ADD(a, b) gsm_L_add(a, b) +# define GSM_ADD(a, b) gsm_add(a, b) +# define GSM_SUB(a, b) gsm_sub(a, b) + +# define GSM_ABS(a) gsm_abs(a) + +*/ + -- cgit v1.2.3