xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_esbr_envcal.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 <stdlib.h>
21 #include <math.h>
22 #include <string.h>
23 
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_error_standards.h"
26 #include "ixheaac_sbr_const.h"
27 #include "ixheaacd_sbrdecsettings.h"
28 #include "ixheaacd_bitbuffer.h"
29 #include "ixheaacd_sbr_common.h"
30 #include "ixheaacd_drc_data_struct.h"
31 #include "ixheaacd_drc_dec.h"
32 #include "ixheaacd_sbrdecoder.h"
33 #include "ixheaacd_bitbuffer.h"
34 #include "ixheaacd_env_extr_part.h"
35 #include "ixheaacd_sbr_rom.h"
36 #include "ixheaacd_common_rom.h"
37 #include "ixheaacd_hybrid.h"
38 #include "ixheaacd_sbr_scale.h"
39 #include "ixheaacd_ps_dec.h"
40 #include "ixheaacd_freq_sca.h"
41 #include "ixheaacd_lpp_tran.h"
42 #include "ixheaacd_env_extr.h"
43 
44 #include "ixheaac_esbr_rom.h"
45 
46 #define ABS(A) fabs(A)
47 
ixheaacd_shellsort(WORD32 * in,WORD32 n)48 VOID ixheaacd_shellsort(WORD32 *in, WORD32 n) {
49   WORD32 i, j, v;
50   WORD32 inc = 1;
51 
52   do
53     inc = 3 * inc + 1;
54   while (inc <= n);
55 
56   do {
57     inc = inc / 3;
58     for (i = inc + 1; i <= n; i++) {
59       v = in[i - 1];
60       j = i;
61       while (in[j - inc - 1] > v) {
62         in[j - 1] = in[j - inc - 1];
63         j -= inc;
64         if (j <= inc) break;
65       }
66       in[j - 1] = v;
67     }
68   } while (inc > 1);
69 }
70 
ixheaacd_sbr_env_calc(ia_sbr_frame_info_data_struct * frame_data,FLOAT32 input_real[][64],FLOAT32 input_imag[][64],FLOAT32 input_real1[][64],FLOAT32 input_imag1[][64],WORD32 x_over_qmf[MAX_NUM_PATCHES],FLOAT32 * scratch_buff,FLOAT32 * env_out,WORD32 ldmps_present,WORD32 ec_flag)71 WORD32 ixheaacd_sbr_env_calc(ia_sbr_frame_info_data_struct *frame_data, FLOAT32 input_real[][64],
72                              FLOAT32 input_imag[][64], FLOAT32 input_real1[][64],
73                              FLOAT32 input_imag1[][64], WORD32 x_over_qmf[MAX_NUM_PATCHES],
74                              FLOAT32 *scratch_buff, FLOAT32 *env_out, WORD32 ldmps_present,
75                              WORD32 ec_flag) {
76   IA_ERRORCODE err_code = IA_NO_ERROR;
77   WORD8 harmonics[64];
78   FLOAT32(*env_tmp)[48];
79   FLOAT32(*noise_level_pvc)[48];
80   FLOAT32(*nrg_est_pvc)[48];
81   FLOAT32(*nrg_ref_pvc)[48];
82   FLOAT32(*nrg_gain_pvc)[48];
83   FLOAT32(*nrg_tone_pvc)[48];
84 
85   WORD32 n, c, li, ui, i, j, k = 0, l, m = 0, kk = 0, o, next = -1, ui2, flag,
86                              tmp, noise_absc_flag, smooth_length;
87   WORD32 upsamp_4_flag = frame_data->pstr_sbr_header->is_usf_4;
88 
89   FLOAT32 *ptr_real_buf, *ptr_imag_buf, nrg = 0, p_ref, p_est, avg_gain, g_max,
90                                         p_adj, boost_gain, sb_gain, sb_noise,
91                                         temp[64];
92 
93   WORD32 t;
94   WORD32 start_pos = 0;
95   WORD32 end_pos = 0;
96 
97   WORD32 slot_idx;
98 
99   FLOAT32 *prev_env_noise_level = frame_data->prev_noise_level;
100   FLOAT32 *nrg_tone = scratch_buff;
101   FLOAT32 *noise_level = scratch_buff + 64;
102   FLOAT32 *nrg_est = scratch_buff + 128;
103   FLOAT32 *nrg_ref = scratch_buff + 192;
104   FLOAT32 *nrg_gain = scratch_buff + 256;
105 
106   const FLOAT32 *smooth_filt;
107 
108   FLOAT32 *sfb_nrg = frame_data->flt_env_sf_arr;
109   FLOAT32 *noise_floor = frame_data->flt_noise_floor;
110   ia_frame_info_struct *p_frame_info = &frame_data->str_frame_info_details;
111 
112   ia_frame_info_struct *pvc_frame_info = &frame_data->str_pvc_frame_info;
113   WORD32 smoothing_length = frame_data->pstr_sbr_header->smoothing_mode ? 0 : 4;
114   WORD32 int_mode = frame_data->pstr_sbr_header->interpol_freq;
115   WORD32 limiter_band = frame_data->pstr_sbr_header->limiter_bands;
116   WORD32 limiter_gains = frame_data->pstr_sbr_header->limiter_gains;
117   WORD32 *add_harmonics = frame_data->add_harmonics;
118   WORD32 sub_band_start =
119       frame_data->pstr_sbr_header->pstr_freq_band_data->sub_band_start;
120   WORD32 sub_band_end =
121       frame_data->pstr_sbr_header->pstr_freq_band_data->sub_band_end;
122   WORD32 reset = frame_data->reset_flag;
123   WORD32 num_subbands = sub_band_end - sub_band_start;
124   WORD32 bs_num_env = p_frame_info->num_env;
125   WORD32 trans_env = p_frame_info->transient_env;
126   WORD32 sbr_mode = frame_data->sbr_mode;
127   WORD32 prev_sbr_mode = frame_data->prev_sbr_mode;
128 
129   WORD16 *freq_band_table[2];
130   const WORD16 *num_sf_bands =
131       frame_data->pstr_sbr_header->pstr_freq_band_data->num_sf_bands;
132   WORD16 *freq_band_table_noise =
133       frame_data->pstr_sbr_header->pstr_freq_band_data->freq_band_tbl_noise;
134   WORD32 num_nf_bands =
135       frame_data->pstr_sbr_header->pstr_freq_band_data->num_nf_bands;
136 
137   WORD32 harm_index = frame_data->harm_index;
138   WORD32 phase_index = frame_data->phase_index;
139   WORD32 esbr_start_up = frame_data->pstr_sbr_header->esbr_start_up;
140   WORD32 esbr_start_up_pvc = frame_data->pstr_sbr_header->esbr_start_up_pvc;
141   WORD8(*harm_flag_prev)[64] = &frame_data->harm_flag_prev;
142   FLOAT32(*e_gain)[5][64] = &frame_data->e_gain;
143   FLOAT32(*noise_buf)[5][64] = &frame_data->noise_buf;
144   WORD32(*lim_table)[4][12 + 1] = &frame_data->lim_table;
145   WORD32(*gate_mode)[4] = &frame_data->gate_mode;
146   WORD32 freq_inv = 1;
147 
148   WORD8(*harm_flag_varlen_prev)[64] = &frame_data->harm_flag_varlen_prev;
149   WORD8(*harm_flag_varlen)[64] = &frame_data->harm_flag_varlen;
150   WORD32 band_loop_end;
151 
152   WORD32 rate = upsamp_4_flag ? 4 : 2;
153   FLOAT64 guard = 1e-17;
154 
155   if (ldmps_present == 1) rate = 1;
156 
157   env_tmp = frame_data->env_tmp;
158   noise_level_pvc = frame_data->noise_level_pvc;
159   nrg_est_pvc = frame_data->nrg_est_pvc;
160   nrg_ref_pvc = frame_data->nrg_ref_pvc;
161   nrg_gain_pvc = frame_data->nrg_gain_pvc;
162   nrg_tone_pvc = frame_data->nrg_tone_pvc;
163 
164   freq_band_table[0] =
165       frame_data->pstr_sbr_header->pstr_freq_band_data->freq_band_table[0];
166   freq_band_table[1] =
167       frame_data->pstr_sbr_header->pstr_freq_band_data->freq_band_table[1];
168 
169   if (reset || (ldmps_present == 1)) {
170     esbr_start_up = 1;
171     esbr_start_up_pvc = 1;
172     if (reset) phase_index = 0;
173     if (ixheaacd_createlimiterbands(
174             (*lim_table), (*gate_mode),
175             frame_data->pstr_sbr_header->pstr_freq_band_data->freq_band_tbl_lo, num_sf_bands[LOW],
176             x_over_qmf, frame_data->sbr_patching_mode, upsamp_4_flag, &frame_data->patch_param,
177             ec_flag))
178       return IA_FATAL_ERROR;
179   }
180 
181   if (frame_data->sbr_patching_mode != frame_data->prev_sbr_patching_mode) {
182     if (ixheaacd_createlimiterbands(
183             (*lim_table), (*gate_mode),
184             frame_data->pstr_sbr_header->pstr_freq_band_data->freq_band_tbl_lo, num_sf_bands[LOW],
185             x_over_qmf, frame_data->sbr_patching_mode, upsamp_4_flag, &frame_data->patch_param,
186             ec_flag))
187       return IA_FATAL_ERROR;
188 
189     frame_data->prev_sbr_patching_mode = frame_data->sbr_patching_mode;
190   }
191 
192   memset(harmonics, 0, 64 * sizeof(WORD8));
193 
194   if (sbr_mode == PVC_SBR) {
195     for (i = 0; i < num_sf_bands[HIGH]; i++) {
196       li =
197           frame_data->pstr_sbr_header->pstr_freq_band_data->freq_band_tbl_hi[i];
198       ui = frame_data->pstr_sbr_header->pstr_freq_band_data
199                ->freq_band_tbl_hi[i + 1];
200       tmp = ((ui + li) - (sub_band_start << 1)) >> 1;
201 
202       if ((tmp >= 64) || (tmp < 0)) {
203         if (ec_flag)
204           tmp = 0;
205         else
206           return -1;
207       }
208 
209       harmonics[tmp] = add_harmonics[i];
210     }
211 
212     for (t = 0; t < p_frame_info->border_vec[0]; t++) {
213       for (c = 0; c < 64; c++) {
214         frame_data->qmapped_pvc[c][t] = frame_data->qmapped_pvc[c][t + 16];
215       }
216     }
217 
218     for (i = 0; i < bs_num_env; i++) {
219       if (kk > MAX_NOISE_ENVELOPES) {
220         if (ec_flag)
221           kk = MAX_NOISE_ENVELOPES;
222         else
223           return IA_FATAL_ERROR;
224       }
225       if (p_frame_info->border_vec[i] == p_frame_info->noise_border_vec[kk]) kk++, next++;
226 
227       start_pos = p_frame_info->border_vec[i];
228       end_pos = p_frame_info->border_vec[i + 1];
229       if ((start_pos < 0) || (end_pos > MAX_FREQ_COEFFS_SBR)) {
230         if (ec_flag) {
231           start_pos = 0;
232           end_pos = MAX_FREQ_COEFFS_SBR;
233         } else
234           return IA_FATAL_ERROR;
235       }
236 
237       for (t = start_pos; t < end_pos; t++) {
238         band_loop_end = num_sf_bands[p_frame_info->freq_res[i]];
239 
240         for (c = 0, o = 0, j = 0; j < band_loop_end; j++) {
241           li = freq_band_table[p_frame_info->freq_res[i]][j];
242           ui = freq_band_table[p_frame_info->freq_res[i]][j + 1];
243           ui2 = frame_data->pstr_sbr_header->pstr_freq_band_data
244                     ->freq_band_tbl_noise[o + 1];
245 
246           for (k = 0; k < ui - li; k++) {
247             o = (k + li >= ui2) ? o + 1 : o;
248             if (o >= MAX_NOISE_COEFFS) {
249               if (ec_flag)
250                 o = MAX_NOISE_COEFFS - 1;
251               else
252                 return IA_FATAL_ERROR;
253             }
254             ui2 = freq_band_table_noise[o + 1];
255 
256             frame_data->qmapped_pvc[c][t] =
257                 noise_floor[next * num_nf_bands + o];
258             c++;
259           }
260         }
261       }
262     }
263 
264     kk = 0;
265     next = -1;
266 
267     for (i = 0; i < bs_num_env; i++) {
268       if (kk > MAX_NOISE_ENVELOPES) {
269         if (ec_flag)
270           kk = MAX_NOISE_ENVELOPES;
271         else
272           return IA_FATAL_ERROR;
273       }
274       if (p_frame_info->border_vec[i] == p_frame_info->noise_border_vec[kk]) kk++, next++;
275 
276       start_pos = pvc_frame_info->border_vec[i];
277       end_pos = pvc_frame_info->border_vec[i + 1];
278       if ((start_pos < 0) || (end_pos > MAX_FREQ_COEFFS_SBR)) {
279         if (ec_flag) {
280           start_pos = 0;
281           end_pos = MAX_FREQ_COEFFS_SBR;
282         } else
283           return IA_FATAL_ERROR;
284       }
285       for (t = start_pos; t < end_pos; t++) {
286         for (c = 0; c < 64; c++) {
287           env_tmp[c][t] = env_out[64 * t + c];
288         }
289       }
290 
291       noise_absc_flag =
292           (i == trans_env || i == frame_data->env_short_flag_prev) ? 1 : 0;
293 
294       if (prev_sbr_mode == ORIG_SBR) noise_absc_flag = 0;
295 
296       smooth_length = (noise_absc_flag ? 0 : smoothing_length);
297       smooth_filt = *ixheaac_fir_table[smooth_length];
298 
299       for (t = start_pos; t < frame_data->sin_len_for_cur_top; t++) {
300         band_loop_end =
301             num_sf_bands[frame_data->str_frame_info_prev
302                              .freq_res[frame_data->var_len_id_prev]];
303 
304         for (c = 0, o = 0, j = 0; j < band_loop_end; j++) {
305           double tmp;
306 
307           li = freq_band_table[frame_data->str_frame_info_prev
308                                    .freq_res[frame_data->var_len_id_prev]][j];
309           ui = freq_band_table[frame_data->str_frame_info_prev
310                                    .freq_res[frame_data->var_len_id_prev]]
311                               [j + 1];
312           ui2 = frame_data->pstr_sbr_header->pstr_freq_band_data
313                     ->freq_band_tbl_noise[o + 1];
314 
315           for (flag = 0, k = li; k < ui; k++) {
316             flag = ((*harm_flag_varlen)[c] &&
317                     (t >= frame_data->sin_start_for_cur_top ||
318                      (*harm_flag_varlen_prev)[c + sub_band_start]))
319                        ? 1
320                        : flag;
321 
322             nrg_ref_pvc[c][t] = env_tmp[k][t];
323             for (nrg = 0, l = 0; l < rate; l++) {
324               nrg +=
325                   (input_real[rate * t + l][k] * input_real[rate * t + l][k]) +
326                   (input_imag[rate * t + l][k] * input_imag[rate * t + l][k]);
327             }
328             nrg_est_pvc[c][t] = nrg / rate;
329             c++;
330           }
331 
332           if (!int_mode && ui != li) {
333             for (nrg = 0, k = c - (ui - li); k < c; k++) {
334               nrg += nrg_est_pvc[k][t];
335             }
336             nrg /= (ui - li);
337           } else {
338             nrg = 0;
339           }
340           c -= (ui - li);
341 
342           for (k = 0; k < ui - li; k++) {
343             o = (k + li >= ui2) ? o + 1 : o;
344             if (o >= MAX_NOISE_COEFFS) {
345               if (ec_flag)
346                 o = MAX_NOISE_COEFFS - 1;
347               else
348                 return IA_FATAL_ERROR;
349             }
350             ui2 = freq_band_table_noise[o + 1];
351             nrg_est_pvc[c][t] = (!int_mode) ? nrg : nrg_est_pvc[c][t];
352             nrg_tone_pvc[c][t] = 0.0f;
353 
354             tmp = frame_data->qmapped_pvc[c][t] /
355                   (1 + frame_data->qmapped_pvc[c][t] + guard);
356 
357             if (flag) {
358               nrg_gain_pvc[c][t] = (FLOAT32)sqrt(nrg_ref_pvc[c][t] * tmp /
359                                                  (nrg_est_pvc[c][t] + 1));
360 
361               nrg_tone_pvc[c][t] = (FLOAT32)(
362                   (harmonics[c] && (t >= frame_data->sine_position ||
363                                     (*harm_flag_prev)[c + sub_band_start]))
364                       ? sqrt(nrg_ref_pvc[c][t] * tmp /
365                              (frame_data->qmapped_pvc[c][t] + guard))
366                       : nrg_tone_pvc[c][t]);
367 
368               nrg_tone_pvc[c][t] =
369                   (FLOAT32)(((*harm_flag_varlen)[c] &&
370                              (t >= frame_data->sin_start_for_cur_top ||
371                               (*harm_flag_varlen_prev)[c + sub_band_start]))
372                                 ? sqrt(nrg_ref_pvc[c][t] * tmp /
373                                        (prev_env_noise_level[o] + guard))
374                                 : nrg_tone_pvc[c][t]);
375 
376             } else {
377               if (noise_absc_flag) {
378                 nrg_gain_pvc[c][t] =
379                     (FLOAT32)sqrt(nrg_ref_pvc[c][t] / (nrg_est_pvc[c][t] + 1));
380               } else {
381                 nrg_gain_pvc[c][t] = (FLOAT32)sqrt(
382                     nrg_ref_pvc[c][t] * tmp /
383                     ((nrg_est_pvc[c][t] + 1) * (frame_data->qmapped_pvc[c][t] + guard)));
384               }
385             }
386 
387             noise_level_pvc[c][t] = (FLOAT32)sqrt(nrg_ref_pvc[c][t] * tmp);
388             c++;
389           }
390         }
391 
392         for (c = 0; c < (*gate_mode)[limiter_band]; c++) {
393           p_ref = p_est = 0.0f;
394           p_adj = 0;
395           for (k = (*lim_table)[limiter_band][c];
396                k < (*lim_table)[limiter_band][c + 1]; k++) {
397             p_ref += nrg_ref_pvc[k][t];
398             p_est += nrg_est_pvc[k][t];
399           }
400           avg_gain = (FLOAT32)sqrt((p_ref + EPS) / (p_est + EPS));
401           g_max = avg_gain * ixheaac_g_lim_gains[limiter_gains];
402           g_max > 1.0e5f ? g_max = 1.0e5f : 0;
403           for (k = (*lim_table)[limiter_band][c];
404                k < (*lim_table)[limiter_band][c + 1]; k++) {
405             if (g_max <= nrg_gain_pvc[k][t]) {
406               noise_level_pvc[k][t] =
407                   (FLOAT32)(noise_level_pvc[k][t] * (g_max / (nrg_gain_pvc[k][t] + guard)));
408               nrg_gain_pvc[k][t] = g_max;
409             }
410 
411             p_adj +=
412                 nrg_gain_pvc[k][t] * nrg_gain_pvc[k][t] * nrg_est_pvc[k][t];
413 
414             if (nrg_tone_pvc[k][t]) {
415               p_adj += nrg_tone_pvc[k][t] * nrg_tone_pvc[k][t];
416             } else if (!noise_absc_flag) {
417               p_adj += noise_level_pvc[k][t] * noise_level_pvc[k][t];
418             }
419           }
420           boost_gain = (FLOAT32)sqrt((p_ref + EPS) / (p_adj + EPS));
421           boost_gain = boost_gain > 1.584893192f ? 1.584893192f : boost_gain;
422 
423           for (k = (*lim_table)[limiter_band][c];
424                k < (*lim_table)[limiter_band][c + 1]; k++) {
425             nrg_gain_pvc[k][t] *= boost_gain;
426             noise_level_pvc[k][t] *= boost_gain;
427             nrg_tone_pvc[k][t] *= boost_gain;
428           }
429         }
430       }
431 
432       for (; t < end_pos; t++) {
433         band_loop_end = num_sf_bands[pvc_frame_info->freq_res[i]];
434 
435         for (c = 0, o = 0, j = 0; j < band_loop_end; j++) {
436           double tmp;
437 
438           li = freq_band_table[pvc_frame_info->freq_res[i]][j];
439           ui = freq_band_table[pvc_frame_info->freq_res[i]][j + 1];
440           ui2 = frame_data->pstr_sbr_header->pstr_freq_band_data
441                     ->freq_band_tbl_noise[o + 1];
442 
443           for (flag = 0, k = li; k < ui; k++) {
444             flag = (harmonics[c] && (t >= frame_data->sine_position ||
445                                      (*harm_flag_prev)[c + sub_band_start]))
446                        ? 1
447                        : flag;
448 
449             nrg_ref_pvc[c][t] = env_tmp[k][t];
450             for (nrg = 0, l = 0; l < rate; l++) {
451               nrg +=
452                   (input_real[rate * t + l][k] * input_real[rate * t + l][k]) +
453                   (input_imag[rate * t + l][k] * input_imag[rate * t + l][k]);
454             }
455             nrg_est_pvc[c][t] = nrg / rate;
456             c++;
457           }
458 
459           if (!int_mode && ui != li) {
460             for (nrg = 0, k = c - (ui - li); k < c; k++) {
461               nrg += nrg_est_pvc[k][t];
462             }
463             nrg /= (ui - li);
464           } else {
465             nrg = 0;
466           }
467           c -= (ui - li);
468 
469           for (k = 0; k < ui - li; k++) {
470             o = (k + li >= ui2) ? o + 1 : o;
471             if (o >= MAX_NOISE_COEFFS) {
472               if (ec_flag)
473                 o = MAX_NOISE_COEFFS - 1;
474               else
475                 return IA_FATAL_ERROR;
476             }
477             ui2 = freq_band_table_noise[o + 1];
478             nrg_est_pvc[c][t] = (!int_mode) ? nrg : nrg_est_pvc[c][t];
479             nrg_tone_pvc[c][t] = 0.0f;
480 
481             tmp = frame_data->qmapped_pvc[c][t] /
482                   (1 + frame_data->qmapped_pvc[c][t] + guard);
483 
484             if (flag) {
485               nrg_gain_pvc[c][t] = (FLOAT32)sqrt(nrg_ref_pvc[c][t] * tmp /
486                                                  (nrg_est_pvc[c][t] + 1));
487 
488               nrg_tone_pvc[c][t] = (FLOAT32)(
489                   (harmonics[c] && (t >= frame_data->sine_position ||
490                                     (*harm_flag_prev)[c + sub_band_start]))
491                       ? sqrt(nrg_ref_pvc[c][t] * tmp /
492                              (frame_data->qmapped_pvc[c][t] + guard))
493                       : nrg_tone_pvc[c][t]);
494             } else {
495               if (noise_absc_flag) {
496                 nrg_gain_pvc[c][t] =
497                     (FLOAT32)sqrt(nrg_ref_pvc[c][t] / (nrg_est_pvc[c][t] + 1));
498               } else {
499                 nrg_gain_pvc[c][t] = (FLOAT32)sqrt(
500                     nrg_ref_pvc[c][t] * tmp /
501                     ((nrg_est_pvc[c][t] + 1) * (frame_data->qmapped_pvc[c][t] + guard)));
502               }
503             }
504 
505             noise_level_pvc[c][t] = (FLOAT32)sqrt(nrg_ref_pvc[c][t] * tmp);
506             c++;
507           }
508         }
509 
510         for (c = 0; c < (*gate_mode)[limiter_band]; c++) {
511           p_ref = p_est = 0.0f;
512           p_adj = 0;
513           for (k = (*lim_table)[limiter_band][c];
514                k < (*lim_table)[limiter_band][c + 1]; k++) {
515             p_ref += nrg_ref_pvc[k][t];
516             p_est += nrg_est_pvc[k][t];
517           }
518           avg_gain = (FLOAT32)sqrt((p_ref + EPS) / (p_est + EPS));
519           g_max = avg_gain * ixheaac_g_lim_gains[limiter_gains];
520           g_max > 1.0e5f ? g_max = 1.0e5f : 0;
521 
522           for (k = (*lim_table)[limiter_band][c];
523                k < (*lim_table)[limiter_band][c + 1]; k++) {
524             if (g_max <= nrg_gain_pvc[k][t]) {
525               noise_level_pvc[k][t] =
526                   (FLOAT32)(noise_level_pvc[k][t] *
527                             (g_max / (nrg_gain_pvc[k][t] + guard)));
528               nrg_gain_pvc[k][t] = g_max;
529             }
530 
531             p_adj +=
532                 nrg_gain_pvc[k][t] * nrg_gain_pvc[k][t] * nrg_est_pvc[k][t];
533 
534             if (nrg_tone_pvc[k][t]) {
535               p_adj += nrg_tone_pvc[k][t] * nrg_tone_pvc[k][t];
536             } else if (!noise_absc_flag) {
537               p_adj += noise_level_pvc[k][t] * noise_level_pvc[k][t];
538             }
539           }
540 
541           boost_gain = (FLOAT32)sqrt((p_ref + EPS) / (p_adj + EPS));
542           boost_gain = boost_gain > 1.584893192f ? 1.584893192f : boost_gain;
543 
544           for (k = (*lim_table)[limiter_band][c];
545                k < (*lim_table)[limiter_band][c + 1]; k++) {
546             nrg_gain_pvc[k][t] *= boost_gain;
547             noise_level_pvc[k][t] *= boost_gain;
548             nrg_tone_pvc[k][t] *= boost_gain;
549           }
550         }
551       }
552 
553       if (esbr_start_up_pvc) {
554         for (n = 0; n < 4; n++) {
555           for (c = 0; c < num_subbands; c++) {
556             (*e_gain)[n][c] = nrg_gain_pvc[c][start_pos];
557             (*noise_buf)[n][c] = noise_level_pvc[c][start_pos];
558           }
559         }
560         esbr_start_up_pvc = 0;
561         esbr_start_up = 0;
562       }
563       for (l = rate * pvc_frame_info->border_vec[i];
564            l < rate * pvc_frame_info->border_vec[1 + i]; l++) {
565         ptr_real_buf = *(input_real + l) + sub_band_start;
566         ptr_imag_buf = *(input_imag + l) + sub_band_start;
567 
568         slot_idx = (WORD32)l / rate;
569         if (sub_band_start & 1) {
570           freq_inv = -1;
571         } else {
572           freq_inv = 1;
573         }
574 
575         for (k = 0; k < num_subbands; k++) {
576           (*e_gain)[4][k] = nrg_gain_pvc[k][slot_idx];
577           (*noise_buf)[4][k] = noise_level_pvc[k][slot_idx];
578           c = 0, sb_gain = 0, sb_noise = 0;
579           for (n = 4 - smooth_length; n <= 4; n++) {
580             sb_gain += (*e_gain)[n][k] * smooth_filt[c];
581             sb_noise += (*noise_buf)[n][k] * smooth_filt[c++];
582           }
583           phase_index = (phase_index + 1) & 511;
584           sb_noise = (nrg_tone_pvc[k][slot_idx] != 0 || noise_absc_flag)
585                          ? 0
586                          : sb_noise;
587 
588           *ptr_real_buf =
589               *ptr_real_buf * sb_gain +
590               sb_noise * ixheaac_random_phase[phase_index][0] +
591               nrg_tone_pvc[k][slot_idx] * ixheaac_hphase_tbl[0][harm_index];
592           *ptr_imag_buf = *ptr_imag_buf * sb_gain +
593                           sb_noise * ixheaac_random_phase[phase_index][1] +
594                           nrg_tone_pvc[k][slot_idx] * freq_inv *
595                               ixheaac_hphase_tbl[1][harm_index];
596 
597           ptr_real_buf++;
598           ptr_imag_buf++;
599           freq_inv = -freq_inv;
600         }
601 
602         harm_index = (harm_index + 1) & 3;
603 
604         memcpy(temp, (*e_gain)[0], 64 * sizeof(FLOAT32));
605         for (n = 0; n < 4; n++) {
606           memcpy((*e_gain)[n], (*e_gain)[n + 1], 64 * sizeof(FLOAT32));
607         }
608         memcpy((*e_gain)[4], temp, 64 * sizeof(FLOAT32));
609 
610         memcpy(temp, (*noise_buf)[0], 64 * sizeof(FLOAT32));
611         for (n = 0; n < 4; n++) {
612           memcpy((*noise_buf)[n], (*noise_buf)[n + 1], 64 * sizeof(FLOAT32));
613         }
614         memcpy((*noise_buf)[4], temp, 64 * sizeof(FLOAT32));
615       }
616     }
617   } else {
618     for (i = 0; i < num_sf_bands[HIGH]; i++) {
619       li =
620           frame_data->pstr_sbr_header->pstr_freq_band_data->freq_band_tbl_hi[i];
621       ui = frame_data->pstr_sbr_header->pstr_freq_band_data
622                ->freq_band_tbl_hi[i + 1];
623       tmp = ((ui + li) - (sub_band_start << 1)) >> 1;
624       if ((tmp >= 64) || (tmp < 0)) return -1;
625 
626       harmonics[tmp] = add_harmonics[i];
627     }
628 
629     for (i = 0; i < bs_num_env; i++) {
630       if (kk > MAX_NOISE_ENVELOPES) {
631         if (ec_flag)
632           kk = MAX_NOISE_ENVELOPES;
633         else
634           return IA_FATAL_ERROR;
635       }
636 
637       if (p_frame_info->border_vec[i] == p_frame_info->noise_border_vec[kk])
638         kk++, next++;
639 
640       noise_absc_flag =
641           (i == trans_env || i == frame_data->env_short_flag_prev) ? 1 : 0;
642 
643       smooth_length = (noise_absc_flag ? 0 : smoothing_length);
644       smooth_filt = *ixheaac_fir_table[smooth_length];
645 
646       if (sbr_mode == ORIG_SBR) {
647         for (c = 0, o = 0, j = 0; j < num_sf_bands[p_frame_info->freq_res[i]];
648              j++) {
649           double tmp;
650           li = freq_band_table[p_frame_info->freq_res[i]][j];
651           ui = freq_band_table[p_frame_info->freq_res[i]][j + 1];
652           ui2 = frame_data->pstr_sbr_header->pstr_freq_band_data
653                     ->freq_band_tbl_noise[o + 1];
654 
655           if (p_frame_info->border_vec[i] >= p_frame_info->border_vec[i + 1]) {
656             for (flag = 0, k = li; k < ui; k++) {
657               flag = (harmonics[c] &&
658                 (i >= trans_env || (*harm_flag_prev)[c + sub_band_start]))
659                 ? 1
660                 : flag;
661               nrg_est[c++] = 0;
662             }
663           } else {
664             for (flag = 0, k = li; k < ui; k++) {
665               for (nrg = 0, l = rate * p_frame_info->border_vec[i];
666                 l < rate * p_frame_info->border_vec[i + 1]; l++) {
667                 nrg += (input_real[l][k] * input_real[l][k]) +
668                   (input_imag[l][k] * input_imag[l][k]);
669               }
670               flag = (harmonics[c] &&
671                 (i >= trans_env || (*harm_flag_prev)[c + sub_band_start]))
672                 ? 1
673                 : flag;
674               nrg_est[c++] = nrg / (rate * p_frame_info->border_vec[i + 1] -
675                 rate * p_frame_info->border_vec[i]);
676             }
677           }
678           if (!int_mode && ui != li) {
679             for (nrg = 0, k = c - (ui - li); k < c; k++) {
680               nrg += nrg_est[k];
681             }
682             nrg /= (ui - li);
683           } else {
684             nrg = 0;
685           }
686           c -= (ui - li);
687 
688           for (k = 0; k < ui - li; k++) {
689             o = (k + li >= ui2) ? o + 1 : o;
690             if (o >= MAX_NOISE_COEFFS) {
691               if (ec_flag)
692                 o = MAX_NOISE_COEFFS - 1;
693               else
694                 return IA_FATAL_ERROR;
695             }
696             ui2 = frame_data->pstr_sbr_header->pstr_freq_band_data
697                       ->freq_band_tbl_noise[o + 1];
698             nrg_ref[c] = sfb_nrg[m];
699             nrg_est[c] = (!int_mode) ? nrg : nrg_est[c];
700             nrg_tone[c] = 0;
701             tmp = noise_floor[next * num_nf_bands + o] /
702                   (1 + noise_floor[next * num_nf_bands + o] + guard);
703             if (flag) {
704               nrg_gain[c] = (FLOAT32)sqrt(nrg_ref[c] * tmp / (nrg_est[c] + 1));
705               nrg_tone[c] = (FLOAT32)(
706                   (harmonics[c] &&
707                    (i >= trans_env || (*harm_flag_prev)[c + sub_band_start]))
708                       ? sqrt(nrg_ref[c] * tmp /
709                              ABS(noise_floor[next * num_nf_bands + o] + guard))
710                       : nrg_tone[c]);
711             } else {
712               if (noise_absc_flag)
713                 nrg_gain[c] = (FLOAT32)sqrt(nrg_ref[c] / (nrg_est[c] + 1));
714               else
715                 nrg_gain[c] = (FLOAT32)sqrt(
716                     nrg_ref[c] * tmp /
717                     ((nrg_est[c] + 1) *
718                      ABS(noise_floor[next * num_nf_bands + o] + guard)));
719             }
720             noise_level[c] = (FLOAT32)sqrt(nrg_ref[c] * tmp);
721             c++;
722           }
723           m++;
724         }
725 
726         for (c = 0; c < (*gate_mode)[limiter_band]; c++) {
727           p_ref = p_est = 0;
728           for (k = (*lim_table)[limiter_band][c];
729                k < (*lim_table)[limiter_band][c + 1]; k++) {
730             p_ref += nrg_ref[k];
731             p_est += nrg_est[k];
732           }
733           avg_gain = (FLOAT32)sqrt((p_ref + EPS) / (p_est + EPS));
734           g_max = avg_gain * ixheaac_g_lim_gains[limiter_gains];
735           g_max > 1.0e5f ? g_max = 1.0e5f : 0;
736           for (k = (*lim_table)[limiter_band][c];
737                k < (*lim_table)[limiter_band][c + 1]; k++) {
738             if (g_max <= nrg_gain[k]) {
739               noise_level[k] = (FLOAT32)(noise_level[k] * (g_max / (nrg_gain[k] + guard)));
740               nrg_gain[k] = g_max;
741             }
742           }
743           p_adj = 0;
744           for (k = (*lim_table)[limiter_band][c];
745                k < (*lim_table)[limiter_band][c + 1]; k++) {
746             p_adj += nrg_gain[k] * nrg_gain[k] * nrg_est[k];
747             if (nrg_tone[k])
748               p_adj += nrg_tone[k] * nrg_tone[k];
749             else if (!noise_absc_flag)
750               p_adj += noise_level[k] * noise_level[k];
751           }
752           boost_gain = (FLOAT32)sqrt((p_ref + EPS) / (p_adj + EPS));
753           boost_gain = boost_gain > 1.584893192f ? 1.584893192f : boost_gain;
754           for (k = (*lim_table)[limiter_band][c];
755                k < (*lim_table)[limiter_band][c + 1]; k++) {
756             nrg_gain[k] *= boost_gain;
757             noise_level[k] *= boost_gain;
758             nrg_tone[k] *= boost_gain;
759           }
760         }
761 
762         if (esbr_start_up && (ldmps_present != 1)) {
763           for (n = 0; n < 4; n++) {
764             memcpy((*e_gain)[n], nrg_gain, num_subbands * sizeof(FLOAT32));
765             memcpy((*noise_buf)[n], noise_level,
766                    num_subbands * sizeof(FLOAT32));
767           }
768           esbr_start_up = 0;
769           esbr_start_up_pvc = 0;
770         }
771 
772         for (l = rate * p_frame_info->border_vec[i];
773              l < rate * p_frame_info->border_vec[i + 1]; l++) {
774           ptr_real_buf = *(input_real + l) + sub_band_start;
775           ptr_imag_buf = *(input_imag + l) + sub_band_start;
776 
777           freq_inv = 1;
778           if ((ldmps_present == 1) && (sub_band_start & 1)) freq_inv = -1;
779 
780           for (k = 0; k < num_subbands; k++) {
781             (*e_gain)[4][k] = nrg_gain[k];
782             (*noise_buf)[4][k] = noise_level[k];
783             c = 0, sb_gain = 0, sb_noise = 0;
784             for (n = 4 - smooth_length; n <= 4; n++) {
785               sb_gain += (*e_gain)[n][k] * smooth_filt[c];
786               sb_noise += (*noise_buf)[n][k] * smooth_filt[c++];
787             }
788 
789             phase_index = (phase_index + 1) & 511;
790             sb_noise = (nrg_tone[k] != 0 || noise_absc_flag) ? 0 : sb_noise;
791 
792             if (ldmps_present == 1) {
793               *ptr_real_buf = *ptr_real_buf * sb_gain +
794                               sb_noise * ixheaac_random_phase[phase_index][0] +
795                               nrg_tone[k] * ixheaac_hphase_tbl[0][harm_index];
796               *ptr_imag_buf =
797                   *ptr_imag_buf * sb_gain +
798                   sb_noise * ixheaac_random_phase[phase_index][1] +
799                   nrg_tone[k] * freq_inv * ixheaac_hphase_tbl[1][harm_index];
800 
801               freq_inv = -freq_inv;
802             } else {
803                 *ptr_real_buf = *ptr_real_buf * sb_gain +
804                             sb_noise * ixheaac_random_phase[phase_index][0];
805                 *ptr_imag_buf = *ptr_imag_buf * sb_gain +
806                             sb_noise * ixheaac_random_phase[phase_index][1];
807             }
808 
809             ptr_real_buf++;
810             ptr_imag_buf++;
811           }
812           if (ldmps_present == 1) harm_index = (harm_index + 1) & 3;
813 
814           memcpy(temp, (*e_gain)[0], 64 * sizeof(FLOAT32));
815           for (n = 0; n < 4; n++)
816             memcpy((*e_gain)[n], (*e_gain)[n + 1], 64 * sizeof(FLOAT32));
817           memcpy((*e_gain)[4], temp, 64 * sizeof(FLOAT32));
818           memcpy(temp, (*noise_buf)[0], 64 * sizeof(FLOAT32));
819           for (n = 0; n < 4; n++)
820             memcpy((*noise_buf)[n], (*noise_buf)[n + 1], 64 * sizeof(FLOAT32));
821           memcpy((*noise_buf)[4], temp, 64 * sizeof(FLOAT32));
822         }
823 
824         if (ldmps_present != 1) {
825           err_code = ixheaacd_apply_inter_tes(
826               *(input_real1 + rate * p_frame_info->border_vec[i]),
827               *(input_imag1 + rate * p_frame_info->border_vec[i]),
828               *(input_real + rate * p_frame_info->border_vec[i]),
829               *(input_imag + rate * p_frame_info->border_vec[i]),
830               rate * p_frame_info->border_vec[i + 1] - rate * p_frame_info->border_vec[i],
831               sub_band_start, num_subbands, frame_data->inter_temp_shape_mode[i]);
832           if (err_code != 0) {
833             return err_code;
834           }
835 
836         for (l = rate * p_frame_info->border_vec[i];
837              l < rate * p_frame_info->border_vec[i + 1]; l++) {
838           ptr_real_buf = *(input_real + l) + sub_band_start;
839           ptr_imag_buf = *(input_imag + l) + sub_band_start;
840           if (sub_band_start & 1) {
841             freq_inv = -1;
842           } else {
843             freq_inv = 1;
844           }
845           for (k = 0; k < num_subbands; k++) {
846             *ptr_real_buf += nrg_tone[k] * ixheaac_hphase_tbl[0][harm_index];
847             *ptr_imag_buf +=
848                 nrg_tone[k] * freq_inv * ixheaac_hphase_tbl[1][harm_index];
849 
850             ptr_real_buf++;
851             ptr_imag_buf++;
852             freq_inv = -freq_inv;
853           }
854           harm_index = (harm_index + 1) & 3;
855         }
856       }
857     }
858   }
859 }
860 
861   for (i = 0; i < 64; i++) {
862     (*harm_flag_varlen_prev)[i] = (*harm_flag_prev)[i];
863     (*harm_flag_varlen)[i] = harmonics[i];
864   }
865 
866   memcpy(&((*harm_flag_prev)[0]) + sub_band_start, harmonics,
867          (64 - sub_band_start) * sizeof(WORD8));
868 
869   if (trans_env == bs_num_env) {
870     frame_data->env_short_flag_prev = 0;
871   } else {
872     frame_data->env_short_flag_prev = -1;
873   }
874 
875   if (ldmps_present != 1) {
876   memcpy((VOID *)&frame_data->str_frame_info_prev,
877          (VOID *)&frame_data->str_frame_info_details,
878          sizeof(ia_frame_info_struct));
879 
880   if (frame_data->str_frame_info_details.num_env == 1) {
881     frame_data->var_len_id_prev = 0;
882   } else if (frame_data->str_frame_info_details.num_env == 2) {
883     frame_data->var_len_id_prev = 1;
884   }
885 
886   if ((frame_data->str_frame_info_details.num_noise_env < 1) ||
887         (frame_data->str_frame_info_details.num_noise_env > 2)) {
888       if (ec_flag)
889         frame_data->str_frame_info_details.num_noise_env = 1;
890       else
891         return IA_FATAL_ERROR;
892     }
893 
894   for (i = 0; i < num_nf_bands; i++) {
895     prev_env_noise_level[i] =
896         frame_data->flt_noise_floor
897             [(frame_data->str_frame_info_details.num_noise_env - 1) *
898                  num_nf_bands +
899              i];
900   }
901 }
902 
903   frame_data->harm_index = harm_index;
904   frame_data->phase_index = phase_index;
905   frame_data->pstr_sbr_header->esbr_start_up = esbr_start_up;
906   frame_data->pstr_sbr_header->esbr_start_up_pvc = esbr_start_up_pvc;
907   return 0;
908 }
909 
ixheaacd_createlimiterbands(WORD32 lim_table[4][12+1],WORD32 gate_mode[4],WORD16 * freq_band_tbl,WORD32 ixheaacd_num_bands,WORD32 x_over_qmf[MAX_NUM_PATCHES],WORD32 b_patching_mode,WORD32 upsamp_4_flag,struct ixheaacd_lpp_trans_patch * patch_param,WORD32 ec_flag)910 IA_ERRORCODE ixheaacd_createlimiterbands(WORD32 lim_table[4][12 + 1], WORD32 gate_mode[4],
911                                          WORD16 *freq_band_tbl, WORD32 ixheaacd_num_bands,
912                                          WORD32 x_over_qmf[MAX_NUM_PATCHES],
913                                          WORD32 b_patching_mode, WORD32 upsamp_4_flag,
914                                          struct ixheaacd_lpp_trans_patch *patch_param,
915                                          WORD32 ec_flag) {
916   WORD32 i, j, k, is_patch_border[2];
917   WORD32 patch_borders[MAX_NUM_PATCHES + 1];
918   WORD32 temp_limiter_band_calc[32 + MAX_NUM_PATCHES + 1];
919 
920   double num_octave;
921   WORD32 num_patches;
922 
923   WORD32 sub_band_start = freq_band_tbl[0];
924   WORD32 sub_band_end = freq_band_tbl[ixheaacd_num_bands];
925 
926   const double log2 = log(2.0);
927   const double limbnd_per_oct[4] = {0, 1.2, 2.0, 3.0};
928 
929   if (!b_patching_mode && (x_over_qmf != NULL)) {
930     num_patches = 0;
931     if (upsamp_4_flag) {
932       for (i = 1; i < MAX_NUM_PATCHES; i++)
933         if (x_over_qmf[i] != 0) num_patches++;
934     } else {
935       for (i = 1; i < 4; i++)
936         if (x_over_qmf[i] != 0) num_patches++;
937     }
938     for (i = 0; i < num_patches; i++) {
939       patch_borders[i] = x_over_qmf[i] - sub_band_start;
940     }
941   } else {
942     num_patches = patch_param->num_patches;
943     for (i = 0; i < num_patches; i++) {
944       patch_borders[i] = patch_param->start_subband[i] - sub_band_start;
945     }
946   }
947   patch_borders[i] = sub_band_end - sub_band_start;
948 
949   lim_table[0][0] = freq_band_tbl[0] - sub_band_start;
950   lim_table[0][1] = freq_band_tbl[ixheaacd_num_bands] - sub_band_start;
951   gate_mode[0] = 1;
952 
953   for (i = 1; i < 4; i++) {
954     for (k = 0; k <= ixheaacd_num_bands; k++) {
955       temp_limiter_band_calc[k] = freq_band_tbl[k] - sub_band_start;
956     }
957 
958     for (k = 1; k < num_patches; k++) {
959       temp_limiter_band_calc[ixheaacd_num_bands + k] = patch_borders[k];
960     }
961 
962     gate_mode[i] = ixheaacd_num_bands + num_patches - 1;
963     ixheaacd_shellsort(temp_limiter_band_calc, gate_mode[i] + 1);
964 
965     for (j = 1; j <= gate_mode[i]; j++) {
966       num_octave = log((double)(temp_limiter_band_calc[j] + sub_band_start) /
967                        (temp_limiter_band_calc[j - 1] + sub_band_start)) /
968                    log2;
969 
970       if (num_octave * limbnd_per_oct[i] < 0.49) {
971         if (temp_limiter_band_calc[j] == temp_limiter_band_calc[j - 1]) {
972           temp_limiter_band_calc[j] = sub_band_end;
973           ixheaacd_shellsort(temp_limiter_band_calc, gate_mode[i] + 1);
974           gate_mode[i]--;
975           j--;
976           continue;
977         }
978 
979         is_patch_border[0] = is_patch_border[1] = 0;
980 
981         for (k = 0; k <= num_patches; k++) {
982           if (temp_limiter_band_calc[j - 1] == patch_borders[k]) {
983             is_patch_border[0] = 1;
984             break;
985           }
986         }
987 
988         for (k = 0; k <= num_patches; k++) {
989           if (temp_limiter_band_calc[j] == patch_borders[k]) {
990             is_patch_border[1] = 1;
991             break;
992           }
993         }
994 
995         if (!is_patch_border[1]) {
996           temp_limiter_band_calc[j] = sub_band_end;
997           ixheaacd_shellsort(temp_limiter_band_calc, gate_mode[i] + 1);
998           gate_mode[i]--;
999           j--;
1000         } else if (!is_patch_border[0]) {
1001           temp_limiter_band_calc[j - 1] = sub_band_end;
1002           ixheaacd_shellsort(temp_limiter_band_calc, gate_mode[i] + 1);
1003           gate_mode[i]--;
1004           j--;
1005         }
1006       }
1007     }
1008     if (gate_mode[i] > 12) {
1009       if (ec_flag)
1010         gate_mode[i] = 12;
1011       else
1012         return IA_FATAL_ERROR;
1013     }
1014     for (k = 0; k <= gate_mode[i]; k++) {
1015       lim_table[i][k] = temp_limiter_band_calc[k];
1016     }
1017   }
1018   return IA_NO_ERROR;
1019 }
1020 
ixheaacd_apply_inter_tes(FLOAT32 * qmf_real1,FLOAT32 * qmf_imag1,FLOAT32 * qmf_real,FLOAT32 * qmf_imag,WORD32 num_sample,WORD32 sub_band_start,WORD32 num_subband,WORD32 gamma_idx)1021 WORD32 ixheaacd_apply_inter_tes(FLOAT32 *qmf_real1, FLOAT32 *qmf_imag1,
1022                                 FLOAT32 *qmf_real, FLOAT32 *qmf_imag,
1023                                 WORD32 num_sample, WORD32 sub_band_start,
1024                                 WORD32 num_subband, WORD32 gamma_idx) {
1025   WORD32 sub_band_end = sub_band_start + num_subband;
1026   FLOAT32 subsample_power_high[TIMESLOT_BUFFER_SIZE],
1027       subsample_power_low[TIMESLOT_BUFFER_SIZE];
1028   FLOAT32 total_power_high = 0.0f;
1029   FLOAT32 total_power_low = 0.0f, total_power_high_after = 1.0e-6f;
1030   FLOAT32 gain[TIMESLOT_BUFFER_SIZE];
1031   FLOAT32 gain_adj, gain_adj_2;
1032   FLOAT32 gamma = ixheaac_q_gamma_table[gamma_idx];
1033   WORD32 i, j;
1034 
1035   if (num_sample > TIMESLOT_BUFFER_SIZE)
1036   {
1037     return IA_FATAL_ERROR;
1038   }
1039   if (gamma > 0) {
1040     for (i = 0; i < num_sample; i++) {
1041       memcpy(&qmf_real[64 * i], &qmf_real1[64 * i],
1042              sub_band_start * sizeof(FLOAT32));
1043       memcpy(&qmf_imag[64 * i], &qmf_imag1[64 * i],
1044              sub_band_start * sizeof(FLOAT32));
1045     }
1046 
1047     for (i = 0; i < num_sample; i++) {
1048       subsample_power_low[i] = 0.0f;
1049       for (j = 0; j < sub_band_start; j++) {
1050         subsample_power_low[i] += qmf_real[64 * i + j] * qmf_real[64 * i + j];
1051         subsample_power_low[i] += qmf_imag[64 * i + j] * qmf_imag[64 * i + j];
1052       }
1053       subsample_power_high[i] = 0.0f;
1054       for (j = sub_band_start; j < sub_band_end; j++) {
1055         subsample_power_high[i] += qmf_real[64 * i + j] * qmf_real[64 * i + j];
1056         subsample_power_high[i] += qmf_imag[64 * i + j] * qmf_imag[64 * i + j];
1057       }
1058       total_power_low += subsample_power_low[i];
1059       total_power_high += subsample_power_high[i];
1060     }
1061 
1062     for (i = 0; i < num_sample; i++) {
1063       gain[i] = (FLOAT32)(sqrt(subsample_power_low[i] * num_sample /
1064                                (total_power_low + 1.0e-6f)));
1065     }
1066 
1067     for (i = 0; i < num_sample; i++) {
1068       gain[i] = (FLOAT32)(1.0f + gamma * (gain[i] - 1.0f));
1069     }
1070 
1071     for (i = 0; i < num_sample; i++) {
1072       if (gain[i] < 0.2f) {
1073         gain[i] = 0.2f;
1074       }
1075 
1076       subsample_power_high[i] *= gain[i] * gain[i];
1077       total_power_high_after += subsample_power_high[i];
1078     }
1079 
1080     gain_adj_2 = total_power_high / total_power_high_after;
1081     gain_adj = (FLOAT32)(sqrt(gain_adj_2));
1082 
1083     for (i = 0; i < num_sample; i++) {
1084       gain[i] *= gain_adj;
1085 
1086       for (j = sub_band_start; j < sub_band_end; j++) {
1087         qmf_real[64 * i + j] *= gain[i];
1088         qmf_imag[64 * i + j] *= gain[i];
1089       }
1090     }
1091   }
1092   return 0;
1093 }
1094