xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_mps_reshape_bb_env.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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