summaryrefslogtreecommitdiff
path: root/audio_codec/libamr/dec_lpc.c (plain)
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
27extern const Word16 D_ROM_dico1_isf[];
28extern const Word16 D_ROM_dico2_isf[];
29extern const Word16 D_ROM_dico21_isf_36b[];
30extern const Word16 D_ROM_dico22_isf_36b[];
31extern const Word16 D_ROM_dico23_isf_36b[];
32extern const Word16 D_ROM_dico21_isf[];
33extern const Word16 D_ROM_dico22_isf[];
34extern const Word16 D_ROM_dico23_isf[];
35extern const Word16 D_ROM_dico24_isf[];
36extern const Word16 D_ROM_dico25_isf[];
37extern const Word16 D_ROM_dico1_isf_noise[];
38extern const Word16 D_ROM_dico2_isf_noise[];
39extern const Word16 D_ROM_dico3_isf_noise[];
40extern const Word16 D_ROM_dico4_isf_noise[];
41extern const Word16 D_ROM_dico5_isf_noise[];
42extern const Word16 D_ROM_mean_isf[];
43extern const Word16 D_ROM_mean_isf_noise[];
44extern 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 */
62static 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 */
92void 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 */
142void 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 */
186static 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 */
239void 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 */
369void 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 */
404void 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 */
500void 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 */
604void 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 */
644void 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