blob: 2bcf8c4bf0638cca2468e9d787dce9314e36ae61
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 <stdlib.h> |
12 | #include "typedef.h" |
13 | #include "dec_util.h" |
14 | |
15 | #define M 16 /* Order of LP filter */ |
16 | #define MP1 (M + 1) |
17 | #define M16k 20 |
18 | #define NC16k (M16k / 2) |
19 | #define MU 10923 /* Prediction factor (1.0/3.0) in Q15 */ |
20 | #define L_MEANBUF 3 |
21 | #define ALPHA 29491 /* 0. 9 in Q15 */ |
22 | #define ONE_ALPHA (32768-ALPHA) /* (1.0 - ALPHA) in Q15 */ |
23 | #define ORDER 16 /* order of linear prediction filter */ |
24 | #define ISF_GAP 128 /* 50 Hz */ |
25 | #define INV_LENGTH 2731 /* 1/12 */ |
26 | |
27 | extern const Word16 D_ROM_dico1_isf[]; |
28 | extern const Word16 D_ROM_dico2_isf[]; |
29 | extern const Word16 D_ROM_dico21_isf_36b[]; |
30 | extern const Word16 D_ROM_dico22_isf_36b[]; |
31 | extern const Word16 D_ROM_dico23_isf_36b[]; |
32 | extern const Word16 D_ROM_dico21_isf[]; |
33 | extern const Word16 D_ROM_dico22_isf[]; |
34 | extern const Word16 D_ROM_dico23_isf[]; |
35 | extern const Word16 D_ROM_dico24_isf[]; |
36 | extern const Word16 D_ROM_dico25_isf[]; |
37 | extern const Word16 D_ROM_dico1_isf_noise[]; |
38 | extern const Word16 D_ROM_dico2_isf_noise[]; |
39 | extern const Word16 D_ROM_dico3_isf_noise[]; |
40 | extern const Word16 D_ROM_dico4_isf_noise[]; |
41 | extern const Word16 D_ROM_dico5_isf_noise[]; |
42 | extern const Word16 D_ROM_mean_isf[]; |
43 | extern const Word16 D_ROM_mean_isf_noise[]; |
44 | extern const Word16 D_ROM_cos[]; |
45 | |
46 | |
47 | /* |
48 | * D_LPC_isf_reorder |
49 | * |
50 | * Parameters: |
51 | * isf I/O: vector of isfs |
52 | * min_dist I: quantized ISFs (in frequency domain) |
53 | * n I: LPC order |
54 | * |
55 | * Function: |
56 | * To make sure that the isfs are properly order and to keep a certain |
57 | * minimum distance between consecutive isfs. |
58 | * |
59 | * Returns: |
60 | * void |
61 | */ |
62 | static void D_LPC_isf_reorder(Word16 *isf, Word16 min_dist, Word16 n) |
63 | { |
64 | Word32 i, isf_min; |
65 | |
66 | isf_min = min_dist; |
67 | |
68 | for (i = 0; i < n - 1; i++) { |
69 | if (isf[i] < isf_min) { |
70 | isf[i] = (Word16)isf_min; |
71 | } |
72 | isf_min = isf[i] + min_dist; |
73 | } |
74 | |
75 | return; |
76 | } |
77 | |
78 | |
79 | /* |
80 | * D_LPC_isf_noise_d |
81 | * |
82 | * Parameters: |
83 | * indice I: indices of the selected codebook entries |
84 | * isf_q O: quantized ISFs (in frequency domain) |
85 | * |
86 | * Function: |
87 | * Decoding of ISF parameters |
88 | * |
89 | * Returns: |
90 | * void |
91 | */ |
92 | void D_LPC_isf_noise_d(Word16 *indice, Word16 *isf_q) |
93 | { |
94 | Word32 i; |
95 | |
96 | for (i = 0; i < 2; i++) { |
97 | isf_q[i] = D_ROM_dico1_isf_noise[indice[0] * 2 + i]; |
98 | } |
99 | |
100 | for (i = 0; i < 3; i++) { |
101 | isf_q[i + 2] = D_ROM_dico2_isf_noise[indice[1] * 3 + i]; |
102 | } |
103 | |
104 | for (i = 0; i < 3; i++) { |
105 | isf_q[i + 5] = D_ROM_dico3_isf_noise[indice[2] * 3 + i]; |
106 | } |
107 | |
108 | for (i = 0; i < 4; i++) { |
109 | isf_q[i + 8] = D_ROM_dico4_isf_noise[indice[3] * 4 + i]; |
110 | } |
111 | |
112 | for (i = 0; i < 4; i++) { |
113 | isf_q[i + 12] = D_ROM_dico5_isf_noise[indice[4] * 4 + i]; |
114 | } |
115 | |
116 | for (i = 0; i < ORDER; i++) { |
117 | isf_q[i] = (Word16)(isf_q[i] + D_ROM_mean_isf_noise[i]); |
118 | } |
119 | |
120 | D_LPC_isf_reorder(isf_q, ISF_GAP, ORDER); |
121 | |
122 | return; |
123 | } |
124 | |
125 | |
126 | /* |
127 | * D_LPC_isf_isp_conversion |
128 | * |
129 | * Parameters: |
130 | * isp O: (Q15) isp[m] (range: -1<=val<1) |
131 | * isf I: (Q15) isf[m] normalized (range: 0.0 <= val <= 0.5) |
132 | * m I: LPC order |
133 | * |
134 | * Function: |
135 | * Transformation isf to isp |
136 | * |
137 | * ISP are immitance spectral pair in cosine domain (-1 to 1). |
138 | * ISF are immitance spectral pair in frequency domain (0 to 6400). |
139 | * Returns: |
140 | * void |
141 | */ |
142 | void D_LPC_isf_isp_conversion(Word16 isf[], Word16 isp[], Word16 m) |
143 | { |
144 | Word32 i, ind, offset, tmp; |
145 | |
146 | for (i = 0; i < m - 1; i++) { |
147 | isp[i] = isf[i]; |
148 | } |
149 | isp[m - 1] = (Word16)(isf[m - 1] << 1); |
150 | |
151 | for (i = 0; i < m; i++) { |
152 | ind = isp[i] >> 7; /* ind = b7-b15 of isf[i] */ |
153 | offset = isp[i] & 0x007f; /* offset = b0-b6 of isf[i] */ |
154 | |
155 | /* isp[i] = table[ind]+ ((table[ind+1]-table[ind])*offset) / 128 */ |
156 | tmp = (D_ROM_cos[ind + 1] - D_ROM_cos[ind]) * offset; |
157 | isp[i] = (Word16)(D_ROM_cos[ind] + (tmp >> 7)); |
158 | } |
159 | return; |
160 | } |
161 | |
162 | |
163 | /* |
164 | * D_LPC_isp_pol_get |
165 | * |
166 | * Parameters: |
167 | * isp I: Immitance spectral pairs (cosine domaine) |
168 | * f O: the coefficients of F1 or F2 |
169 | * n I: no of coefficients (m/2) |
170 | * k16 I: 16k flag |
171 | * |
172 | * Function: |
173 | * Find the polynomial F1(z) or F2(z) from the ISPs. |
174 | * This is performed by expanding the product polynomials: |
175 | * |
176 | * F1(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) |
177 | * i=0,2,4,6,8 |
178 | * F2(z) = product ( 1 - 2 isp_i z^-1 + z^-2 ) |
179 | * i=1,3,5,7 |
180 | * |
181 | * where isp_i are the ISPs in the cosine domain. |
182 | * |
183 | * Returns: |
184 | * void |
185 | */ |
186 | static void D_LPC_isp_pol_get(Word16 *isp, Word32 *f, Word32 n, Word16 k16) |
187 | { |
188 | Word32 i, j, t0, s1, s2; |
189 | Word16 hi, lo; |
190 | |
191 | s1 = 8388608; |
192 | s2 = 512; |
193 | |
194 | if (k16) { |
195 | s1 >>= 2; |
196 | s2 >>= 2; |
197 | } |
198 | |
199 | /* All computation in Q23 */ |
200 | f[0] = s1; /* f[0] = 1.0; in Q23 */ |
201 | f[1] = isp[0] * (-s2); /* f[1] = -2.0*isp[0] in Q23 */ |
202 | f += 2; /* Advance f pointer */ |
203 | isp += 2; /* Advance isp pointer */ |
204 | |
205 | for (i = 2; i <= n; i++) { |
206 | *f = f[ - 2]; |
207 | |
208 | for (j = 1; j < i; j++, f--) { |
209 | D_UTIL_l_extract(f[- 1], &hi, &lo); |
210 | t0 = D_UTIL_mpy_32_16(hi, lo, *isp); /* t0 = f[-1] * isp */ |
211 | t0 = (t0 << 1); |
212 | *f = (*f - t0); /* *f -= t0 */ |
213 | *f = (*f + f[ - 2]); /* *f += f[-2] */ |
214 | } |
215 | |
216 | *f = *f - (*isp * s2); /* *f -= isp << 8 */ |
217 | f += i; /* Advance f pointer */ |
218 | isp += 2; /* Advance isp pointer */ |
219 | } |
220 | |
221 | return; |
222 | } |
223 | |
224 | |
225 | /* |
226 | * D_LPC_isp_a_conversion |
227 | * |
228 | * Parameters: |
229 | * isp I: (Q15) Immittance spectral pairs |
230 | * a O: (Q12) Predictor coefficients (order = M) |
231 | * m I: order of LP filter |
232 | * |
233 | * Function: |
234 | * Convert ISPs to predictor coefficients a[] |
235 | * |
236 | * Returns: |
237 | * void |
238 | */ |
239 | void D_LPC_isp_a_conversion(Word16 isp[], Word16 a[], Word32 adaptive_scaling, |
240 | Word16 m) |
241 | { |
242 | Word32 j, i, nc, tmax, q, q_sug, r; |
243 | Word32 f1[NC16k + 1], f2[NC16k]; |
244 | Word32 t0; |
245 | Word16 hi, lo; |
246 | |
247 | nc = m >> 1; |
248 | |
249 | if (nc > 8) { |
250 | D_LPC_isp_pol_get(&isp[0], f1, nc, 1); |
251 | |
252 | for (i = 0; i <= nc; i++) { |
253 | f1[i] = (f1[i] << 2); |
254 | } |
255 | } else { |
256 | D_LPC_isp_pol_get(&isp[0], f1, nc, 0); |
257 | } |
258 | |
259 | if (nc > 8) { |
260 | D_LPC_isp_pol_get(&isp[1], f2, nc - 1, 1); |
261 | |
262 | for (i = 0; i <= nc - 1; i++) { |
263 | f2[i] = (f2[i] << 2); |
264 | } |
265 | } else { |
266 | D_LPC_isp_pol_get(&isp[1], f2, nc - 1, 0); |
267 | } |
268 | |
269 | /* |
270 | * Multiply F2(z) by (1 - z^-2) |
271 | */ |
272 | for (i = nc - 1; i > 1; i--) { |
273 | f2[i] = f2[i] - f2[i - 2]; /* f2[i] -= f2[i-2]; */ |
274 | } |
275 | |
276 | /* |
277 | * Scale F1(z) by (1+isp[m-1]) and F2(z) by (1-isp[m-1]) |
278 | */ |
279 | for (i = 0; i < nc; i++) { |
280 | /* f1[i] *= (1.0 + isp[M-1]); */ |
281 | D_UTIL_l_extract(f1[i], &hi, &lo); |
282 | t0 = D_UTIL_mpy_32_16(hi, lo, isp[m - 1]); |
283 | f1[i] = f1[i] + t0; |
284 | |
285 | /* f2[i] *= (1.0 - isp[M-1]); */ |
286 | D_UTIL_l_extract(f2[i], &hi, &lo); |
287 | t0 = D_UTIL_mpy_32_16(hi, lo, isp[m - 1]); |
288 | f2[i] = f2[i] - t0; |
289 | } |
290 | |
291 | /* |
292 | * A(z) = (F1(z)+F2(z))/2 |
293 | * F1(z) is symmetric and F2(z) is antisymmetric |
294 | */ |
295 | |
296 | /* a[0] = 1.0; */ |
297 | a[0] = 4096; |
298 | tmax = 1; |
299 | |
300 | for (i = 1, j = m - 1; i < nc; i++, j--) { |
301 | /* a[i] = 0.5*(f1[i] + f2[i]); */ |
302 | t0 = f1[i] + f2[i]; /* f1[i] + f2[i] */ |
303 | tmax |= labs(t0); |
304 | a[i] = (Word16)((t0 + 0x800) >> 12); /* from Q23 to Q12 and * 0.5 */ |
305 | |
306 | /* a[j] = 0.5*(f1[i] - f2[i]); */ |
307 | t0 = (f1[i] - f2[i]); /* f1[i] - f2[i] */ |
308 | tmax |= labs(t0); |
309 | a[j] = (Word16)((t0 + 0x800) >> 12); /* from Q23 to Q12 and * 0.5 */ |
310 | } |
311 | |
312 | /* rescale data if overflow has occured and reprocess the loop */ |
313 | |
314 | if (adaptive_scaling) { |
315 | q = 4 - D_UTIL_norm_l(tmax); /* adaptive scaling enabled */ |
316 | } else { |
317 | q = 0; /* adaptive scaling disabled */ |
318 | } |
319 | |
320 | if (q > 0) { |
321 | q_sug = 12 + q; |
322 | r = 1 << (q_sug - 1); |
323 | |
324 | for (i = 1, j = m - 1; i < nc; i++, j--) { |
325 | /* a[i] = 0.5*(f1[i] + f2[i]); */ |
326 | t0 = f1[i] + f2[i]; /* f1[i] + f2[i] */ |
327 | a[i] = (Word16)((t0 + r) >> q_sug); /* from Q23 to Q12 and * 0.5 */ |
328 | |
329 | /* a[j] = 0.5*(f1[i] - f2[i]); */ |
330 | t0 = f1[i] - f2[i]; /* f1[i] - f2[i] */ |
331 | a[j] = (Word16)((t0 + r) >> q_sug); /* from Q23 to Q12 and * 0.5 */ |
332 | } |
333 | a[0] = (Word16)(a[0] >> q); |
334 | } else { |
335 | q_sug = 12; |
336 | r = 1 << (q_sug - 1); |
337 | q = 0; |
338 | } |
339 | |
340 | /* a[NC] = 0.5*f1[NC]*(1.0 + isp[M-1]); */ |
341 | D_UTIL_l_extract(f1[nc], &hi, &lo); |
342 | t0 = D_UTIL_mpy_32_16(hi, lo, isp[m - 1]); |
343 | t0 = f1[nc] + t0; |
344 | a[nc] = (Word16)((t0 + r) >> q_sug); /* from Q23 to Q12 and * 0.5 */ |
345 | |
346 | /* a[m] = isp[m-1]; */ |
347 | a[m] = (Word16)((isp[m - 1] >> (2 + q)) + 1); /* from Q15 to Q12 */ |
348 | a[m] = (Word16)(a[m] >> 1); |
349 | |
350 | return; |
351 | } |
352 | |
353 | |
354 | /* |
355 | * D_LPC_a_weight |
356 | * |
357 | * Parameters: |
358 | * a I: LP filter coefficients |
359 | * ap O: weighted LP filter coefficients |
360 | * gamma I: weighting factor |
361 | * m I: order of LP filter |
362 | * |
363 | * Function: |
364 | * Weighting of LP filter coefficients, ap[i] = a[i] * (gamma^i). |
365 | * |
366 | * Returns: |
367 | * void |
368 | */ |
369 | void D_LPC_a_weight(Word16 a[], Word16 ap[], Word16 gamma, Word16 m) |
370 | { |
371 | Word32 i, fac; |
372 | |
373 | ap[0] = a[0]; |
374 | fac = gamma; |
375 | |
376 | for (i = 1; i < m; i++) { |
377 | ap[i] = (Word16)(((a[i] * fac) + 0x4000) >> 15); |
378 | fac = ((fac * gamma) + 0x4000) >> 15; |
379 | } |
380 | |
381 | ap[m] = (Word16)(((a[m] * fac) + 0x4000) >> 15); |
382 | |
383 | return; |
384 | } |
385 | |
386 | |
387 | /* |
388 | * D_LPC_isf_2s3s_decode |
389 | * |
390 | * Parameters: |
391 | * indice I: quantisation indices |
392 | * isf_q O: quantised ISFs in the cosine domain |
393 | * past_isfq I/O: past ISF quantizer |
394 | * isfold I: past quantised ISF |
395 | * isf_buf O: isf buffer |
396 | * bfi I: Bad frame indicator |
397 | * |
398 | * Function: |
399 | * Decoding of ISF parameters. |
400 | * |
401 | * Returns: |
402 | * void |
403 | */ |
404 | void D_LPC_isf_2s3s_decode(Word16 *indice, Word16 *isf_q, Word16 *past_isfq, |
405 | Word16 *isfold, Word16 *isf_buf, Word16 bfi) |
406 | { |
407 | |
408 | Word32 ref_isf[M]; |
409 | Word32 L_tmp, i, j; |
410 | Word16 tmp; |
411 | |
412 | if (bfi == 0) { /* Good frame */ |
413 | for (i = 0; i < 9; i++) { |
414 | isf_q[i] = D_ROM_dico1_isf[indice[0] * 9 + i]; |
415 | } |
416 | |
417 | for (i = 0; i < 7; i++) { |
418 | isf_q[i + 9] = D_ROM_dico2_isf[indice[1] * 7 + i]; |
419 | } |
420 | |
421 | for (i = 0; i < 5; i++) { |
422 | isf_q[i] = |
423 | (Word16)(isf_q[i] + D_ROM_dico21_isf_36b[indice[2] * 5 + i]); |
424 | } |
425 | |
426 | for (i = 0; i < 4; i++) { |
427 | isf_q[i + 5] = |
428 | (Word16)(isf_q[i + 5] + D_ROM_dico22_isf_36b[indice[3] * 4 + i]); |
429 | } |
430 | |
431 | for (i = 0; i < 7; i++) { |
432 | isf_q[i + 9] = |
433 | (Word16)(isf_q[i + 9] + D_ROM_dico23_isf_36b[indice[4] * 7 + i]); |
434 | } |
435 | |
436 | for (i = 0; i < ORDER; i++) { |
437 | tmp = isf_q[i]; |
438 | isf_q[i] = |
439 | (Word16)((tmp + D_ROM_mean_isf[i]) + ((MU * past_isfq[i]) >> 15)); |
440 | past_isfq[i] = tmp; |
441 | } |
442 | |
443 | for (i = 0; i < M; i++) { |
444 | for (j = (L_MEANBUF - 1); j > 0; j--) { |
445 | isf_buf[j * M + i] = isf_buf[(j - 1) * M + i]; |
446 | } |
447 | isf_buf[i] = isf_q[i]; |
448 | } |
449 | |
450 | } else { |
451 | /* bad frame */ |
452 | |
453 | for (i = 0; i < M; i++) { |
454 | L_tmp = D_ROM_mean_isf[i]; |
455 | |
456 | for (j = 0; j < L_MEANBUF; j++) { |
457 | L_tmp = L_tmp + isf_buf[j * M + i]; |
458 | } |
459 | ref_isf[i] = (L_tmp + 0x1) >> 2; |
460 | } |
461 | |
462 | /* use the past ISFs slightly shifted towards their mean */ |
463 | for (i = 0; i < ORDER; i++) { |
464 | isf_q[i] = (Word16)((((ALPHA * isfold[i]) >> 15) + |
465 | ((ONE_ALPHA * ref_isf[i]) >> 15))); |
466 | } |
467 | |
468 | /* estimate past quantized residual to be used in next frame */ |
469 | for (i = 0; i < ORDER; i++) { |
470 | /* predicted ISF */ |
471 | L_tmp = ref_isf[i] + ((past_isfq[i] * MU) >> 15); |
472 | /* past_isfq[i] *= 0.5 */ |
473 | past_isfq[i] = (Word16)((isf_q[i] - L_tmp) >> 1); |
474 | } |
475 | } |
476 | |
477 | D_LPC_isf_reorder(isf_q, ISF_GAP, ORDER); |
478 | |
479 | return; |
480 | } |
481 | |
482 | |
483 | /* |
484 | * D_LPC_isf_2s5s_decode |
485 | * |
486 | * Parameters: |
487 | * indice I: quantization indices |
488 | * isf_q O: quantized ISFs in the cosine domain |
489 | * past_isfq I/O: past ISF quantizer |
490 | * isfold I: past quantized ISF |
491 | * isf_buf O: isf buffer |
492 | * bfi I: Bad frame indicator |
493 | * |
494 | * Function: |
495 | * Decoding of ISF parameters. |
496 | * |
497 | * Returns: |
498 | * void |
499 | */ |
500 | void D_LPC_isf_2s5s_decode(Word16 *indice, Word16 *isf_q, Word16 *past_isfq, |
501 | Word16 *isfold, Word16 *isf_buf, Word16 bfi) |
502 | { |
503 | Word32 ref_isf[M]; |
504 | Word32 i, j, L_tmp; |
505 | Word16 tmp; |
506 | |
507 | if (bfi == 0) { /* Good frame */ |
508 | for (i = 0; i < 9; i++) { |
509 | isf_q[i] = D_ROM_dico1_isf[indice[0] * 9 + i]; |
510 | } |
511 | |
512 | for (i = 0; i < 7; i++) { |
513 | isf_q[i + 9] = D_ROM_dico2_isf[indice[1] * 7 + i]; |
514 | } |
515 | |
516 | for (i = 0; i < 3; i++) { |
517 | isf_q[i] = (Word16)(isf_q[i] + D_ROM_dico21_isf[indice[2] * 3 + i]); |
518 | } |
519 | |
520 | for (i = 0; i < 3; i++) { |
521 | isf_q[i + 3] = |
522 | (Word16)(isf_q[i + 3] + D_ROM_dico22_isf[indice[3] * 3 + i]); |
523 | } |
524 | |
525 | for (i = 0; i < 3; i++) { |
526 | isf_q[i + 6] = |
527 | (Word16)(isf_q[i + 6] + D_ROM_dico23_isf[indice[4] * 3 + i]); |
528 | } |
529 | |
530 | for (i = 0; i < 3; i++) { |
531 | isf_q[i + 9] = |
532 | (Word16)(isf_q[i + 9] + D_ROM_dico24_isf[indice[5] * 3 + i]); |
533 | } |
534 | |
535 | for (i = 0; i < 4; i++) { |
536 | isf_q[i + 12] = |
537 | (Word16)(isf_q[i + 12] + D_ROM_dico25_isf[indice[6] * 4 + i]); |
538 | } |
539 | |
540 | for (i = 0; i < ORDER; i++) { |
541 | tmp = isf_q[i]; |
542 | isf_q[i] = |
543 | (Word16)((tmp + D_ROM_mean_isf[i]) + ((MU * past_isfq[i]) >> 15)); |
544 | past_isfq[i] = tmp; |
545 | } |
546 | |
547 | |
548 | for (i = 0; i < M; i++) { |
549 | for (j = (L_MEANBUF - 1); j > 0; j--) { |
550 | isf_buf[j * M + i] = isf_buf[(j - 1) * M + i]; |
551 | } |
552 | isf_buf[i] = isf_q[i]; |
553 | } |
554 | |
555 | } else { |
556 | /* bad frame */ |
557 | |
558 | for (i = 0; i < M; i++) { |
559 | L_tmp = D_ROM_mean_isf[i]; |
560 | |
561 | for (j = 0; j < L_MEANBUF; j++) { |
562 | L_tmp = L_tmp + isf_buf[j * M + i]; |
563 | } |
564 | |
565 | ref_isf[i] = (L_tmp + 0x1) >> 2; |
566 | } |
567 | |
568 | /* use the past ISFs slightly shifted towards their mean */ |
569 | for (i = 0; i < ORDER; i++) { |
570 | isf_q[i] = (Word16)(((ALPHA * isfold[i]) >> 15) + |
571 | ((ONE_ALPHA * ref_isf[i]) >> 15)); |
572 | } |
573 | |
574 | /* estimate past quantized residual to be used in next frame */ |
575 | for (i = 0; i < ORDER; i++) { |
576 | /* predicted ISF */ |
577 | L_tmp = ref_isf[i] + ((past_isfq[i] * MU) >> 15); |
578 | /* past_isfq[i] *= 0.5 */ |
579 | past_isfq[i] = (Word16)((isf_q[i] - L_tmp) >> 1); |
580 | } |
581 | } |
582 | |
583 | D_LPC_isf_reorder(isf_q, ISF_GAP, ORDER); |
584 | |
585 | return; |
586 | } |
587 | |
588 | |
589 | /* |
590 | * D_LPC_int_isp_find |
591 | * |
592 | * Parameters: |
593 | * isp_old I: isps from past frame |
594 | * isp_new I: isps from present frame |
595 | * frac I: (Q15) fraction for 3 first subfr |
596 | * Az O: LP coefficients in 4 subframes |
597 | * |
598 | * Function: |
599 | * Find the interpolated ISP parameters for all subframes. |
600 | * |
601 | * Returns: |
602 | * void |
603 | */ |
604 | void D_LPC_int_isp_find(Word16 isp_old[], Word16 isp_new[], |
605 | const Word16 frac[], Word16 Az[]) |
606 | { |
607 | Word32 tmp, i, k, fac_old, fac_new; |
608 | Word16 isp[M]; |
609 | |
610 | for (k = 0; k < 3; k++) { |
611 | fac_new = frac[k]; |
612 | fac_old = (32767 - fac_new) + 1; /* 1.0 - fac_new */ |
613 | |
614 | for (i = 0; i < M; i++) { |
615 | tmp = isp_old[i] * fac_old; |
616 | tmp += isp_new[i] * fac_new; |
617 | isp[i] = (Word16)((tmp + 0x4000) >> 15); |
618 | } |
619 | |
620 | D_LPC_isp_a_conversion(isp, Az, 0, M); |
621 | Az += MP1; |
622 | } |
623 | |
624 | /* 4th subframe: isp_new (frac=1.0) */ |
625 | D_LPC_isp_a_conversion(isp_new, Az, 0, M); |
626 | |
627 | return; |
628 | } |
629 | |
630 | |
631 | /* |
632 | * D_LPC_isf_extrapolation |
633 | * |
634 | * Parameters: |
635 | * HfIsf I/O: ISF vector |
636 | * |
637 | * Function: |
638 | * Conversion of 16th-order 12.8kHz ISF vector |
639 | * into 20th-order 16kHz ISF vector |
640 | * |
641 | * Returns: |
642 | * void |
643 | */ |
644 | void D_LPC_isf_extrapolation(Word16 HfIsf[]) |
645 | { |
646 | Word32 IsfDiff[M - 2]; |
647 | Word32 IsfCorr[3]; |
648 | Word32 tmp, tmp2, tmp3, mean, i; |
649 | Word32 MaxCorr, exp, exp2, coeff; |
650 | Word16 hi, lo; |
651 | |
652 | HfIsf[M16k - 1] = HfIsf[M - 1]; |
653 | |
654 | /* Difference vector */ |
655 | for (i = 1; i < M - 1; i++) { |
656 | IsfDiff[i - 1] = HfIsf[i] - HfIsf[i - 1]; |
657 | } |
658 | |
659 | tmp = 0; |
660 | |
661 | /* Mean of difference vector */ |
662 | for (i = 3; i < (M - 1); i++) { |
663 | tmp = tmp + (IsfDiff[i - 1] * INV_LENGTH); |
664 | } |
665 | |
666 | mean = (tmp + 0x4000) >> 15; |
667 | IsfCorr[0] = 0; |
668 | IsfCorr[1] = 0; |
669 | IsfCorr[2] = 0; |
670 | tmp = 0; |
671 | |
672 | for (i = 0; i < M - 2; i++) { |
673 | if (IsfDiff[i] > tmp) { |
674 | tmp = IsfDiff[i]; |
675 | } |
676 | } |
677 | |
678 | exp = D_UTIL_norm_s((Word16)tmp); |
679 | |
680 | for (i = 0; i < M - 2; i++) { |
681 | IsfDiff[i] = IsfDiff[i] << exp; |
682 | } |
683 | |
684 | mean = mean << exp; |
685 | |
686 | for (i = 7; i < M - 2; i++) { |
687 | tmp2 = IsfDiff[i] - mean; |
688 | tmp3 = IsfDiff[i - 2] - mean; |
689 | tmp = (tmp2 * tmp3) << 1; |
690 | D_UTIL_l_extract(tmp, &hi, &lo); |
691 | tmp = D_UTIL_mpy_32(hi, lo, hi, lo); |
692 | IsfCorr[0] = (IsfCorr[0] + tmp); |
693 | } |
694 | |
695 | for (i = 7; i < M - 2; i++) { |
696 | tmp2 = IsfDiff[i] - mean; |
697 | tmp3 = IsfDiff[i - 3] - mean; |
698 | tmp = (tmp2 * tmp3) << 1; |
699 | D_UTIL_l_extract(tmp, &hi, &lo); |
700 | tmp = D_UTIL_mpy_32(hi, lo, hi, lo); |
701 | IsfCorr[1] = (IsfCorr[1] + tmp); |
702 | } |
703 | |
704 | for (i = 7; i < M - 2; i++) { |
705 | tmp2 = IsfDiff[i] - mean; |
706 | tmp3 = IsfDiff[i - 4] - mean; |
707 | tmp = (tmp2 * tmp3) << 1; |
708 | D_UTIL_l_extract(tmp, &hi, &lo); |
709 | tmp = D_UTIL_mpy_32(hi, lo, hi, lo); |
710 | IsfCorr[2] = (IsfCorr[2] + tmp); |
711 | } |
712 | |
713 | if (IsfCorr[0] > IsfCorr[1]) { |
714 | MaxCorr = 0; |
715 | } else { |
716 | MaxCorr = 1; |
717 | } |
718 | |
719 | if (IsfCorr[2] > IsfCorr[MaxCorr]) { |
720 | MaxCorr = 2; |
721 | } |
722 | |
723 | MaxCorr = MaxCorr + 1; /* Maximum correlation of difference vector */ |
724 | |
725 | for (i = M - 1; i < (M16k - 1); i++) { |
726 | tmp = (HfIsf[i - 1 - MaxCorr] - HfIsf[i - 2 - MaxCorr]); |
727 | HfIsf[i] = (Word16)(HfIsf[i - 1] + tmp); |
728 | } |
729 | |
730 | /* tmp=7965+(HfIsf[2]-HfIsf[3]-HfIsf[4])/6; */ |
731 | tmp = HfIsf[4] + HfIsf[3]; |
732 | tmp = HfIsf[2] - tmp; |
733 | tmp = (tmp * 5461) >> 15; |
734 | tmp = tmp + 20390; |
735 | |
736 | if (tmp > 19456) { |
737 | /* Maximum value of ISF should be at most 7600 Hz */ |
738 | tmp = 19456; |
739 | } |
740 | |
741 | tmp = tmp - HfIsf[M - 2]; |
742 | tmp2 = HfIsf[M16k - 2] - HfIsf[M - 2]; |
743 | exp2 = D_UTIL_norm_s((Word16)tmp2); |
744 | exp = D_UTIL_norm_s((Word16)tmp); |
745 | exp = exp - 1; |
746 | tmp = tmp << exp; |
747 | tmp2 = tmp2 << exp2; |
748 | coeff = (tmp << 15) / tmp2; /* Coefficient for stretching the ISF vector */ |
749 | exp = exp2 - exp; |
750 | |
751 | if (exp >= 0) { |
752 | for (i = M - 1; i < M16k - 1; i++) { |
753 | tmp = ((HfIsf[i] - HfIsf[i - 1]) * coeff) >> 15; |
754 | IsfDiff[i - (M - 1)] = tmp << exp; |
755 | } |
756 | } else { |
757 | exp = 15 - exp; |
758 | |
759 | for (i = M - 1; i < M16k - 1; i++) { |
760 | IsfDiff[i - (M - 1)] = ((HfIsf[i] - HfIsf[i - 1]) * coeff) >> exp; |
761 | } |
762 | } |
763 | |
764 | for (i = M; i < (M16k - 1); i++) { |
765 | /* The difference between ISF(n) and ISF(n-2) should be at least 500 Hz */ |
766 | tmp = ((IsfDiff[i - (M - 1)] + IsfDiff[i - M]) - 1280); |
767 | |
768 | if (tmp < 0) { |
769 | if (IsfDiff[i - (M - 1)] > IsfDiff[i - M]) { |
770 | IsfDiff[i - M] = (1280 - IsfDiff[i - (M - 1)]); |
771 | } else { |
772 | IsfDiff[i - (M - 1)] = (1280 - IsfDiff[i - M]); |
773 | } |
774 | } |
775 | } |
776 | |
777 | for (i = M - 1; i < M16k - 1; i++) { |
778 | HfIsf[i] = (Word16)(HfIsf[i - 1] + IsfDiff[i - (M - 1)]); |
779 | } |
780 | |
781 | for (i = 0; i < M16k - 1; i++) { |
782 | HfIsf[i] = (Word16)((HfIsf[i] * 13107) >> 14); |
783 | /* Scale the ISF vector correctly for 16000 kHz */ |
784 | } |
785 | |
786 | D_LPC_isf_isp_conversion(HfIsf, HfIsf, M16k); |
787 | |
788 | return; |
789 | } |
790 |