/*1* Copyright 1992 by Jutta Degener and Carsten Bormann, Technische2* Universitaet Berlin. See the accompanying file "COPYRIGHT" for3* details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.4*/56/* $Header: /tmp_amd/presto/export/kbs/jutta/src/gsm/RCS/rpe.c,v 1.3 1994/05/10 20:18:46 jutta Exp $ */78#include <stdio.h>9#include <assert.h>1011#include "private.h"1213#include "gsm.h"14#include "proto.h"1516/* 4.2.13 .. 4.2.17 RPE ENCODING SECTION17*/1819/* 4.2.13 */2021static void Weighting_filter P2((e, x),22register word * e, /* signal [-5..0.39.44] IN */23word * x /* signal [0..39] OUT */24)25/*26* The coefficients of the weighting filter are stored in a table27* (see table 4.4). The following scaling is used:28*29* H[0..10] = integer( real_H[ 0..10] * 8192 );30*/31{32/* word wt[ 50 ]; */3334register longword L_result;35register int k /* , i */ ;3637/* Initialization of a temporary working array wt[0...49]38*/3940/* for (k = 0; k <= 4; k++) wt[k] = 0;41* for (k = 5; k <= 44; k++) wt[k] = *e++;42* for (k = 45; k <= 49; k++) wt[k] = 0;43*44* (e[-5..-1] and e[40..44] are allocated by the caller,45* are initially zero and are not written anywhere.)46*/47e -= 5;4849/* Compute the signal x[0..39]50*/51for (k = 0; k <= 39; k++) {5253L_result = 8192 >> 1;5455/* for (i = 0; i <= 10; i++) {56* L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] );57* L_result = GSM_L_ADD( L_result, L_temp );58* }59*/6061#undef STEP62#define STEP( i, H ) (e[ k + i ] * (longword)H)6364/* Every one of these multiplications is done twice --65* but I don't see an elegant way to optimize this.66* Do you?67*/6869#ifdef STUPID_COMPILER70L_result += STEP( 0, -134 ) ;71L_result += STEP( 1, -374 ) ;72/* + STEP( 2, 0 ) */73L_result += STEP( 3, 2054 ) ;74L_result += STEP( 4, 5741 ) ;75L_result += STEP( 5, 8192 ) ;76L_result += STEP( 6, 5741 ) ;77L_result += STEP( 7, 2054 ) ;78/* + STEP( 8, 0 ) */79L_result += STEP( 9, -374 ) ;80L_result += STEP( 10, -134 ) ;81#else82L_result +=83STEP( 0, -134 )84+ STEP( 1, -374 )85/* + STEP( 2, 0 ) */86+ STEP( 3, 2054 )87+ STEP( 4, 5741 )88+ STEP( 5, 8192 )89+ STEP( 6, 5741 )90+ STEP( 7, 2054 )91/* + STEP( 8, 0 ) */92+ STEP( 9, -374 )93+ STEP(10, -134 )94;95#endif9697/* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *)98* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *)99*100* x[k] = SASR( L_result, 16 );101*/102103/* 2 adds vs. >>16 => 14, minus one shift to compensate for104* those we lost when replacing L_MULT by '*'.105*/106107L_result = SASR( L_result, 13 );108x[k] = ( L_result < MIN_WORD ? MIN_WORD109: (L_result > MAX_WORD ? MAX_WORD : L_result ));110}111}112113/* 4.2.14 */114115static void RPE_grid_selection P3((x,xM,Mc_out),116word * x, /* [0..39] IN */117word * xM, /* [0..12] OUT */118word * Mc_out /* OUT */119)120/*121* The signal x[0..39] is used to select the RPE grid which is122* represented by Mc.123*/124{125/* register word temp1; */126register int /* m, */ i;127register longword L_result, L_temp;128longword EM; /* xxx should be L_EM? */129word Mc;130131longword L_common_0_3;132133EM = 0;134Mc = 0;135136/* for (m = 0; m <= 3; m++) {137* L_result = 0;138*139*140* for (i = 0; i <= 12; i++) {141*142* temp1 = SASR( x[m + 3*i], 2 );143*144* assert(temp1 != MIN_WORD);145*146* L_temp = GSM_L_MULT( temp1, temp1 );147* L_result = GSM_L_ADD( L_temp, L_result );148* }149*150* if (L_result > EM) {151* Mc = m;152* EM = L_result;153* }154* }155*/156157#undef STEP158#define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \159L_result += L_temp * L_temp;160161/* common part of 0 and 3 */162163L_result = 0;164STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );165STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );166STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);167L_common_0_3 = L_result;168169/* i = 0 */170171STEP( 0, 0 );172L_result <<= 1; /* implicit in L_MULT */173EM = L_result;174175/* i = 1 */176177L_result = 0;178STEP( 1, 0 );179STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );180STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );181STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);182L_result <<= 1;183if (L_result > EM) {184Mc = 1;185EM = L_result;186}187188/* i = 2 */189190L_result = 0;191STEP( 2, 0 );192STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );193STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );194STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);195L_result <<= 1;196if (L_result > EM) {197Mc = 2;198EM = L_result;199}200201/* i = 3 */202203L_result = L_common_0_3;204STEP( 3, 12 );205L_result <<= 1;206if (L_result > EM) {207Mc = 3;208EM = L_result;209}210211/**/212213/* Down-sampling by a factor 3 to get the selected xM[0..12]214* RPE sequence.215*/216for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];217*Mc_out = Mc;218}219220/* 4.12.15 */221222static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),223word xmaxc, /* IN */224word * exp_out, /* OUT */225word * mant_out ) /* OUT */226{227word exp, mant;228229/* Compute exponent and mantissa of the decoded version of xmaxc230*/231232exp = 0;233if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;234mant = xmaxc - (exp << 3);235236if (mant == 0) {237exp = -4;238mant = 7;239}240else {241while (mant <= 7) {242mant = mant << 1 | 1;243exp--;244}245mant -= 8;246}247248assert( exp >= -4 && exp <= 6 );249assert( mant >= 0 && mant <= 7 );250251*exp_out = exp;252*mant_out = mant;253}254255static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),256word * xM, /* [0..12] IN */257258word * xMc, /* [0..12] OUT */259word * mant_out, /* OUT */260word * exp_out, /* OUT */261word * xmaxc_out /* OUT */262)263{264int i, itest;265266word xmax, xmaxc, temp, temp1, temp2;267word exp, mant;268269270/* Find the maximum absolute value xmax of xM[0..12].271*/272273xmax = 0;274for (i = 0; i <= 12; i++) {275temp = xM[i];276temp = GSM_ABS(temp);277if (temp > xmax) xmax = temp;278}279280/* Qantizing and coding of xmax to get xmaxc.281*/282283exp = 0;284temp = SASR( xmax, 9 );285itest = 0;286287for (i = 0; i <= 5; i++) {288289itest |= (temp <= 0);290temp = SASR( temp, 1 );291292assert(exp <= 5);293if (itest == 0) exp++; /* exp = add (exp, 1) */294}295296assert(exp <= 6 && exp >= 0);297temp = exp + 5;298299assert(temp <= 11 && temp >= 0);300xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );301302/* Quantizing and coding of the xM[0..12] RPE sequence303* to get the xMc[0..12]304*/305306APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );307308/* This computation uses the fact that the decoded version of xmaxc309* can be calculated by using the exponent and the mantissa part of310* xmaxc (logarithmic table).311* So, this method avoids any division and uses only a scaling312* of the RPE samples by a function of the exponent. A direct313* multiplication by the inverse of the mantissa (NRFAC[0..7]314* found in table 4.5) gives the 3 bit coded version xMc[0..12]315* of the RPE samples.316*/317318319/* Direct computation of xMc[0..12] using table 4.5320*/321322assert( exp <= 4096 && exp >= -4096);323assert( mant >= 0 && mant <= 7 );324325temp1 = 6 - exp; /* normalization by the exponent */326temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */327328for (i = 0; i <= 12; i++) {329330assert(temp1 >= 0 && temp1 < 16);331332temp = xM[i] << temp1;333temp = GSM_MULT( temp, temp2 );334temp = SASR(temp, 12);335xMc[i] = temp + 4; /* see note below */336}337338/* NOTE: This equation is used to make all the xMc[i] positive.339*/340341*mant_out = mant;342*exp_out = exp;343*xmaxc_out = xmaxc;344}345346/* 4.2.16 */347348static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),349register word * xMc, /* [0..12] IN */350word mant,351word exp,352register word * xMp) /* [0..12] OUT */353/*354* This part is for decoding the RPE sequence of coded xMc[0..12]355* samples to obtain the xMp[0..12] array. Table 4.6 is used to get356* the mantissa of xmaxc (FAC[0..7]).357*/358{359int i;360word temp, temp1, temp2, temp3;361longword ltmp;362363assert( mant >= 0 && mant <= 7 );364365temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */366temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */367temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));368369for (i = 13; i--;) {370371assert( *xMc <= 7 && *xMc >= 0 ); /* 3 bit unsigned */372373/* temp = gsm_sub( *xMc++ << 1, 7 ); */374temp = (*xMc++ << 1) - 7; /* restore sign */375assert( temp <= 7 && temp >= -7 ); /* 4 bit signed */376377temp <<= 12; /* 16 bit signed */378temp = GSM_MULT_R( temp1, temp );379temp = GSM_ADD( temp, temp3 );380*xMp++ = gsm_asr( temp, temp2 );381}382}383384/* 4.2.17 */385386static void RPE_grid_positioning P3((Mc,xMp,ep),387word Mc, /* grid position IN */388register word * xMp, /* [0..12] IN */389register word * ep /* [0..39] OUT */390)391/*392* This procedure computes the reconstructed long term residual signal393* ep[0..39] for the LTP analysis filter. The inputs are the Mc394* which is the grid position selection and the xMp[0..12] decoded395* RPE samples which are upsampled by a factor of 3 by inserting zero396* values.397*/398{399int i = 13;400401assert(0 <= Mc && Mc <= 3);402403switch (Mc) {404case 3: *ep++ = 0;405case 2: do {406*ep++ = 0;407case 1: *ep++ = 0;408case 0: *ep++ = *xMp++;409} while (--i);410}411while (++Mc < 4) *ep++ = 0;412413/*414415int i, k;416for (k = 0; k <= 39; k++) ep[k] = 0;417for (i = 0; i <= 12; i++) {418ep[ Mc + (3*i) ] = xMp[i];419}420*/421}422423/* 4.2.18 */424425/* This procedure adds the reconstructed long term residual signal426* ep[0..39] to the estimated signal dpp[0..39] from the long term427* analysis filter to compute the reconstructed short term residual428* signal dp[-40..-1]; also the reconstructed short term residual429* array dp[-120..-41] is updated.430*/431432#if 0 /* Has been inlined in code.c */433void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),434word * dpp, /* [0...39] IN */435word * ep, /* [0...39] IN */436word * dp) /* [-120...-1] IN/OUT */437{438int k;439440for (k = 0; k <= 79; k++)441dp[ -120 + k ] = dp[ -80 + k ];442443for (k = 0; k <= 39; k++)444dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );445}446#endif /* Has been inlined in code.c */447448void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),449450struct gsm_state * S,451452word * e, /* -5..-1][0..39][40..44 IN/OUT */453word * xmaxc, /* OUT */454word * Mc, /* OUT */455word * xMc) /* [0..12] OUT */456{457word x[40];458word xM[13], xMp[13];459word mant, exp;460461Weighting_filter(e, x);462RPE_grid_selection(x, xM, Mc);463464APCM_quantization( xM, xMc, &mant, &exp, xmaxc);465APCM_inverse_quantization( xMc, mant, exp, xMp);466467RPE_grid_positioning( *Mc, xMp, e );468469}470471void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),472struct gsm_state * S,473474word xmaxcr,475word Mcr,476word * xMcr, /* [0..12], 3 bits IN */477word * erp /* [0..39] OUT */478)479{480word exp, mant;481word xMp[ 13 ];482483APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );484APCM_inverse_quantization( xMcr, mant, exp, xMp );485RPE_grid_positioning( Mcr, xMp, erp );486487}488489490