/src/libxaac/encoder/ixheaace_tns_hp.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * * |
3 | | * Copyright (C) 2023 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 | | |
21 | | #include <math.h> |
22 | | #include <stddef.h> |
23 | | #include "ixheaac_type_def.h" |
24 | | #include "ixheaac_constants.h" |
25 | | #include "impd_drc_common_enc.h" |
26 | | #include "impd_drc_uni_drc.h" |
27 | | #include "impd_drc_tables.h" |
28 | | #include "impd_drc_api.h" |
29 | | #include "ixheaace_api.h" |
30 | | #include "ixheaace_aac_constants.h" |
31 | | #include "ixheaace_common_rom.h" |
32 | | #include "ixheaace_psy_const.h" |
33 | | #include "ixheaace_tns.h" |
34 | | #include "ixheaace_tns_params.h" |
35 | | #include "ixheaace_rom.h" |
36 | | #include "ixheaace_bitbuffer.h" |
37 | | #include "ixheaace_psy_configuration.h" |
38 | | #include "ixheaace_tns_func.h" |
39 | | #include "ixheaac_basic_ops32.h" |
40 | | #include "ixheaac_basic_ops16.h" |
41 | | #include "ixheaac_basic_ops40.h" |
42 | | #include "ixheaac_basic_ops.h" |
43 | | |
44 | | VOID ia_enhaacplus_enc_calc_weighted_spectrum(FLOAT32 *ptr_spectrum, FLOAT32 *ptr_weighted_spec, |
45 | | FLOAT32 *ptr_sfb_energy, |
46 | | const WORD32 *ptr_sfb_offset, WORD32 lpc_start_line, |
47 | | WORD32 lpc_stop_line, WORD32 lpc_start_band, |
48 | | WORD32 lpc_stop_band, FLOAT32 *ptr_shared_buffer1, |
49 | 699k | WORD32 aot) { |
50 | 699k | WORD32 i, sfb, tempcnt; |
51 | 699k | FLOAT32 tmp; |
52 | 699k | FLOAT32 *ptr_tns_sfb_mean = ptr_shared_buffer1; |
53 | 699k | FLOAT32 temp1, temp2; |
54 | 699k | FLOAT32 *ptr_spec; |
55 | 699k | FLOAT32 *ptr_ws1; |
56 | 699k | WORD sfb_width, j; |
57 | | |
58 | 4.51M | for (sfb = lpc_start_band; sfb < lpc_stop_band; sfb++) { |
59 | 3.81M | FLOAT32 sfb_nrg_tmp = ptr_sfb_energy[sfb]; |
60 | 3.81M | ptr_tns_sfb_mean[sfb] = 1 / ((FLOAT32)sqrt(sfb_nrg_tmp) + 1e-30f); |
61 | 3.81M | } |
62 | | |
63 | 699k | sfb = lpc_start_band; |
64 | | |
65 | 699k | tmp = ptr_tns_sfb_mean[sfb]; |
66 | | |
67 | 4.51M | for (i = lpc_start_line; i < lpc_stop_line; i += sfb_width) { |
68 | 3.81M | ptr_spec = &ptr_weighted_spec[i]; |
69 | 3.81M | WORD start = i, stop = ptr_sfb_offset[sfb + 1]; |
70 | | |
71 | 3.81M | stop = MIN(stop, lpc_stop_line); |
72 | 3.81M | sfb_width = stop - start; |
73 | | |
74 | 42.1M | for (j = (sfb_width >> 1) - 1; j >= 0; j--) { |
75 | 38.3M | *ptr_spec++ = tmp; |
76 | 38.3M | *ptr_spec++ = tmp; |
77 | 38.3M | } |
78 | 3.81M | sfb++; |
79 | | |
80 | 3.81M | if ((sfb + 1) < lpc_stop_band) { |
81 | 2.45M | tmp = ptr_tns_sfb_mean[sfb]; |
82 | 2.45M | } |
83 | 3.81M | } |
84 | | |
85 | | /* Filter down */ |
86 | 699k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS || aot == AOT_AAC_ELD) { |
87 | 75.6M | for (i = lpc_stop_line - 2; i >= lpc_start_line; i--) { |
88 | 74.9M | ptr_weighted_spec[i] = (ptr_weighted_spec[i] + ptr_weighted_spec[i + 1]) * 0.5f; |
89 | 74.9M | } |
90 | 75.6M | for (i = lpc_start_line + 1; i < lpc_stop_line; i++) { |
91 | 74.9M | ptr_weighted_spec[i] = (ptr_weighted_spec[i] + ptr_weighted_spec[i - 1]) * 0.5f; |
92 | 74.9M | } |
93 | | |
94 | | /* Weight and normalize */ |
95 | 76.3M | for (i = lpc_start_line; i < lpc_stop_line; i++) { |
96 | 75.6M | ptr_weighted_spec[i] = ptr_weighted_spec[i] * ptr_spectrum[i]; |
97 | 75.6M | } |
98 | 682k | } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) { |
99 | 17.0k | WORD32 remaining; |
100 | 17.0k | FLOAT32 multout_temp; |
101 | | |
102 | 17.0k | ptr_ws1 = &ptr_weighted_spec[lpc_stop_line - 1]; |
103 | 17.0k | tempcnt = (lpc_stop_line - lpc_start_line) >> 2; |
104 | 17.0k | remaining = lpc_stop_line - lpc_start_line - (tempcnt << 2); |
105 | | |
106 | 17.0k | temp1 = *ptr_ws1--; |
107 | 17.0k | temp2 = (*ptr_ws1 + temp1); |
108 | 268k | for (i = tempcnt - 1; i >= 0; i--) { |
109 | 250k | *ptr_ws1-- = temp2; |
110 | 250k | temp1 = (*ptr_ws1 + temp2 * 0.5f); |
111 | 250k | *ptr_ws1-- = temp1; |
112 | 250k | temp2 = (*ptr_ws1 + temp1 * 0.5f); |
113 | 250k | *ptr_ws1-- = temp2; |
114 | 250k | temp1 = (*ptr_ws1 + temp2 * 0.5f); |
115 | 250k | *ptr_ws1-- = temp1; |
116 | 250k | temp2 = (*ptr_ws1 + temp1 * 0.5f); |
117 | 250k | } |
118 | 17.0k | ptr_ws1++; |
119 | 17.0k | if (remaining) { |
120 | 0 | for (i = remaining - 1; i >= 0; i--) { |
121 | 0 | temp1 = *ptr_ws1--; |
122 | 0 | *ptr_ws1 = (*ptr_ws1 + temp1 * 0.5f); |
123 | 0 | } |
124 | 0 | } |
125 | | |
126 | 17.0k | ptr_weighted_spec[lpc_start_line + 1] = (FLOAT32)( |
127 | 17.0k | ((ptr_weighted_spec[lpc_start_line + 1]) + (ptr_weighted_spec[lpc_start_line])) * 0.5f); |
128 | 17.0k | multout_temp = (ptr_weighted_spec[lpc_start_line] * ptr_spectrum[lpc_start_line]); |
129 | 17.0k | ptr_weighted_spec[lpc_start_line] = multout_temp; |
130 | | |
131 | | /* Weight and normalize */ |
132 | 17.0k | ptr_spec = &ptr_spectrum[lpc_start_line + 1]; |
133 | 17.0k | ptr_ws1 = &ptr_weighted_spec[lpc_start_line + 1]; |
134 | | |
135 | 17.0k | tempcnt = (lpc_stop_line - lpc_start_line - 2) >> 2; |
136 | 17.0k | remaining = (lpc_stop_line - lpc_start_line - 2) - (tempcnt << 2); |
137 | 17.0k | temp2 = *ptr_ws1; |
138 | | |
139 | 252k | for (i = tempcnt - 1; i >= 0; i--) { |
140 | 235k | temp1 = *(ptr_ws1 + 1); |
141 | 235k | temp1 = (FLOAT32)((temp1 + temp2) * 0.5f); |
142 | 235k | multout_temp = (temp2 * *ptr_spec++); |
143 | 235k | *ptr_ws1++ = multout_temp; |
144 | | |
145 | 235k | temp2 = *(ptr_ws1 + 1); |
146 | 235k | temp2 = (FLOAT32)((temp2 + temp1) * 0.5f); |
147 | 235k | multout_temp = (temp1 * *ptr_spec++); |
148 | 235k | *ptr_ws1++ = multout_temp; |
149 | | |
150 | 235k | temp1 = *(ptr_ws1 + 1); |
151 | 235k | temp1 = (FLOAT32)((temp2 + temp1) * 0.5f); |
152 | 235k | multout_temp = (temp2 * *ptr_spec++); |
153 | 235k | *ptr_ws1++ = multout_temp; |
154 | | |
155 | 235k | temp2 = *(ptr_ws1 + 1); |
156 | 235k | temp2 = (FLOAT32)((temp2 + temp1) * 0.5f); |
157 | 235k | multout_temp = (temp1 * *ptr_spec++); |
158 | 235k | *ptr_ws1++ = multout_temp; |
159 | 235k | } |
160 | | |
161 | 17.0k | if (remaining) { |
162 | 51.1k | for (i = remaining - 1; i >= 0; i--) { |
163 | 34.1k | temp1 = *(ptr_ws1 + 1); |
164 | | |
165 | 34.1k | multout_temp = (temp2 * *ptr_spec++); |
166 | 34.1k | *ptr_ws1++ = multout_temp; |
167 | 34.1k | temp2 = (FLOAT32)((temp1 + temp2) * 0.5f); |
168 | 34.1k | } |
169 | 17.0k | } |
170 | | |
171 | 17.0k | multout_temp = (temp2 + ptr_spectrum[lpc_stop_line - 1]); |
172 | | |
173 | 17.0k | ptr_weighted_spec[lpc_stop_line - 1] = multout_temp; |
174 | 17.0k | } |
175 | 699k | } |
176 | | |
177 | | VOID ia_enhaacplus_enc_auto_correlation(const FLOAT32 *ptr_input, FLOAT32 *ptr_corr, |
178 | 699k | WORD32 samples, WORD32 corr_coeff) { |
179 | 699k | WORD32 i, j; |
180 | 699k | FLOAT32 tmp_var; |
181 | 699k | WORD32 remaining; |
182 | 699k | remaining = corr_coeff - ((corr_coeff >> 1) << 1); |
183 | | |
184 | 39.0M | for (i = 0; i < samples; i += 2) { |
185 | 38.3M | const FLOAT32 *ptr_input1 = &ptr_input[i]; |
186 | 38.3M | FLOAT32 temp1 = *ptr_input1; |
187 | 38.3M | FLOAT32 temp2 = *(ptr_input1 + 1); |
188 | 38.3M | FLOAT32 inp_tmp1 = *ptr_input1++; |
189 | 245M | for (j = 0; j < (corr_coeff >> 1) << 1; j++) { |
190 | 206M | FLOAT32 inp_tmp2; |
191 | 206M | tmp_var = (temp1 * inp_tmp1); |
192 | 206M | inp_tmp2 = *ptr_input1++; |
193 | 206M | tmp_var += (temp2 * inp_tmp2); |
194 | 206M | ptr_corr[j] += tmp_var; |
195 | 206M | j++; |
196 | 206M | tmp_var = (temp1 * inp_tmp2); |
197 | 206M | inp_tmp1 = *ptr_input1++; |
198 | 206M | tmp_var += (temp2 * inp_tmp1); |
199 | 206M | ptr_corr[j] += (tmp_var); |
200 | 206M | } |
201 | 38.3M | if (remaining) { |
202 | 30.5M | tmp_var = (temp1 * inp_tmp1); |
203 | 30.5M | tmp_var += (temp2 * *ptr_input1); |
204 | 30.5M | ptr_corr[j] += (tmp_var); |
205 | 30.5M | } |
206 | 38.3M | } |
207 | 699k | } |
208 | | |
209 | | VOID ia_enhaacplus_enc_analysis_filter_lattice(const FLOAT32 *ptr_signal, WORD32 num_lines, |
210 | | const FLOAT32 *ptr_par_coeff, WORD32 order, |
211 | 349k | FLOAT32 *ptr_output) { |
212 | 349k | FLOAT32 state_par[TEMPORAL_NOISE_SHAPING_MAX_ORDER] = {0}; |
213 | 349k | WORD32 j; |
214 | | |
215 | 349k | if (order <= 0) { |
216 | 16 | return; |
217 | 16 | } |
218 | | |
219 | 66.5M | for (j = 0; j < num_lines; j++) { |
220 | 66.2M | WORD32 i; |
221 | 66.2M | FLOAT32 x = ptr_signal[j]; |
222 | 66.2M | FLOAT32 accu, tmp, tmp_save; |
223 | | |
224 | 66.2M | tmp_save = x; |
225 | 66.2M | accu = x; |
226 | | |
227 | 485M | for (i = 0; i < order - 1; i++) { |
228 | 419M | tmp = (accu * ptr_par_coeff[i]); |
229 | | |
230 | 419M | tmp += state_par[i]; |
231 | | |
232 | 419M | accu += (state_par[i] * ptr_par_coeff[i]); |
233 | | |
234 | 419M | state_par[i] = tmp_save; |
235 | 419M | tmp_save = tmp; |
236 | 419M | } |
237 | | |
238 | | /* last stage: only need half operations */ |
239 | 66.2M | accu += (state_par[order - 1] * ptr_par_coeff[order - 1]); |
240 | | |
241 | 66.2M | state_par[order - 1] = tmp_save; |
242 | | |
243 | 66.2M | ptr_output[j] = accu; |
244 | 66.2M | } |
245 | 349k | } |