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