1 /* 2 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische 3 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for 4 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. 5 */ 6 7 /* $Header: /nfshome/cvs/xine-lib/src/libxineadec/gsm610/rpe.c,v 1.3 2003/12/07 15:34:30 f1rmb Exp $ */ 8 9 #ifdef HAVE_CONFIG_H 10 #include "config.h" 11 #endif 12 13 #include <stdio.h> 14 #include <xine/xineutils.h> 15 #include "private.h" 16 17 #include "gsm.h" 18 #include "proto.h" 19 20 /* 4.2.13 .. 4.2.17 RPE ENCODING SECTION 21 */ 22 23 /* 4.2.13 */ 24 25 static void Weighting_filter P2((e, x), 26 register word * e, /* signal [-5..0.39.44] IN */ 27 word * x /* signal [0..39] OUT */ 28 ) 29 /* 30 * The coefficients of the weighting filter are stored in a table 31 * (see table 4.4). The following scaling is used: 32 * 33 * H[0..10] = integer( real_H[ 0..10] * 8192 ); 34 */ 35 { 36 /* word wt[ 50 ]; */ 37 38 register longword L_result; 39 register int k /* , i */ ; 40 41 /* Initialization of a temporary working array wt[0...49] 42 */ 43 44 /* for (k = 0; k <= 4; k++) wt[k] = 0; 45 * for (k = 5; k <= 44; k++) wt[k] = *e++; 46 * for (k = 45; k <= 49; k++) wt[k] = 0; 47 * 48 * (e[-5..-1] and e[40..44] are allocated by the caller, 49 * are initially zero and are not written anywhere.) 50 */ 51 e -= 5; 52 53 /* Compute the signal x[0..39] 54 */ 55 for (k = 0; k <= 39; k++) { 56 57 L_result = 8192 >> 1; 58 59 /* for (i = 0; i <= 10; i++) { 60 * L_temp = GSM_L_MULT( wt[k+i], gsm_H[i] ); 61 * L_result = GSM_L_ADD( L_result, L_temp ); 62 * } 63 */ 64 65 #undef STEP 66 #define STEP( i, H ) (e[ k + i ] * (longword)H) 67 68 /* Every one of these multiplications is done twice -- 69 * but I don't see an elegant way to optimize this. 70 * Do you? 71 */ 72 73 #ifdef STUPID_COMPILER 74 L_result += STEP( 0, -134 ) ; 75 L_result += STEP( 1, -374 ) ; 76 /* + STEP( 2, 0 ) */ 77 L_result += STEP( 3, 2054 ) ; 78 L_result += STEP( 4, 5741 ) ; 79 L_result += STEP( 5, 8192 ) ; 80 L_result += STEP( 6, 5741 ) ; 81 L_result += STEP( 7, 2054 ) ; 82 /* + STEP( 8, 0 ) */ 83 L_result += STEP( 9, -374 ) ; 84 L_result += STEP( 10, -134 ) ; 85 #else 86 L_result += 87 STEP( 0, -134 ) 88 + STEP( 1, -374 ) 89 /* + STEP( 2, 0 ) */ 90 + STEP( 3, 2054 ) 91 + STEP( 4, 5741 ) 92 + STEP( 5, 8192 ) 93 + STEP( 6, 5741 ) 94 + STEP( 7, 2054 ) 95 /* + STEP( 8, 0 ) */ 96 + STEP( 9, -374 ) 97 + STEP(10, -134 ) 98 ; 99 #endif 100 101 /* L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x2) *) 102 * L_result = GSM_L_ADD( L_result, L_result ); (* scaling(x4) *) 103 * 104 * x[k] = SASR( L_result, 16 ); 105 */ 106 107 /* 2 adds vs. >>16 => 14, minus one shift to compensate for 108 * those we lost when replacing L_MULT by '*'. 109 */ 110 111 L_result = SASR( L_result, 13 ); 112 x[k] = ( L_result < MIN_WORD ? MIN_WORD 113 : (L_result > MAX_WORD ? MAX_WORD : L_result )); 114 } 115 } 116 117 /* 4.2.14 */ 118 119 static void RPE_grid_selection P3((x,xM,Mc_out), 120 word * x, /* [0..39] IN */ 121 word * xM, /* [0..12] OUT */ 122 word * Mc_out /* OUT */ 123 ) 124 /* 125 * The signal x[0..39] is used to select the RPE grid which is 126 * represented by Mc. 127 */ 128 { 129 /* register word temp1; */ 130 register int /* m, */ i; 131 register longword L_result, L_temp; 132 longword EM; /* xxx should be L_EM? */ 133 word Mc; 134 135 longword L_common_0_3; 136 137 EM = 0; 138 Mc = 0; 139 140 /* for (m = 0; m <= 3; m++) { 141 * L_result = 0; 142 * 143 * 144 * for (i = 0; i <= 12; i++) { 145 * 146 * temp1 = SASR( x[m + 3*i], 2 ); 147 * 148 * _x_assert(temp1 != MIN_WORD); 149 * 150 * L_temp = GSM_L_MULT( temp1, temp1 ); 151 * L_result = GSM_L_ADD( L_temp, L_result ); 152 * } 153 * 154 * if (L_result > EM) { 155 * Mc = m; 156 * EM = L_result; 157 * } 158 * } 159 */ 160 161 #undef STEP 162 #define STEP( m, i ) L_temp = SASR( x[m + 3 * i], 2 ); \ 163 L_result += L_temp * L_temp; 164 165 /* common part of 0 and 3 */ 166 167 L_result = 0; 168 STEP( 0, 1 ); STEP( 0, 2 ); STEP( 0, 3 ); STEP( 0, 4 ); 169 STEP( 0, 5 ); STEP( 0, 6 ); STEP( 0, 7 ); STEP( 0, 8 ); 170 STEP( 0, 9 ); STEP( 0, 10); STEP( 0, 11); STEP( 0, 12); 171 L_common_0_3 = L_result; 172 173 /* i = 0 */ 174 175 STEP( 0, 0 ); 176 L_result <<= 1; /* implicit in L_MULT */ 177 EM = L_result; 178 179 /* i = 1 */ 180 181 L_result = 0; 182 STEP( 1, 0 ); 183 STEP( 1, 1 ); STEP( 1, 2 ); STEP( 1, 3 ); STEP( 1, 4 ); 184 STEP( 1, 5 ); STEP( 1, 6 ); STEP( 1, 7 ); STEP( 1, 8 ); 185 STEP( 1, 9 ); STEP( 1, 10); STEP( 1, 11); STEP( 1, 12); 186 L_result <<= 1; 187 if (L_result > EM) { 188 Mc = 1; 189 EM = L_result; 190 } 191 192 /* i = 2 */ 193 194 L_result = 0; 195 STEP( 2, 0 ); 196 STEP( 2, 1 ); STEP( 2, 2 ); STEP( 2, 3 ); STEP( 2, 4 ); 197 STEP( 2, 5 ); STEP( 2, 6 ); STEP( 2, 7 ); STEP( 2, 8 ); 198 STEP( 2, 9 ); STEP( 2, 10); STEP( 2, 11); STEP( 2, 12); 199 L_result <<= 1; 200 if (L_result > EM) { 201 Mc = 2; 202 EM = L_result; 203 } 204 205 /* i = 3 */ 206 207 L_result = L_common_0_3; 208 STEP( 3, 12 ); 209 L_result <<= 1; 210 if (L_result > EM) { 211 Mc = 3; 212 EM = L_result; 213 } 214 215 /**/ 216 217 /* Down-sampling by a factor 3 to get the selected xM[0..12] 218 * RPE sequence. 219 */ 220 for (i = 0; i <= 12; i ++) xM[i] = x[Mc + 3*i]; 221 *Mc_out = Mc; 222 } 223 224 /* 4.12.15 */ 225 226 static void APCM_quantization_xmaxc_to_exp_mant P3((xmaxc,exp_out,mant_out), 227 word xmaxc, /* IN */ 228 word * exp_out, /* OUT */ 229 word * mant_out ) /* OUT */ 230 { 231 word exp, mant; 232 233 /* Compute exponent and mantissa of the decoded version of xmaxc 234 */ 235 236 exp = 0; 237 if (xmaxc > 15) exp = SASR(xmaxc, 3) - 1; 238 mant = xmaxc - (exp << 3); 239 240 if (mant == 0) { 241 exp = -4; 242 mant = 7; 243 } 244 else { 245 while (mant <= 7) { 246 mant = mant << 1 | 1; 247 exp--; 248 } 249 mant -= 8; 250 } 251 252 _x_assert( exp >= -4 && exp <= 6 ); 253 _x_assert( mant >= 0 && mant <= 7 ); 254 255 *exp_out = exp; 256 *mant_out = mant; 257 } 258 259 static void APCM_quantization P5((xM,xMc,mant_out,exp_out,xmaxc_out), 260 word * xM, /* [0..12] IN */ 261 262 word * xMc, /* [0..12] OUT */ 263 word * mant_out, /* OUT */ 264 word * exp_out, /* OUT */ 265 word * xmaxc_out /* OUT */ 266 ) 267 { 268 int i, itest; 269 270 word xmax, xmaxc, temp, temp1, temp2; 271 word exp, mant; 272 273 274 /* Find the maximum absolute value xmax of xM[0..12]. 275 */ 276 277 xmax = 0; 278 for (i = 0; i <= 12; i++) { 279 temp = xM[i]; 280 temp = GSM_ABS(temp); 281 if (temp > xmax) xmax = temp; 282 } 283 284 /* Qantizing and coding of xmax to get xmaxc. 285 */ 286 287 exp = 0; 288 temp = SASR( xmax, 9 ); 289 itest = 0; 290 291 for (i = 0; i <= 5; i++) { 292 293 itest |= (temp <= 0); 294 temp = SASR( temp, 1 ); 295 296 _x_assert(exp <= 5); 297 if (itest == 0) exp++; /* exp = add (exp, 1) */ 298 } 299 300 _x_assert(exp <= 6 && exp >= 0); 301 temp = exp + 5; 302 303 _x_assert(temp <= 11 && temp >= 0); 304 xmaxc = gsm_add( SASR(xmax, temp), exp << 3 ); 305 306 /* Quantizing and coding of the xM[0..12] RPE sequence 307 * to get the xMc[0..12] 308 */ 309 310 APCM_quantization_xmaxc_to_exp_mant( xmaxc, &exp, &mant ); 311 312 /* This computation uses the fact that the decoded version of xmaxc 313 * can be calculated by using the exponent and the mantissa part of 314 * xmaxc (logarithmic table). 315 * So, this method avoids any division and uses only a scaling 316 * of the RPE samples by a function of the exponent. A direct 317 * multiplication by the inverse of the mantissa (NRFAC[0..7] 318 * found in table 4.5) gives the 3 bit coded version xMc[0..12] 319 * of the RPE samples. 320 */ 321 322 323 /* Direct computation of xMc[0..12] using table 4.5 324 */ 325 326 _x_assert((exp <= 4096) && (exp >= -4096)); 327 _x_assert((mant >= 0) && (mant <= 7)); 328 329 temp1 = 6 - exp; /* normalization by the exponent */ 330 temp2 = gsm_NRFAC[ mant ]; /* inverse mantissa */ 331 332 for (i = 0; i <= 12; i++) { 333 334 _x_assert(temp1 >= 0 && temp1 < 16); 335 336 temp = xM[i] << temp1; 337 temp = GSM_MULT( temp, temp2 ); 338 temp = SASR(temp, 12); 339 xMc[i] = temp + 4; /* see note below */ 340 } 341 342 /* NOTE: This equation is used to make all the xMc[i] positive. 343 */ 344 345 *mant_out = mant; 346 *exp_out = exp; 347 *xmaxc_out = xmaxc; 348 } 349 350 /* 4.2.16 */ 351 352 static void APCM_inverse_quantization P4((xMc,mant,exp,xMp), 353 register word * xMc, /* [0..12] IN */ 354 word mant, 355 word exp, 356 register word * xMp) /* [0..12] OUT */ 357 /* 358 * This part is for decoding the RPE sequence of coded xMc[0..12] 359 * samples to obtain the xMp[0..12] array. Table 4.6 is used to get 360 * the mantissa of xmaxc (FAC[0..7]). 361 */ 362 { 363 int i; 364 word temp, temp1, temp2, temp3; 365 longword ltmp; 366 367 _x_assert((mant >= 0) && (mant <= 7)); 368 369 temp1 = gsm_FAC[ mant ]; /* see 4.2-15 for mant */ 370 temp2 = gsm_sub( 6, exp ); /* see 4.2-15 for exp */ 371 temp3 = gsm_asl( 1, gsm_sub( temp2, 1 )); 372 373 for (i = 13; i--;) { 374 _x_assert((mant >= 0) && (mant <= 7)); 375 376 _x_assert((*xMc <= 7) && (*xMc >= 0)); /* 3 bit unsigned */ 377 378 /* temp = gsm_sub( *xMc++ << 1, 7 ); */ 379 temp = (*xMc++ << 1) - 7; /* restore sign */ 380 381 _x_assert((temp <= 7) && (temp >= -7)); /* 4 bit signed */ 382 383 temp <<= 12; /* 16 bit signed */ 384 temp = GSM_MULT_R( temp1, temp ); 385 temp = GSM_ADD( temp, temp3 ); 386 *xMp++ = gsm_asr( temp, temp2 ); 387 } 388 } 389 390 /* 4.2.17 */ 391 392 static void RPE_grid_positioning P3((Mc,xMp,ep), 393 word Mc, /* grid position IN */ 394 register word * xMp, /* [0..12] IN */ 395 register word * ep /* [0..39] OUT */ 396 ) 397 /* 398 * This procedure computes the reconstructed long term residual signal 399 * ep[0..39] for the LTP analysis filter. The inputs are the Mc 400 * which is the grid position selection and the xMp[0..12] decoded 401 * RPE samples which are upsampled by a factor of 3 by inserting zero 402 * values. 403 */ 404 { 405 int i = 13; 406 407 _x_assert((0 <= Mc) && (Mc <= 3)); 408 409 switch (Mc) { 410 case 3: *ep++ = 0; 411 /* fall through */ 412 case 2: do { 413 *ep++ = 0; 414 /* fall through */ 415 case 1: *ep++ = 0; 416 /* fall through */ 417 case 0: *ep++ = *xMp++; 418 } while (--i); 419 } 420 while (++Mc < 4) *ep++ = 0; 421 422 /* 423 424 int i, k; 425 for (k = 0; k <= 39; k++) ep[k] = 0; 426 for (i = 0; i <= 12; i++) { 427 ep[ Mc + (3*i) ] = xMp[i]; 428 } 429 */ 430 } 431 432 /* 4.2.18 */ 433 434 /* This procedure adds the reconstructed long term residual signal 435 * ep[0..39] to the estimated signal dpp[0..39] from the long term 436 * analysis filter to compute the reconstructed short term residual 437 * signal dp[-40..-1]; also the reconstructed short term residual 438 * array dp[-120..-41] is updated. 439 */ 440 441 #if 0 /* Has been inlined in code.c */ 442 void Gsm_Update_of_reconstructed_short_time_residual_signal P3((dpp, ep, dp), 443 word * dpp, /* [0...39] IN */ 444 word * ep, /* [0...39] IN */ 445 word * dp) /* [-120...-1] IN/OUT */ 446 { 447 int k; 448 449 for (k = 0; k <= 79; k++) 450 dp[ -120 + k ] = dp[ -80 + k ]; 451 452 for (k = 0; k <= 39; k++) 453 dp[ -40 + k ] = gsm_add( ep[k], dpp[k] ); 454 } 455 #endif /* Has been inlined in code.c */ 456 457 void Gsm_RPE_Encoding P5((S,e,xmaxc,Mc,xMc), 458 459 struct gsm_state * S, 460 461 word * e, /* -5..-1][0..39][40..44 IN/OUT */ 462 word * xmaxc, /* OUT */ 463 word * Mc, /* OUT */ 464 word * xMc) /* [0..12] OUT */ 465 { 466 word x[40]; 467 word xM[13], xMp[13]; 468 word mant, exp; 469 470 (void)S; 471 Weighting_filter(e, x); 472 RPE_grid_selection(x, xM, Mc); 473 474 APCM_quantization( xM, xMc, &mant, &exp, xmaxc); 475 APCM_inverse_quantization( xMc, mant, exp, xMp); 476 477 RPE_grid_positioning( *Mc, xMp, e ); 478 479 } 480 481 void Gsm_RPE_Decoding P5((S, xmaxcr, Mcr, xMcr, erp), 482 struct gsm_state * S, 483 484 word xmaxcr, 485 word Mcr, 486 word * xMcr, /* [0..12], 3 bits IN */ 487 word * erp /* [0..39] OUT */ 488 ) 489 { 490 word exp, mant; 491 word xMp[ 13 ]; 492 493 (void)S; 494 APCM_quantization_xmaxc_to_exp_mant( xmaxcr, &exp, &mant ); 495 APCM_inverse_quantization( xMcr, mant, exp, xMp ); 496 RPE_grid_positioning( Mcr, xMp, erp ); 497 498 } 499 500