/src/libxaac/encoder/ixheaace_psy_mod.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 <stdlib.h> |
22 | | #include <math.h> |
23 | | |
24 | | #include <string.h> |
25 | | |
26 | | #include "ixheaac_type_def.h" |
27 | | #include "ixheaac_constants.h" |
28 | | #include "impd_drc_common_enc.h" |
29 | | #include "impd_drc_uni_drc.h" |
30 | | #include "impd_drc_tables.h" |
31 | | #include "impd_drc_api.h" |
32 | | #include "ixheaace_api.h" |
33 | | #include "ixheaace_aac_constants.h" |
34 | | #include "ixheaac_error_standards.h" |
35 | | #include "ixheaace_psy_const.h" |
36 | | #include "ixheaace_tns.h" |
37 | | #include "ixheaace_tns_params.h" |
38 | | #include "ixheaace_rom.h" |
39 | | #include "ixheaace_common_rom.h" |
40 | | #include "ixheaace_bitbuffer.h" |
41 | | |
42 | | #include "ixheaac_basic_ops32.h" |
43 | | #include "ixheaac_basic_ops16.h" |
44 | | #include "ixheaac_basic_ops40.h" |
45 | | #include "ixheaac_basic_ops.h" |
46 | | |
47 | | #include "ixheaace_block_switch.h" |
48 | | #include "ixheaace_psy_utils_spreading.h" |
49 | | #include "ixheaace_psy_utils.h" |
50 | | #include "ixheaace_calc_ms_band_energy.h" |
51 | | #include "ixheaace_tns.h" |
52 | | #include "ixheaace_adjust_threshold_data.h" |
53 | | #include "ixheaace_dynamic_bits.h" |
54 | | #include "ixheaace_qc_data.h" |
55 | | #include "ixheaace_psy_data.h" |
56 | | #include "ixheaace_ms_stereo.h" |
57 | | #include "ixheaace_interface.h" |
58 | | |
59 | | #include "ixheaace_write_bitstream.h" |
60 | | #include "ixheaace_psy_configuration.h" |
61 | | #include "ixheaace_psy_mod.h" |
62 | | #include "ixheaace_stereo_preproc.h" |
63 | | #include "ixheaace_enc_main.h" |
64 | | #include "ixheaace_group_data.h" |
65 | | |
66 | | #include "ixheaace_tns_func.h" |
67 | | |
68 | | #include "ixheaace_tns_params.h" |
69 | | #include "ixheaace_common_utils.h" |
70 | | #include "ixheaace_fft.h" |
71 | | |
72 | | static WORD32 ia_enhaacplus_enc_block_type_to_window_shape_lc[] = {KBD_WINDOW, SINE_WINDOW, |
73 | | SINE_WINDOW, KBD_WINDOW}; |
74 | | |
75 | | static WORD32 ia_enhaacplus_enc_block_type_to_window_shape_ld[] = {SINE_WINDOW, LD_WINDOW, |
76 | | LD_WINDOW, SINE_WINDOW}; |
77 | | |
78 | | WORD32 ia_enhaacplus_enc_psy_new(ixheaace_psy_kernel *pstr_h_psy, WORD32 num_chan, |
79 | | WORD32 *ptr_shared_buffer_2, WORD32 long_frame_len) |
80 | | |
81 | 4.68k | { |
82 | 4.68k | WORD32 i; |
83 | 11.5k | for (i = 0; i < num_chan; i++) { |
84 | 6.86k | pstr_h_psy->psy_data[i]->ptr_spec_coeffs = |
85 | 6.86k | (FLOAT32 *)(&ptr_shared_buffer_2[i * long_frame_len]); |
86 | | |
87 | 6.86k | memset(pstr_h_psy->psy_data[i]->ptr_spec_coeffs, 0, |
88 | 6.86k | long_frame_len * sizeof(*pstr_h_psy->psy_data[i]->ptr_spec_coeffs)); |
89 | 6.86k | } |
90 | | |
91 | 4.68k | pstr_h_psy->p_scratch_tns_float = (FLOAT32 *)(&ptr_shared_buffer_2[2 * long_frame_len]); |
92 | 4.68k | if (long_frame_len == FRAME_LEN_960) { |
93 | 1.01k | pstr_h_psy->p_scratch_tns_float = pstr_h_psy->p_scratch_tns_float + 128; |
94 | 1.01k | } |
95 | | |
96 | 4.68k | memset(pstr_h_psy->p_scratch_tns_float, 0, |
97 | 4.68k | long_frame_len * sizeof(*pstr_h_psy->p_scratch_tns_float)); |
98 | | |
99 | 4.68k | return IA_NO_ERROR; |
100 | 4.68k | } |
101 | | |
102 | | IA_ERRORCODE ia_enhaacplus_enc_psy_main_init(ixheaace_psy_kernel *pstr_h_psy, WORD32 sample_rate, |
103 | | WORD32 bit_rate, WORD32 channels, WORD32 tns_mask, |
104 | | WORD32 bandwidth, WORD32 aot, |
105 | | ixheaace_aac_tables *pstr_aac_tables, |
106 | | WORD32 frame_len_long) |
107 | | |
108 | 4.68k | { |
109 | 4.68k | WORD32 ch; |
110 | 4.68k | IA_ERRORCODE err; |
111 | | |
112 | 4.68k | err = ia_enhaacplus_enc_init_psy_configuration(bit_rate / channels, sample_rate, bandwidth, aot, |
113 | 4.68k | &(pstr_h_psy->psy_conf_long), pstr_aac_tables, |
114 | 4.68k | frame_len_long); |
115 | 4.68k | if (err != IA_NO_ERROR) { |
116 | 0 | return err; |
117 | 0 | } |
118 | | |
119 | 4.68k | if (!err) { |
120 | 4.68k | err = ia_enhaacplus_enc_init_tns_configuration( |
121 | 4.68k | bit_rate, sample_rate, channels, &pstr_h_psy->psy_conf_long.str_tns_conf, |
122 | 4.68k | &(pstr_h_psy->psy_conf_long), (WORD32)(tns_mask & 1), pstr_aac_tables->pstr_tns_tab, |
123 | 4.68k | frame_len_long, aot); |
124 | | |
125 | 4.68k | if (err != IA_NO_ERROR) { |
126 | 0 | return err; |
127 | 0 | } |
128 | 4.68k | } |
129 | 4.68k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { |
130 | 2.96k | if (!err) { |
131 | 2.96k | err = ia_enhaacplus_enc_init_psy_configuration_short( |
132 | 2.96k | bit_rate / channels, sample_rate, bandwidth, aot, &pstr_h_psy->psy_conf_short, |
133 | 2.96k | pstr_aac_tables, frame_len_long / BLK_SWITCH_WIN); |
134 | 2.96k | if (err != IA_NO_ERROR) { |
135 | 0 | return err; |
136 | 0 | } |
137 | 2.96k | } |
138 | | |
139 | 2.96k | if (!err) { |
140 | 2.96k | err = ia_enhaacplus_enc_init_tns_configuration_short( |
141 | 2.96k | bit_rate, sample_rate, channels, &pstr_h_psy->psy_conf_short.str_tns_conf, |
142 | 2.96k | &(pstr_h_psy->psy_conf_short), (WORD32)(tns_mask & 1), pstr_aac_tables->pstr_tns_tab, |
143 | 2.96k | frame_len_long / BLK_SWITCH_WIN, aot); |
144 | 2.96k | if (err != IA_NO_ERROR) { |
145 | 0 | return err; |
146 | 0 | } |
147 | 2.96k | } |
148 | 2.96k | } |
149 | | |
150 | 4.68k | if (!err) { |
151 | | /* pstr_h_psy->psy_data[] */ |
152 | 11.5k | for (ch = 0; ch < channels; ch++) { |
153 | 6.86k | switch (aot) { |
154 | 1.51k | case AOT_AAC_LC: |
155 | 4.11k | case AOT_SBR: |
156 | 4.34k | case AOT_PS: |
157 | 4.34k | iaace_init_block_switching(&pstr_h_psy->psy_data[ch]->blk_switch_cntrl, bit_rate, |
158 | 4.34k | channels); |
159 | 4.34k | break; |
160 | | |
161 | 752 | case AOT_AAC_LD: |
162 | 2.52k | case AOT_AAC_ELD: |
163 | 2.52k | pstr_h_psy->psy_data[ch]->blk_switch_cntrl.win_seq = LONG_WINDOW; |
164 | 2.52k | pstr_h_psy->psy_data[ch]->blk_switch_cntrl.nxt_win_seq = LONG_WINDOW; |
165 | 2.52k | break; |
166 | 6.86k | } |
167 | 6.86k | ia_enhaacplus_enc_init_pre_echo_control(pstr_h_psy->psy_data[ch]->sfb_threshold_nm1_float, |
168 | 6.86k | pstr_h_psy->psy_conf_long.sfb_cnt, |
169 | 6.86k | pstr_h_psy->psy_conf_long.sfb_threshold_quiet); |
170 | 6.86k | } |
171 | 4.68k | } |
172 | | |
173 | 4.68k | return IA_NO_ERROR; |
174 | 4.68k | } |
175 | | |
176 | | static VOID ia_enhaacplus_enc_advance_psy_long_ms( |
177 | | ixheaace_psy_data **psy_data, |
178 | 105k | ixheaace_psy_configuration_long *pstr_psy_conf_long) { |
179 | 105k | ia_enhaacplus_enc_calc_band_energy_ms( |
180 | 105k | psy_data[0]->ptr_spec_coeffs, psy_data[1]->ptr_spec_coeffs, pstr_psy_conf_long->sfb_offsets, |
181 | 105k | pstr_psy_conf_long->sfb_active, pstr_psy_conf_long->sfb_cnt, |
182 | 105k | psy_data[0]->sfb_energy_ms.long_nrg, &psy_data[0]->sfb_energy_sum_ms.long_nrg, |
183 | 105k | psy_data[1]->sfb_energy_ms.long_nrg, &psy_data[1]->sfb_energy_sum_ms.long_nrg); |
184 | 105k | } |
185 | | |
186 | | static VOID ia_enhaacplus_enc_advance_psy_short_ms( |
187 | | ixheaace_psy_data **psy_data, |
188 | 33.6k | ixheaace_psy_configuration_short *pstr_psy_conf_short, WORD32 ccfl) { |
189 | 33.6k | WORD32 w; |
190 | 33.6k | WORD32 frame_len_short = FRAME_LEN_SHORT_128; |
191 | | |
192 | 33.6k | if (ccfl == FRAME_LEN_960) { |
193 | 15.5k | frame_len_short = FRAME_LEN_SHORT_120; |
194 | 15.5k | } |
195 | 302k | for (w = 0; w < TRANS_FAC; w++) { |
196 | 268k | WORD32 w_offset = w * frame_len_short; |
197 | | |
198 | 268k | ia_enhaacplus_enc_calc_band_energy_ms( |
199 | 268k | psy_data[0]->ptr_spec_coeffs + w_offset, psy_data[1]->ptr_spec_coeffs + w_offset, |
200 | 268k | pstr_psy_conf_short->sfb_offsets, pstr_psy_conf_short->sfb_active, |
201 | 268k | pstr_psy_conf_short->sfb_cnt, psy_data[0]->sfb_energy_ms.short_nrg[w], |
202 | 268k | &psy_data[0]->sfb_energy_sum_ms.short_nrg[w], psy_data[1]->sfb_energy_ms.short_nrg[w], |
203 | 268k | &psy_data[1]->sfb_energy_sum_ms.short_nrg[w]); |
204 | 268k | } |
205 | 33.6k | } |
206 | | |
207 | | static IA_ERRORCODE ia_enhaacplus_enc_advance_psy_short( |
208 | | ixheaace_psy_data *pstr_psy_data, ixheaace_temporal_noise_shaping_data *pstr_tns_data, |
209 | | ixheaace_psy_configuration_short *pstr_psy_conf_short, |
210 | | ixheaace_psy_out_channel *pstr_psy_out_ch, FLOAT32 *ptr_tns_scratch, |
211 | | const ixheaace_temporal_noise_shaping_data *ptr_tns_data2, const WORD32 ch, WORD32 aot, |
212 | 82.6k | FLOAT32 *ptr_shared_buffer1, ixheaace_aac_tables *pstr_aac_tables, WORD32 frame_len_long) { |
213 | 82.6k | IA_ERRORCODE error_code = IA_NO_ERROR; |
214 | 82.6k | WORD32 w; |
215 | 82.6k | FLOAT32 energy_shift = 0.25f; |
216 | 82.6k | FLOAT32 clip_energy = pstr_psy_conf_short->clip_energy * energy_shift; |
217 | | |
218 | 744k | for (w = 0; w < TRANS_FAC; w++) { |
219 | 661k | WORD32 w_offset = w * frame_len_long; |
220 | 661k | WORD32 i, offset; |
221 | 661k | FLOAT32 *ptr_mdct = |
222 | 661k | &pstr_psy_data->ptr_spec_coeffs[pstr_psy_conf_short->lowpass_line + w_offset]; |
223 | | |
224 | | /* Low pass */ |
225 | 661k | offset = frame_len_long - pstr_psy_conf_short->lowpass_line; |
226 | 661k | memset(ptr_mdct, 0, sizeof(FLOAT32) * offset); |
227 | | |
228 | | /* Calc sfb-bandwise MDCT-energies for left and right channel */ |
229 | 661k | ia_enhaacplus_enc_calc_band_energy( |
230 | 661k | pstr_psy_data->ptr_spec_coeffs + w_offset, pstr_psy_conf_short->sfb_offsets, |
231 | 661k | pstr_psy_conf_short->sfb_active, pstr_psy_data->sfb_energy.short_nrg[w], |
232 | 661k | pstr_psy_conf_short->sfb_cnt, &pstr_psy_data->sfb_energy_sum.short_nrg[w]); |
233 | | |
234 | | /* TNS Detect*/ |
235 | 661k | error_code = ia_enhaacplus_enc_tns_detect( |
236 | 661k | pstr_tns_data, pstr_psy_conf_short->str_tns_conf, ptr_tns_scratch, |
237 | 661k | pstr_psy_conf_short->sfb_offsets, pstr_psy_data->ptr_spec_coeffs + w_offset, w, |
238 | 661k | pstr_psy_data->blk_switch_cntrl.win_seq, aot, pstr_psy_data->sfb_energy.short_nrg[w], |
239 | 661k | ptr_shared_buffer1, frame_len_long); |
240 | | |
241 | 661k | if (error_code != IA_NO_ERROR) { |
242 | 0 | return error_code; |
243 | 0 | } |
244 | | |
245 | | /* TNS Sync */ |
246 | 661k | if (ch == 1) { |
247 | 268k | ia_enhaacplus_enc_tns_sync(pstr_tns_data, ptr_tns_data2, pstr_psy_conf_short->str_tns_conf, |
248 | 268k | w, (WORD32)pstr_psy_data->blk_switch_cntrl.win_seq); |
249 | 268k | } |
250 | | |
251 | | /* TNS Encode */ |
252 | 661k | ia_enhaacplus_enc_tns_encode( |
253 | 661k | &pstr_psy_out_ch->tns_info, pstr_tns_data, pstr_psy_conf_short->sfb_cnt, |
254 | 661k | pstr_psy_conf_short->str_tns_conf, pstr_psy_conf_short->lowpass_line, |
255 | 661k | pstr_psy_data->ptr_spec_coeffs + w_offset, w, pstr_psy_data->blk_switch_cntrl.win_seq, |
256 | 661k | pstr_aac_tables->pstr_tns_tab); |
257 | | |
258 | 10.2M | for (i = 0; i < pstr_psy_conf_short->sfb_cnt; i++) { |
259 | 9.63M | pstr_psy_data->sfb_threshold.short_nrg[w][i] = |
260 | 9.63M | pstr_psy_data->sfb_energy.short_nrg[w][i] * pstr_psy_conf_short->ratio_float; |
261 | | |
262 | 9.63M | pstr_psy_data->sfb_threshold.short_nrg[w][i] = |
263 | 9.63M | MIN(pstr_psy_data->sfb_threshold.short_nrg[w][i], clip_energy); |
264 | 9.63M | } |
265 | | |
266 | | /* Calc sfb-bandwise MDCT-energies for left and right channel again, if TNS has modified the |
267 | | * spectrum */ |
268 | 661k | if (pstr_psy_out_ch->tns_info.tns_active[w]) { |
269 | 154k | ia_enhaacplus_enc_calc_band_energy( |
270 | 154k | pstr_psy_data->ptr_spec_coeffs + w_offset, pstr_psy_conf_short->sfb_offsets, |
271 | 154k | pstr_psy_conf_short->sfb_active, pstr_psy_data->sfb_energy.short_nrg[w], |
272 | 154k | pstr_psy_conf_short->sfb_cnt, &pstr_psy_data->sfb_energy_sum.short_nrg[w]); |
273 | 154k | } |
274 | | |
275 | | /* Spreading */ |
276 | 661k | ia_enhaacplus_enc_spreading_max( |
277 | 661k | pstr_psy_conf_short->sfb_cnt, pstr_psy_conf_short->sfb_mask_low_factor, |
278 | 661k | pstr_psy_conf_short->sfb_mask_high_factor, pstr_psy_data->sfb_threshold.short_nrg[w]); |
279 | | |
280 | 10.2M | for (i = 0; i < pstr_psy_conf_short->sfb_cnt; i++) { |
281 | 9.63M | pstr_psy_data->sfb_threshold.short_nrg[w][i] = |
282 | 9.63M | MAX(pstr_psy_data->sfb_threshold.short_nrg[w][i], |
283 | 9.63M | (pstr_psy_conf_short->sfb_threshold_quiet[i] * energy_shift)); |
284 | 9.63M | } |
285 | | |
286 | | /* Pre-echo Control */ |
287 | 661k | ia_enhaacplus_enc_pre_echo_control(pstr_psy_data->sfb_threshold_nm1_float, |
288 | 661k | pstr_psy_conf_short->sfb_cnt, |
289 | 661k | pstr_psy_conf_short->min_remaining_threshold_factor, |
290 | 661k | pstr_psy_data->sfb_threshold.short_nrg[w]); |
291 | | |
292 | | /* Apply TNS mult table on CB thresholds */ |
293 | 661k | if (pstr_psy_out_ch->tns_info.tns_active[w]) { |
294 | 154k | ia_enhaacplus_enc_apply_tns_mult_table_to_ratios( |
295 | 154k | pstr_psy_conf_short->str_tns_conf.tns_ratio_patch_lowest_cb, |
296 | 154k | pstr_psy_conf_short->str_tns_conf.tns_start_band, |
297 | 154k | pstr_psy_data->sfb_threshold.short_nrg[w]); |
298 | 154k | } |
299 | | |
300 | | /* Spreaded energy for avoid hole detection */ |
301 | 10.2M | for (i = 0; i < pstr_psy_conf_short->sfb_cnt; i++) { |
302 | 9.63M | pstr_psy_data->sfb_sreaded_energy.short_nrg[w][i] = |
303 | 9.63M | pstr_psy_data->sfb_energy.short_nrg[w][i]; |
304 | 9.63M | } |
305 | | |
306 | 661k | ia_enhaacplus_enc_spreading_max(pstr_psy_conf_short->sfb_cnt, |
307 | 661k | pstr_psy_conf_short->sfb_mask_low_factor_spread_nrg, |
308 | 661k | pstr_psy_conf_short->sfb_mask_high_factor_spread_nrg, |
309 | 661k | pstr_psy_data->sfb_sreaded_energy.short_nrg[w]); |
310 | 661k | } |
311 | 82.6k | return error_code; |
312 | 82.6k | } |
313 | | |
314 | | static IA_ERRORCODE ia_enhaacplus_enc_advance_psy_long( |
315 | | ixheaace_psy_data *pstr_psy_data, ixheaace_temporal_noise_shaping_data *pstr_tns_data, |
316 | | ixheaace_psy_configuration_long *pstr_psy_conf_long, |
317 | | ixheaace_psy_out_channel *pstr_psy_out_ch, FLOAT32 *ptr_scratch_tns, |
318 | | const ixheaace_temporal_noise_shaping_data *pstr_tns_data2, const WORD32 ch, WORD32 aot, |
319 | 359k | FLOAT32 *ptr_shared_buffer1, ixheaace_aac_tables *pstr_aac_tables, WORD32 frame_len_long) { |
320 | 359k | WORD32 i; |
321 | 359k | IA_ERRORCODE error_code = IA_NO_ERROR; |
322 | 359k | FLOAT32 energy_shift = 0.25f; |
323 | 359k | FLOAT32 clip_energy = pstr_psy_conf_long->clip_energy / 4; |
324 | 359k | FLOAT32 *ptr_sfb_energy_long = pstr_psy_data->sfb_energy.long_nrg; |
325 | 359k | FLOAT32 *ptr_sfb_spreaded_energy = pstr_psy_data->sfb_sreaded_energy.long_nrg; |
326 | | |
327 | | /* Low pass */ |
328 | 359k | memset(&pstr_psy_data->ptr_spec_coeffs[pstr_psy_conf_long->lowpass_line], 0, |
329 | 359k | sizeof(*pstr_psy_data->ptr_spec_coeffs) * |
330 | 359k | (frame_len_long - pstr_psy_conf_long->lowpass_line)); |
331 | | |
332 | | /* Calculate scale_factor_band - bandwise MDCT-energies for left and right channels */ |
333 | 359k | ia_enhaacplus_enc_calc_band_energy( |
334 | 359k | pstr_psy_data->ptr_spec_coeffs, pstr_psy_conf_long->sfb_offsets, |
335 | 359k | pstr_psy_conf_long->sfb_active, pstr_psy_data->sfb_energy.long_nrg, |
336 | 359k | pstr_psy_conf_long->sfb_cnt, &pstr_psy_data->sfb_energy_sum.long_nrg); |
337 | | |
338 | | /* TNS Detect */ |
339 | 359k | error_code = ia_enhaacplus_enc_tns_detect( |
340 | 359k | pstr_tns_data, pstr_psy_conf_long->str_tns_conf, ptr_scratch_tns, |
341 | 359k | pstr_psy_conf_long->sfb_offsets, pstr_psy_data->ptr_spec_coeffs, 0, |
342 | 359k | pstr_psy_data->blk_switch_cntrl.win_seq, aot, pstr_psy_data->sfb_energy.long_nrg, |
343 | 359k | ptr_shared_buffer1, frame_len_long); |
344 | | |
345 | 359k | if (error_code != IA_NO_ERROR) { |
346 | 0 | return error_code; |
347 | 0 | } |
348 | | |
349 | | /* TNS Sync */ |
350 | 359k | if (ch == 1) { |
351 | 105k | ia_enhaacplus_enc_tns_sync(pstr_tns_data, pstr_tns_data2, pstr_psy_conf_long->str_tns_conf, 0, |
352 | 105k | (WORD32)pstr_psy_data->blk_switch_cntrl.win_seq); |
353 | 105k | } |
354 | | |
355 | | /* TNS Encode */ |
356 | 359k | ia_enhaacplus_enc_tns_encode(&pstr_psy_out_ch->tns_info, pstr_tns_data, |
357 | 359k | pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->str_tns_conf, |
358 | 359k | pstr_psy_conf_long->lowpass_line, pstr_psy_data->ptr_spec_coeffs, |
359 | 359k | 0, (WORD32)pstr_psy_data->blk_switch_cntrl.win_seq, |
360 | 359k | pstr_aac_tables->pstr_tns_tab); |
361 | | |
362 | 359k | if (aot == AOT_AAC_ELD) { |
363 | 2.76M | for (i = 0; i < pstr_psy_conf_long->sfb_active; i++) { |
364 | 2.64M | pstr_psy_data->sfb_threshold.long_nrg[i] = |
365 | 2.64M | pstr_psy_data->sfb_energy.long_nrg[i] * pstr_psy_conf_long->ratio_float; |
366 | | |
367 | 2.64M | pstr_psy_data->sfb_threshold.long_nrg[i] = |
368 | 2.64M | MIN(pstr_psy_data->sfb_threshold.long_nrg[i], clip_energy); |
369 | 2.64M | } |
370 | 245k | } else { |
371 | 10.6M | for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) { |
372 | 10.3M | pstr_psy_data->sfb_threshold.long_nrg[i] = |
373 | 10.3M | pstr_psy_data->sfb_energy.long_nrg[i] * pstr_psy_conf_long->ratio_float; |
374 | | |
375 | 10.3M | pstr_psy_data->sfb_threshold.long_nrg[i] = |
376 | 10.3M | MIN(pstr_psy_data->sfb_threshold.long_nrg[i], clip_energy); |
377 | 10.3M | } |
378 | 245k | } |
379 | | |
380 | | /* Calculate scale factor band - bandwise MDCT-energies for left and right channel again, if TNS |
381 | | * has modified the spectrum */ |
382 | 359k | if (pstr_psy_out_ch->tns_info.tns_active[0] == 1) { |
383 | 168k | ia_enhaacplus_enc_calc_band_energy( |
384 | 168k | pstr_psy_data->ptr_spec_coeffs, pstr_psy_conf_long->sfb_offsets, |
385 | 168k | pstr_psy_conf_long->sfb_active, pstr_psy_data->sfb_energy.long_nrg, |
386 | 168k | pstr_psy_conf_long->sfb_cnt, &pstr_psy_data->sfb_energy_sum.long_nrg); |
387 | 168k | } |
388 | | |
389 | | /* Spreading */ |
390 | 359k | if (aot == AOT_AAC_ELD) { |
391 | 113k | ia_enhaacplus_enc_spreading_max( |
392 | 113k | pstr_psy_conf_long->sfb_active, pstr_psy_conf_long->sfb_mask_low_factor, |
393 | 113k | pstr_psy_conf_long->sfb_mask_high_factor, pstr_psy_data->sfb_threshold.long_nrg); |
394 | 245k | } else { |
395 | 245k | ia_enhaacplus_enc_spreading_max( |
396 | 245k | pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->sfb_mask_low_factor, |
397 | 245k | pstr_psy_conf_long->sfb_mask_high_factor, pstr_psy_data->sfb_threshold.long_nrg); |
398 | 245k | } |
399 | | |
400 | | /* Threshold in quiet */ |
401 | 359k | if (aot == AOT_AAC_ELD) { |
402 | 2.76M | for (i = 0; i < pstr_psy_conf_long->sfb_active; i++) { |
403 | 2.64M | pstr_psy_data->sfb_threshold.long_nrg[i] = |
404 | 2.64M | MAX(pstr_psy_data->sfb_threshold.long_nrg[i], |
405 | 2.64M | (pstr_psy_conf_long->sfb_threshold_quiet[i] * energy_shift)); |
406 | 2.64M | } |
407 | 245k | } else { |
408 | 10.6M | for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) { |
409 | 10.3M | pstr_psy_data->sfb_threshold.long_nrg[i] = |
410 | 10.3M | MAX(pstr_psy_data->sfb_threshold.long_nrg[i], |
411 | 10.3M | (pstr_psy_conf_long->sfb_threshold_quiet[i] * energy_shift)); |
412 | 10.3M | } |
413 | 245k | } |
414 | | |
415 | | /* Pre-echo control */ |
416 | 359k | if (pstr_psy_data->blk_switch_cntrl.win_seq == STOP_WINDOW) { |
417 | | /* Prevent pre-echo control from comparing stop thresholds with short thresholds */ |
418 | 842k | for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) { |
419 | 823k | pstr_psy_data->sfb_threshold_nm1_float[i] = 1.0e20f; |
420 | 823k | } |
421 | 18.6k | } |
422 | | |
423 | 359k | ia_enhaacplus_enc_pre_echo_control( |
424 | 359k | pstr_psy_data->sfb_threshold_nm1_float, pstr_psy_conf_long->sfb_cnt, |
425 | 359k | pstr_psy_conf_long->min_remaining_threshold_factor, pstr_psy_data->sfb_threshold.long_nrg); |
426 | | |
427 | 359k | if (pstr_psy_data->blk_switch_cntrl.win_seq == START_WINDOW) { |
428 | | /* Prevent pre-echo control in next frame from comparing start thresholds with short |
429 | | * thresholds */ |
430 | 945k | for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) { |
431 | 924k | pstr_psy_data->sfb_threshold_nm1_float[i] = 1.0e20f; |
432 | 924k | } |
433 | 20.8k | } |
434 | | |
435 | | /* Apply TNS mult table on CB thresholds */ |
436 | 359k | if (pstr_psy_out_ch->tns_info.tns_active[0]) { |
437 | 168k | ia_enhaacplus_enc_apply_tns_mult_table_to_ratios( |
438 | 168k | pstr_psy_conf_long->str_tns_conf.tns_ratio_patch_lowest_cb, |
439 | 168k | pstr_psy_conf_long->str_tns_conf.tns_start_band, pstr_psy_data->sfb_threshold.long_nrg); |
440 | 168k | } |
441 | | |
442 | | /* Spreaded energy for avoid hole detection */ |
443 | | |
444 | 359k | memcpy(&ptr_sfb_spreaded_energy[0], &ptr_sfb_energy_long[0], |
445 | 359k | sizeof(ptr_sfb_spreaded_energy[0]) * pstr_psy_conf_long->sfb_cnt); |
446 | | |
447 | 359k | if (aot == AOT_AAC_ELD) { |
448 | 113k | ia_enhaacplus_enc_spreading_max(pstr_psy_conf_long->sfb_active, |
449 | 113k | pstr_psy_conf_long->sfb_mask_low_factor_spread_nrg, |
450 | 113k | pstr_psy_conf_long->sfb_mask_high_factor_spread_nrg, |
451 | 113k | pstr_psy_data->sfb_sreaded_energy.long_nrg); |
452 | 245k | } else { |
453 | 245k | ia_enhaacplus_enc_spreading_max(pstr_psy_conf_long->sfb_cnt, |
454 | 245k | pstr_psy_conf_long->sfb_mask_low_factor_spread_nrg, |
455 | 245k | pstr_psy_conf_long->sfb_mask_high_factor_spread_nrg, |
456 | 245k | pstr_psy_data->sfb_sreaded_energy.long_nrg); |
457 | 245k | } |
458 | | |
459 | 359k | return error_code; |
460 | 359k | } |
461 | | |
462 | | IA_ERRORCODE ia_enhaacplus_enc_psy_main( |
463 | | WORD32 time_sn_stride, ixheaace_element_info *pstr_elem_info, const FLOAT32 *ptr_time_signal, |
464 | | WORD32 aot, ixheaace_psy_data **psy_data, |
465 | | ixheaace_temporal_noise_shaping_data **tns_data, |
466 | | ixheaace_psy_configuration_long *pstr_psy_conf_long, |
467 | | ixheaace_psy_configuration_short *pstr_psy_conf_short, |
468 | | ixheaace_psy_out_channel **psy_out_ch, |
469 | | ixheaace_psy_out_element *pstr_psy_out_element, FLOAT32 *ptr_scratch_tns, |
470 | | FLOAT32 *ptr_shared_buffer1, WORD8 *ptr_shared_buffer5, ixheaace_aac_tables *pstr_aac_tables, |
471 | | WORD32 frame_len_long) |
472 | | |
473 | 303k | { |
474 | 303k | IA_ERRORCODE error_code = IA_NO_ERROR; |
475 | 303k | WORD32 grouped_sfb_offset[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND + |
476 | 303k | 1]; /* plus one for last dummy offset ! */ |
477 | 303k | FLOAT32 grouped_sfb_min_snr[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND]; |
478 | 303k | WORD32 max_sfb_per_grp[IXHEAACE_MAX_CH_IN_BS_ELE] = {0}; |
479 | 303k | WORD32 ch, sfb, line; |
480 | 303k | WORD32 num_channels = pstr_elem_info->n_channels_in_el; |
481 | | |
482 | 303k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { |
483 | 201k | if (pstr_elem_info->el_type != ID_LFE) { |
484 | 465k | for (ch = 0; ch < num_channels; ch++) { |
485 | 277k | iaace_block_switching(&psy_data[ch]->blk_switch_cntrl, |
486 | 277k | ptr_time_signal + pstr_elem_info->channel_index[ch], frame_len_long, |
487 | 277k | num_channels); |
488 | 277k | } |
489 | 188k | } else { |
490 | 25.5k | for (ch = 0; ch < num_channels; ch++) { |
491 | 12.7k | psy_data[ch]->blk_switch_cntrl.win_seq = LONG_WINDOW; |
492 | 12.7k | } |
493 | 12.7k | } |
494 | | |
495 | | /* synch left and right block type */ |
496 | 201k | if (num_channels == NUM_CHANS_MONO) { |
497 | 112k | iaace_sync_block_switching(&psy_data[0]->blk_switch_cntrl, NULL, num_channels); |
498 | 112k | } |
499 | 88.8k | else { |
500 | 88.8k | iaace_sync_block_switching(&psy_data[0]->blk_switch_cntrl, &psy_data[1]->blk_switch_cntrl, |
501 | 88.8k | num_channels); |
502 | 88.8k | } |
503 | 201k | } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) { |
504 | 253k | for (ch = 0; ch < num_channels; ch++) { |
505 | 151k | psy_data[ch]->blk_switch_cntrl.win_seq_ld = LONG_WINDOW; |
506 | 151k | psy_data[ch]->blk_switch_cntrl.next_win_seq_ld = LONG_WINDOW; |
507 | 151k | psy_data[ch]->blk_switch_cntrl.win_seq = LONG_WINDOW; |
508 | 151k | psy_data[ch]->blk_switch_cntrl.nxt_win_seq = LONG_WINDOW; |
509 | 151k | psy_data[ch]->blk_switch_cntrl.total_groups_cnt = 1; |
510 | 151k | } |
511 | 101k | } |
512 | | /* transform */ |
513 | 745k | for (ch = 0; ch < num_channels; ch++) { |
514 | 441k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { |
515 | 290k | ixheaace_transform_real_lc_ld( |
516 | 290k | psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch], |
517 | 290k | time_sn_stride, psy_data[ch]->ptr_spec_coeffs, psy_data[ch]->blk_switch_cntrl.win_seq, |
518 | 290k | frame_len_long, ptr_shared_buffer5); |
519 | 290k | } else if (aot == AOT_AAC_LD) { |
520 | 38.0k | if (frame_len_long == FRAME_LEN_480) { |
521 | 13.7k | ia_enhaacplus_enc_transform_real( |
522 | 13.7k | psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch], |
523 | 13.7k | time_sn_stride, psy_data[ch]->ptr_spec_coeffs, pstr_aac_tables->pstr_mdct_tab, |
524 | 13.7k | ptr_scratch_tns, ptr_shared_buffer5, frame_len_long); |
525 | 24.2k | } else { |
526 | 24.2k | ixheaace_transform_real_lc_ld( |
527 | 24.2k | psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch], |
528 | 24.2k | time_sn_stride, psy_data[ch]->ptr_spec_coeffs, psy_data[ch]->blk_switch_cntrl.win_seq, |
529 | 24.2k | frame_len_long, ptr_shared_buffer5); |
530 | 24.2k | } |
531 | 113k | } else if (aot == AOT_AAC_ELD) { |
532 | 113k | if (frame_len_long == FRAME_LEN_480) { |
533 | 50.9k | ia_enhaacplus_enc_transform_real( |
534 | 50.9k | psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch], |
535 | 50.9k | time_sn_stride, psy_data[ch]->ptr_spec_coeffs, pstr_aac_tables->pstr_mdct_tab, |
536 | 50.9k | ptr_scratch_tns, ptr_shared_buffer5, frame_len_long); |
537 | 62.7k | } else { |
538 | 62.7k | ia_enhaacplus_enc_transform_real_eld( |
539 | 62.7k | psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch], |
540 | 62.7k | time_sn_stride, psy_data[ch]->ptr_spec_coeffs, ptr_shared_buffer5, frame_len_long); |
541 | 62.7k | } |
542 | 113k | } |
543 | 441k | } |
544 | | |
545 | 745k | for (ch = 0; ch < num_channels; ch++) { |
546 | 441k | if (psy_data[ch]->blk_switch_cntrl.win_seq != SHORT_WINDOW) { |
547 | 359k | error_code = ia_enhaacplus_enc_advance_psy_long( |
548 | 359k | psy_data[ch], tns_data[ch], pstr_psy_conf_long, psy_out_ch[ch], ptr_scratch_tns, |
549 | 359k | tns_data[1 - ch], ch, aot, ptr_shared_buffer1, pstr_aac_tables, frame_len_long); |
550 | | |
551 | 359k | if (error_code != IA_NO_ERROR) { |
552 | 0 | return error_code; |
553 | 0 | } |
554 | | |
555 | 5.79M | for (sfb = pstr_psy_conf_long->sfb_cnt - 1; sfb >= 0; sfb--) { |
556 | 5.71M | for (line = pstr_psy_conf_long->sfb_offsets[sfb + 1] - 1; |
557 | 172M | line >= pstr_psy_conf_long->sfb_offsets[sfb]; line--) { |
558 | 167M | if (psy_data[ch]->ptr_spec_coeffs[line] != 0) { |
559 | 281k | break; |
560 | 281k | } |
561 | 167M | } |
562 | 5.71M | if (line >= pstr_psy_conf_long->sfb_offsets[sfb]) { |
563 | 281k | break; |
564 | 281k | } |
565 | 5.71M | } |
566 | | |
567 | 359k | max_sfb_per_grp[ch] = sfb + 1; |
568 | | |
569 | | /* Calculate bandwise energies for mid and side channels - only if 2 channels exist */ |
570 | 359k | if (ch == 1) { |
571 | 105k | ia_enhaacplus_enc_advance_psy_long_ms(psy_data, pstr_psy_conf_long); |
572 | 105k | } |
573 | 359k | } else { |
574 | 82.6k | error_code = ia_enhaacplus_enc_advance_psy_short( |
575 | 82.6k | psy_data[ch], tns_data[ch], pstr_psy_conf_short, psy_out_ch[ch], ptr_scratch_tns, |
576 | 82.6k | tns_data[1 - ch], ch, aot, ptr_shared_buffer1, pstr_aac_tables, frame_len_long / 8); |
577 | | |
578 | 82.6k | if (error_code != IA_NO_ERROR) { |
579 | 0 | return error_code; |
580 | 0 | } |
581 | | |
582 | | /* Calculate bandwise energies for mid and side channels - only if 2 channels exist */ |
583 | 82.6k | if (ch == 1) { |
584 | 33.6k | ia_enhaacplus_enc_advance_psy_short_ms(psy_data, pstr_psy_conf_short, frame_len_long); |
585 | 33.6k | } |
586 | 82.6k | } |
587 | 441k | } |
588 | | |
589 | | /* Group short data (max_sfb for short blocks is determined here) */ |
590 | 303k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { |
591 | 491k | for (ch = 0; ch < num_channels; ch++) { |
592 | 290k | if (psy_data[ch]->blk_switch_cntrl.win_seq == SHORT_WINDOW) { |
593 | 82.6k | iaace_group_short_data(psy_data[ch]->ptr_spec_coeffs, ptr_scratch_tns, |
594 | 82.6k | &psy_data[ch]->sfb_threshold, &psy_data[ch]->sfb_energy, |
595 | 82.6k | &psy_data[ch]->sfb_energy_ms, &psy_data[ch]->sfb_sreaded_energy, |
596 | 82.6k | pstr_psy_conf_short->sfb_cnt, pstr_psy_conf_short->sfb_offsets, |
597 | 82.6k | pstr_psy_conf_short->sfb_min_snr, grouped_sfb_offset[ch], |
598 | 82.6k | &max_sfb_per_grp[ch], grouped_sfb_min_snr[ch], |
599 | 82.6k | psy_data[ch]->blk_switch_cntrl.total_groups_cnt, |
600 | 82.6k | psy_data[ch]->blk_switch_cntrl.group_len, frame_len_long); |
601 | 82.6k | } |
602 | 290k | } |
603 | 201k | } |
604 | | |
605 | 303k | #if (IXHEAACE_MAX_CH_IN_BS_ELE > 1) |
606 | | /* Stereo Processing */ |
607 | 303k | if (num_channels == 2) { |
608 | 138k | pstr_psy_out_element->tools_info.ms_digest = MS_NONE; |
609 | | |
610 | 138k | max_sfb_per_grp[0] = max_sfb_per_grp[1] = MAX(max_sfb_per_grp[0], max_sfb_per_grp[1]); |
611 | | |
612 | 138k | if (psy_data[0]->blk_switch_cntrl.win_seq != SHORT_WINDOW) { |
613 | 105k | iaace_ms_apply( |
614 | 105k | psy_data, psy_data[0]->ptr_spec_coeffs, psy_data[1]->ptr_spec_coeffs, |
615 | 105k | &pstr_psy_out_element->tools_info.ms_digest, pstr_psy_out_element->tools_info.ms_mask, |
616 | 105k | pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->sfb_cnt, max_sfb_per_grp[0], |
617 | 105k | pstr_psy_conf_long->sfb_offsets, &pstr_psy_out_element->weight_ms_lr_pe_ratio); |
618 | 105k | } else { |
619 | 33.6k | iaace_ms_apply(psy_data, psy_data[0]->ptr_spec_coeffs, psy_data[1]->ptr_spec_coeffs, |
620 | 33.6k | &pstr_psy_out_element->tools_info.ms_digest, |
621 | 33.6k | pstr_psy_out_element->tools_info.ms_mask, |
622 | 33.6k | psy_data[0]->blk_switch_cntrl.total_groups_cnt * |
623 | 33.6k | pstr_psy_conf_short->sfb_cnt, |
624 | 33.6k | pstr_psy_conf_short->sfb_cnt, max_sfb_per_grp[0], grouped_sfb_offset[0], |
625 | 33.6k | &pstr_psy_out_element->weight_ms_lr_pe_ratio); |
626 | 33.6k | } |
627 | 138k | } |
628 | 303k | #endif |
629 | | |
630 | | /* Build output */ |
631 | 303k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { |
632 | 491k | for (ch = 0; ch < num_channels; ch++) { |
633 | 290k | if (psy_data[ch]->blk_switch_cntrl.win_seq != SHORT_WINDOW) { |
634 | 207k | ia_enhaacplus_enc_build_interface( |
635 | 207k | psy_data[ch]->ptr_spec_coeffs, &psy_data[ch]->sfb_threshold, |
636 | 207k | &psy_data[ch]->sfb_energy, |
637 | 207k | &psy_data[ch]->sfb_sreaded_energy, psy_data[ch]->sfb_energy_sum, |
638 | 207k | psy_data[ch]->sfb_energy_sum_ms, psy_data[ch]->blk_switch_cntrl.win_seq, |
639 | 207k | ia_enhaacplus_enc_block_type_to_window_shape_lc[psy_data[ch] |
640 | 207k | ->blk_switch_cntrl.win_seq], |
641 | 207k | pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->sfb_offsets, max_sfb_per_grp[ch], |
642 | 207k | pstr_psy_conf_long->sfb_min_snr, psy_data[ch]->blk_switch_cntrl.total_groups_cnt, |
643 | 207k | psy_data[ch]->blk_switch_cntrl.group_len, psy_out_ch[ch]); |
644 | 207k | } else { |
645 | 82.6k | ia_enhaacplus_enc_build_interface( |
646 | 82.6k | psy_data[ch]->ptr_spec_coeffs, &psy_data[ch]->sfb_threshold, |
647 | 82.6k | &psy_data[ch]->sfb_energy, |
648 | 82.6k | &psy_data[ch]->sfb_sreaded_energy, psy_data[ch]->sfb_energy_sum, |
649 | 82.6k | psy_data[ch]->sfb_energy_sum_ms, SHORT_WINDOW, SINE_WINDOW, |
650 | 82.6k | psy_data[ch]->blk_switch_cntrl.total_groups_cnt * pstr_psy_conf_short->sfb_cnt, |
651 | 82.6k | grouped_sfb_offset[ch], max_sfb_per_grp[ch], grouped_sfb_min_snr[ch], |
652 | 82.6k | psy_data[ch]->blk_switch_cntrl.total_groups_cnt, |
653 | 82.6k | psy_data[ch]->blk_switch_cntrl.group_len, psy_out_ch[ch]); |
654 | 82.6k | } |
655 | 290k | } |
656 | 201k | } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) { |
657 | 253k | for (ch = 0; ch < num_channels; ch++) { |
658 | 151k | ia_enhaacplus_enc_build_interface( |
659 | 151k | psy_data[ch]->ptr_spec_coeffs, &psy_data[ch]->sfb_threshold, &psy_data[ch]->sfb_energy, |
660 | 151k | &psy_data[ch]->sfb_sreaded_energy, psy_data[ch]->sfb_energy_sum, |
661 | 151k | psy_data[ch]->sfb_energy_sum_ms, LONG_WINDOW, |
662 | 151k | ia_enhaacplus_enc_block_type_to_window_shape_ld[psy_data[ch] |
663 | 151k | ->blk_switch_cntrl.win_seq_ld], |
664 | 151k | ((aot == AOT_AAC_ELD) ? pstr_psy_conf_long->sfb_active : pstr_psy_conf_long->sfb_cnt), |
665 | 151k | pstr_psy_conf_long->sfb_offsets, max_sfb_per_grp[ch], pstr_psy_conf_long->sfb_min_snr, |
666 | 151k | psy_data[ch]->blk_switch_cntrl.total_groups_cnt, |
667 | 151k | psy_data[ch]->blk_switch_cntrl.group_len, psy_out_ch[ch]); |
668 | 151k | } |
669 | 101k | } |
670 | 303k | return error_code; |
671 | 303k | } |