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