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 #include "ixheaac_type_def.h"
21 #include "ixheaacd_mps_struct_def.h"
22 #include "ixheaacd_mps_res_rom.h"
23 #include "ixheaacd_mps_aac_struct.h"
24 #include "ixheaac_constants.h"
25 #include "ixheaac_basic_ops32.h"
26 #include "ixheaac_basic_ops40.h"
27 #include "ixheaacd_bitbuffer.h"
28 #include "ixheaacd_error_codes.h"
29 #include "ixheaacd_common_rom.h"
30 #include "ixheaacd_sbrdecsettings.h"
31 #include "ixheaacd_sbr_scale.h"
32 #include "ixheaacd_env_extr_part.h"
33 #include "ixheaacd_sbr_rom.h"
34 #include "ixheaacd_hybrid.h"
35 #include "ixheaacd_ps_dec.h"
36 #include "ixheaacd_mps_polyphase.h"
37 #include "ixheaacd_config.h"
38 #include "ixheaacd_qmf_dec.h"
39 #include "ixheaacd_mps_dec.h"
40 #include "ixheaacd_mps_bitdec.h"
41 #include "ixheaacd_mps_macro_def.h"
42 #include "ixheaacd_mps_basic_op.h"
43 #include "ixheaacd_mps_reshape_bb_env.h"
44 #include "ixheaac_error_standards.h"
45
46 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
47
ixheaacd_init_bb_env(ia_heaac_mps_state_struct * pstr_mps_state)48 VOID ixheaacd_init_bb_env(ia_heaac_mps_state_struct *pstr_mps_state) {
49 WORD32 k, j;
50 ia_mps_dec_reshape_bb_env_state_struct *reshape_bb_env_state =
51 pstr_mps_state->mps_persistent_mem.reshape_bb_env_state;
52
53 for (k = 0; k < 2 * MAX_OUTPUT_CHANNELS_MPS + MAX_INPUT_CHANNELS_MPS; k++) {
54 reshape_bb_env_state->norm_nrg_prev[k] = ONE_IN_Q30;
55 reshape_bb_env_state->frame_nrg_prev[k] = 0;
56 reshape_bb_env_state->q_frame_nrg_prev[k] = 30;
57 reshape_bb_env_state->q_norm_nrg_prev[k] = 30;
58 for (j = 0; j < MAX_PARAMETER_BANDS; j++) {
59 reshape_bb_env_state->part_nrg_prev[k][j] = 0;
60 reshape_bb_env_state->q_part_nrg_prev[k][j] = 30;
61 }
62 }
63 }
64
ixheaacd_extract_bb_env(ia_heaac_mps_state_struct * pstr_mps_state,WORD32 inp,WORD32 ch,WORD32 * env,VOID * scratch,WORD32 flag)65 static VOID ixheaacd_extract_bb_env(ia_heaac_mps_state_struct *pstr_mps_state, WORD32 inp,
66 WORD32 ch, WORD32 *env, VOID *scratch, WORD32 flag) {
67 ia_mps_dec_reshape_bb_env_state_struct *reshape_bb_env_state =
68 pstr_mps_state->mps_persistent_mem.reshape_bb_env_state;
69 WORD64 *slot_nrg_fix, *slot_nrg;
70 WORD16 *q_slot_nrg_fix, *q_slot_nrg;
71 WORD32 *part_nrg_fix;
72 WORD16 *q_part_nrg_fix;
73
74 WORD32 *p_buffer_real, *p_buffer_imag, *p_buffer_re, *p_buffer_im;
75 WORD32 ts, qs, pb;
76
77 WORD32 start_p = 10;
78 WORD32 end_p = 18;
79 WORD32 env_fix_l;
80 WORD16 q_env_fix_l;
81
82 WORD16 alpha_fix = ALPHA_Q15;
83 WORD16 beta_fix = BETA_Q15;
84
85 WORD16 one_min_alpha_fix = ONE_MINUS_ALPHA_Q16;
86 WORD16 one_min_beta_fix = ONE_MINUS_BETA_Q16;
87 WORD16 one_by_nine = ONE_BY_NINE_Q16;
88 WORD32 frame_nrg_fix = 0;
89 WORD32 *norm_nrg_fix;
90 WORD16 q_frame_nrg_fix = 0;
91 WORD16 *q_norm_nrg_fix;
92 WORD32 temp_1, temp4;
93 WORD16 qtemp1, q_env;
94
95 WORD32 prev_ch_offs;
96 WORD32 cnt = min(42, pstr_mps_state->hybrid_bands);
97 WORD32 time_slots = pstr_mps_state->time_slots;
98 const WORD32 *sqrt_tab = pstr_mps_state->ia_mps_dec_mps_table.common_table_ptr->sqrt_tab;
99 WORD32 *hyb_output_real_dry, *n_slot_nrg;
100 WORD32 *hyb_output_imag_dry;
101
102 const WORD32 *bb_env_kernels =
103 pstr_mps_state->ia_mps_dec_mps_table.bitdec_table_ptr->kernel_table.bb_env_kernels;
104
105 q_slot_nrg_fix = (WORD16 *)scratch;
106 n_slot_nrg =
107 (WORD32 *)((WORD8 *)scratch + IXHEAAC_GET_SIZE_ALIGNED(RESHAPE_OFFSET_1, BYTE_ALIGN_8));
108 slot_nrg_fix =
109 (WORD64 *)((WORD8 *)scratch + IXHEAAC_GET_SIZE_ALIGNED(RESHAPE_OFFSET_2, BYTE_ALIGN_8));
110 switch (inp) {
111 WORD32 frame_nrg_prev;
112 WORD16 q_frame_nrg_prev;
113 WORD32 *p_hyb_out_dry_real, *p_hyb_out_dry_imag;
114
115 case INP_DRY_WET:
116 frame_nrg_prev = reshape_bb_env_state->frame_nrg_prev[ch];
117 q_frame_nrg_prev = reshape_bb_env_state->q_frame_nrg_prev[ch];
118
119 part_nrg_fix = &reshape_bb_env_state->part_nrg_prev[ch][0];
120 q_part_nrg_fix = &reshape_bb_env_state->q_part_nrg_prev[ch][0];
121
122 norm_nrg_fix = &reshape_bb_env_state->norm_nrg_prev[ch];
123 q_norm_nrg_fix = &reshape_bb_env_state->q_norm_nrg_prev[ch];
124
125 p_buffer_real = pstr_mps_state->array_struct->buf_real + ch * TSXHB + 12;
126 p_buffer_imag = pstr_mps_state->array_struct->buf_imag + ch * TSXHB + 12;
127
128 p_hyb_out_dry_real = pstr_mps_state->array_struct->hyb_output_real_dry + ch * TSXHB + 12;
129 p_hyb_out_dry_imag = pstr_mps_state->array_struct->hyb_output_imag_dry + ch * TSXHB + 12;
130
131 for (ts = 0; ts < time_slots; ts++) {
132 WORD32 prev_idx = 10;
133
134 slot_nrg = slot_nrg_fix + 4;
135 for (pb = 14; pb <= end_p; pb++) *slot_nrg++ = 0;
136
137 slot_nrg = slot_nrg_fix;
138
139 p_buffer_re = p_buffer_real;
140 p_buffer_im = p_buffer_imag;
141
142 hyb_output_real_dry = p_hyb_out_dry_real;
143 hyb_output_imag_dry = p_hyb_out_dry_imag;
144
145 for (qs = 12; qs < 16; qs++) {
146 temp_1 = (*hyb_output_real_dry + *p_buffer_re);
147 temp4 = (*hyb_output_imag_dry + *p_buffer_im);
148
149 *slot_nrg++ = (WORD64)temp_1 * (WORD64)temp_1 + (WORD64)temp4 * (WORD64)temp4;
150
151 p_buffer_re++;
152 p_buffer_im++;
153 hyb_output_real_dry++;
154 hyb_output_imag_dry++;
155 }
156 prev_idx = 14;
157 for (; qs < 30; qs++) {
158 WORD32 idx = bb_env_kernels[qs];
159 if (prev_idx != idx) {
160 slot_nrg++;
161 prev_idx = idx;
162 }
163 temp_1 = (*hyb_output_real_dry + *p_buffer_re);
164 temp4 = (*hyb_output_imag_dry + *p_buffer_im);
165
166 *slot_nrg += (WORD64)temp_1 * (WORD64)temp_1 + (WORD64)temp4 * (WORD64)temp4;
167
168 p_buffer_re++;
169 p_buffer_im++;
170 hyb_output_real_dry++;
171 hyb_output_imag_dry++;
172 }
173 slot_nrg++;
174 for (; qs < cnt; qs++) {
175 temp_1 = (*hyb_output_real_dry + *p_buffer_re);
176 temp4 = (*hyb_output_imag_dry + *p_buffer_im);
177
178 *slot_nrg += (WORD64)temp_1 * (WORD64)temp_1 + (WORD64)temp4 * (WORD64)temp4;
179
180 p_buffer_re++;
181 p_buffer_im++;
182 hyb_output_real_dry++;
183 hyb_output_imag_dry++;
184 }
185
186 slot_nrg = slot_nrg_fix;
187 q_slot_nrg = q_slot_nrg_fix;
188
189 frame_nrg_fix = 0;
190 q_frame_nrg_fix = 30;
191 for (pb = start_p; pb <= end_p; pb++) {
192 *n_slot_nrg = ixheaacd_mps_narrow(*slot_nrg, q_slot_nrg);
193 slot_nrg++;
194 temp_1 = ixheaac_mult32x16in32(*n_slot_nrg, one_min_alpha_fix);
195 temp4 = ixheaac_mult32x16in32((part_nrg_fix[pb]) << 1, alpha_fix);
196 part_nrg_fix[pb] =
197 ixheaacd_mps_reshape_add32(temp4, temp_1, &q_part_nrg_fix[pb], *q_slot_nrg);
198
199 frame_nrg_fix = ixheaacd_mps_reshape_add32(frame_nrg_fix, *n_slot_nrg++,
200 &q_frame_nrg_fix, *q_slot_nrg++);
201 }
202
203 frame_nrg_fix = ixheaac_mult32x16in32(frame_nrg_fix, one_by_nine);
204
205 temp_1 = ixheaac_mult32x16in32(frame_nrg_fix, one_min_alpha_fix);
206 temp4 = ixheaac_mult32x16in32((frame_nrg_prev) << 1, alpha_fix);
207 frame_nrg_fix =
208 ixheaacd_mps_reshape_add32(temp_1, temp4, &q_frame_nrg_fix, q_frame_nrg_prev);
209
210 frame_nrg_prev = frame_nrg_fix;
211 q_frame_nrg_prev = q_frame_nrg_fix;
212
213 env_fix_l = 0;
214 q_env_fix_l = 30;
215 q_slot_nrg = q_slot_nrg_fix;
216
217 n_slot_nrg -= PB_OFFSET;
218 for (pb = start_p; pb <= end_p; pb++) {
219 temp_1 = ixheaacd_mps_div_32(*n_slot_nrg++, part_nrg_fix[pb], &qtemp1);
220 qtemp1 = *q_slot_nrg++ + qtemp1 - q_part_nrg_fix[pb];
221 env_fix_l = ixheaacd_mps_reshape_add32(env_fix_l, temp_1, &q_env_fix_l, qtemp1);
222 }
223 n_slot_nrg -= PB_OFFSET;
224
225 env_fix_l =
226 ixheaacd_mps_mult32x32(env_fix_l, frame_nrg_fix, &q_env_fix_l, q_frame_nrg_fix);
227
228 temp_1 = ixheaac_mult32x16in32(env_fix_l, one_min_beta_fix);
229 temp4 = ixheaac_mult32x16in32((*norm_nrg_fix) << 1, beta_fix);
230 *norm_nrg_fix = ixheaacd_mps_reshape_add32(temp4, temp_1, q_norm_nrg_fix, q_env_fix_l);
231
232 if (flag) {
233 temp_1 = ixheaacd_mps_div_32(env_fix_l, *norm_nrg_fix, &qtemp1);
234 q_env = q_env_fix_l + qtemp1 - *q_norm_nrg_fix;
235 env[ts] = ixheaacd_mps_sqrt(temp_1, &(q_env), sqrt_tab);
236 env[ts] = ixheaacd_mps_convert_to_qn(env[ts], q_env, 15);
237 }
238
239 p_buffer_real += MAX_HYBRID_BANDS;
240 p_buffer_imag += MAX_HYBRID_BANDS;
241
242 p_hyb_out_dry_real += MAX_HYBRID_BANDS;
243 p_hyb_out_dry_imag += MAX_HYBRID_BANDS;
244 }
245 reshape_bb_env_state->frame_nrg_prev[ch] = frame_nrg_prev;
246 reshape_bb_env_state->q_frame_nrg_prev[ch] = q_frame_nrg_prev;
247
248 break;
249 case INP_DMX:
250 prev_ch_offs = ch + pstr_mps_state->num_output_channels;
251
252 frame_nrg_prev = reshape_bb_env_state->frame_nrg_prev[prev_ch_offs];
253 q_frame_nrg_prev = reshape_bb_env_state->q_frame_nrg_prev[prev_ch_offs];
254
255 part_nrg_fix = &reshape_bb_env_state->part_nrg_prev[prev_ch_offs][0];
256 q_part_nrg_fix = &reshape_bb_env_state->q_part_nrg_prev[prev_ch_offs][0];
257
258 norm_nrg_fix = &reshape_bb_env_state->norm_nrg_prev[prev_ch_offs];
259 q_norm_nrg_fix = &reshape_bb_env_state->q_norm_nrg_prev[prev_ch_offs];
260
261 p_buffer_real = pstr_mps_state->array_struct->x_real + ch * TSXHB + 12;
262 p_buffer_imag = pstr_mps_state->array_struct->x_imag + ch * TSXHB + 12;
263 for (ts = 0; ts < time_slots; ts++) {
264 WORD32 prev_idx;
265
266 slot_nrg = slot_nrg_fix + 4;
267 for (pb = 14; pb <= end_p; pb++) *slot_nrg++ = 0;
268
269 slot_nrg = slot_nrg_fix;
270
271 hyb_output_real_dry = p_buffer_real;
272 hyb_output_imag_dry = p_buffer_imag;
273
274 for (qs = 12; qs < 16; qs++) {
275 *slot_nrg++ = ((WORD64)(*hyb_output_real_dry) * (WORD64)(*hyb_output_real_dry)) +
276 ((WORD64)(*hyb_output_imag_dry) * (WORD64)(*hyb_output_imag_dry));
277
278 hyb_output_real_dry++;
279 hyb_output_imag_dry++;
280 }
281 prev_idx = 14;
282 for (; qs < 30; qs++) {
283 WORD32 idx = bb_env_kernels[qs];
284 if (prev_idx != idx) {
285 slot_nrg++;
286 prev_idx = idx;
287 }
288
289 *slot_nrg += ((WORD64)(*hyb_output_real_dry) * (WORD64)(*hyb_output_real_dry)) +
290 ((WORD64)(*hyb_output_imag_dry) * (WORD64)(*hyb_output_imag_dry));
291
292 hyb_output_real_dry++;
293 hyb_output_imag_dry++;
294 }
295 slot_nrg++;
296 for (; qs < cnt; qs++) {
297 *slot_nrg += ((WORD64)(*hyb_output_real_dry) * (WORD64)(*hyb_output_real_dry)) +
298 ((WORD64)(*hyb_output_imag_dry) * (WORD64)(*hyb_output_imag_dry));
299
300 hyb_output_real_dry++;
301 hyb_output_imag_dry++;
302 }
303
304 slot_nrg = slot_nrg_fix;
305 q_slot_nrg = q_slot_nrg_fix;
306
307 frame_nrg_fix = 0;
308 q_frame_nrg_fix = 30;
309 for (pb = start_p; pb <= end_p; pb++) {
310 *n_slot_nrg = ixheaacd_mps_narrow(*slot_nrg, q_slot_nrg);
311 slot_nrg++;
312 temp_1 = ixheaac_mult32x16in32(*n_slot_nrg, one_min_alpha_fix);
313 temp4 = ixheaac_mult32x16in32((part_nrg_fix[pb]) << 1, alpha_fix);
314 part_nrg_fix[pb] =
315 ixheaacd_mps_reshape_add32(temp4, temp_1, &q_part_nrg_fix[pb], *q_slot_nrg);
316 frame_nrg_fix = ixheaacd_mps_reshape_add32(frame_nrg_fix, *n_slot_nrg++,
317 &q_frame_nrg_fix, *q_slot_nrg++);
318 }
319
320 frame_nrg_fix = ixheaac_mult32x16in32(frame_nrg_fix, one_by_nine);
321
322 temp_1 = ixheaac_mult32x16in32(frame_nrg_fix, one_min_alpha_fix);
323 temp4 = ixheaac_mult32x16in32((frame_nrg_prev) << 1, alpha_fix);
324 frame_nrg_fix =
325 ixheaacd_mps_reshape_add32(temp_1, temp4, &q_frame_nrg_fix, q_frame_nrg_prev);
326
327 frame_nrg_prev = frame_nrg_fix;
328 q_frame_nrg_prev = q_frame_nrg_fix;
329
330 env_fix_l = 0;
331 q_env_fix_l = 30;
332
333 q_slot_nrg = q_slot_nrg_fix;
334 n_slot_nrg -= PB_OFFSET;
335 for (pb = start_p; pb <= end_p; pb++) {
336 temp_1 = ixheaacd_mps_div_32(*n_slot_nrg++, part_nrg_fix[pb], &qtemp1);
337 qtemp1 = *q_slot_nrg++ + qtemp1 - q_part_nrg_fix[pb];
338 env_fix_l = ixheaacd_mps_reshape_add32(env_fix_l, temp_1, &q_env_fix_l, qtemp1);
339 }
340 n_slot_nrg -= PB_OFFSET;
341
342 env_fix_l =
343 ixheaacd_mps_mult32x32(env_fix_l, frame_nrg_fix, &q_env_fix_l, q_frame_nrg_fix);
344
345 temp_1 = ixheaac_mult32x16in32(env_fix_l, one_min_beta_fix);
346 temp4 = ixheaac_mult32x16in32((*norm_nrg_fix) << 1, beta_fix);
347 *norm_nrg_fix = ixheaacd_mps_reshape_add32(temp4, temp_1, q_norm_nrg_fix, q_env_fix_l);
348
349 temp_1 = ixheaacd_mps_div_32(env_fix_l, *norm_nrg_fix, &qtemp1);
350 q_env = q_env_fix_l + qtemp1 - *q_norm_nrg_fix;
351 env[ts] = ixheaacd_mps_sqrt(temp_1, &(q_env), sqrt_tab);
352 env[ts] = ixheaacd_mps_convert_to_qn(env[ts], q_env, 15);
353
354 p_buffer_real += MAX_HYBRID_BANDS;
355 p_buffer_imag += MAX_HYBRID_BANDS;
356 }
357 reshape_bb_env_state->frame_nrg_prev[prev_ch_offs] = frame_nrg_prev;
358 reshape_bb_env_state->q_frame_nrg_prev[prev_ch_offs] = q_frame_nrg_prev;
359
360 break;
361 default:
362 break;
363 }
364 return;
365 }
366
ixheaacd_reshape_bb_env(ia_heaac_mps_state_struct * pstr_mps_state)367 VOID ixheaacd_reshape_bb_env(ia_heaac_mps_state_struct *pstr_mps_state) {
368 WORD32 *env_dry;
369 WORD32 *env_dmx_0, *env_dmx_1;
370
371 WORD32 *p_buffer_real, *p_buffer_imag, *p_buffer_re, *p_buffer_im;
372 WORD32 *hyb_output_real_wet, *hyb_output_imag_wet;
373
374 WORD32 temp_1, temp_2;
375 WORD16 qtemp1, qtemp2;
376 WORD32 tmp, dry_fac, slot_amp_dry, slot_amp_wet;
377 WORD16 q_dry_fac, q_slot_amp_dry, q_slot_amp_wet;
378
379 WORD32 slot_amp_ratio;
380 WORD16 q_slot_amp_ratio;
381 WORD32 ch, ch2, ts, qs;
382 WORD32 *hyb_output_real_dry, *hyb_out_dry_real;
383 WORD32 *hyb_output_imag_dry, *hyb_out_dry_imag;
384 WORD64 *inter;
385
386 VOID *free_scratch;
387 const WORD32 *sqrt_tab = pstr_mps_state->ia_mps_dec_mps_table.common_table_ptr->sqrt_tab;
388 ia_mps_dec_auxilary_struct *p_aux_struct = pstr_mps_state->aux_struct;
389 WORD32 *temp_shape_enable_channel_ges = p_aux_struct->temp_shape_enable_channel_ges;
390
391 WORD32 start_hsb;
392 WORD32 time_slots = pstr_mps_state->time_slots;
393 WORD32 num_output_channels = pstr_mps_state->num_output_channels;
394 WORD32 tree_config = pstr_mps_state->tree_config;
395 WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
396
397 const WORD32 *ch_idx = &pstr_mps_state->ia_mps_dec_mps_table.m1_m2_table_ptr->idx_table
398 .row_2_channel_ges[tree_config][0];
399 WORD64 acc, acc2;
400 start_hsb = 6;
401
402 free_scratch = pstr_mps_state->mps_scratch_mem_v;
403 env_dry = free_scratch;
404 env_dmx_0 = pstr_mps_state->array_struct->env_dmx_0;
405 env_dmx_1 = pstr_mps_state->array_struct->env_dmx_1;
406 inter = (WORD64 *)((WORD8 *)free_scratch +
407 IXHEAAC_GET_SIZE_ALIGNED(MAX_TIME_SLOTSX12, BYTE_ALIGN_8));
408 free_scratch =
409 inter + IXHEAAC_GET_SIZE_ALIGNED_TYPE(MAX_TIME_SLOTS, sizeof(*inter), BYTE_ALIGN_8);
410
411 p_buffer_real = pstr_mps_state->array_struct->buf_real + start_hsb;
412 p_buffer_imag = pstr_mps_state->array_struct->buf_imag + start_hsb;
413
414 for (ch = 0; ch < num_output_channels; ch++) {
415 ch2 = ch_idx[ch];
416
417 if (ch2 == -1) continue;
418
419 p_buffer_re = p_buffer_real;
420 p_buffer_im = p_buffer_imag;
421
422 ixheaacd_extract_bb_env(pstr_mps_state, INP_DRY_WET, ch, env_dry, free_scratch,
423 temp_shape_enable_channel_ges[ch2]);
424
425 if (temp_shape_enable_channel_ges[ch2]) {
426 WORD32 *env = &p_aux_struct->env_shape_data[ch2][0];
427 switch (tree_config) {
428 case TREE_5151:
429 case TREE_5152:
430 for (ts = 0; ts < time_slots; ts++) {
431 inter[ts] = (WORD64)((WORD64)*env++ * (WORD64)env_dmx_0[ts]);
432 }
433 break;
434
435 case TREE_525:
436 case TREE_7271:
437 case TREE_7272:
438
439 switch (ch2) {
440 case 0:
441 case 3:
442 case 5:
443
444 for (ts = 0; ts < time_slots; ts++) {
445 inter[ts] = (WORD64)((WORD64)*env++ * (WORD64)env_dmx_0[ts]);
446 }
447 break;
448 case 1:
449 case 4:
450 case 6:
451
452 for (ts = 0; ts < time_slots; ts++) {
453 inter[ts] = (WORD64)((WORD64)*env++ * (WORD64)env_dmx_1[ts]);
454 }
455 break;
456 case 2:
457
458 for (ts = 0; ts < time_slots; ts++) {
459 temp_2 = (env_dmx_0[ts] + env_dmx_1[ts]) >> 1;
460 inter[ts] = (WORD64)((WORD64)*env++ * (WORD64)temp_2);
461 }
462 break;
463 default:
464 break;
465 }
466 break;
467
468 case TREE_7571:
469 case TREE_7572:
470 switch (ch2) {
471 case 0:
472 case 2:
473 for (ts = 0; ts < time_slots; ts++) {
474 inter[ts] = (WORD64)((WORD64)*env++ * (WORD64)env_dmx_0[ts]);
475 }
476
477 break;
478 case 1:
479 case 3:
480 for (ts = 0; ts < time_slots; ts++) {
481 inter[ts] = (WORD64)((WORD64)*env++ * (WORD64)env_dmx_1[ts]);
482 }
483 break;
484 default:
485 break;
486 }
487 default:
488 break;
489 }
490
491 hyb_out_dry_real =
492 pstr_mps_state->array_struct->hyb_output_real_dry + ch * TSXHB + start_hsb;
493 hyb_out_dry_imag =
494 pstr_mps_state->array_struct->hyb_output_imag_dry + ch * TSXHB + start_hsb;
495
496 for (ts = 0; ts < time_slots; ts++) {
497 tmp = ixheaacd_mps_narrow(inter[ts], &qtemp1);
498
499 if (env_dry[ts] == 0) {
500 q_dry_fac = 0;
501 dry_fac = MAX_32;
502 } else {
503 dry_fac = ixheaacd_mps_div_32(tmp, env_dry[ts], &q_dry_fac);
504 q_dry_fac += qtemp1 - 5;
505 }
506
507 hyb_output_real_wet = p_buffer_re;
508 hyb_output_imag_wet = p_buffer_im;
509
510 hyb_output_real_dry = hyb_out_dry_real;
511 hyb_output_imag_dry = hyb_out_dry_imag;
512 acc = 0;
513 acc2 = 0;
514
515 for (qs = start_hsb; qs < hybrid_bands; qs++) {
516 acc += (WORD64)(*hyb_output_real_dry) * (WORD64)(*hyb_output_real_dry);
517 hyb_output_real_dry++;
518 acc += (WORD64)(*hyb_output_imag_dry) * (WORD64)(*hyb_output_imag_dry);
519 hyb_output_imag_dry++;
520
521 acc2 += (WORD64)(*hyb_output_real_wet) * (WORD64)(*hyb_output_real_wet);
522 hyb_output_real_wet++;
523 acc2 += (WORD64)(*hyb_output_imag_wet) * (WORD64)(*hyb_output_imag_wet);
524 hyb_output_imag_wet++;
525 }
526 slot_amp_dry = ixheaacd_mps_narrow(acc, &q_slot_amp_dry);
527 slot_amp_wet = ixheaacd_mps_narrow(acc2, &q_slot_amp_wet);
528
529 qtemp1 = q_slot_amp_dry;
530
531 temp_1 = ixheaacd_mps_add32(slot_amp_dry, ABS_THR_FIX, &qtemp1, 15);
532 temp_2 = ixheaacd_mps_div_32(slot_amp_wet, temp_1, &qtemp2);
533 q_slot_amp_ratio = qtemp2 + q_slot_amp_wet - qtemp1;
534 slot_amp_ratio = ixheaacd_mps_sqrt(temp_2, &q_slot_amp_ratio, sqrt_tab);
535
536 temp_1 = ixheaacd_mps_convert_to_qn(dry_fac, q_dry_fac, 15);
537 temp_1 -= ONE_IN_Q15;
538 temp_1 = ixheaacd_mps_mult32_shr_16(temp_1, slot_amp_ratio);
539 q_slot_amp_ratio -= 1;
540
541 temp_1 = ixheaacd_mps_add32(temp_1, dry_fac, &q_slot_amp_ratio, q_dry_fac);
542
543 temp_1 = ixheaacd_mps_convert_to_qn(temp_1, q_slot_amp_ratio, 15);
544 temp_1 = max(ONE_IN_Q13, temp_1);
545 dry_fac = min(FOUR_IN_Q15, temp_1);
546
547 hyb_output_real_dry = hyb_out_dry_real;
548 hyb_output_imag_dry = hyb_out_dry_imag;
549
550 for (qs = start_hsb; qs < hybrid_bands; qs++) {
551 *hyb_output_real_dry = ixheaacd_mps_mult32_shr_15(*hyb_output_real_dry, dry_fac);
552 hyb_output_real_dry++;
553 *hyb_output_imag_dry = ixheaacd_mps_mult32_shr_15(*hyb_output_imag_dry, dry_fac);
554 hyb_output_imag_dry++;
555 }
556 p_buffer_re += MAX_HYBRID_BANDS;
557 p_buffer_im += MAX_HYBRID_BANDS;
558 hyb_out_dry_real += MAX_HYBRID_BANDS;
559 hyb_out_dry_imag += MAX_HYBRID_BANDS;
560 }
561 }
562 p_buffer_real += TSXHB;
563 p_buffer_imag += TSXHB;
564 }
565 return;
566 }
567
ixheaacd_pre_reshape_bb_env(ia_heaac_mps_state_struct * pstr_mps_state)568 VOID ixheaacd_pre_reshape_bb_env(ia_heaac_mps_state_struct *pstr_mps_state) {
569 WORD32 *env_dmx_0, *env_dmx_1;
570
571 VOID *free_scratch;
572
573 WORD32 tree_config = pstr_mps_state->tree_config;
574
575 free_scratch = pstr_mps_state->mps_scratch_mem_v;
576 env_dmx_0 = pstr_mps_state->array_struct->env_dmx_0;
577 env_dmx_1 = pstr_mps_state->array_struct->env_dmx_1;
578
579 switch (tree_config) {
580 case TREE_7572:
581 ixheaacd_extract_bb_env(pstr_mps_state, INP_DMX, 0 + 4, env_dmx_0, free_scratch, 0);
582 ixheaacd_extract_bb_env(pstr_mps_state, INP_DMX, 1 + 4, env_dmx_1, free_scratch, 0);
583 break;
584 default:
585 ixheaacd_extract_bb_env(pstr_mps_state, INP_DMX, 0, env_dmx_0, free_scratch, 0);
586 if (min(pstr_mps_state->num_input_channels, 2) == 2) {
587 ixheaacd_extract_bb_env(pstr_mps_state, INP_DMX, 1, env_dmx_1, free_scratch, 0);
588 }
589 }
590 return;
591 }
592