/src/libxaac/decoder/ixheaacd_tcx_fwd_mdct.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * * |
3 | | * Copyright (C) 2018 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | #include <float.h> |
21 | | #include <stdlib.h> |
22 | | #include <stdio.h> |
23 | | #include <math.h> |
24 | | #include <string.h> |
25 | | |
26 | | #include "ixheaacd_cnst.h" |
27 | | #include "ixheaac_type_def.h" |
28 | | #include "ixheaacd_bitbuffer.h" |
29 | | #include "ixheaacd_acelp_com.h" |
30 | | |
31 | | #include "ixheaacd_bitbuffer.h" |
32 | | #include "ixheaacd_interface.h" |
33 | | |
34 | | #include "ixheaacd_tns_usac.h" |
35 | | #include "ixheaacd_cnst.h" |
36 | | |
37 | | #include "ixheaacd_acelp_info.h" |
38 | | |
39 | | #include "ixheaacd_td_mdct.h" |
40 | | |
41 | | #include "ixheaacd_sbrdecsettings.h" |
42 | | #include "ixheaacd_info.h" |
43 | | #include "ixheaacd_sbr_common.h" |
44 | | #include "ixheaacd_drc_data_struct.h" |
45 | | #include "ixheaacd_drc_dec.h" |
46 | | #include "ixheaacd_sbrdecoder.h" |
47 | | #include "ixheaacd_mps_polyphase.h" |
48 | | #include "ixheaac_sbr_const.h" |
49 | | |
50 | | #include "ixheaac_constants.h" |
51 | | #include "ixheaac_basic_ops32.h" |
52 | | #include "ixheaac_basic_ops40.h" |
53 | | #include "ixheaacd_ec_defines.h" |
54 | | #include "ixheaacd_ec_struct_def.h" |
55 | | #include "ixheaacd_main.h" |
56 | | #include "ixheaacd_arith_dec.h" |
57 | | |
58 | | #define FREQ_MAX 6400.0f |
59 | | |
60 | 54.8M | #define ABS(A) ((A) < 0 ? (-A) : (A)) |
61 | | |
62 | | static VOID ixheaacd_compute_coeff_poly_f(FLOAT32 lsp[], FLOAT32 *f1, |
63 | 1.60M | FLOAT32 *f2) { |
64 | 1.60M | FLOAT32 b1, b2; |
65 | 1.60M | FLOAT32 *ptr_lsp; |
66 | 1.60M | WORD32 i, j; |
67 | | |
68 | 1.60M | ptr_lsp = lsp; |
69 | 1.60M | f1[0] = f2[0] = 1.0f; |
70 | | |
71 | 14.4M | for (i = 1; i <= ORDER_BY_2; i++) { |
72 | 12.8M | b1 = -2.0f * (*ptr_lsp++); |
73 | 12.8M | b2 = -2.0f * (*ptr_lsp++); |
74 | 12.8M | f1[i] = (b1 * f1[i - 1]) + (2.0f * f1[i - 2]); |
75 | 12.8M | f2[i] = (b2 * f2[i - 1]) + (2.0f * f2[i - 2]); |
76 | 57.7M | for (j = i - 1; j > 0; j--) { |
77 | 44.9M | f1[j] += (b1 * f1[j - 1]) + f1[j - 2]; |
78 | 44.9M | f2[j] += (b2 * f2[j - 1]) + f2[j - 2]; |
79 | 44.9M | } |
80 | 12.8M | } |
81 | | |
82 | 1.60M | return; |
83 | 1.60M | } |
84 | 1.60M | VOID ixheaacd_lsp_to_lp_conversion(FLOAT32 *lsp, FLOAT32 *lp_flt_coff_a) { |
85 | 1.60M | WORD32 i; |
86 | 1.60M | FLOAT32 *ppoly_f1, *ppoly_f2; |
87 | 1.60M | FLOAT32 *plp_flt_coff_a_bott, *plp_flt_coff_a_top; |
88 | 1.60M | FLOAT32 poly1[ORDER_BY_2 + 2], poly2[ORDER_BY_2 + 2]; |
89 | | |
90 | 1.60M | poly1[0] = 0.0f; |
91 | 1.60M | poly2[0] = 0.0f; |
92 | | |
93 | 1.60M | ixheaacd_compute_coeff_poly_f(lsp, &poly1[1], &poly2[1]); |
94 | | |
95 | 1.60M | ppoly_f1 = poly1 + ORDER_BY_2 + 1; |
96 | 1.60M | ppoly_f2 = poly2 + ORDER_BY_2 + 1; |
97 | | |
98 | 14.4M | for (i = 0; i < ORDER_BY_2; i++) { |
99 | 12.8M | ppoly_f1[0] += ppoly_f1[-1]; |
100 | 12.8M | ppoly_f2[0] -= ppoly_f2[-1]; |
101 | 12.8M | ppoly_f1--; |
102 | 12.8M | ppoly_f2--; |
103 | 12.8M | } |
104 | | |
105 | 1.60M | plp_flt_coff_a_bott = lp_flt_coff_a; |
106 | 1.60M | *plp_flt_coff_a_bott++ = 1.0f; |
107 | 1.60M | plp_flt_coff_a_top = lp_flt_coff_a + ORDER; |
108 | 1.60M | ppoly_f1 = poly1 + 2; |
109 | 1.60M | ppoly_f2 = poly2 + 2; |
110 | 14.4M | for (i = 0; i < ORDER_BY_2; i++) { |
111 | 12.8M | *plp_flt_coff_a_bott++ = 0.5f * (*ppoly_f1 + *ppoly_f2); |
112 | 12.8M | *plp_flt_coff_a_top-- = 0.5f * (*ppoly_f1++ - *ppoly_f2++); |
113 | 12.8M | } |
114 | | |
115 | 1.60M | return; |
116 | 1.60M | } |
117 | | |
118 | 234k | VOID ixheaacd_lpc_to_td(FLOAT32 *coeff, WORD32 order, FLOAT32 *gains, WORD32 lg) { |
119 | 234k | FLOAT32 data_r[LEN_SUPERFRAME * 2]; |
120 | 234k | FLOAT32 data_i[LEN_SUPERFRAME * 2]; |
121 | 234k | FLOAT64 avg_fac; |
122 | 234k | WORD32 idata_r[LEN_SUPERFRAME * 2]; |
123 | 234k | WORD32 idata_i[LEN_SUPERFRAME * 2]; |
124 | 234k | WORD8 qshift; |
125 | 234k | WORD32 preshift = 0; |
126 | 234k | WORD32 itemp; |
127 | 234k | FLOAT32 ftemp = 0; |
128 | 234k | FLOAT32 tmp, qfac; |
129 | 234k | WORD32 i, size_n; |
130 | | |
131 | 234k | size_n = 2 * lg; |
132 | 234k | avg_fac = PI / (FLOAT32)(size_n); |
133 | | |
134 | 4.21M | for (i = 0; i < order + 1; i++) { |
135 | 3.98M | tmp = (FLOAT32)(((FLOAT32)i) * avg_fac); |
136 | 3.98M | data_r[i] = (FLOAT32)(coeff[i] * cos(tmp)); |
137 | 3.98M | data_i[i] = (FLOAT32)(-coeff[i] * sin(tmp)); |
138 | 3.98M | } |
139 | 23.4M | for (; i < size_n; i++) { |
140 | 23.1M | data_r[i] = 0.f; |
141 | 23.1M | data_i[i] = 0.f; |
142 | 23.1M | } |
143 | | |
144 | 27.4M | for (i = 0; i < size_n; i++) { |
145 | 27.1M | if (ABS(data_r[i]) > ftemp) ftemp = ABS(data_r[i]); |
146 | 27.1M | if (ABS(data_i[i]) > ftemp) ftemp = ABS(data_i[i]); |
147 | 27.1M | } |
148 | | |
149 | 234k | itemp = (WORD32)ftemp; |
150 | 234k | qshift = ixheaac_norm32(itemp); |
151 | | |
152 | 27.4M | for (i = 0; i < size_n; i++) { |
153 | 27.1M | idata_r[i] = (WORD32)(data_r[i] * ((WORD64)1 << qshift)); |
154 | 27.1M | idata_i[i] = (WORD32)(data_i[i] * ((WORD64)1 << qshift)); |
155 | 27.1M | } |
156 | | |
157 | 234k | ixheaacd_complex_fft(idata_r, idata_i, size_n, -1, &preshift); |
158 | | |
159 | 234k | qfac = 1.0f / ((FLOAT32)((WORD64)1 << (qshift - preshift))); |
160 | | |
161 | 27.4M | for (i = 0; i < size_n; i++) { |
162 | 27.1M | data_r[i] = (FLOAT32)((FLOAT32)idata_r[i] * qfac); |
163 | 27.1M | data_i[i] = (FLOAT32)((FLOAT32)idata_i[i] * qfac); |
164 | 27.1M | } |
165 | | |
166 | 13.8M | for (i = 0; i < size_n / 2; i++) { |
167 | 13.5M | gains[i] = |
168 | 13.5M | (FLOAT32)(1.0f / (sqrt(data_r[i] * data_r[i] + data_i[i] * data_i[i]) + FLT_EPSILON)); |
169 | 13.5M | } |
170 | | |
171 | 234k | return; |
172 | 234k | } |
173 | | |
174 | | VOID ixheaacd_noise_shaping(FLOAT32 r[], WORD32 lg, WORD32 M, FLOAT32 g1[], |
175 | 117k | FLOAT32 g2[]) { |
176 | 117k | WORD32 i, k; |
177 | 117k | FLOAT32 rr_prev, a = 0, b = 0; |
178 | 117k | FLOAT32 rr[1024]; |
179 | | |
180 | 117k | k = lg / M; |
181 | | |
182 | 117k | rr_prev = 0; |
183 | | |
184 | 117k | memcpy(&rr, r, lg * sizeof(FLOAT32)); |
185 | | |
186 | 33.3M | for (i = 0; i < lg; i++) { |
187 | 33.2M | if ((i % k) == 0) { |
188 | 6.79M | a = 2.0f * g1[i / k] * g2[i / k] / (g1[i / k] + g2[i / k]); |
189 | 6.79M | b = (g2[i / k] - g1[i / k]) / (g1[i / k] + g2[i / k]); |
190 | 6.79M | } |
191 | | |
192 | 33.2M | rr[i] = a * rr[i] + b * rr_prev; |
193 | 33.2M | rr_prev = rr[i]; |
194 | 33.2M | } |
195 | | |
196 | 16.7M | for (i = 0; i < lg / 2; i++) { |
197 | 16.6M | r[i] = rr[2 * i]; |
198 | 16.6M | r[lg / 2 + i] = rr[lg - 2 * i - 1]; |
199 | 16.6M | } |
200 | 117k | return; |
201 | 117k | } |
202 | | |
203 | | VOID ixheaacd_lpc_coef_gen(FLOAT32 lsf_old[], FLOAT32 lsf_new[], FLOAT32 a[], |
204 | 117k | WORD32 nb_subfr, WORD32 m) { |
205 | 117k | FLOAT32 lsf[ORDER], *ptr_a; |
206 | 117k | FLOAT32 inc, fnew, fold; |
207 | 117k | WORD32 i; |
208 | | |
209 | 117k | ptr_a = a; |
210 | | |
211 | 117k | inc = 1.0f / (FLOAT32)nb_subfr; |
212 | 117k | fnew = 0.5f - (0.5f * inc); |
213 | 117k | fold = 1.0f - fnew; |
214 | | |
215 | 1.99M | for (i = 0; i < m; i++) { |
216 | 1.87M | lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew); |
217 | 1.87M | } |
218 | 117k | ixheaacd_lsp_to_lp_conversion(lsf, ptr_a); |
219 | 117k | ptr_a += (m + 1); |
220 | 117k | ixheaacd_lsp_to_lp_conversion(lsf_old, ptr_a); |
221 | 117k | ptr_a += (m + 1); |
222 | 117k | ixheaacd_lsp_to_lp_conversion(lsf_new, ptr_a); |
223 | 117k | ptr_a += (m + 1); |
224 | | |
225 | 117k | return; |
226 | 117k | } |
227 | | |
228 | | VOID ixheaacd_interpolation_lsp_params(FLOAT32 lsp_old[], FLOAT32 lsp_new[], |
229 | | FLOAT32 lp_flt_coff_a[], |
230 | 229k | WORD32 nb_subfr) { |
231 | 229k | FLOAT32 lsp[ORDER]; |
232 | 229k | FLOAT32 factor; |
233 | 229k | WORD32 i, k; |
234 | 229k | FLOAT32 x_plus_y, x_minus_y; |
235 | | |
236 | 229k | factor = 1.0f / (FLOAT32)nb_subfr; |
237 | | |
238 | 229k | x_plus_y = 0.5f * factor; |
239 | | |
240 | 1.25M | for (k = 0; k < nb_subfr; k++) { |
241 | 1.02M | x_minus_y = 1.0f - x_plus_y; |
242 | 17.4M | for (i = 0; i < ORDER; i++) { |
243 | 16.3M | lsp[i] = (lsp_old[i] * x_minus_y) + (lsp_new[i] * x_plus_y); |
244 | 16.3M | } |
245 | 1.02M | x_plus_y += factor; |
246 | | |
247 | 1.02M | ixheaacd_lsp_to_lp_conversion(lsp, lp_flt_coff_a); |
248 | | |
249 | 1.02M | lp_flt_coff_a += (ORDER + 1); |
250 | 1.02M | } |
251 | | |
252 | 229k | ixheaacd_lsp_to_lp_conversion(lsp_new, lp_flt_coff_a); |
253 | | |
254 | 229k | return; |
255 | 229k | } |