blob: 9d0f6c550ca390bba06b7098ece13a5d68eb4779
1 | /* |
2 | *=================================================================== |
3 | * 3GPP AMR Wideband Floating-point Speech Codec |
4 | *=================================================================== |
5 | */ |
6 | #include <stdio.h> |
7 | #include <stdlib.h> |
8 | #include <string.h> |
9 | #include <fcntl.h> |
10 | #include <math.h> |
11 | //#include <memory.h> |
12 | #include "typedef.h" |
13 | #include "dec_main.h" |
14 | #include "dec_lpc.h" |
15 | |
16 | #define MAX_16 (Word16)0x7FFF |
17 | #define MIN_16 (Word16)0x8000 |
18 | #define L_SUBFR 64 /* Subframe size */ |
19 | #define L_SUBFR16k 80 /* Subframe size at 16kHz */ |
20 | #define M16k 20 /* Order of LP filter */ |
21 | #define PREEMPH_FAC 22282 /* preemphasis factor (0.68 in Q15) */ |
22 | #define FAC4 4 |
23 | #define FAC5 5 |
24 | #define UP_FAC 20480 /* 5/4 in Q14 */ |
25 | #define INV_FAC5 6554 /* 1/5 in Q15 */ |
26 | #define NB_COEF_UP 12 |
27 | #define L_FIR 31 |
28 | #define MODE_7k 0 |
29 | #define MODE_24k 8 |
30 | |
31 | |
32 | extern const Word16 D_ROM_pow2[]; |
33 | extern const Word16 D_ROM_isqrt[]; |
34 | extern const Word16 D_ROM_log2[]; |
35 | extern const Word16 D_ROM_fir_up[]; |
36 | extern const Word16 D_ROM_fir_6k_7k[]; |
37 | extern const Word16 D_ROM_fir_7k[]; |
38 | extern const Word16 D_ROM_hp_gain[]; |
39 | |
40 | #ifdef WIN32 |
41 | #pragma warning( disable : 4310) |
42 | #endif |
43 | /* |
44 | * D_UTIL_random |
45 | * |
46 | * Parameters: |
47 | * seed I/O: seed for random number |
48 | * |
49 | * Function: |
50 | * Signed 16 bits random generator. |
51 | * |
52 | * Returns: |
53 | * random number |
54 | */ |
55 | Word16 D_UTIL_random(Word16 *seed) |
56 | { |
57 | /*static Word16 seed = 21845;*/ |
58 | *seed = (Word16)(*seed * 31821L + 13849L); |
59 | return(*seed); |
60 | } |
61 | |
62 | |
63 | /* |
64 | * D_UTIL_pow2 |
65 | * |
66 | * Parameters: |
67 | * exponant I: (Q0) Integer part. (range: 0 <= val <= 30) |
68 | * fraction I: (Q15) Fractionnal part. (range: 0.0 <= val < 1.0) |
69 | * |
70 | * Function: |
71 | * L_x = pow(2.0, exponant.fraction) (exponant = interger part) |
72 | * = pow(2.0, 0.fraction) << exponant |
73 | * |
74 | * Algorithm: |
75 | * |
76 | * The function Pow2(L_x) is approximated by a table and linear |
77 | * interpolation. |
78 | * |
79 | * 1 - i = bit10 - b15 of fraction, 0 <= i <= 31 |
80 | * 2 - a = bit0 - b9 of fraction |
81 | * 3 - L_x = table[i] << 16 - (table[i] - table[i + 1]) * a * 2 |
82 | * 4 - L_x = L_x >> (30-exponant) (with rounding) |
83 | * |
84 | * Returns: |
85 | * range 0 <= val <= 0x7fffffff |
86 | */ |
87 | Word32 D_UTIL_pow2(Word16 exponant, Word16 fraction) |
88 | { |
89 | Word32 L_x, tmp, i, exp; |
90 | Word16 a; |
91 | |
92 | L_x = fraction * 32; /* L_x = fraction<<6 */ |
93 | i = L_x >> 15; /* Extract b10-b16 of fraction */ |
94 | a = (Word16)(L_x); /* Extract b0-b9 of fraction */ |
95 | a = (Word16)(a & (Word16)0x7fff); |
96 | L_x = D_ROM_pow2[i] << 16; /* table[i] << 16 */ |
97 | tmp = D_ROM_pow2[i] - D_ROM_pow2[i + 1]; /* table[i] - table[i+1] */ |
98 | tmp = L_x - ((tmp * a) << 1); /* L_x -= tmp*a*2 */ |
99 | exp = 30 - exponant; |
100 | if (exp <= 31) { |
101 | L_x = tmp >> exp; |
102 | |
103 | if ((1 << (exp - 1)) & tmp) { |
104 | L_x++; |
105 | } |
106 | } else { |
107 | L_x = 0; |
108 | } |
109 | |
110 | return(L_x); |
111 | } |
112 | |
113 | |
114 | /* |
115 | * D_UTIL_norm_l |
116 | * |
117 | * Parameters: |
118 | * L_var1 I: 32 bit Word32 signed integer (Word32) whose value |
119 | * falls in the range 0x8000 0000 <= var1 <= 0x7fff ffff. |
120 | * |
121 | * Function: |
122 | * Produces the number of left shifts needed to normalize the 32 bit |
123 | * variable L_var1 for positive values on the interval with minimum of |
124 | * 1073741824 and maximum of 2147483647, and for negative values on |
125 | * the interval with minimum of -2147483648 and maximum of -1073741824; |
126 | * in order to normalize the result, the following operation must be done : |
127 | * norm_L_var1 = L_shl(L_var1,norm_l(L_var1)). |
128 | * |
129 | * Returns: |
130 | * 16 bit Word16 signed integer (Word16) whose value falls in the range |
131 | * 0x0000 0000 <= var_out <= 0x0000 001f. |
132 | */ |
133 | Word16 D_UTIL_norm_l(Word32 L_var1) |
134 | { |
135 | Word16 var_out; |
136 | |
137 | if (L_var1 == 0) { |
138 | var_out = 0; |
139 | } else { |
140 | if (L_var1 == (Word32)0xffffffffL) { |
141 | var_out = 31; |
142 | } else { |
143 | if (L_var1 < 0) { |
144 | L_var1 = ~L_var1; |
145 | } |
146 | |
147 | for (var_out = 0; L_var1 < (Word32)0x40000000L; var_out++) { |
148 | L_var1 <<= 1; |
149 | } |
150 | } |
151 | } |
152 | |
153 | return(var_out); |
154 | } |
155 | |
156 | |
157 | /* |
158 | * D_UTIL_norm_s |
159 | * |
160 | * Parameters: |
161 | * L_var1 I: 32 bit Word32 signed integer (Word32) whose value |
162 | * falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff. |
163 | * |
164 | * Function: |
165 | * Produces the number of left shift needed to normalize the 16 bit |
166 | * variable var1 for positive values on the interval with minimum |
167 | * of 16384 and maximum of 32767, and for negative values on |
168 | * the interval with minimum of -32768 and maximum of -16384. |
169 | * |
170 | * Returns: |
171 | * 16 bit Word16 signed integer (Word16) whose value falls in the range |
172 | * 0x0000 0000 <= var_out <= 0x0000 000f. |
173 | */ |
174 | Word16 D_UTIL_norm_s(Word16 var1) |
175 | { |
176 | Word16 var_out; |
177 | |
178 | if (var1 == 0) { |
179 | var_out = 0; |
180 | } else { |
181 | if (var1 == -1) { |
182 | var_out = 15; |
183 | } else { |
184 | if (var1 < 0) { |
185 | var1 = (Word16)~var1; |
186 | } |
187 | |
188 | for (var_out = 0; var1 < 0x4000; var_out++) { |
189 | var1 <<= 1; |
190 | } |
191 | } |
192 | } |
193 | return(var_out); |
194 | } |
195 | |
196 | |
197 | /* |
198 | * D_UTIL_dot_product12 |
199 | * |
200 | * Parameters: |
201 | * x I: 12bit x vector |
202 | * y I: 12bit y vector |
203 | * lg I: vector length |
204 | * exp O: exponent of result (0..+30) |
205 | * |
206 | * Function: |
207 | * Compute scalar product of <x[],y[]> using accumulator. |
208 | * The result is normalized (in Q31) with exponent (0..30). |
209 | * |
210 | * Returns: |
211 | * Q31 normalised result (1 < val <= -1) |
212 | */ |
213 | Word32 D_UTIL_dot_product12(Word16 x[], Word16 y[], Word16 lg, Word16 *exp) |
214 | { |
215 | Word32 sum, i, sft; |
216 | |
217 | sum = 0L; |
218 | |
219 | for (i = 0; i < lg; i++) { |
220 | sum += x[i] * y[i]; |
221 | } |
222 | sum = (sum << 1) + 1; |
223 | |
224 | /* Normalize acc in Q31 */ |
225 | sft = D_UTIL_norm_l(sum); |
226 | sum = sum << sft; |
227 | *exp = (Word16)(30 - sft); /* exponent = 0..30 */ |
228 | |
229 | return(sum); |
230 | } |
231 | |
232 | |
233 | /* |
234 | * D_UTIL_normalised_inverse_sqrt |
235 | * |
236 | * Parameters: |
237 | * frac I/O: (Q31) normalized value (1.0 < frac <= 0.5) |
238 | * exp I/O: exponent (value = frac x 2^exponent) |
239 | * |
240 | * Function: |
241 | * Compute 1/sqrt(value). |
242 | * If value is negative or zero, result is 1 (frac=7fffffff, exp=0). |
243 | * |
244 | * The function 1/sqrt(value) is approximated by a table and linear |
245 | * interpolation. |
246 | * 1. If exponant is odd then shift fraction right once. |
247 | * 2. exponant = -((exponant - 1) >> 1) |
248 | * 3. i = bit25 - b30 of fraction, 16 <= i <= 63 ->because of normalization. |
249 | * 4. a = bit10 - b24 |
250 | * 5. i -= 16 |
251 | * 6. fraction = table[i]<<16 - (table[i] - table[i+1]) * a * 2 |
252 | * |
253 | * Returns: |
254 | * void |
255 | */ |
256 | void D_UTIL_normalised_inverse_sqrt(Word32 *frac, Word16 *exp) |
257 | { |
258 | Word32 i, tmp; |
259 | Word16 a; |
260 | |
261 | if (*frac <= (Word32)0) { |
262 | *exp = 0; |
263 | *frac = 0x7fffffffL; |
264 | return; |
265 | } |
266 | |
267 | if ((*exp & 0x1) == 1) { /* If exponant odd -> shift right */ |
268 | *frac = *frac >> 1; |
269 | } |
270 | *exp = (Word16)(-((*exp - 1) >> 1)); |
271 | *frac = *frac >> 9; |
272 | i = *frac >> 16; /* Extract b25-b31 */ |
273 | *frac = *frac >> 1; |
274 | a = (Word16)(*frac); /* Extract b10-b24 */ |
275 | a = (Word16)(a & (Word16)0x7fff); |
276 | i = i - 16; |
277 | *frac = D_ROM_isqrt[i] << 16; /* table[i] << 16 */ |
278 | tmp = D_ROM_isqrt[i] - D_ROM_isqrt[i + 1]; /* table[i] - table[i+1]) */ |
279 | *frac = *frac - ((tmp * a) << 1); /* frac -= tmp*a*2 */ |
280 | |
281 | return; |
282 | } |
283 | |
284 | |
285 | /* |
286 | * D_UTIL_inverse_sqrt |
287 | * |
288 | * Parameters: |
289 | * L_x I/O: (Q0) input value (range: 0<=val<=7fffffff) |
290 | * |
291 | * Function: |
292 | * Compute 1/sqrt(L_x). |
293 | * If value is negative or zero, result is 1 (7fffffff). |
294 | * |
295 | * The function 1/sqrt(value) is approximated by a table and linear |
296 | * interpolation. |
297 | * 1. Normalization of L_x |
298 | * 2. call Normalised_Inverse_sqrt(L_x, exponant) |
299 | * 3. L_y = L_x << exponant |
300 | * |
301 | * Returns: |
302 | * (Q31) output value (range: 0 <= val < 1) |
303 | */ |
304 | Word32 D_UTIL_inverse_sqrt(Word32 L_x) |
305 | { |
306 | Word32 L_y; |
307 | Word16 exp; |
308 | |
309 | exp = D_UTIL_norm_l(L_x); |
310 | L_x = (L_x << exp); /* L_x is normalized */ |
311 | exp = (Word16)(31 - exp); |
312 | D_UTIL_normalised_inverse_sqrt(&L_x, &exp); |
313 | |
314 | if (exp < 0) { |
315 | L_y = (L_x >> -exp); /* denormalization */ |
316 | } else { |
317 | L_y = (L_x << exp); /* denormalization */ |
318 | } |
319 | |
320 | return(L_y); |
321 | } |
322 | |
323 | |
324 | /* |
325 | * D_UTIL_normalised_log2 |
326 | * |
327 | * Parameters: |
328 | * L_x I: input value (normalized) |
329 | * exp I: norm_l (L_x) |
330 | * exponent O: Integer part of Log2. (range: 0<=val<=30) |
331 | * fraction O: Fractional part of Log2. (range: 0<=val<1) |
332 | * |
333 | * Function: |
334 | * Computes log2(L_x, exp), where L_x is positive and |
335 | * normalized, and exp is the normalisation exponent |
336 | * If L_x is negative or zero, the result is 0. |
337 | * |
338 | * The function Log2(L_x) is approximated by a table and linear |
339 | * interpolation. The following steps are used to compute Log2(L_x) |
340 | * |
341 | * 1. exponent = 30 - norm_exponent |
342 | * 2. i = bit25 - b31 of L_x; 32 <= i <= 63 (because of normalization). |
343 | * 3. a = bit10 - b24 |
344 | * 4. i -= 32 |
345 | * 5. fraction = table[i] << 16 - (table[i] - table[i + 1]) * a * 2 |
346 | * |
347 | * |
348 | * Returns: |
349 | * void |
350 | */ |
351 | static void D_UTIL_normalised_log2(Word32 L_x, Word16 exp, Word16 *exponent, |
352 | Word16 *fraction) |
353 | { |
354 | Word32 i, a, tmp; |
355 | Word32 L_y; |
356 | |
357 | if (L_x <= 0) { |
358 | *exponent = 0; |
359 | *fraction = 0; |
360 | return; |
361 | } |
362 | |
363 | *exponent = (Word16)(30 - exp); |
364 | |
365 | L_x = L_x >> 10; |
366 | i = L_x >> 15; /* Extract b25-b31 */ |
367 | a = L_x; /* Extract b10-b24 of fraction */ |
368 | a = a & 0x00007fff; |
369 | i = i - 32; |
370 | L_y = D_ROM_log2[i] << 16; /* table[i] << 16 */ |
371 | tmp = D_ROM_log2[i] - D_ROM_log2[i + 1]; /* table[i] - table[i+1] */ |
372 | L_y = L_y - ((tmp * a) << 1); /* L_y -= tmp*a*2 */ |
373 | *fraction = (Word16)(L_y >> 16); |
374 | |
375 | return; |
376 | } |
377 | |
378 | |
379 | /* |
380 | * D_UTIL_log2 |
381 | * |
382 | * Parameters: |
383 | * L_x I: input value |
384 | * exponent O: Integer part of Log2. (range: 0<=val<=30) |
385 | * fraction O: Fractional part of Log2. (range: 0<=val<1) |
386 | * |
387 | * Function: |
388 | * Computes log2(L_x), where L_x is positive. |
389 | * If L_x is negative or zero, the result is 0. |
390 | * |
391 | * Returns: |
392 | * void |
393 | */ |
394 | void D_UTIL_log2(Word32 L_x, Word16 *exponent, Word16 *fraction) |
395 | { |
396 | Word16 exp; |
397 | |
398 | exp = D_UTIL_norm_l(L_x); |
399 | D_UTIL_normalised_log2((L_x << exp), exp, exponent, fraction); |
400 | } |
401 | |
402 | |
403 | /* |
404 | * D_UTIL_l_extract |
405 | * |
406 | * Parameters: |
407 | * L_32 I: 32 bit integer. |
408 | * hi O: b16 to b31 of L_32 |
409 | * lo O: (L_32 - hi<<16)>>1 |
410 | * |
411 | * Function: |
412 | * Extract from a 32 bit integer two 16 bit DPF. |
413 | * |
414 | * Returns: |
415 | * void |
416 | */ |
417 | void D_UTIL_l_extract(Word32 L_32, Word16 *hi, Word16 *lo) |
418 | { |
419 | *hi = (Word16)(L_32 >> 16); |
420 | *lo = (Word16)((L_32 >> 1) - (*hi * 32768)); |
421 | |
422 | return; |
423 | } |
424 | |
425 | |
426 | /* |
427 | * D_UTIL_mpy_32_16 |
428 | * |
429 | * Parameters: |
430 | * hi I: hi part of 32 bit number |
431 | * lo I: lo part of 32 bit number |
432 | * n I: 16 bit number |
433 | * |
434 | * Function: |
435 | * Multiply a 16 bit integer by a 32 bit (DPF). The result is divided |
436 | * by 2^15. |
437 | * |
438 | * L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 |
439 | * |
440 | * Returns: |
441 | * 32 bit result |
442 | */ |
443 | Word32 D_UTIL_mpy_32_16(Word16 hi, Word16 lo, Word16 n) |
444 | { |
445 | Word32 L_32; |
446 | |
447 | L_32 = hi * n; |
448 | L_32 += (lo * n) >> 15; |
449 | |
450 | return(L_32 << 1); |
451 | } |
452 | |
453 | |
454 | /* |
455 | * D_UTIL_mpy_32 |
456 | * |
457 | * Parameters: |
458 | * hi1 I: hi part of first number |
459 | * lo1 I: lo part of first number |
460 | * hi2 I: hi part of second number |
461 | * lo2 I: lo part of second number |
462 | * |
463 | * Function: |
464 | * Multiply two 32 bit integers (DPF). The result is divided by 2^31 |
465 | * |
466 | * L_32 = (hi1*lo2)<<1 + ((lo1*lo2)>>15)<<1 |
467 | * |
468 | * Returns: |
469 | * 32 bit result |
470 | */ |
471 | Word32 D_UTIL_mpy_32(Word16 hi1, Word16 lo1, Word16 hi2, Word16 lo2) |
472 | { |
473 | Word32 L_32; |
474 | |
475 | L_32 = hi1 * hi2; |
476 | L_32 += (hi1 * lo2) >> 15; |
477 | L_32 += (lo1 * hi2) >> 15; |
478 | |
479 | return(L_32 << 1); |
480 | } |
481 | |
482 | /* |
483 | * D_UTIL_saturate |
484 | * |
485 | * Parameters: |
486 | * inp I: 32-bit number |
487 | * |
488 | * Function: |
489 | * Saturation to 16-bit number |
490 | * |
491 | * Returns: |
492 | * 16-bit number |
493 | */ |
494 | Word16 D_UTIL_saturate(Word32 inp) |
495 | { |
496 | Word16 out; |
497 | if ((inp < MAX_16) & (inp > MIN_16)) { |
498 | out = (Word16)inp; |
499 | } else { |
500 | if (inp > 0) { |
501 | out = MAX_16; |
502 | } else { |
503 | out = MIN_16; |
504 | } |
505 | } |
506 | |
507 | return(out); |
508 | } |
509 | |
510 | /* |
511 | * D_UTIL_signal_up_scale |
512 | * |
513 | * Parameters: |
514 | * x I/O: signal to scale |
515 | * lg I: size of x[] |
516 | * exp I: exponent: x = round(x << exp) |
517 | * |
518 | * Function: |
519 | * Scale signal up to get maximum of dynamic. |
520 | * |
521 | * Returns: |
522 | * 32 bit result |
523 | */ |
524 | void D_UTIL_signal_up_scale(Word16 x[], Word16 lg, Word16 exp) |
525 | { |
526 | Word32 i, tmp; |
527 | |
528 | for (i = 0; i < lg; i++) { |
529 | tmp = x[i] << exp; |
530 | x[i] = D_UTIL_saturate(tmp); |
531 | } |
532 | |
533 | return; |
534 | } |
535 | |
536 | |
537 | /* |
538 | * D_UTIL_signal_down_scale |
539 | * |
540 | * Parameters: |
541 | * x I/O: signal to scale |
542 | * lg I: size of x[] |
543 | * exp I: exponent: x = round(x << exp) |
544 | * |
545 | * Function: |
546 | * Scale signal up to get maximum of dynamic. |
547 | * |
548 | * Returns: |
549 | * 32 bit result |
550 | */ |
551 | void D_UTIL_signal_down_scale(Word16 x[], Word16 lg, Word16 exp) |
552 | { |
553 | Word32 i, tmp; |
554 | |
555 | for (i = 0; i < lg; i++) { |
556 | tmp = x[i] << 16; |
557 | tmp = tmp >> exp; |
558 | x[i] = (Word16)((tmp + 0x8000) >> 16); |
559 | } |
560 | |
561 | return; |
562 | } |
563 | |
564 | |
565 | /* |
566 | * D_UTIL_deemph_32 |
567 | * |
568 | * Parameters: |
569 | * x_hi I: input signal (bit31..16) |
570 | * x_lo I: input signal (bit15..4) |
571 | * y O: output signal (x16) |
572 | * mu I: (Q15) deemphasis factor |
573 | * L I: vector size |
574 | * mem I/O: memory (y[-1]) |
575 | * |
576 | * Function: |
577 | * Filtering through 1/(1-mu z^-1) |
578 | * |
579 | * Returns: |
580 | * void |
581 | */ |
582 | static void D_UTIL_deemph_32(Word16 x_hi[], Word16 x_lo[], Word16 y[], |
583 | Word16 mu, Word16 L, Word16 *mem) |
584 | { |
585 | Word32 i, fac; |
586 | Word32 tmp; |
587 | |
588 | fac = mu >> 1; /* Q15 --> Q14 */ |
589 | |
590 | /* L_tmp = hi<<16 + lo<<4 */ |
591 | tmp = (x_hi[0] << 12) + x_lo[0]; |
592 | tmp = (tmp << 6) + (*mem * fac); |
593 | tmp = (tmp + 0x2000) >> 14; |
594 | y[0] = D_UTIL_saturate(tmp); |
595 | |
596 | for (i = 1; i < L; i++) { |
597 | tmp = (x_hi[i] << 12) + x_lo[i]; |
598 | tmp = (tmp << 6) + (y[i - 1] * fac); |
599 | tmp = (tmp + 0x2000) >> 14; |
600 | y[i] = D_UTIL_saturate(tmp); |
601 | } |
602 | |
603 | *mem = y[L - 1]; |
604 | |
605 | return; |
606 | } |
607 | |
608 | |
609 | /* |
610 | * D_UTIL_synthesis_32 |
611 | * |
612 | * Parameters: |
613 | * a I: LP filter coefficients |
614 | * m I: order of LP filter |
615 | * exc I: excitation |
616 | * Qnew I: exc scaling = 0(min) to 8(max) |
617 | * sig_hi O: synthesis high |
618 | * sig_lo O: synthesis low |
619 | * lg I: size of filtering |
620 | * |
621 | * Function: |
622 | * Perform the synthesis filtering 1/A(z). |
623 | * |
624 | * Returns: |
625 | * void |
626 | */ |
627 | static void D_UTIL_synthesis_32(Word16 a[], Word16 m, Word16 exc[], |
628 | Word16 Qnew, Word16 sig_hi[], Word16 sig_lo[], |
629 | Word16 lg) |
630 | { |
631 | Word32 i, j, a0, s; |
632 | Word32 tmp, tmp2; |
633 | |
634 | /* See if a[0] is scaled */ |
635 | s = D_UTIL_norm_s((Word16)a[0]) - 2; |
636 | |
637 | a0 = a[0] >> (4 + Qnew); /* input / 16 and >>Qnew */ |
638 | |
639 | /* Do the filtering. */ |
640 | for (i = 0; i < lg; i++) { |
641 | tmp = 0; |
642 | |
643 | for (j = 1; j <= m; j++) { |
644 | tmp -= sig_lo[i - j] * a[j]; |
645 | } |
646 | |
647 | tmp = tmp >> (15 - 4); /* -4 : sig_lo[i] << 4 */ |
648 | |
649 | tmp2 = exc[i] * a0; |
650 | |
651 | for (j = 1; j <= m; j++) { |
652 | tmp2 -= sig_hi[i - j] * a[j]; |
653 | } |
654 | |
655 | tmp += tmp2 << 1; |
656 | tmp <<= s; |
657 | |
658 | /* sig_hi = bit16 to bit31 of synthesis */ |
659 | sig_hi[i] = (Word16)(tmp >> 13); |
660 | |
661 | /* sig_lo = bit4 to bit15 of synthesis */ |
662 | sig_lo[i] = (Word16)((tmp >> 1) - (sig_hi[i] * 4096)); |
663 | } |
664 | |
665 | return; |
666 | } |
667 | |
668 | |
669 | /* |
670 | * D_UTIL_hp50_12k8 |
671 | * |
672 | * Parameters: |
673 | * signal I/O: signal |
674 | * lg I: lenght of signal |
675 | * mem I/O: filter memory [6] |
676 | * |
677 | * Function: |
678 | * 2nd order high pass filter with cut off frequency at 50 Hz. |
679 | * |
680 | * Algorithm: |
681 | * |
682 | * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] |
683 | * + a[1]*y[i-1] + a[2]*y[i-2]; |
684 | * |
685 | * b[3] = {0.989501953f, -1.979003906f, 0.989501953f}; |
686 | * a[3] = {1.000000000F, 1.978881836f,-0.966308594f}; |
687 | * |
688 | * |
689 | * Returns: |
690 | * void |
691 | */ |
692 | static void D_UTIL_hp50_12k8(Word16 signal[], Word16 lg, Word16 mem[]) |
693 | { |
694 | Word32 i, L_tmp; |
695 | Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2; |
696 | |
697 | y2_hi = mem[0]; |
698 | y2_lo = mem[1]; |
699 | y1_hi = mem[2]; |
700 | y1_lo = mem[3]; |
701 | x0 = mem[4]; |
702 | x1 = mem[5]; |
703 | |
704 | for (i = 0; i < lg; i++) { |
705 | x2 = x1; |
706 | x1 = x0; |
707 | x0 = signal[i]; |
708 | |
709 | /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] */ |
710 | /* + a[1]*y[i-1] + a[2] * y[i-2]; */ |
711 | L_tmp = 8192L; /* rounding to maximise precision */ |
712 | L_tmp = L_tmp + (y1_lo * 16211); |
713 | L_tmp = L_tmp + (y2_lo * (-8021)); |
714 | L_tmp = L_tmp >> 14; |
715 | L_tmp = L_tmp + (y1_hi * 32422); |
716 | L_tmp = L_tmp + (y2_hi * (-16042)); |
717 | L_tmp = L_tmp + (x0 * 8106); |
718 | L_tmp = L_tmp + (x1 * (-16212)); |
719 | L_tmp = L_tmp + (x2 * 8106); |
720 | L_tmp = L_tmp << 2; /* coeff Q11 --> Q14 */ |
721 | y2_hi = y1_hi; |
722 | y2_lo = y1_lo; |
723 | D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo); |
724 | L_tmp = (L_tmp + 0x4000) >> 15; /* coeff Q14 --> Q15 with saturation */ |
725 | signal[i] = D_UTIL_saturate(L_tmp); |
726 | |
727 | } |
728 | mem[0] = y2_hi; |
729 | mem[1] = y2_lo; |
730 | mem[2] = y1_hi; |
731 | mem[3] = y1_lo; |
732 | mem[4] = x0; |
733 | mem[5] = x1; |
734 | |
735 | return; |
736 | } |
737 | |
738 | |
739 | /* |
740 | * D_UTIL_interpol |
741 | * |
742 | * Parameters: |
743 | * x I: input vector |
744 | * fir I: filter coefficient |
745 | * frac I: fraction (0..resol) |
746 | * up_samp I: resolution |
747 | * nb_coef I: number of coefficients |
748 | * |
749 | * Function: |
750 | * Fractional interpolation of signal at position (frac/up_samp) |
751 | * |
752 | * Returns: |
753 | * result of interpolation |
754 | */ |
755 | Word16 D_UTIL_interpol(Word16 *x, Word16 const *fir, Word16 frac, |
756 | Word16 resol, Word16 nb_coef) |
757 | { |
758 | Word32 i, k; |
759 | Word32 sum; |
760 | |
761 | x = x - nb_coef + 1; |
762 | sum = 0L; |
763 | |
764 | for (i = 0, k = ((resol - 1) - frac); i < 2 * nb_coef; i++, |
765 | k = (Word16)(k + resol)) { |
766 | sum = sum + (x[i] * fir[k]); |
767 | } |
768 | |
769 | if ((sum < 536846336) & (sum > -536879104)) { |
770 | sum = (sum + 0x2000) >> 14; |
771 | } else if (sum > 536846336) { |
772 | sum = 32767; |
773 | } else { |
774 | sum = -32768; |
775 | } |
776 | |
777 | return((Word16)sum); /* saturation can occur here */ |
778 | } |
779 | |
780 | |
781 | /* |
782 | * D_UTIL_up_samp |
783 | * |
784 | * Parameters: |
785 | * res_d I: signal to upsampling |
786 | * res_u O: upsampled output |
787 | * L_frame I: length of output |
788 | * |
789 | * Function: |
790 | * Upsampling |
791 | * |
792 | * Returns: |
793 | * void |
794 | */ |
795 | static void D_UTIL_up_samp(Word16 *sig_d, Word16 *sig_u, Word16 L_frame) |
796 | { |
797 | Word32 pos, i, j; |
798 | Word16 frac; |
799 | |
800 | pos = 0; /* position with 1/5 resolution */ |
801 | |
802 | for (j = 0; j < L_frame; j++) { |
803 | i = (pos * INV_FAC5) >> 15; /* integer part = pos * 1/5 */ |
804 | frac = (Word16)(pos - ((i << 2) + i)); /* frac = pos - (pos/5)*5 */ |
805 | sig_u[j] = D_UTIL_interpol(&sig_d[i], D_ROM_fir_up, frac, FAC5, NB_COEF_UP); |
806 | pos = pos + FAC4; /* position + 4/5 */ |
807 | } |
808 | |
809 | return; |
810 | } |
811 | |
812 | |
813 | /* |
814 | * D_UTIL_oversamp_16k |
815 | * |
816 | * Parameters: |
817 | * sig12k8 I: signal to oversampling |
818 | * lg I: length of input |
819 | * sig16k O: oversampled signal |
820 | * mem I/O: memory (2*12) |
821 | * |
822 | * Function: |
823 | * Oversampling from 12.8kHz to 16kHz |
824 | * |
825 | * Returns: |
826 | * void |
827 | */ |
828 | static void D_UTIL_oversamp_16k(Word16 sig12k8[], Word16 lg, Word16 sig16k[], |
829 | Word16 mem[]) |
830 | { |
831 | Word16 lg_up; |
832 | Word16 signal[L_SUBFR + (2 * NB_COEF_UP)]; |
833 | |
834 | memcpy(signal, mem, (2 * NB_COEF_UP) * sizeof(Word16)); |
835 | memcpy(signal + (2 * NB_COEF_UP), sig12k8, lg * sizeof(Word16)); |
836 | lg_up = (Word16)(((lg * UP_FAC) >> 15) << 1); |
837 | D_UTIL_up_samp(signal + NB_COEF_UP, sig16k, lg_up); |
838 | memcpy(mem, signal + lg, (2 * NB_COEF_UP) * sizeof(Word16)); |
839 | |
840 | return; |
841 | } |
842 | |
843 | |
844 | /* |
845 | * D_UTIL_hp400_12k8 |
846 | * |
847 | * Parameters: |
848 | * signal I/O: signal |
849 | * lg I: lenght of signal |
850 | * mem I/O: filter memory [6] |
851 | * |
852 | * Function: |
853 | * 2nd order high pass filter with cut off frequency at 400 Hz. |
854 | * |
855 | * Algorithm: |
856 | * |
857 | * y[i] = b[0]*x[i] + b[1]*x[i-1] + b[2]*x[i-2] |
858 | * + a[1]*y[i-1] + a[2]*y[i-2]; |
859 | * |
860 | * b[3] = {0.893554687, -1.787109375, 0.893554687}; |
861 | * a[3] = {1.000000000, 1.787109375, -0.864257812}; |
862 | * |
863 | * |
864 | * Returns: |
865 | * void |
866 | */ |
867 | void D_UTIL_hp400_12k8(Word16 signal[], Word16 lg, Word16 mem[]) |
868 | { |
869 | |
870 | Word32 i, L_tmp; |
871 | Word16 y2_hi, y2_lo, y1_hi, y1_lo, x0, x1, x2; |
872 | |
873 | y2_hi = mem[0]; |
874 | y2_lo = mem[1]; |
875 | y1_hi = mem[2]; |
876 | y1_lo = mem[3]; |
877 | x0 = mem[4]; |
878 | x1 = mem[5]; |
879 | |
880 | for (i = 0; i < lg; i++) { |
881 | x2 = x1; |
882 | x1 = x0; |
883 | x0 = signal[i]; |
884 | |
885 | /* y[i] = b[0]*x[i] + b[1]*x[i-1] + b140[2]*x[i-2] */ |
886 | /* + a[1]*y[i-1] + a[2] * y[i-2]; */ |
887 | L_tmp = 8192L + (y1_lo * 29280); |
888 | L_tmp = L_tmp + (y2_lo * (-14160)); |
889 | L_tmp = (L_tmp >> 14); |
890 | L_tmp = L_tmp + (y1_hi * 58560); |
891 | L_tmp = L_tmp + (y2_hi * (-28320)); |
892 | L_tmp = L_tmp + (x0 * 1830); |
893 | L_tmp = L_tmp + (x1 * (-3660)); |
894 | L_tmp = L_tmp + (x2 * 1830); |
895 | L_tmp = (L_tmp << 1); /* coeff Q12 --> Q13 */ |
896 | y2_hi = y1_hi; |
897 | y2_lo = y1_lo; |
898 | D_UTIL_l_extract(L_tmp, &y1_hi, &y1_lo); |
899 | |
900 | /* signal is divided by 16 to avoid overflow in energy computation */ |
901 | signal[i] = (Word16)((L_tmp + 0x8000) >> 16); |
902 | } |
903 | mem[0] = y2_hi; |
904 | mem[1] = y2_lo; |
905 | mem[2] = y1_hi; |
906 | mem[3] = y1_lo; |
907 | mem[4] = x0; |
908 | mem[5] = x1; |
909 | |
910 | return; |
911 | } |
912 | |
913 | |
914 | /* |
915 | * D_UTIL_synthesis |
916 | * |
917 | * Parameters: |
918 | * a I: LP filter coefficients |
919 | * m I: order of LP filter |
920 | * x I: input signal |
921 | * y O: output signal |
922 | * lg I: size of filtering |
923 | * mem I/O: initial filter states |
924 | * update_m I: update memory flag |
925 | * |
926 | * Function: |
927 | * Perform the synthesis filtering 1/A(z). |
928 | * |
929 | * Returns: |
930 | * void |
931 | */ |
932 | static void D_UTIL_synthesis(Word16 a[], Word16 m, Word16 x[], Word16 y[], |
933 | Word16 lg, Word16 mem[], Word16 update) |
934 | { |
935 | Word32 i, j, tmp, s; |
936 | Word16 y_buf[L_SUBFR16k + M16k], a0; |
937 | Word16 *yy; |
938 | |
939 | yy = &y_buf[m]; |
940 | |
941 | /* See if a[0] is scaled */ |
942 | s = D_UTIL_norm_s(a[0]) - 2; |
943 | /* copy initial filter states into synthesis buffer */ |
944 | memcpy(y_buf, mem, m * sizeof(Word16)); |
945 | |
946 | a0 = (Word16)(a[0] >> 1); /* input / 2 */ |
947 | |
948 | /* Do the filtering. */ |
949 | for (i = 0; i < lg; i++) { |
950 | tmp = x[i] * a0; |
951 | |
952 | for (j = 1; j <= m; j++) { |
953 | tmp -= a[j] * yy[i - j]; |
954 | } |
955 | tmp <<= s; |
956 | |
957 | y[i] = yy[i] = (Word16)((tmp + 0x800) >> 12); |
958 | } |
959 | |
960 | /* Update memory if required */ |
961 | if (update) { |
962 | memcpy(mem, &yy[lg - m], m * sizeof(Word16)); |
963 | } |
964 | |
965 | return; |
966 | } |
967 | |
968 | |
969 | /* |
970 | * D_UTIL_bp_6k_7k |
971 | * |
972 | * Parameters: |
973 | * signal I/O: signal |
974 | * lg I: lenght of signal |
975 | * mem I/O: filter memory [4] |
976 | * |
977 | * Function: |
978 | * 15th order band pass 6kHz to 7kHz FIR filter. |
979 | * |
980 | * Returns: |
981 | * void |
982 | */ |
983 | void D_UTIL_bp_6k_7k(Word16 signal[], Word16 lg, Word16 mem[]) |
984 | { |
985 | Word32 x[L_SUBFR16k + (L_FIR - 1)]; |
986 | Word32 i, j, tmp; |
987 | |
988 | for (i = 0; i < (L_FIR - 1); i++) { |
989 | x[i] = (Word16)mem[i]; /* gain of filter = 4 */ |
990 | } |
991 | |
992 | for (i = 0; i < lg; i++) { |
993 | x[i + L_FIR - 1] = signal[i] >> 2; /* gain of filter = 4 */ |
994 | } |
995 | |
996 | for (i = 0; i < lg; i++) { |
997 | tmp = 0; |
998 | |
999 | for (j = 0; j < L_FIR; j++) { |
1000 | tmp += x[i + j] * D_ROM_fir_6k_7k[j]; |
1001 | } |
1002 | |
1003 | signal[i] = (Word16)((tmp + 0x4000) >> 15); |
1004 | } |
1005 | |
1006 | for (i = 0; i < (L_FIR - 1); i++) { |
1007 | mem[i] = (Word16)x[lg + i]; /* gain of filter = 4 */ |
1008 | } |
1009 | |
1010 | return; |
1011 | } |
1012 | |
1013 | |
1014 | /* |
1015 | * D_UTIL_hp_7k |
1016 | * |
1017 | * Parameters: |
1018 | * signal I/O: ISF vector |
1019 | * lg I: length of signal |
1020 | * mem I/O: memory (30) |
1021 | * |
1022 | * Function: |
1023 | * 15th order high pass 7kHz FIR filter |
1024 | * |
1025 | * Returns: |
1026 | * void |
1027 | */ |
1028 | static void D_UTIL_hp_7k(Word16 signal[], Word16 lg, Word16 mem[]) |
1029 | { |
1030 | |
1031 | Word32 i, j, tmp; |
1032 | Word16 x[L_SUBFR16k + (L_FIR - 1)]; |
1033 | |
1034 | memcpy(x, mem, (L_FIR - 1) * sizeof(Word16)); |
1035 | memcpy(&x[L_FIR - 1], signal, lg * sizeof(Word16)); |
1036 | |
1037 | for (i = 0; i < lg; i++) { |
1038 | tmp = 0; |
1039 | |
1040 | for (j = 0; j < L_FIR; j++) { |
1041 | tmp += x[i + j] * D_ROM_fir_7k[j]; |
1042 | } |
1043 | |
1044 | signal[i] = (Word16)((tmp + 0x4000) >> 15); |
1045 | } |
1046 | |
1047 | memcpy(mem, x + lg, (L_FIR - 1) * sizeof(Word16)); |
1048 | |
1049 | return; |
1050 | } |
1051 | |
1052 | |
1053 | /* |
1054 | * D_UTIL_Dec_synthesis |
1055 | * |
1056 | * Parameters: |
1057 | * Aq I: quantized Az |
1058 | * exc I: excitation at 12kHz |
1059 | * Q_new I: scaling performed on exc |
1060 | * synth16k O: 16kHz synthesis signal |
1061 | * prms I: parameters |
1062 | * HfIsf I/O: High frequency ISF:s |
1063 | * mode I: codec mode |
1064 | * newDTXState I: dtx state |
1065 | * bfi I: bad frame indicator |
1066 | * st I/O: State structure |
1067 | * |
1068 | * Function: |
1069 | * Synthesis of signal at 16kHz with HF extension. |
1070 | * |
1071 | * Returns: |
1072 | * void |
1073 | */ |
1074 | void D_UTIL_dec_synthesis(Word16 Aq[], Word16 exc[], Word16 Q_new, |
1075 | Word16 synth16k[], Word16 prms, Word16 HfIsf[], |
1076 | Word16 mode, Word16 newDTXState, Word16 bfi, |
1077 | Decoder_State *st) |
1078 | { |
1079 | Word32 tmp, i; |
1080 | Word16 exp; |
1081 | Word16 ener, exp_ener; |
1082 | Word32 fac; |
1083 | Word16 synth_hi[M + L_SUBFR], synth_lo[M + L_SUBFR]; |
1084 | Word16 synth[L_SUBFR]; |
1085 | Word16 HF[L_SUBFR16k]; /* High Frequency vector */ |
1086 | Word16 Ap[M16k + 1]; |
1087 | Word16 HfA[M16k + 1]; |
1088 | Word16 HF_corr_gain; |
1089 | Word16 HF_gain_ind; |
1090 | Word32 gain1, gain2; |
1091 | Word16 weight1, weight2; |
1092 | |
1093 | /* |
1094 | * Speech synthesis |
1095 | * |
1096 | * - Find synthesis speech corresponding to exc2[]. |
1097 | * - Perform fixed deemphasis and hp 50hz filtering. |
1098 | * - Oversampling from 12.8kHz to 16kHz. |
1099 | */ |
1100 | memcpy(synth_hi, st->mem_syn_hi, M * sizeof(Word16)); |
1101 | memcpy(synth_lo, st->mem_syn_lo, M * sizeof(Word16)); |
1102 | D_UTIL_synthesis_32(Aq, M, exc, Q_new, synth_hi + M, synth_lo + M, L_SUBFR); |
1103 | memcpy(st->mem_syn_hi, synth_hi + L_SUBFR, M * sizeof(Word16)); |
1104 | memcpy(st->mem_syn_lo, synth_lo + L_SUBFR, M * sizeof(Word16)); |
1105 | D_UTIL_deemph_32(synth_hi + M, synth_lo + M, synth, PREEMPH_FAC, L_SUBFR, |
1106 | &(st->mem_deemph)); |
1107 | D_UTIL_hp50_12k8(synth, L_SUBFR, st->mem_sig_out); |
1108 | D_UTIL_oversamp_16k(synth, L_SUBFR, synth16k, st->mem_oversamp); |
1109 | |
1110 | /* |
1111 | * HF noise synthesis |
1112 | * |
1113 | * - Generate HF noise between 5.5 and 7.5 kHz. |
1114 | * - Set energy of noise according to synthesis tilt. |
1115 | * tilt > 0.8 ==> - 14 dB (voiced) |
1116 | * tilt 0.5 ==> - 6 dB (voiced or noise) |
1117 | * tilt < 0.0 ==> 0 dB (noise) |
1118 | */ |
1119 | |
1120 | /* generate white noise vector */ |
1121 | for (i = 0; i < L_SUBFR16k; i++) { |
1122 | HF[i] = (Word16)(D_UTIL_random(&(st->mem_seed2)) >> 3); |
1123 | } |
1124 | |
1125 | /* energy of excitation */ |
1126 | D_UTIL_signal_down_scale(exc, L_SUBFR, 3); |
1127 | Q_new = (Word16)(Q_new - 3); |
1128 | ener = (Word16)(D_UTIL_dot_product12(exc, exc, L_SUBFR, &exp_ener) >> 16); |
1129 | exp_ener = (Word16)(exp_ener - (Q_new << 1)); |
1130 | |
1131 | /* set energy of white noise to energy of excitation */ |
1132 | tmp = (Word16)(D_UTIL_dot_product12(HF, HF, L_SUBFR16k, &exp) >> 16); |
1133 | |
1134 | if (tmp > ener) { |
1135 | tmp = tmp >> 1; /* Be sure tmp < ener */ |
1136 | exp = (Word16)(exp + 1); |
1137 | } |
1138 | |
1139 | tmp = (tmp << 15) / ener; |
1140 | |
1141 | if (tmp > 32767) { |
1142 | tmp = 32767; |
1143 | } |
1144 | |
1145 | tmp = tmp << 16; /* result is normalized */ |
1146 | exp = (Word16)(exp - exp_ener); |
1147 | D_UTIL_normalised_inverse_sqrt(&tmp, &exp); |
1148 | |
1149 | /* L_tmp x 2, L_tmp in Q31 */ |
1150 | /* tmp = 2 x sqrt(ener_exc/ener_hf) */ |
1151 | if (exp >= 0) { |
1152 | tmp = tmp >> (15 - exp); |
1153 | } else { |
1154 | tmp = tmp >> (-exp); |
1155 | tmp = tmp >> 15; |
1156 | } |
1157 | |
1158 | /* saturation */ |
1159 | if (tmp > 0x7FFF) { |
1160 | tmp = 0x7FFF; |
1161 | } |
1162 | |
1163 | for (i = 0; i < L_SUBFR16k; i++) { |
1164 | HF[i] = (Word16)((HF[i] * tmp) >> 15); |
1165 | } |
1166 | |
1167 | /* find tilt of synthesis speech (tilt: 1=voiced, -1=unvoiced) */ |
1168 | D_UTIL_hp400_12k8(synth, L_SUBFR, st->mem_hp400); |
1169 | tmp = 0L; |
1170 | |
1171 | for (i = 0; i < L_SUBFR; i++) { |
1172 | tmp = tmp + (synth[i] * synth[i]); |
1173 | } |
1174 | |
1175 | tmp = (tmp << 1) + 1; |
1176 | exp = D_UTIL_norm_l(tmp); |
1177 | ener = (Word16)((tmp << exp) >> 16); /* ener = r[0] */ |
1178 | tmp = 0L; |
1179 | |
1180 | for (i = 1; i < L_SUBFR; i++) { |
1181 | tmp = tmp + (synth[i] * synth[i - 1]); |
1182 | } |
1183 | |
1184 | tmp = (tmp << 1) + 1; |
1185 | tmp = (tmp << exp) >> 16; /* tmp = r[1] */ |
1186 | |
1187 | if (tmp > 0) { |
1188 | fac = ((tmp << 15) / ener); |
1189 | |
1190 | if (fac > 32767) { |
1191 | fac = 32767; |
1192 | } |
1193 | } else { |
1194 | fac = 0; |
1195 | } |
1196 | |
1197 | /* modify energy of white noise according to synthesis tilt */ |
1198 | gain1 = (32767 - fac); |
1199 | gain2 = ((32767 - fac) * 20480) >> 15; |
1200 | gain2 = (gain2 << 1); |
1201 | |
1202 | if (gain2 > 32767) { |
1203 | gain2 = 32767; |
1204 | } |
1205 | |
1206 | if (st->mem_vad_hist > 0) { |
1207 | weight1 = 0; |
1208 | weight2 = 32767; |
1209 | } else { |
1210 | weight1 = 32767; |
1211 | weight2 = 0; |
1212 | } |
1213 | |
1214 | tmp = (weight1 * gain1) >> 15; |
1215 | tmp = tmp + ((weight2 * gain2) >> 15); |
1216 | |
1217 | if (tmp != 0) { |
1218 | tmp = tmp + 1; |
1219 | } |
1220 | |
1221 | if (tmp < 3277) { |
1222 | tmp = 3277; /* 0.1 in Q15 */ |
1223 | } |
1224 | |
1225 | if ((mode == MODE_24k) & (bfi == 0)) { |
1226 | /* HF correction gain */ |
1227 | HF_gain_ind = prms; |
1228 | HF_corr_gain = D_ROM_hp_gain[HF_gain_ind]; |
1229 | |
1230 | /* HF gain */ |
1231 | for (i = 0; i < L_SUBFR16k; i++) { |
1232 | HF[i] = (Word16)(((HF[i] * HF_corr_gain) >> 15) << 1); |
1233 | } |
1234 | } else { |
1235 | for (i = 0; i < L_SUBFR16k; i++) { |
1236 | HF[i] = (Word16)((HF[i] * tmp) >> 15); |
1237 | } |
1238 | } |
1239 | |
1240 | if ((mode <= MODE_7k) & (newDTXState == SPEECH)) { |
1241 | D_LPC_isf_extrapolation(HfIsf); |
1242 | D_LPC_isp_a_conversion(HfIsf, HfA, 0, M16k); |
1243 | D_LPC_a_weight(HfA, Ap, 29491, M16k); /* fac=0.9 */ |
1244 | D_UTIL_synthesis(Ap, M16k, HF, HF, L_SUBFR16k, st->mem_syn_hf, 1); |
1245 | } else { |
1246 | /* synthesis of noise: 4.8kHz..5.6kHz --> 6kHz..7kHz */ |
1247 | D_LPC_a_weight(Aq, Ap, 19661, M); /* fac=0.6 */ |
1248 | D_UTIL_synthesis(Ap, M, HF, HF, L_SUBFR16k, st->mem_syn_hf + (M16k - M), 1); |
1249 | } |
1250 | |
1251 | /* noise High Pass filtering (1ms of delay) */ |
1252 | D_UTIL_bp_6k_7k(HF, L_SUBFR16k, st->mem_hf); |
1253 | |
1254 | if (mode == MODE_24k) { |
1255 | /* Low Pass filtering (7 kHz) */ |
1256 | D_UTIL_hp_7k(HF, L_SUBFR16k, st->mem_hf3); |
1257 | } |
1258 | |
1259 | /* add filtered HF noise to speech synthesis */ |
1260 | for (i = 0; i < L_SUBFR16k; i++) { |
1261 | tmp = (synth16k[i] + HF[i]); |
1262 | synth16k[i] = D_UTIL_saturate(tmp); |
1263 | } |
1264 | |
1265 | return; |
1266 | } |
1267 | |
1268 | |
1269 | /* |
1270 | * D_UTIL_preemph |
1271 | * |
1272 | * Parameters: |
1273 | * x I/O: signal |
1274 | * mu I: preemphasis factor |
1275 | * lg I: vector size |
1276 | * mem I/O: memory (x[-1]) |
1277 | * |
1278 | * Function: |
1279 | * Filtering through 1 - mu z^-1 |
1280 | * |
1281 | * |
1282 | * Returns: |
1283 | * void |
1284 | */ |
1285 | void D_UTIL_preemph(Word16 x[], Word16 mu, Word16 lg, Word16 *mem) |
1286 | { |
1287 | Word32 i, L_tmp; |
1288 | Word16 temp; |
1289 | |
1290 | temp = x[lg - 1]; |
1291 | |
1292 | for (i = lg - 1; i > 0; i--) { |
1293 | L_tmp = x[i] << 15; |
1294 | L_tmp = L_tmp - (x[i - 1] * mu); |
1295 | x[i] = (Word16)((L_tmp + 0x4000) >> 15); |
1296 | } |
1297 | |
1298 | L_tmp = x[0] << 15; |
1299 | L_tmp = L_tmp - (*mem * mu); |
1300 | x[0] = (Word16)((L_tmp + 0x4000) >> 15); |
1301 | *mem = temp; |
1302 | |
1303 | return; |
1304 | } |
1305 |