Mercurial > hg > audiostuff
comparison intercom/gsm/rpe.c @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:9cadc470e3da | 2:13be24d74cd2 |
---|---|
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 } |