FreeCalypso > hg > efr-experiments
comparison src/lsp_az.c @ 0:56410792419a
src: original EFR source from ETSI
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Wed, 03 Apr 2024 05:31:37 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:56410792419a |
---|---|
1 /************************************************************************* | |
2 * | |
3 * FUNCTION: Lsp_Az | |
4 * | |
5 * PURPOSE: Converts from the line spectral pairs (LSP) to | |
6 * LP coefficients, for a 10th order filter. | |
7 * | |
8 * DESCRIPTION: | |
9 * - Find the coefficients of F1(z) and F2(z) (see Get_lsp_pol) | |
10 * - Multiply F1(z) by 1+z^{-1} and F2(z) by 1-z^{-1} | |
11 * - A(z) = ( F1(z) + F2(z) ) / 2 | |
12 * | |
13 *************************************************************************/ | |
14 | |
15 #include "typedef.h" | |
16 #include "basic_op.h" | |
17 #include "oper_32b.h" | |
18 #include "count.h" | |
19 #include "sig_proc.h" | |
20 | |
21 /* local function */ | |
22 | |
23 static void Get_lsp_pol (Word16 *lsp, Word32 *f); | |
24 | |
25 void Lsp_Az ( | |
26 Word16 lsp[], /* (i) : line spectral frequencies */ | |
27 Word16 a[] /* (o) : predictor coefficients (order = 10) */ | |
28 ) | |
29 { | |
30 Word16 i, j; | |
31 Word32 f1[6], f2[6]; | |
32 Word32 t0; | |
33 | |
34 Get_lsp_pol (&lsp[0], f1); | |
35 Get_lsp_pol (&lsp[1], f2); | |
36 | |
37 for (i = 5; i > 0; i--) | |
38 { | |
39 f1[i] = L_add (f1[i], f1[i - 1]); move32 (); /* f1[i] += f1[i-1]; */ | |
40 f2[i] = L_sub (f2[i], f2[i - 1]); move32 (); /* f2[i] -= f2[i-1]; */ | |
41 } | |
42 | |
43 a[0] = 4096; move16 (); | |
44 for (i = 1, j = 10; i <= 5; i++, j--) | |
45 { | |
46 t0 = L_add (f1[i], f2[i]); /* f1[i] + f2[i] */ | |
47 a[i] = extract_l (L_shr_r (t0, 13)); move16 (); | |
48 t0 = L_sub (f1[i], f2[i]); /* f1[i] - f2[i] */ | |
49 a[j] = extract_l (L_shr_r (t0, 13)); move16 (); | |
50 } | |
51 | |
52 return; | |
53 } | |
54 | |
55 /************************************************************************* | |
56 * | |
57 * FUNCTION: Get_lsp_pol | |
58 * | |
59 * PURPOSE: Find the polynomial F1(z) or F2(z) from the LSPs. | |
60 * If the LSP vector is passed at address 0 F1(z) is computed | |
61 * and if it is passed at address 1 F2(z) is computed. | |
62 * | |
63 * DESCRIPTION: | |
64 * This is performed by expanding the product polynomials: | |
65 * | |
66 * F1(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 ) | |
67 * i=0,2,4,6,8 | |
68 * F2(z) = product ( 1 - 2 lsp[i] z^-1 + z^-2 ) | |
69 * i=1,3,5,7,9 | |
70 * | |
71 * where lsp[] is the LSP vector in the cosine domain. | |
72 * | |
73 * The expansion is performed using the following recursion: | |
74 * | |
75 * f[0] = 1 | |
76 * b = -2.0 * lsp[0] | |
77 * f[1] = b | |
78 * for i=2 to 5 do | |
79 * b = -2.0 * lsp[2*i-2]; | |
80 * f[i] = b*f[i-1] + 2.0*f[i-2]; | |
81 * for j=i-1 down to 2 do | |
82 * f[j] = f[j] + b*f[j-1] + f[j-2]; | |
83 * f[1] = f[1] + b; | |
84 * | |
85 *************************************************************************/ | |
86 | |
87 static void Get_lsp_pol (Word16 *lsp, Word32 *f) | |
88 { | |
89 Word16 i, j, hi, lo; | |
90 Word32 t0; | |
91 | |
92 /* f[0] = 1.0; */ | |
93 *f = L_mult (4096, 2048); move32 (); | |
94 f++; move32 (); | |
95 *f = L_msu ((Word32) 0, *lsp, 512); /* f[1] = -2.0 * lsp[0]; */ | |
96 f++; move32 (); | |
97 lsp += 2; /* Advance lsp pointer */ | |
98 | |
99 for (i = 2; i <= 5; i++) | |
100 { | |
101 *f = f[-2]; move32 (); | |
102 | |
103 for (j = 1; j < i; j++, f--) | |
104 { | |
105 L_Extract (f[-1], &hi, &lo); | |
106 t0 = Mpy_32_16 (hi, lo, *lsp); /* t0 = f[-1] * lsp */ | |
107 t0 = L_shl (t0, 1); | |
108 *f = L_add (*f, f[-2]); move32 (); /* *f += f[-2] */ | |
109 *f = L_sub (*f, t0);move32 (); /* *f -= t0 */ | |
110 } | |
111 *f = L_msu (*f, *lsp, 512); move32 (); /* *f -= lsp<<9 */ | |
112 f += i; /* Advance f pointer */ | |
113 lsp += 2; /* Advance lsp pointer */ | |
114 } | |
115 | |
116 return; | |
117 } |