00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <stdio.h>
00010 #include <assert.h>
00011
00012 #include "private.h"
00013
00014 #include "gsm.h"
00015 #include "proto.h"
00016
00017
00018
00019
00020
00021 #ifdef K6OPT
00022 #include "k6opt.h"
00023 #else
00024 static void Weighting_filter P2((e, x),
00025 register word * e,
00026 word * x
00027 )
00028
00029
00030
00031
00032
00033
00034 {
00035
00036
00037 register longword L_result;
00038 register int k ;
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 e -= 5;
00051
00052
00053
00054 for (k = 0; k <= 39; k++) {
00055
00056 L_result = 8192 >> 1;
00057
00058
00059
00060
00061
00062
00063
00064 #undef STEP
00065 #define STEP( i, H ) (e[ k + i ] * (longword)H)
00066
00067
00068
00069
00070
00071
00072 #ifdef STUPID_COMPILER
00073 L_result += STEP( 0, -134 ) ;
00074 L_result += STEP( 1, -374 ) ;
00075
00076 L_result += STEP( 3, 2054 ) ;
00077 L_result += STEP( 4, 5741 ) ;
00078 L_result += STEP( 5, 8192 ) ;
00079 L_result += STEP( 6, 5741 ) ;
00080 L_result += STEP( 7, 2054 ) ;
00081
00082 L_result += STEP( 9, -374 ) ;
00083 L_result += STEP( 10, -134 ) ;
00084 #else
00085 L_result +=
00086 STEP( 0, -134 )
00087 + STEP( 1, -374 )
00088
00089 + STEP( 3, 2054 )
00090 + STEP( 4, 5741 )
00091 + STEP( 5, 8192 )
00092 + STEP( 6, 5741 )
00093 + STEP( 7, 2054 )
00094
00095 + STEP( 9, -374 )
00096 + STEP(10, -134 )
00097 ;
00098 #endif
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 L_result = SASR( L_result, 13 );
00111 x[k] = ( L_result < MIN_WORD ? MIN_WORD
00112 : (L_result > MAX_WORD ? MAX_WORD : L_result ));
00113 }
00114 }
00115 #endif
00116
00117
00118
00119 static void RPE_grid_selection P3((x,xM,Mc_out),
00120 word * x,
00121 word * xM,
00122 word * Mc_out
00123 )
00124
00125
00126
00127
00128 {
00129
00130 register int i;
00131 register longword L_result, L_temp;
00132 longword EM;
00133 word Mc;
00134
00135 longword L_common_0_3;
00136
00137 EM = 0;
00138 Mc = 0;
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 #undef STEP
00162 #define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \
00163 L_result += L_temp * L_temp;
00164
00165
00166
00167 L_result = 0;
00168 STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 );
00169 STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 );
00170 STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12);
00171 L_common_0_3 = L_result;
00172
00173
00174
00175 STEP( 0, 0 );
00176 L_result <<= 1;
00177 EM = L_result;
00178
00179
00180
00181 L_result = 0;
00182 STEP( 1, 0 );
00183 STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 );
00184 STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 );
00185 STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12);
00186 L_result <<= 1;
00187 if (L_result > EM) {
00188 Mc = 1;
00189 EM = L_result;
00190 }
00191
00192
00193
00194 L_result = 0;
00195 STEP( 2, 0 );
00196 STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 );
00197 STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 );
00198 STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12);
00199 L_result <<= 1;
00200 if (L_result > EM) {
00201 Mc = 2;
00202 EM = L_result;
00203 }
00204
00205
00206
00207 L_result = L_common_0_3;
00208 STEP( 3, 12 );
00209 L_result <<= 1;
00210 if (L_result > EM) {
00211 Mc = 3;
00212 EM = L_result;
00213 }
00214
00215
00216
00217
00218
00219
00220 for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i];
00221 *Mc_out = Mc;
00222 }
00223
00224
00225
00226 static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out),
00227 word xmaxc,
00228 word * exp_out,
00229 word * mant_out )
00230 {
00231 word exp, mant;
00232
00233
00234
00235
00236 exp = 0;
00237 if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1;
00238 mant = xmaxc - (exp << 3);
00239
00240 if (mant == 0) {
00241 exp = -4;
00242 mant = 7;
00243 }
00244 else {
00245 while (mant <= 7) {
00246 mant = mant << 1 | 1;
00247 exp--;
00248 }
00249 mant -= 8;
00250 }
00251
00252 assert( exp >= -4 && exp <= 6 );
00253 assert( mant >= 0 && mant <= 7 );
00254
00255 *exp_out = exp;
00256 *mant_out = mant;
00257 }
00258
00259 static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out),
00260 word * xM,
00261
00262 word * xMc,
00263 word * mant_out,
00264 word * exp_out,
00265 word * xmaxc_out
00266 )
00267 {
00268 int i, itest;
00269
00270 word xmax, xmaxc, temp, temp1, temp2;
00271 word exp, mant;
00272
00273
00274
00275
00276
00277 xmax = 0;
00278 for (i = 0; i <= 12; i++) {
00279 temp = xM[i];
00280 temp = GSM_ABS(temp);
00281 if (temp > xmax) xmax = temp;
00282 }
00283
00284
00285
00286
00287 exp = 0;
00288 temp = SASR( xmax, 9 );
00289 itest = 0;
00290
00291 for (i = 0; i <= 5; i++) {
00292
00293 itest |= (temp <= 0);
00294 temp = SASR( temp, 1 );
00295
00296 assert(exp <= 5);
00297 if (itest == 0) exp++;
00298 }
00299
00300 assert(exp <= 6 && exp >= 0);
00301 temp = exp + 5;
00302
00303 assert(temp <= 11 && temp >= 0);
00304 xmaxc = gsm_add( SASR(xmax, temp), exp << 3 );
00305
00306
00307
00308
00309
00310 APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant );
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 assert( exp <= 4096 && exp >= -4096);
00327 assert( mant >= 0 && mant <= 7 );
00328
00329 temp1 = 6 - exp;
00330 temp2 = gsm_NRFAC[ mant ];
00331
00332 for (i = 0; i <= 12; i++) {
00333
00334 assert(temp1 >= 0 && temp1 < 16);
00335
00336 temp = xM[i] << temp1;
00337 temp = GSM_MULT( temp, temp2 );
00338 temp = SASR(temp, 12);
00339 xMc[i] = temp + 4;
00340 }
00341
00342
00343
00344
00345 *mant_out = mant;
00346 *exp_out = exp;
00347 *xmaxc_out = xmaxc;
00348 }
00349
00350
00351
00352 static void APCM_inverse_quantization P4((xMc,mant,exp,xMp),
00353 register word * xMc,
00354 word mant,
00355 word exp,
00356 register word * xMp)
00357
00358
00359
00360
00361
00362 {
00363 int i;
00364 word temp, temp1, temp2, temp3;
00365 longword ltmp;
00366
00367 assert( mant >= 0 && mant <= 7 );
00368
00369 temp1 = gsm_FAC[ mant ];
00370 temp2 = gsm_sub( 6, exp );
00371 temp3 = gsm_asl( 1, gsm_sub( temp2, 1 ));
00372
00373 for (i = 13; i--;) {
00374
00375 assert( *xMc <= 7 && *xMc >= 0 );
00376
00377
00378 temp = (*xMc++ << 1) - 7;
00379 assert( temp <= 7 && temp >= -7 );
00380
00381 temp <<= 12;
00382 temp = GSM_MULT_R( temp1, temp );
00383 temp = GSM_ADD( temp, temp3 );
00384 *xMp++ = gsm_asr( temp, temp2 );
00385 }
00386 }
00387
00388
00389
00390 static void RPE_grid_positioning P3((Mc,xMp,ep),
00391 word Mc,
00392 register word * xMp,
00393 register word * ep
00394 )
00395
00396
00397
00398
00399
00400
00401
00402 {
00403 int i = 13;
00404
00405 assert(0 <= Mc && Mc <= 3);
00406
00407 switch (Mc) {
00408 case 3: *ep++ = 0;
00409 case 2: do {
00410 *ep++ = 0;
00411 case 1: *ep++ = 0;
00412 case 0: *ep++ = *xMp++;
00413 } while (--i);
00414 }
00415 while (++Mc < 4) *ep++ = 0;
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436 #if 0
00437 void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp),
00438 word * dpp,
00439 word * ep,
00440 word * dp)
00441 {
00442 int k;
00443
00444 for (k = 0; k <= 79; k++)
00445 dp[ -120 + k ] = dp[ -80 + k ];
00446
00447 for (k = 0; k <= 39; k++)
00448 dp[ -40 + k ] = gsm_add( ep[k], dpp[k] );
00449 }
00450 #endif
00451
00452 void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc),
00453
00454 struct gsm_state * S,
00455
00456 word * e,
00457 word * xmaxc,
00458 word * Mc,
00459 word * xMc)
00460 {
00461 word x[40];
00462 word xM[13], xMp[13];
00463 word mant, exp;
00464
00465 Weighting_filter(e, x);
00466 RPE_grid_selection(x, xM, Mc);
00467
00468 APCM_quantization( xM, xMc, &mant, &exp, xmaxc);
00469 APCM_inverse_quantization( xMc, mant, exp, xMp);
00470
00471 RPE_grid_positioning( *Mc, xMp, e );
00472
00473 }
00474
00475 void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp),
00476 struct gsm_state * S,
00477
00478 word xmaxcr,
00479 word Mcr,
00480 word * xMcr,
00481 word * erp
00482 )
00483 {
00484 word exp, mant;
00485 word xMp[ 13 ];
00486
00487 APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant );
00488 APCM_inverse_quantization( xMcr, mant, exp, xMp );
00489 RPE_grid_positioning( Mcr, xMp, erp );
00490
00491 }