• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 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 <math.h>
21 #include "ixheaacd_type_def.h"
22 #include "ixheaacd_constants.h"
23 #include "ixheaacd_bitbuffer.h"
24 #include "ixheaacd_common_rom.h"
25 #include "ixheaacd_sbrdecsettings.h"
26 #include "ixheaacd_sbr_scale.h"
27 #include "ixheaacd_env_extr_part.h"
28 #include "ixheaacd_sbr_rom.h"
29 #include "ixheaacd_config.h"
30 #include "ixheaacd_hybrid.h"
31 #include "ixheaacd_ps_dec.h"
32 #include "ixheaacd_qmf_dec.h"
33 #include "ixheaacd_mps_polyphase.h"
34 #include "ixheaacd_mps_struct_def.h"
35 #include "ixheaacd_mps_res_rom.h"
36 #include "ixheaacd_mps_aac_struct.h"
37 #include "ixheaacd_mps_dec.h"
38 #include "ixheaacd_mps_process.h"
39 #include "ixheaacd_lpp_tran.h"
40 #include "ixheaacd_env_extr.h"
41 #include "ixheaacd_env_calc.h"
42 #include "ixheaacd_sbr_const.h"
43 #include "ixheaacd_pvc_dec.h"
44 #include "ixheaacd_sbr_dec.h"
45 #include "ixheaacd_audioobjtypes.h"
46 #include "ixheaacd_basic_ops32.h"
47 #include "ixheaacd_basic_ops40.h"
48 #include "ixheaacd_mps_bitdec.h"
49 #include "ixheaacd_mps_macro_def.h"
50 #include "ixheaacd_mps_get_index.h"
51 #include "ixheaacd_mps_basic_op.h"
52 #include "ixheaacd_mps_tp_process.h"
53 #include "ixheaacd_error_codes.h"
54 #define HP_SIZE (9)
55 
56 #define STP_LPF_COEFF1 (0.950f)
57 #define STP_LPF_COEFF2 (0.450f)
58 #define STP_UPDATE_ENERGY_RATE (32)
59 #define STP_SCALE_LIMIT (2.82f)
60 #define STP_DAMP (0.1f)
61 
62 static const FLOAT32 ixheaacd_bp[BP_SIZE] = {
63   0.0000f, 0.0005f, 0.0092f, 0.0587f, 0.2580f, 0.7392f, 0.9791f,
64   0.9993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9984f,
65   0.9908f, 0.9639f, 0.8952f, 0.7711f, 0.6127f, 0.4609f, 0.3391f,
66   0.2493f, 0.1848f, 0.1387f, 0.1053f};
67 
68 static const FLOAT32 ixheaacd_gf[BP_SIZE] = {
69   0.f,     0.f,     0.f,     0.f,     0.f,
70   0.f,     1e-008f,   8.1e-007f,   3.61e-006f,  8.41e-006f,
71   1.6e-005f,   2.704e-005f, 3.969e-005f, 5.625e-005f, 7.396e-005f,
72   9.801e-005f, 0.00012321f, 0.00015625f, 0.00019881f, 0.00024964f,
73   0.00032041f, 0.00041209f, 0.00053824f, 0.00070756f, 0.00094249f};
74 
75 extern const WORD32 ixheaacd_mps_gain_set_indx[29];
76 
ixheaacd_mps_temp_process_scale_calc(ia_mps_dec_state_struct * self,WORD32 ts,FLOAT32 * scale)77 static VOID ixheaacd_mps_temp_process_scale_calc(ia_mps_dec_state_struct* self,
78                                                  WORD32 ts, FLOAT32* scale) {
79   FLOAT32 dir_energy;
80   FLOAT32 diff_energy[2];
81   FLOAT32 temp;
82 
83   WORD32 ch, n;
84   WORD32 left_ch = 0, right_ch = 1;
85 
86   if (self->subband_var.init_flag == 0) {
87     for (ch = 0; ch < 2; ch++) {
88       self->subband_var.tp_scale_last[ch] = 1.0f;
89       self->subband_var.nrg_diff_prev[ch] = 32768 * 32768;
90     }
91 
92     self->subband_var.nrg_dir_prev = 32768 * 32768;
93     self->subband_var.init_flag = 1;
94   }
95 
96   if (self->subband_var.update_old_ener == STP_UPDATE_ENERGY_RATE) {
97     self->subband_var.update_old_ener = 1;
98     self->subband_var.nrg_dir_prev = self->subband_var.nrg_dir;
99     for (ch = 0; ch < self->out_ch_count; ch++)
100       self->subband_var.nrg_diff_prev[ch] = self->subband_var.nrg_diff[ch];
101   } else
102     self->subband_var.update_old_ener++;
103 
104   dir_energy = 0;
105 
106   for (n = 6; n < BP_SIZE; n++) {
107     FLOAT32 dir_left_re = self->hyb_dir_out[left_ch][ts][n + 7].re;
108     FLOAT32 dir_right_re = self->hyb_dir_out[right_ch][ts][n + 7].re;
109     FLOAT32 dir_left_im = self->hyb_dir_out[left_ch][ts][n + 7].im;
110     FLOAT32 dir_right_im = self->hyb_dir_out[right_ch][ts][n + 7].im;
111 
112     temp = ((dir_left_re + dir_right_re) * (dir_left_re + dir_right_re)) +
113            ((dir_left_im + dir_right_im) * (dir_left_im + dir_right_im));
114     dir_energy += temp * ixheaacd_bp[n] * ixheaacd_bp[n] * ixheaacd_gf[n] *
115                   ixheaacd_gf[n];
116   }
117 
118   self->subband_var.nrg_dir =
119       (FLOAT32)(STP_LPF_COEFF1 * self->subband_var.nrg_dir +
120                 (1.0 - STP_LPF_COEFF1) * dir_energy);
121 
122   dir_energy /= (self->subband_var.nrg_dir_prev + ABS_THR);
123 
124   for (ch = 0; ch < self->out_ch_count; ch++) {
125     diff_energy[ch] = 0;
126     for (n = 6; n < BP_SIZE; n++) {
127       FLOAT32 diff_re = self->hyb_diff_out[ch][ts][n + 7].re;
128       FLOAT32 diff_im = self->hyb_diff_out[ch][ts][n + 7].im;
129 
130       temp = (diff_re * diff_re) + (diff_im * diff_im);
131       diff_energy[ch] += temp * ixheaacd_bp[n] * ixheaacd_bp[n] *
132                          ixheaacd_gf[n] * ixheaacd_gf[n];
133     }
134 
135     self->subband_var.nrg_diff[ch] =
136         (FLOAT32)(STP_LPF_COEFF1 * self->subband_var.nrg_diff[ch] +
137                   (1.0 - STP_LPF_COEFF1) * diff_energy[ch]);
138     diff_energy[ch] /= (self->subband_var.nrg_diff_prev[ch] + ABS_THR);
139   }
140 
141   scale[left_ch] = (FLOAT32)sqrt((dir_energy) / (diff_energy[left_ch] + 1e-9));
142   scale[right_ch] =
143       (FLOAT32)sqrt((dir_energy) / (diff_energy[right_ch] + 1e-9));
144 
145   for (ch = 0; ch < self->out_ch_count; ch++) {
146     scale[ch] = STP_DAMP + (1 - STP_DAMP) * scale[ch];
147   }
148 
149   for (ch = 0; ch < self->out_ch_count; ch++) {
150     scale[ch] =
151         min(max(scale[ch], (FLOAT32)(1.0 / STP_SCALE_LIMIT)), STP_SCALE_LIMIT);
152   }
153 
154   for (ch = 0; ch < self->out_ch_count; ch++) {
155     scale[ch] =
156         (FLOAT32)(STP_LPF_COEFF2 * scale[ch] +
157                   (1.0 - STP_LPF_COEFF2) * self->subband_var.tp_scale_last[ch]);
158     self->subband_var.tp_scale_last[ch] = scale[ch];
159   }
160 }
161 
ixheaacd_mps_subbandtp(ia_mps_dec_state_struct * self,WORD32 ts)162 static VOID ixheaacd_mps_subbandtp(ia_mps_dec_state_struct* self, WORD32 ts) {
163   FLOAT32 scale[2];
164   WORD32 ch, n;
165   WORD32 no_scaling;
166   FLOAT32 temp;
167   const WORD32 ixheaacd_hybrid_to_qmf_map[] = {0, 0, 0, 0, 0, 0, 1, 1, 2, 2};
168   const WORD32 ixheaacd_hybrid_to_qmf_map_ldmps[] = {0, 1, 2};
169   const WORD32* ptr_ixheaacd_hybrid_to_qmf_map;
170   WORD32 loop_counter = 0;
171 
172   if (self->ldmps_config.ldmps_present_flag) {
173     ptr_ixheaacd_hybrid_to_qmf_map = ixheaacd_hybrid_to_qmf_map_ldmps;
174     loop_counter = 3;
175   } else {
176     ptr_ixheaacd_hybrid_to_qmf_map = ixheaacd_hybrid_to_qmf_map;
177     loop_counter = 10;
178   }
179 
180   ixheaacd_mps_temp_process_scale_calc(self, ts, scale);
181 
182   for (ch = 0; ch < self->out_ch_count; ch++) {
183     no_scaling = 1;
184 
185     if ((self->config->bs_temp_shape_config == 1) ||
186         (self->config->bs_temp_shape_config == 2))
187       no_scaling = !self->temp_shape_enable_ch_stp[ch];
188 
189     if (no_scaling == 1) {
190       for (n = 0; n < self->hyb_band_count_max; n++) {
191         self->hyb_dir_out[ch][ts][n].re += self->hyb_diff_out[ch][ts][n].re;
192         self->hyb_dir_out[ch][ts][n].im += self->hyb_diff_out[ch][ts][n].im;
193       }
194     } else {
195       if (self->ldmps_config.ldmps_present_flag) {
196         for (n = 0; n < 3; n++) {
197           temp = (FLOAT32)(scale[ch] *
198                            ixheaacd_bp[ptr_ixheaacd_hybrid_to_qmf_map[n]]);
199           self->hyb_dir_out[ch][ts][n].re +=
200               (self->hyb_diff_out[ch][ts][n].re * temp);
201           self->hyb_dir_out[ch][ts][n].im +=
202               (self->hyb_diff_out[ch][ts][n].im * temp);
203         }
204       } else {
205         for (n = 0; n < loop_counter; n++) {
206           temp = (FLOAT32)(scale[ch] *
207                            ixheaacd_bp[ptr_ixheaacd_hybrid_to_qmf_map[n]]);
208           self->hyb_dir_out[ch][ts][n].re +=
209               (self->hyb_diff_out[ch][ts][n].re * temp);
210           self->hyb_dir_out[ch][ts][n].im +=
211               (self->hyb_diff_out[ch][ts][n].im * temp);
212         }
213       }
214       for (n = 7; n < HP_SIZE - 3 + 10; n++) {
215         temp = (FLOAT32)(scale[ch] * ixheaacd_bp[n + 3 - 10]);
216         self->hyb_dir_out[ch][ts][n].re +=
217             (self->hyb_diff_out[ch][ts][n].re * temp);
218         self->hyb_dir_out[ch][ts][n].im +=
219             (self->hyb_diff_out[ch][ts][n].im * temp);
220       }
221       for (; n < self->hyb_band_count_max; n++) {
222         temp = (FLOAT32)(scale[ch]);
223         self->hyb_dir_out[ch][ts][n].re +=
224             (self->hyb_diff_out[ch][ts][n].re * temp);
225         self->hyb_dir_out[ch][ts][n].im +=
226             (self->hyb_diff_out[ch][ts][n].im * temp);
227       }
228     }
229   }
230 }
231 
ixheaacd_mps_temp_process(ia_mps_dec_state_struct * self)232 WORD32 ixheaacd_mps_temp_process(ia_mps_dec_state_struct* self) {
233   WORD32 ch, ts, hyb;
234   WORD32 err = 0;
235   ia_sbr_frame_info_data_struct* ptr_frame_data =
236       (ia_sbr_frame_info_data_struct*)self->p_sbr_frame[0];
237   if (self->res_bands != 28) {
238     if (self->config->bs_temp_shape_config == 1) {
239       WORD32 dif_s = ((self->res_bands == 0)
240                           ? 0
241                           : ixheaacd_mps_gain_set_indx[self->res_bands]);
242       for (ch = 0; ch < self->out_ch_count; ch++) {
243         for (ts = 0; ts < self->time_slots; ts++) {
244           for (hyb = dif_s; hyb < HYBRID_BAND_BORDER; hyb++) {
245             self->hyb_dir_out[ch][ts][hyb].re +=
246                 self->hyb_diff_out[ch][ts][hyb].re;
247             self->hyb_dir_out[ch][ts][hyb].im +=
248                 self->hyb_diff_out[ch][ts][hyb].im;
249             self->hyb_diff_out[ch][ts][hyb].re = 0;
250             self->hyb_diff_out[ch][ts][hyb].im = 0;
251           }
252         }
253       }
254 
255       for (ts = 0; ts < self->time_slots; ts++)
256         ixheaacd_mps_subbandtp(self, ts);
257 
258     } else {
259       WORD32 dif_s = ((self->res_bands == 0)
260                           ? 0
261                           : ixheaacd_mps_gain_set_indx[self->res_bands]);
262       for (ch = 0; ch < self->out_ch_count; ch++) {
263         for (ts = 0; ts < self->time_slots; ts++) {
264           for (hyb = dif_s; hyb < self->hyb_band_count_max; hyb++) {
265             self->hyb_dir_out[ch][ts][hyb].re +=
266                 self->hyb_diff_out[ch][ts][hyb].re;
267             self->hyb_dir_out[ch][ts][hyb].im +=
268                 self->hyb_diff_out[ch][ts][hyb].im;
269           }
270         }
271       }
272     }
273   }
274 
275   ixheaacd_mps_qmf_hyb_synthesis(self);
276 
277   if (self->ldmps_config.ldmps_present_flag != 1) {
278     for (ch = 0; ch < self->out_ch_count; ch++) {
279       err =
280           ixheaacd_sbr_dec_from_mps(&self->qmf_out_dir[ch][0][0].re, self->p_sbr_dec[ch],
281                                     self->p_sbr_frame[ch], self->p_sbr_header[ch], self->ec_flag);
282       if (err) return err;
283     }
284   }
285 
286   if (self->object_type == AOT_ER_AAC_ELD || self->object_type == AOT_ER_AAC_LD)
287     self->synth_count = self->hyb_band_count[0];
288   else
289   {
290     if (ptr_frame_data->mps_sbr_flag) {
291       self->synth_count =
292         ptr_frame_data->pstr_sbr_header->pstr_freq_band_data->sub_band_end;
293     }
294     else {
295       self->synth_count = self->band_count[0];
296     }
297   }
298 
299   ixheaacd_mps_synt_calc(self);
300   return err;
301 }
302 
ixheaacd_subband_tp(ia_heaac_mps_state_struct * pstr_mps_state,WORD32 ts)303 static VOID ixheaacd_subband_tp(ia_heaac_mps_state_struct *pstr_mps_state, WORD32 ts) {
304   ia_mps_dec_tp_process_tables_struct *tp_process_table_ptr =
305       pstr_mps_state->ia_mps_dec_mps_table.tp_process_table_ptr;
306   const WORD32 *sqrt_tab =
307       pstr_mps_state->ia_mps_dec_mps_table.common_table_ptr->sqrt_tab;
308   ia_mps_dec_subband_tp_params_struct *sub_band_tp =
309       pstr_mps_state->mps_persistent_mem.sub_band_params;
310   ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
311 
312   WORD32 temp_1, temp_2;
313   WORD16 qtemp1, qtemp2;
314   WORD32 *qmf_output_real_dry;
315   WORD32 *qmf_output_imag_dry;
316   WORD32 *qmf_output_real_wet;
317   WORD32 *qmf_output_imag_wet;
318 
319   WORD32 *dmx_real;
320   WORD32 *dmx_imag;
321   WORD32 *dry_ener;
322   WORD32 *wet_ener;
323   WORD16 *q_dry_ener;
324   WORD16 *q_wet_ener;
325 
326   WORD32 *p_buffer_real, *p_buffer_imag, *p_buffer_re, *p_buffer_im;
327   WORD32 *p_buf_real, *p_buf_imag, *p_buf_re, *p_buf_im;
328   WORD32 *scale;
329   WORD16 *q_scale;
330   WORD32 damp, one_minus_damp;
331   WORD32 temp;
332 
333   WORD32 *prev_tp_scale = sub_band_tp->prev_tp_scale;
334 
335   WORD32 *old_wet_ener = sub_band_tp->old_wet_ener;
336   WORD16 *q_old_wet_ener = sub_band_tp->q_old_wet_ener;
337 
338   WORD32 *run_wet_ener = sub_band_tp->run_wet_ener;
339   WORD16 *q_run_wet_ener = sub_band_tp->q_run_wet_ener;
340 
341   WORD32 *old_dry_ener = sub_band_tp->old_dry_ener;
342   WORD16 *q_old_dry_ener = sub_band_tp->q_old_dry_ener;
343 
344   WORD32 *run_dry_ener = sub_band_tp->run_dry_ener;
345   WORD16 *q_run_dry_ener = sub_band_tp->q_run_dry_ener;
346 
347   WORD32 *hyb_output_real_dry, *hyb_output_imag_dry;
348 
349   WORD32 *p_hyb_out_dry_real, *p_hyb_out_dry_imag;
350 
351   WORD32 ch, n, no_scaling, i, k = 0, offset;
352   WORD32 i_lf = 0, i_rf = 0, i_c = 0, i_lfe = 0, i_ls = 0, i_rs = 0, i_al = 0, i_ar = 0;
353 
354   WORD32 loop_counter = 0;
355 
356   WORD32 num_input_channels = pstr_mps_state->num_input_channels;
357   WORD32 num_output_channels = pstr_mps_state->num_output_channels;
358   WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
359 
360   WORD32 tree_config = pstr_mps_state->tree_config;
361 
362   dry_ener = pstr_mps_state->mps_scratch_mem_v;
363   q_dry_ener = (WORD16 *)pstr_mps_state->mps_scratch_mem_v + INPUT_CHX2;
364 
365   wet_ener = dry_ener + INPUT_CHX1_5;
366   q_wet_ener = q_dry_ener + IN_CH_2XOUT_CH;
367 
368   scale = wet_ener + OUTPUT_CHX1_5;
369   q_scale = q_wet_ener + OUTPUT_CHX3;
370 
371   dmx_real = scale + OUTPUT_CHX1_5;
372   dmx_imag = dmx_real + IN_CHXBP_SIZE;
373 
374   qmf_output_real_dry = dmx_imag + IN_CHXBP_SIZE;
375 
376   qmf_output_imag_dry = qmf_output_real_dry + OUT_CHXQB;
377 
378   qmf_output_real_wet = qmf_output_imag_dry + OUT_CHXQB;
379 
380   qmf_output_imag_wet = qmf_output_real_wet + OUT_CHXQB;
381 
382   if (sub_band_tp->update_old_ener == STP_UPDATE_ENERGY_RATE) {
383     sub_band_tp->update_old_ener = 1;
384     for (ch = 0; ch < num_input_channels; ch++) {
385       old_dry_ener[ch] = run_dry_ener[ch];
386       q_old_dry_ener[ch] = q_run_dry_ener[ch];
387     }
388     for (ch = 0; ch < num_output_channels; ch++) {
389       old_wet_ener[ch] = run_wet_ener[ch];
390       q_old_wet_ener[ch] = q_run_wet_ener[ch];
391     }
392   } else
393     sub_band_tp->update_old_ener++;
394 
395   for (ch = 0; ch < MAX_OUTPUT_CHANNELS_MPS; ch++) {
396     scale[ch] = ONE_IN_Q15;
397     q_scale[ch] = 15;
398   }
399 
400   switch (tree_config) {
401     case TREE_5151:
402       i_lf = 0;
403       i_rf = 1;
404       i_c = 2;
405       i_lfe = 3;
406       i_ls = 4;
407       i_rs = 5;
408       loop_counter = 6;
409       break;
410     case TREE_5152:
411       i_lf = 0;
412       i_rf = 2;
413       i_c = 4;
414       i_lfe = 5;
415       i_ls = 1;
416       i_rs = 3;
417       loop_counter = 5;
418       break;
419     case TREE_525:
420       i_lf = 0;
421       i_rf = 2;
422       i_c = 4;
423       i_lfe = 5;
424       i_ls = 1;
425       i_rs = 3;
426       loop_counter = 4;
427       break;
428     case TREE_7271:
429     case TREE_7272:
430     case TREE_7572:
431       i_lf = 0;
432       i_rf = 3;
433       i_c = 6;
434       i_lfe = 7;
435       i_ls = 2;
436       i_rs = 5;
437       i_al = 1;
438       i_ar = 4;
439       loop_counter = 6;
440       break;
441     case TREE_7571:
442       i_lf = 0;
443       i_rf = 3;
444       i_c = 6;
445       i_lfe = 7;
446       i_ls = 2;
447       i_rs = 5;
448       i_al = 1;
449       i_ar = 4;
450       loop_counter = 5;
451       break;
452     default:
453       break;
454   }
455 
456   offset = ts * MAX_HYBRID_BANDS;
457   p_buffer_real = p_array_struct->buf_real + offset + HYBRID_BAND_BORDER;
458   p_buffer_imag = p_array_struct->buf_imag + offset + HYBRID_BAND_BORDER;
459 
460   for (ch = 0; ch < num_output_channels; ch++) {
461     p_buffer_re = p_buffer_real;
462     p_buffer_im = p_buffer_imag;
463 
464     for (i = QMF_OUT_START_IDX; i < BP_SIZE; i++) {
465       *qmf_output_real_wet++ = *p_buffer_re++;
466       *qmf_output_imag_wet++ = *p_buffer_im++;
467     }
468     p_buffer_real += TSXHB;
469     p_buffer_imag += TSXHB;
470   }
471   i = QMF_OUT_OFFSET * num_output_channels;
472   qmf_output_real_wet -= i;
473   qmf_output_imag_wet -= i;
474 
475   p_buffer_re = qmf_output_real_dry;
476   p_buffer_im = qmf_output_imag_dry;
477 
478   hyb_output_real_dry =
479       p_array_struct->hyb_output_real_dry + ts * MAX_HYBRID_BANDS + 6;
480   hyb_output_imag_dry =
481       p_array_struct->hyb_output_imag_dry + ts * MAX_HYBRID_BANDS + 6;
482 
483   for (ch = 0; ch < loop_counter; ch++) {
484     *p_buffer_re++ = hyb_output_real_dry[0] + hyb_output_real_dry[1];
485     *p_buffer_im++ = hyb_output_imag_dry[0] + hyb_output_imag_dry[1];
486 
487     hyb_output_real_dry += TSXHB;
488     hyb_output_imag_dry += TSXHB;
489   }
490 
491   hyb_output_real_dry =
492       p_array_struct->hyb_output_real_dry + ts * MAX_HYBRID_BANDS + 8;
493   hyb_output_imag_dry =
494       p_array_struct->hyb_output_imag_dry + ts * MAX_HYBRID_BANDS + 8;
495 
496   for (ch = 0; ch < loop_counter; ch++) {
497     *p_buffer_re++ = hyb_output_real_dry[0] + hyb_output_real_dry[1];
498     *p_buffer_im++ = hyb_output_imag_dry[0] + hyb_output_imag_dry[1];
499 
500     hyb_output_real_dry += TSXHB;
501     hyb_output_imag_dry += TSXHB;
502   }
503 
504   p_hyb_out_dry_real =
505       p_array_struct->hyb_output_real_dry + ts * MAX_HYBRID_BANDS + 10;
506   p_hyb_out_dry_imag =
507       p_array_struct->hyb_output_imag_dry + ts * MAX_HYBRID_BANDS + 10;
508 
509   for (i = 3; i < BP_SIZE; i++) {
510     hyb_output_real_dry = p_hyb_out_dry_real;
511     hyb_output_imag_dry = p_hyb_out_dry_imag;
512 
513     for (ch = 0; ch < loop_counter; ch++) {
514       *p_buffer_re++ = *hyb_output_real_dry;
515       *p_buffer_im++ = *hyb_output_imag_dry;
516 
517       hyb_output_real_dry += TSXHB;
518       hyb_output_imag_dry += TSXHB;
519     }
520     p_hyb_out_dry_real++;
521     p_hyb_out_dry_imag++;
522   }
523 
524   for (n = 1; n < BP_SIZE; n++) {
525     switch (tree_config) {
526       case TREE_5151:
527         *dmx_real = *qmf_output_real_dry++;
528         *dmx_real += *qmf_output_real_dry++;
529         *dmx_real += *qmf_output_real_dry++;
530         qmf_output_real_dry++;
531         *dmx_real += *qmf_output_real_dry++;
532         *dmx_real += *qmf_output_real_dry++;
533 
534         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
535                                                tp_process_table_ptr->bpxgf[n]);
536         dmx_real++;
537         dmx_real++;
538 
539         break;
540       case TREE_5152:
541         *dmx_real = *qmf_output_real_dry++;
542         *dmx_real += *qmf_output_real_dry++;
543         *dmx_real += *qmf_output_real_dry++;
544         *dmx_real += *qmf_output_real_dry++;
545         *dmx_real += *qmf_output_real_dry++;
546 
547         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
548                                                tp_process_table_ptr->bpxgf[n]);
549         dmx_real++;
550         dmx_real++;
551 
552         break;
553       case TREE_525:
554         *dmx_real = *qmf_output_real_dry++;
555         *dmx_real += *qmf_output_real_dry++;
556         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
557                                                tp_process_table_ptr->bpxgf[n]);
558         dmx_real++;
559 
560         *dmx_real = *qmf_output_real_dry++;
561         *dmx_real += *qmf_output_real_dry++;
562         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
563                                                tp_process_table_ptr->bpxgf[n]);
564         dmx_real++;
565 
566         break;
567       case TREE_7271:
568       case TREE_7272:
569         *dmx_real = *qmf_output_real_dry++;
570         *dmx_real += *qmf_output_real_dry++;
571         *dmx_real += *qmf_output_real_dry++;
572 
573         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
574                                                tp_process_table_ptr->bpxgf[n]);
575         dmx_real++;
576 
577         *dmx_real = *qmf_output_real_dry++;
578         *dmx_real += *qmf_output_real_dry++;
579         *dmx_real += *qmf_output_real_dry++;
580 
581         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
582                                                tp_process_table_ptr->bpxgf[n]);
583         dmx_real++;
584 
585         break;
586       case TREE_7571:
587 
588         *dmx_real = *qmf_output_real_dry++;
589         *dmx_real += *qmf_output_real_dry++;
590 
591         qmf_output_real_dry++;
592 
593         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
594                                                tp_process_table_ptr->bpxgf[n]);
595         dmx_real++;
596 
597         *dmx_real = *qmf_output_real_dry++;
598         *dmx_real += *qmf_output_real_dry++;
599 
600         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
601                                                tp_process_table_ptr->bpxgf[n]);
602         dmx_real++;
603 
604         break;
605       case TREE_7572:
606         qmf_output_real_dry++;
607         *dmx_real = *qmf_output_real_dry++;
608         *dmx_real += *qmf_output_real_dry++;
609 
610         qmf_output_real_dry++;
611         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
612                                                tp_process_table_ptr->bpxgf[n]);
613         dmx_real++;
614 
615         *dmx_real = *qmf_output_real_dry++;
616         *dmx_real += *qmf_output_real_dry++;
617 
618         *dmx_real = ixheaacd_mps_mult32_shr_30(*dmx_real,
619                                                tp_process_table_ptr->bpxgf[n]);
620         dmx_real++;
621 
622         break;
623       default:
624         break;
625     }
626   }
627   dmx_real -= DMX_OFFSET;
628 
629   for (n = 1; n < BP_SIZE; n++) {
630     switch (tree_config) {
631       case TREE_5151:
632         *dmx_imag = *qmf_output_imag_dry++;
633         *dmx_imag += *qmf_output_imag_dry++;
634         *dmx_imag += *qmf_output_imag_dry++;
635 
636         qmf_output_imag_dry++;
637 
638         *dmx_imag += *qmf_output_imag_dry++;
639         *dmx_imag++ += *qmf_output_imag_dry++;
640 
641         dmx_imag++;
642 
643         dmx_imag[0] = ixheaacd_mps_mult32_shr_30(
644             dmx_imag[0], tp_process_table_ptr->bpxgf[n]);
645         break;
646       case TREE_5152:
647 
648         *dmx_imag = *qmf_output_imag_dry++;
649         *dmx_imag += *qmf_output_imag_dry++;
650         *dmx_imag += *qmf_output_imag_dry++;
651 
652         *dmx_imag += *qmf_output_imag_dry++;
653         *dmx_imag++ += *qmf_output_imag_dry++;
654 
655         dmx_imag++;
656 
657         dmx_imag[0] = ixheaacd_mps_mult32_shr_30(
658             dmx_imag[0], tp_process_table_ptr->bpxgf[n]);
659         break;
660       case TREE_525:
661         *dmx_imag = *qmf_output_imag_dry++;
662         *dmx_imag += *qmf_output_imag_dry++;
663         *dmx_imag = ixheaacd_mps_mult32_shr_30(dmx_imag[0],
664                                                tp_process_table_ptr->bpxgf[n]);
665         dmx_imag++;
666 
667         *dmx_imag = *qmf_output_imag_dry++;
668         *dmx_imag += *qmf_output_imag_dry++;
669         *dmx_imag = ixheaacd_mps_mult32_shr_30(*dmx_imag,
670                                                tp_process_table_ptr->bpxgf[n]);
671         dmx_imag++;
672         break;
673       case TREE_7271:
674       case TREE_7272:
675         *dmx_imag = *qmf_output_imag_dry++;
676         *dmx_imag += *qmf_output_imag_dry++;
677         *dmx_imag += *qmf_output_imag_dry++;
678         *dmx_imag = ixheaacd_mps_mult32_shr_30(*dmx_imag,
679                                                tp_process_table_ptr->bpxgf[n]);
680         dmx_imag++;
681 
682         *dmx_imag = *qmf_output_imag_dry++;
683         *dmx_imag += *qmf_output_imag_dry++;
684         *dmx_imag += *qmf_output_imag_dry++;
685 
686         *dmx_imag = ixheaacd_mps_mult32_shr_30(*dmx_imag,
687                                                tp_process_table_ptr->bpxgf[n]);
688         dmx_imag++;
689 
690         break;
691       case TREE_7571:
692         *dmx_imag = *qmf_output_imag_dry++;
693         *dmx_imag += *qmf_output_imag_dry++;
694         qmf_output_imag_dry++;
695         *dmx_imag = ixheaacd_mps_mult32_shr_30(*dmx_imag,
696                                                tp_process_table_ptr->bpxgf[n]);
697         dmx_imag++;
698 
699         *dmx_imag = *qmf_output_imag_dry++;
700         *dmx_imag += *qmf_output_imag_dry++;
701         *dmx_imag = ixheaacd_mps_mult32_shr_30(*dmx_imag,
702                                                tp_process_table_ptr->bpxgf[n]);
703         dmx_imag++;
704 
705         break;
706       case TREE_7572:
707         qmf_output_imag_dry++;
708 
709         *dmx_imag = *qmf_output_imag_dry++;
710         *dmx_imag += *qmf_output_imag_dry++;
711 
712         qmf_output_imag_dry++;
713 
714         *dmx_imag = ixheaacd_mps_mult32_shr_30(*dmx_imag,
715                                                tp_process_table_ptr->bpxgf[n]);
716         dmx_imag++;
717 
718         *dmx_imag = *qmf_output_imag_dry++;
719         *dmx_imag += *qmf_output_imag_dry++;
720         *dmx_imag = ixheaacd_mps_mult32_shr_30(*dmx_imag,
721                                                tp_process_table_ptr->bpxgf[n]);
722         dmx_imag++;
723 
724         break;
725       default:
726         break;
727     }
728   }
729   dmx_imag -= DMX_OFFSET;
730 
731   for (ch = 0; ch < min(2, num_input_channels); ch++) {
732     dry_ener[ch] = 0;
733     q_dry_ener[ch] = 15;
734 
735     for (n = 1; n < BP_SIZE; n++) {
736       qtemp1 = 10;
737       temp_1 = ixheaacd_mps_mult32(*dmx_real, *dmx_real, &qtemp1, qtemp1);
738       dmx_real += 2;
739       dry_ener[ch] =
740           ixheaacd_mps_add32(dry_ener[ch], temp_1, &q_dry_ener[ch], qtemp1);
741 
742       qtemp1 = 10;
743       temp_1 = ixheaacd_mps_mult32(*dmx_imag, *dmx_imag, &qtemp1, qtemp1);
744       dmx_imag += 2;
745       dry_ener[ch] =
746           ixheaacd_mps_add32(dry_ener[ch], temp_1, &q_dry_ener[ch], qtemp1);
747     }
748     dmx_real -= DMX_OFFSET_MINUS_ONE;
749     dmx_imag -= DMX_OFFSET_MINUS_ONE;
750 
751     temp_1 = ixheaacd_mps_mult32_shr_15(run_dry_ener[ch], STP_LPF_COEFF1_FIX);
752 
753     temp_2 = ONE_IN_Q15 - STP_LPF_COEFF1_FIX;
754     temp_2 = ixheaacd_mps_mult32_shr_15(temp_2, dry_ener[ch]);
755 
756     run_dry_ener[ch] = ixheaacd_mps_add32(temp_1, temp_2, &(q_run_dry_ener[ch]),
757                                           q_dry_ener[ch]);
758 
759     qtemp1 = q_old_dry_ener[ch];
760     temp_1 = ixheaacd_mps_add32(old_dry_ener[ch], ABS_THR_FIX, &qtemp1, 15);
761     ;
762 
763     dry_ener[ch] = ixheaacd_mps_div_32(dry_ener[ch], temp_1, &qtemp2);
764     q_dry_ener[ch] = qtemp2 + q_dry_ener[ch] - qtemp1;
765   }
766 
767   for (ch = 0; ch < num_output_channels; ch++) {
768     if (ch == i_lfe) continue;
769     if ((tree_config >= TREE_525) && (ch == i_c)) continue;
770     if ((tree_config == TREE_7571) && ((ch == i_ls) || (ch == i_rs))) continue;
771     if ((tree_config == TREE_7572) && ((ch == i_lf) || (ch == i_rf))) continue;
772 
773     wet_ener[ch] = 0;
774     q_wet_ener[ch] = 15;
775 
776     wet_ener[ch] = 0;
777     q_wet_ener[ch] = 15;
778     for (n = FIVE; n < BP_SIZE; n++) {
779       qtemp1 = 10;
780       temp_1 = ixheaacd_mps_mult32(*qmf_output_real_wet, *qmf_output_real_wet,
781                                    &qtemp1, qtemp1);
782       qmf_output_real_wet++;
783 
784       qtemp2 = 10;
785       temp_2 = ixheaacd_mps_mult32(*qmf_output_imag_wet, *qmf_output_imag_wet,
786                                    &qtemp2, qtemp2);
787       qmf_output_imag_wet++;
788 
789       temp_1 = ixheaacd_mps_add32(temp_1, temp_2, &qtemp1, qtemp2);
790 
791       temp_1 = ixheaacd_mps_mult32(temp_1, tp_process_table_ptr->bp2xgf2[n],
792                                    &qtemp1, 57);
793 
794       wet_ener[ch] =
795           ixheaacd_mps_add32(wet_ener[ch], temp_1, &q_wet_ener[ch], qtemp1);
796     }
797     temp_1 = ixheaacd_mps_mult32_shr_15(run_wet_ener[ch], STP_LPF_COEFF1_FIX);
798 
799     temp_2 = ONE_IN_Q15 - STP_LPF_COEFF1_FIX;
800 
801     temp_2 = ixheaacd_mps_mult32_shr_15(temp_2, wet_ener[ch]);
802 
803     run_wet_ener[ch] =
804         ixheaacd_mps_add32(temp_1, temp_2, &q_run_wet_ener[ch], q_wet_ener[ch]);
805 
806     qtemp1 = q_old_wet_ener[ch];
807     temp_1 = ixheaacd_mps_add32(old_wet_ener[ch], ABS_THR_FIX, &qtemp1, 15);
808 
809     wet_ener[ch] = ixheaacd_mps_div_32(wet_ener[ch], temp_1, &qtemp2);
810     q_wet_ener[ch] = qtemp2 + q_wet_ener[ch] - qtemp1;
811   }
812 
813   damp = POINT_ONE_Q15;
814   one_minus_damp = POINT_NINE_Q15;
815   switch (tree_config) {
816     case TREE_5151:
817     case TREE_5152:
818       if (wet_ener[i_lf] != 0) {
819         scale[i_lf] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_lf], &qtemp2);
820         q_scale[i_lf] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_lf];
821       } else {
822         temp_1 = ixheaacd_norm32(dry_ener[0]);
823         scale[i_lf] = dry_ener[0] << temp_1;
824         q_scale[i_lf] = q_dry_ener[0] + temp_1 - 30;
825       }
826       scale[i_lf] = ixheaacd_mps_sqrt(scale[i_lf], &(q_scale[i_lf]), sqrt_tab);
827 
828       if (wet_ener[i_rf] != 0) {
829         scale[i_rf] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_rf], &qtemp2);
830         q_scale[i_rf] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_rf];
831       } else {
832         temp_1 = ixheaacd_norm32(dry_ener[0]);
833         scale[i_rf] = dry_ener[0] << temp_1;
834         q_scale[i_rf] = q_dry_ener[0] + temp_1 - 30;
835       }
836       scale[i_rf] = ixheaacd_mps_sqrt(scale[i_rf], &(q_scale[i_rf]), sqrt_tab);
837 
838       if (wet_ener[i_c] != 0) {
839         scale[i_c] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_c], &qtemp2);
840         q_scale[i_c] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_c];
841       } else {
842         temp_1 = ixheaacd_norm32(dry_ener[0]);
843         scale[i_c] = dry_ener[0] << temp_1;
844         q_scale[i_c] = q_dry_ener[0] + temp_1 - 30;
845       }
846       scale[i_c] = ixheaacd_mps_sqrt(scale[i_c], &(q_scale[i_c]), sqrt_tab);
847 
848       if (wet_ener[i_ls] != 0) {
849         scale[i_ls] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_ls], &qtemp2);
850         q_scale[i_ls] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_ls];
851       } else {
852         temp_1 = ixheaacd_norm32(dry_ener[0]);
853         scale[i_ls] = dry_ener[0] << temp_1;
854         q_scale[i_ls] = q_dry_ener[0] + temp_1 - 30;
855       }
856       scale[i_ls] = ixheaacd_mps_sqrt(scale[i_ls], &(q_scale[i_ls]), sqrt_tab);
857 
858       if (wet_ener[i_rs] != 0) {
859         scale[i_rs] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_rs], &qtemp2);
860         q_scale[i_rs] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_rs];
861       } else {
862         temp_1 = ixheaacd_norm32(dry_ener[0]);
863         scale[i_rs] = dry_ener[0] << temp_1;
864         q_scale[i_rs] = q_dry_ener[0] + temp_1 - 30;
865       }
866       scale[i_rs] = ixheaacd_mps_sqrt(scale[i_rs], &(q_scale[i_rs]), sqrt_tab);
867 
868       for (ch = 0; ch < 6; ch++) {
869         if (ch == 3 && tree_config == 0) continue;
870         temp_1 = ixheaacd_mps_mult32_shr_15(scale[ch], one_minus_damp);
871         scale[ch] = ixheaacd_mps_add32(temp_1, damp, &(q_scale[ch]), 15);
872         scale[ch] = ixheaacd_mps_convert_to_qn(scale[ch], q_scale[ch], 15);
873         if (scale[ch] > STP_SCALE_LIMIT_FIX) scale[ch] = STP_SCALE_LIMIT_FIX;
874         if (scale[ch] < ONE_BY_STP_SCALE_LIMIT)
875           scale[ch] = ONE_BY_STP_SCALE_LIMIT;
876       }
877 
878       break;
879     case TREE_525:
880       if (wet_ener[i_lf] != 0) {
881         scale[i_lf] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_lf], &qtemp2);
882         q_scale[i_lf] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_lf];
883       } else {
884         temp_1 = ixheaacd_norm32(dry_ener[0]);
885         scale[i_lf] = dry_ener[0] << temp_1;
886         q_scale[i_lf] = q_dry_ener[0] + temp_1 - 30;
887       }
888       scale[i_lf] = ixheaacd_mps_sqrt(scale[i_lf], &(q_scale[i_lf]), sqrt_tab);
889 
890       if (wet_ener[i_rf] != 0) {
891         scale[i_rf] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_rf], &qtemp2);
892         q_scale[i_rf] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_rf];
893       } else {
894         temp_1 = ixheaacd_norm32(dry_ener[1]);
895         scale[i_rf] = dry_ener[1] << temp_1;
896         q_scale[i_rf] = q_dry_ener[1] + temp_1 - 30;
897       }
898       scale[i_rf] = ixheaacd_mps_sqrt(scale[i_rf], &(q_scale[i_rf]), sqrt_tab);
899 
900       if (wet_ener[i_ls] != 0) {
901         scale[i_ls] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_ls], &qtemp2);
902         q_scale[i_ls] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_ls];
903       } else {
904         temp_1 = ixheaacd_norm32(dry_ener[0]);
905         scale[i_ls] = dry_ener[0] << temp_1;
906         q_scale[i_ls] = q_dry_ener[0] + temp_1 - 30;
907       }
908       scale[i_ls] = ixheaacd_mps_sqrt(scale[i_ls], &(q_scale[i_ls]), sqrt_tab);
909 
910       if (wet_ener[i_rs] != 0) {
911         scale[i_rs] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_rs], &qtemp2);
912         q_scale[i_rs] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_rs];
913       } else {
914         temp_1 = ixheaacd_norm32(dry_ener[1]);
915         scale[i_rs] = dry_ener[1] << temp_1;
916         q_scale[i_rs] = q_dry_ener[1] + temp_1 - 30;
917       }
918       scale[i_rs] = ixheaacd_mps_sqrt(scale[i_rs], &(q_scale[i_rs]), sqrt_tab);
919 
920       for (ch = 0; ch < 4; ch++) {
921         temp_1 = ixheaacd_mps_mult32_shr_15(scale[ch], one_minus_damp);
922         scale[ch] = ixheaacd_mps_add32(temp_1, damp, &(q_scale[ch]), 15);
923         scale[ch] = ixheaacd_mps_convert_to_qn(scale[ch], q_scale[ch], 15);
924         if (scale[ch] > STP_SCALE_LIMIT_FIX) scale[ch] = STP_SCALE_LIMIT_FIX;
925         if (scale[ch] < ONE_BY_STP_SCALE_LIMIT)
926           scale[ch] = ONE_BY_STP_SCALE_LIMIT;
927       }
928       break;
929     case TREE_7271:
930     case TREE_7272:
931       if (wet_ener[i_lf] != 0) {
932         scale[i_lf] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_lf], &qtemp2);
933         q_scale[i_lf] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_lf];
934       } else {
935         temp_1 = ixheaacd_norm32(dry_ener[0]);
936         scale[i_lf] = dry_ener[0] << temp_1;
937         q_scale[i_lf] = q_dry_ener[0] + temp_1 - 30;
938       }
939       scale[i_lf] = ixheaacd_mps_sqrt(scale[i_lf], &(q_scale[i_lf]), sqrt_tab);
940 
941       if (wet_ener[i_rf] != 0) {
942         scale[i_rf] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_rf], &qtemp2);
943         q_scale[i_rf] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_rf];
944       } else {
945         temp_1 = ixheaacd_norm32(dry_ener[1]);
946         scale[i_rf] = dry_ener[1] << temp_1;
947         q_scale[i_rf] = q_dry_ener[1] + temp_1 - 30;
948       }
949       scale[i_rf] = ixheaacd_mps_sqrt(scale[i_rf], &(q_scale[i_rf]), sqrt_tab);
950 
951       if (wet_ener[i_ls] != 0) {
952         scale[i_ls] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_ls], &qtemp2);
953         q_scale[i_ls] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_ls];
954       } else {
955         temp_1 = ixheaacd_norm32(dry_ener[0]);
956         scale[i_ls] = dry_ener[0] << temp_1;
957         q_scale[i_ls] = q_dry_ener[0] + temp_1 - 30;
958       }
959       scale[i_ls] = ixheaacd_mps_sqrt(scale[i_ls], &(q_scale[i_ls]), sqrt_tab);
960 
961       if (wet_ener[i_rs] != 0) {
962         scale[i_rs] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_rs], &qtemp2);
963         q_scale[i_rs] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_rs];
964       } else {
965         temp_1 = ixheaacd_norm32(dry_ener[1]);
966         scale[i_rs] = dry_ener[1] << temp_1;
967         q_scale[i_rs] = q_dry_ener[1] + temp_1 - 30;
968       }
969       scale[i_rs] = ixheaacd_mps_sqrt(scale[i_rs], &(q_scale[i_rs]), sqrt_tab);
970 
971       if (wet_ener[i_al] != 0) {
972         scale[i_al] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_al], &qtemp2);
973         q_scale[i_al] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_al];
974       } else {
975         temp_1 = ixheaacd_norm32(dry_ener[0]);
976         scale[i_al] = dry_ener[0] << temp_1;
977         q_scale[i_al] = q_dry_ener[0] + temp_1 - 30;
978       }
979       scale[i_al] = ixheaacd_mps_sqrt(scale[i_al], &(q_scale[i_al]), sqrt_tab);
980 
981       if (wet_ener[i_ar] != 0) {
982         scale[i_ar] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_ar], &qtemp2);
983         q_scale[i_ar] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_ar];
984       } else {
985         temp_1 = ixheaacd_norm32(dry_ener[1]);
986         scale[i_ar] = dry_ener[1] << temp_1;
987         q_scale[i_ar] = q_dry_ener[1] + temp_1 - 30;
988       }
989       scale[i_ar] = ixheaacd_mps_sqrt(scale[i_ar], &(q_scale[i_ar]), sqrt_tab);
990 
991       for (ch = 0; ch < 6; ch++) {
992         temp_1 = ixheaacd_mps_mult32_shr_15(scale[ch], one_minus_damp);
993         scale[ch] = ixheaacd_mps_add32(temp_1, damp, &(q_scale[ch]), 15);
994         scale[ch] = ixheaacd_mps_convert_to_qn(scale[ch], q_scale[ch], 15);
995         if (scale[ch] > STP_SCALE_LIMIT_FIX) scale[ch] = STP_SCALE_LIMIT_FIX;
996         if (scale[ch] < ONE_BY_STP_SCALE_LIMIT)
997           scale[ch] = ONE_BY_STP_SCALE_LIMIT;
998       }
999 
1000       break;
1001     case TREE_7571:
1002       if (wet_ener[i_lf] != 0) {
1003         scale[i_lf] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_lf], &qtemp2);
1004         q_scale[i_lf] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_lf];
1005       } else {
1006         temp_1 = ixheaacd_norm32(dry_ener[0]);
1007         scale[i_lf] = dry_ener[0] << temp_1;
1008         q_scale[i_lf] = q_dry_ener[0] + temp_1 - 30;
1009       }
1010       scale[i_lf] = ixheaacd_mps_sqrt(scale[i_lf], &(q_scale[i_lf]), sqrt_tab);
1011 
1012       if (wet_ener[i_rf] != 0) {
1013         scale[i_rf] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_rf], &qtemp2);
1014         q_scale[i_rf] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_rf];
1015       } else {
1016         temp_1 = ixheaacd_norm32(dry_ener[1]);
1017         scale[i_rf] = dry_ener[1] << temp_1;
1018         q_scale[i_rf] = q_dry_ener[1] + temp_1 - 30;
1019       }
1020       scale[i_rf] = ixheaacd_mps_sqrt(scale[i_rf], &(q_scale[i_rf]), sqrt_tab);
1021 
1022       if (wet_ener[i_al] != 0) {
1023         scale[i_al] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_al], &qtemp2);
1024         q_scale[i_al] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_al];
1025       } else {
1026         temp_1 = ixheaacd_norm32(dry_ener[0]);
1027         scale[i_al] = dry_ener[0] << temp_1;
1028         q_scale[i_al] = q_dry_ener[0] + temp_1 - 30;
1029       }
1030       scale[i_al] = ixheaacd_mps_sqrt(scale[i_al], &(q_scale[i_al]), sqrt_tab);
1031 
1032       if (wet_ener[i_ar] != 0) {
1033         scale[i_ar] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_ar], &qtemp2);
1034         q_scale[i_ar] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_ar];
1035       } else {
1036         temp_1 = ixheaacd_norm32(dry_ener[1]);
1037         scale[i_ar] = dry_ener[1] << temp_1;
1038         q_scale[i_ar] = q_dry_ener[1] + temp_1 - 30;
1039       }
1040       scale[i_ar] = ixheaacd_mps_sqrt(scale[i_ar], &(q_scale[i_ar]), sqrt_tab);
1041       for (ch = 0; ch < FIVE; ch++) {
1042         if (ch == 2) continue;
1043         temp_1 = ixheaacd_mps_mult32_shr_15(scale[ch], one_minus_damp);
1044         scale[ch] = ixheaacd_mps_add32(temp_1, damp, &(q_scale[ch]), 15);
1045         scale[ch] = ixheaacd_mps_convert_to_qn(scale[ch], q_scale[ch], 15);
1046         if (scale[ch] > STP_SCALE_LIMIT_FIX) scale[ch] = STP_SCALE_LIMIT_FIX;
1047         if (scale[ch] < ONE_BY_STP_SCALE_LIMIT)
1048           scale[ch] = ONE_BY_STP_SCALE_LIMIT;
1049       }
1050 
1051       break;
1052     case TREE_7572:
1053       if (wet_ener[i_ls] != 0) {
1054         scale[i_ls] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_ls], &qtemp2);
1055         q_scale[i_ls] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_ls];
1056       } else {
1057         temp_1 = ixheaacd_norm32(dry_ener[0]);
1058         scale[i_ls] = dry_ener[0] << temp_1;
1059         q_scale[i_ls] = q_dry_ener[0] + temp_1 - 30;
1060       }
1061       scale[i_ls] = ixheaacd_mps_sqrt(scale[i_ls], &(q_scale[i_ls]), sqrt_tab);
1062 
1063       if (wet_ener[i_rs] != 0) {
1064         scale[i_rs] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_rs], &qtemp2);
1065         q_scale[i_rs] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_rs];
1066       } else {
1067         temp_1 = ixheaacd_norm32(dry_ener[1]);
1068         scale[i_rs] = dry_ener[1] << temp_1;
1069         q_scale[i_rs] = q_dry_ener[1] + temp_1 - 30;
1070       }
1071       scale[i_rs] = ixheaacd_mps_sqrt(scale[i_rs], &(q_scale[i_rs]), sqrt_tab);
1072 
1073       if (wet_ener[i_al] != 0) {
1074         scale[i_al] = ixheaacd_mps_div_32(dry_ener[0], wet_ener[i_al], &qtemp2);
1075         q_scale[i_al] = qtemp2 + q_dry_ener[0] - q_wet_ener[i_al];
1076       } else {
1077         temp_1 = ixheaacd_norm32(dry_ener[0]);
1078         scale[i_al] = dry_ener[0] << temp_1;
1079         q_scale[i_al] = q_dry_ener[0] + temp_1 - 30;
1080       }
1081       scale[i_al] = ixheaacd_mps_sqrt(scale[i_al], &(q_scale[i_al]), sqrt_tab);
1082 
1083       if (wet_ener[i_ar] != 0) {
1084         scale[i_ar] = ixheaacd_mps_div_32(dry_ener[1], wet_ener[i_ar], &qtemp2);
1085         q_scale[i_ar] = qtemp2 + q_dry_ener[1] - q_wet_ener[i_ar];
1086       } else {
1087         temp_1 = ixheaacd_norm32(dry_ener[1]);
1088         scale[i_ar] = dry_ener[1] << temp_1;
1089         q_scale[i_ar] = q_dry_ener[1] + temp_1 - 30;
1090       }
1091       scale[i_ar] = ixheaacd_mps_sqrt(scale[i_ar], &(q_scale[i_ar]), sqrt_tab);
1092       for (ch = 0; ch < 6; ch++) {
1093         if (ch == 3 || ch == 0) continue;
1094         temp_1 = ixheaacd_mps_mult32_shr_15(scale[ch], one_minus_damp);
1095         scale[ch] = ixheaacd_mps_add32(temp_1, damp, &(q_scale[ch]), 15);
1096         scale[ch] = ixheaacd_mps_convert_to_qn(scale[ch], q_scale[ch], 15);
1097         if (scale[ch] > STP_SCALE_LIMIT_FIX) scale[ch] = STP_SCALE_LIMIT_FIX;
1098         if (scale[ch] < ONE_BY_STP_SCALE_LIMIT)
1099           scale[ch] = ONE_BY_STP_SCALE_LIMIT;
1100       }
1101 
1102       break;
1103     default:
1104       break;
1105   }
1106 
1107   for (ch = 0; ch < num_output_channels; ch++) {
1108     temp_1 = ixheaacd_mps_mult32_shr_15(STP_LPF_COEFF2_FIX, scale[ch]);
1109     temp_2 =
1110         ixheaacd_mps_mult32_shr_15(ONE_MINUS_STP_LPF_COEFF2, prev_tp_scale[ch]);
1111     scale[ch] = temp_1 + temp_2;
1112     prev_tp_scale[ch] = scale[ch];
1113   }
1114 
1115   offset = ts * MAX_HYBRID_BANDS;
1116   p_buffer_real = p_array_struct->buf_real + offset + HYBRID_BAND_BORDER;
1117   p_buffer_imag = p_array_struct->buf_imag + offset + HYBRID_BAND_BORDER;
1118 
1119   p_buf_real = p_array_struct->buffer_real + offset + FIVE;
1120   p_buf_imag = p_array_struct->buffer_imag + offset + FIVE;
1121 
1122   p_hyb_out_dry_real = p_array_struct->hyb_output_real_dry +
1123                        ts * MAX_HYBRID_BANDS + HYBRID_BAND_BORDER;
1124   p_hyb_out_dry_imag = p_array_struct->hyb_output_imag_dry +
1125                        ts * MAX_HYBRID_BANDS + HYBRID_BAND_BORDER;
1126 
1127   for (ch = 0; ch < num_output_channels; ch++) {
1128     no_scaling = 1;
1129 
1130     ixheaacd_get_ch_idx(pstr_mps_state, ch, &i);
1131     if (i != -1) {
1132       no_scaling = !pstr_mps_state->aux_struct->temp_shape_enable_channel_stp[i];
1133     }
1134     p_buffer_re = p_buffer_real;
1135     p_buffer_im = p_buffer_imag;
1136 
1137     p_buf_re = p_buf_real;
1138     p_buf_im = p_buf_imag;
1139 
1140     hyb_output_real_dry = p_hyb_out_dry_real;
1141     hyb_output_imag_dry = p_hyb_out_dry_imag;
1142 
1143     if (no_scaling == 1) {
1144       for (n = HYBRID_BAND_BORDER; n < (HP_SIZE + QMF_TO_HYB_OFFSET); n++) {
1145         *p_buf_re++ = *hyb_output_real_dry++ + *p_buffer_re++;
1146 
1147         *p_buf_im++ = *hyb_output_imag_dry++ + *p_buffer_im++;
1148       }
1149 
1150       for (; n < hybrid_bands; n++, k++) {
1151         temp = (no_scaling ? ONE_IN_Q15 : scale[ch]);
1152 
1153         *p_buf_re++ = *hyb_output_real_dry++ + *p_buffer_re++;
1154 
1155         *p_buf_im++ = *hyb_output_imag_dry++ + *p_buffer_im++;
1156       }
1157     } else {
1158       for (n = HYBRID_BAND_BORDER; n < (HP_SIZE + QMF_TO_HYB_OFFSET); n++) {
1159         temp = ixheaacd_mps_mult32_shr_30(
1160             scale[ch], tp_process_table_ptr->bp[n - QMF_TO_HYB_OFFSET]);
1161 
1162         *p_buf_re++ = *hyb_output_real_dry++ +
1163                       ixheaacd_mps_mult32_shr_15(temp, *p_buffer_re);
1164         p_buffer_re++;
1165 
1166         *p_buf_im++ = *hyb_output_imag_dry++ +
1167                       ixheaacd_mps_mult32_shr_15(temp, *p_buffer_im);
1168         p_buffer_im++;
1169       }
1170 
1171       for (; n < hybrid_bands; n++, k++) {
1172         temp = (no_scaling ? ONE_IN_Q15 : scale[ch]);
1173 
1174         *p_buf_re++ = *hyb_output_real_dry++ +
1175                       ixheaacd_mps_mult32_shr_15(temp, *p_buffer_re);
1176         p_buffer_re++;
1177 
1178         *p_buf_im++ = *hyb_output_imag_dry++ +
1179                       ixheaacd_mps_mult32_shr_15(temp, *p_buffer_im);
1180         p_buffer_im++;
1181       }
1182     }
1183 
1184     p_buffer_real += TSXHB;
1185     p_buffer_imag += TSXHB;
1186 
1187     p_buf_real += TSXHB;
1188     p_buf_imag += TSXHB;
1189 
1190     p_hyb_out_dry_real += TSXHB;
1191     p_hyb_out_dry_imag += TSXHB;
1192   }
1193 
1194   return;
1195 }
1196 
ixheaacd_tp_process(ia_heaac_mps_state_struct * pstr_mps_state)1197 VOID ixheaacd_tp_process(ia_heaac_mps_state_struct *pstr_mps_state) {
1198   WORD32 ch, ts, hyb, n;
1199   WORD32 temp, temp_1, temp_2;
1200   ia_mps_dec_synthesis_interface *syn = pstr_mps_state->syn;
1201   WORD32 *hyb_output_real_wet, *hyb_output_imag_wet;
1202   WORD32 *hyb_output_real_dry, *hyb_output_imag_dry;
1203 
1204   WORD32 *p_buffer_real, *p_buffer_imag, *p_buffer_re, *p_buffer_im;
1205   WORD32 *p_buf_real, *p_buf_imag, *p_buf_re, *p_buf_im;
1206   WORD32 *buf_real, *buf_imag;
1207 
1208   WORD32 num_output_channels = pstr_mps_state->num_output_channels;
1209   WORD32 time_slots = pstr_mps_state->time_slots;
1210   WORD32 qmf_bands = pstr_mps_state->qmf_bands;
1211   WORD32 num_output_channels_at = pstr_mps_state->num_output_channels_at;
1212   WORD32 tree_config = pstr_mps_state->tree_config;
1213   WORD32 up_mix_type = pstr_mps_state->up_mix_type;
1214   WORD32 tp_hyb_band_border = pstr_mps_state->tp_hyb_band_border;
1215 
1216   ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
1217   WORD32 *p_hyb_out_dry_real = p_array_struct->hyb_output_real_dry;
1218   WORD32 *p_hyb_out_dry_imag = p_array_struct->hyb_output_imag_dry;
1219   WORD32 *p_hyb_out_dry_re, *p_hyb_out_dry_im;
1220 
1221   WORD32 *p_time_out;
1222 
1223   p_buffer_real = p_array_struct->buf_real;
1224   p_buffer_imag = p_array_struct->buf_imag;
1225 
1226   p_buf_real = p_array_struct->buffer_real;
1227   p_buf_imag = p_array_struct->buffer_imag;
1228 
1229   if (!pstr_mps_state->scaling_enable) {
1230     for (ch = 0; ch < num_output_channels; ch++) {
1231       p_buffer_re = p_buffer_real;
1232       p_buffer_im = p_buffer_imag;
1233 
1234       p_buf_re = p_buf_real;
1235       p_buf_im = p_buf_imag;
1236 
1237       p_hyb_out_dry_re = p_hyb_out_dry_real;
1238       p_hyb_out_dry_im = p_hyb_out_dry_imag;
1239 
1240       for (ts = 0; ts < time_slots; ts++) {
1241         hyb_output_real_wet = p_buffer_re;
1242         hyb_output_imag_wet = p_buffer_im;
1243         hyb_output_real_dry = p_hyb_out_dry_re;
1244         hyb_output_imag_dry = p_hyb_out_dry_im;
1245 
1246         buf_real = p_buf_re;
1247         buf_imag = p_buf_im;
1248 
1249         temp_1 = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1250         temp_2 = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1251         for (n = 1; n < 6; n++) {
1252           temp_1 += *hyb_output_real_dry++ + *hyb_output_real_wet++;
1253           temp_2 += *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1254         }
1255 
1256         *buf_real++ = temp_1;
1257         *buf_imag++ = temp_2;
1258 
1259         temp = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1260         *buf_real = temp + *hyb_output_real_dry++ + *hyb_output_real_wet++;
1261         temp = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1262         *buf_imag = temp + *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1263 
1264         buf_real++;
1265         buf_imag++;
1266 
1267         temp = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1268         *buf_real = temp + *hyb_output_real_dry++ + *hyb_output_real_wet++;
1269         temp = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1270         *buf_imag = temp + *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1271 
1272         buf_real++;
1273         buf_imag++;
1274 
1275         for (n = 0; n < qmf_bands; n++) {
1276           *buf_real++ = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1277           *buf_imag++ = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1278         }
1279 
1280         p_buffer_re += MAX_HYBRID_BANDS;
1281         p_buffer_im += MAX_HYBRID_BANDS;
1282 
1283         p_buf_re += MAX_HYBRID_BANDS;
1284         p_buf_im += MAX_HYBRID_BANDS;
1285 
1286         p_hyb_out_dry_re += MAX_HYBRID_BANDS;
1287         p_hyb_out_dry_im += MAX_HYBRID_BANDS;
1288       }
1289       p_buffer_real += TSXHB;
1290       p_buffer_imag += TSXHB;
1291 
1292       p_buf_real += TSXHB;
1293       p_buf_imag += TSXHB;
1294 
1295       p_hyb_out_dry_real += TSXHB;
1296       p_hyb_out_dry_imag += TSXHB;
1297     }
1298   } else {
1299     for (ch = 0; ch < num_output_channels; ch++) {
1300       p_buffer_re = p_buffer_real;
1301       p_buffer_im = p_buffer_imag;
1302 
1303       p_buf_re = p_buf_real;
1304       p_buf_im = p_buf_imag;
1305 
1306       p_hyb_out_dry_re = p_hyb_out_dry_real;
1307       p_hyb_out_dry_im = p_hyb_out_dry_imag;
1308 
1309       for (ts = 0; ts < time_slots; ts++) {
1310         hyb_output_real_wet = p_buffer_re;
1311         hyb_output_imag_wet = p_buffer_im;
1312         hyb_output_real_dry = p_hyb_out_dry_re;
1313         hyb_output_imag_dry = p_hyb_out_dry_im;
1314 
1315         buf_real = p_buf_re;
1316         buf_imag = p_buf_im;
1317 
1318         temp_1 = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1319         temp_2 = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1320         for (n = 1; n < 6; n++) {
1321           temp_1 += *hyb_output_real_dry++ + *hyb_output_real_wet++;
1322           temp_2 += *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1323         }
1324 
1325         *buf_real++ = temp_1;
1326         *buf_imag++ = temp_2;
1327 
1328         *buf_real = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1329         *buf_real += *hyb_output_real_dry++ + *hyb_output_real_wet++;
1330 
1331         *buf_imag = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1332         *buf_imag += *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1333 
1334         buf_real++;
1335         buf_imag++;
1336 
1337         *buf_real = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1338         *buf_real += *hyb_output_real_dry++ + *hyb_output_real_wet++;
1339         *buf_imag = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1340         *buf_imag += *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1341 
1342         buf_real++;
1343         buf_imag++;
1344 
1345         for (hyb = 3; hyb < tp_hyb_band_border - QMF_TO_HYB_OFFSET; hyb++) {
1346           *buf_real++ = *hyb_output_real_dry++ + *hyb_output_real_wet++;
1347           *buf_imag++ = *hyb_output_imag_dry++ + *hyb_output_imag_wet++;
1348         }
1349         p_buffer_re += MAX_HYBRID_BANDS;
1350         p_buffer_im += MAX_HYBRID_BANDS;
1351 
1352         p_buf_re += MAX_HYBRID_BANDS;
1353         p_buf_im += MAX_HYBRID_BANDS;
1354 
1355         p_hyb_out_dry_re += MAX_HYBRID_BANDS;
1356         p_hyb_out_dry_im += MAX_HYBRID_BANDS;
1357       }
1358       p_buffer_real += TSXHB;
1359       p_buffer_imag += TSXHB;
1360 
1361       p_buf_real += TSXHB;
1362       p_buf_imag += TSXHB;
1363 
1364       p_hyb_out_dry_real += TSXHB;
1365       p_hyb_out_dry_imag += TSXHB;
1366     }
1367 
1368     for (ts = 0; ts < time_slots; ts++) {
1369       ixheaacd_subband_tp(pstr_mps_state, ts);
1370     }
1371   }
1372 
1373   if ((!pstr_mps_state->bs_config.arbitrary_tree) &&
1374       ((up_mix_type != 2) && (up_mix_type != 3))) {
1375     WORD32 *time_out_5xxx =
1376         pstr_mps_state->ia_mps_dec_mps_table.tp_process_table_ptr->time_out_idx_5xxx;
1377     WORD32 *time_out_7xxx =
1378         pstr_mps_state->ia_mps_dec_mps_table.tp_process_table_ptr->time_out_idx_7xxx;
1379 
1380     p_buf_real = p_array_struct->buffer_real;
1381     p_buf_imag = p_array_struct->buffer_imag;
1382 
1383     for (ch = 0; ch < num_output_channels_at; ch++) {
1384       WORD32 tempch = 0;
1385       switch (tree_config) {
1386         case TREE_5151:
1387           tempch = ch;
1388           break;
1389         case TREE_5152:
1390         case TREE_525:
1391           tempch = time_out_5xxx[ch];
1392           break;
1393         case TREE_7271:
1394         case TREE_7272:
1395         case TREE_7571:
1396         case TREE_7572:
1397           tempch = time_out_7xxx[ch];
1398           break;
1399         default:
1400           break;
1401       }
1402       p_time_out = p_array_struct->time_out + tempch * QBXTS;
1403       syn->syn_filter_bank(&pstr_mps_state->syn_qmf_bank, p_buf_real, p_buf_imag,
1404                            p_time_out, ch, qmf_bands, time_slots,
1405                            pstr_mps_state->ia_mps_dec_mps_table.qmf_table_ptr);
1406 
1407       p_buf_real += TSXHB;
1408       p_buf_imag += TSXHB;
1409     }
1410   } else {
1411     p_time_out = p_array_struct->time_out;
1412     for (ch = 0; ch < num_output_channels_at; ch++) {
1413       syn->syn_filter_bank(&pstr_mps_state->syn_qmf_bank, p_buf_real, p_buf_imag,
1414                            p_time_out, ch, qmf_bands, time_slots,
1415                            pstr_mps_state->ia_mps_dec_mps_table.qmf_table_ptr);
1416 
1417       p_buf_real += TSXHB;
1418       p_buf_imag += TSXHB;
1419       p_time_out += QBXTS;
1420     }
1421   }
1422 
1423   return;
1424 }
1425