xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_sbr_env_est.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2023 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19  */
20 
21 #include <string.h>
22 #include <math.h>
23 #include <limits.h>
24 
25 #include "ixheaac_type_def.h"
26 #include "ixheaac_constants.h"
27 #include "ixheaace_aac_constants.h"
28 #include "ixheaac_error_standards.h"
29 #include "ixheaace_error_codes.h"
30 #include "ixheaac_basic_ops32.h"
31 #include "ixheaac_basic_ops16.h"
32 #include "ixheaac_basic_ops40.h"
33 #include "ixheaac_basic_ops.h"
34 
35 #include "ixheaace_sbr_header.h"
36 #include "ixheaace_sbr_def.h"
37 #include "ixheaace_resampler.h"
38 
39 #include "ixheaace_sbr_rom.h"
40 #include "ixheaace_common_rom.h"
41 #include "ixheaace_sbr_hbe.h"
42 #include "ixheaace_sbr_qmf_enc.h"
43 #include "ixheaace_sbr_tran_det.h"
44 #include "ixheaace_sbr_frame_info_gen.h"
45 #include "ixheaace_sbr_env_est.h"
46 #include "ixheaace_sbr_code_envelope.h"
47 #include "ixheaace_sbr_main.h"
48 #include "ixheaace_sbr_missing_harmonics_det.h"
49 #include "ixheaace_sbr_inv_filtering_estimation.h"
50 #include "ixheaace_sbr_noise_floor_est.h"
51 
52 #include "ixheaace_common_rom.h"
53 #include "ixheaace_sbr_ton_corr.h"
54 #include "iusace_esbr_pvc.h"
55 #include "iusace_esbr_inter_tes.h"
56 #include "ixheaace_sbr.h"
57 
58 #include "ixheaace_bitbuffer.h"
59 
60 #include "ixheaace_sbr_cmondata.h"
61 #include "ixheaace_sbr_write_bitstream.h"
62 
63 #include "ixheaace_sbr_hybrid.h"
64 #include "ixheaace_sbr_ps_enc.h"
65 
66 #include "ixheaace_common_utils.h"
67 
68 #include "ixheaace_sbr_header.h"
69 #include "ixheaace_sbr_def.h"
70 #include "ixheaace_resampler.h"
71 #include "ixheaace_sbr_rom.h"
72 #include "ixheaace_common_rom.h"
73 #include "ixheaace_sbr_hbe.h"
74 #include "ixheaace_sbr_qmf_enc.h"
75 #include "ixheaace_sbr_tran_det.h"
76 #include "ixheaace_sbr_frame_info_gen.h"
77 #include "ixheaace_sbr_env_est.h"
78 #include "ixheaace_sbr_code_envelope.h"
79 #include "ixheaace_psy_const.h"
80 #include "ixheaace_tns.h"
81 #include "ixheaace_tns_params.h"
82 #include "ixheaace_rom.h"
83 #include "ixheaace_common_rom.h"
84 #include "ixheaace_bitbuffer.h"
85 
86 #include "ixheaace_sbr_main.h"
87 #include "ixheaace_common_rom.h"
88 #include "ixheaace_sbr_missing_harmonics_det.h"
89 #include "ixheaace_sbr_inv_filtering_estimation.h"
90 #include "ixheaace_sbr_noise_floor_est.h"
91 #include "ixheaace_sbr_ton_corr.h"
92 #include "iusace_esbr_pvc.h"
93 #include "ixheaace_sbr.h"
94 
95 #include "ixheaace_sbr_freq_scaling.h"
96 
97 #include "ixheaace_bitbuffer.h"
98 
99 #include "ixheaace_sbr_hybrid.h"
100 #include "ixheaace_sbr_ps_enc.h"
101 
102 #include "ixheaace_sbr_crc.h"
103 #include "ixheaace_sbr_cmondata.h"
104 #include "ixheaace_sbr_enc_struct.h"
105 #include "ixheaace_sbr_write_bitstream.h"
106 
107 #include "ixheaace_common_utils.h"
108 
ixheaace_map_panorama(WORD32 nrg_val,WORD32 amp_res,WORD32 * ptr_quant_error)109 static WORD32 ixheaace_map_panorama(WORD32 nrg_val, WORD32 amp_res, WORD32 *ptr_quant_error) {
110   WORD32 i = 0;
111   ;
112   WORD32 min_val, val;
113   WORD32 pan_tab[2][10] = {{0, 2, 4, 6, 8, 12, 16, 20, 24}, {0, 2, 4, 8, 12}};
114   WORD32 max_index[2] = {9, 5};
115 
116   WORD32 pan_index;
117   WORD32 sign;
118 
119   sign = nrg_val > 0 ? 1 : -1;
120 
121   nrg_val = sign * nrg_val;
122 
123   min_val = INT_MAX;
124   pan_index = 0;
125 
126   while (i < max_index[amp_res]) {
127     val = ixheaac_abs32(nrg_val - pan_tab[amp_res][i]);
128     if (val < min_val) {
129       min_val = val;
130       pan_index = i;
131     }
132     i++;
133   }
134 
135   *ptr_quant_error = min_val;
136 
137   return pan_tab[amp_res][max_index[amp_res] - 1] + sign * pan_tab[amp_res][pan_index];
138 }
139 
ixheaace_sbr_noise_floor_levels_quantisation(WORD32 * ptr_noise_levels,FLOAT32 * ptr_flt_noise_levels,WORD32 coupling)140 static VOID ixheaace_sbr_noise_floor_levels_quantisation(WORD32 *ptr_noise_levels,
141                                                          FLOAT32 *ptr_flt_noise_levels,
142                                                          WORD32 coupling) {
143   WORD32 i = 0;
144   WORD32 dummy;
145 
146   while (i < MAXIMUM_NUM_NOISE_VALUES) {
147     WORD32 tmp;
148 
149     tmp = ptr_flt_noise_levels[i] > 30.0f ? 30 : (WORD32)(ptr_flt_noise_levels[i] + 0.5f);
150 
151     if (coupling) {
152       tmp = tmp < -30 ? -30 : tmp;
153       tmp = ixheaace_map_panorama(tmp, 1, &dummy);
154     }
155     ptr_noise_levels[i] = tmp;
156 
157     i++;
158   }
159 }
160 
ixheaace_couple_noise_floor(FLOAT32 * ptr_noise_lvl_left,FLOAT32 * ptr_noise_lvl_right)161 static VOID ixheaace_couple_noise_floor(FLOAT32 *ptr_noise_lvl_left,
162                                         FLOAT32 *ptr_noise_lvl_right) {
163   WORD32 i = 0;
164 
165   while (i < MAXIMUM_NUM_NOISE_VALUES) {
166     FLOAT32 pow_left, pow_right;
167 
168     pow_left = (FLOAT32)pow(2.0f, (SBR_NOISE_FLOOR_OFFSET - ptr_noise_lvl_left[i]));
169     pow_right = (FLOAT32)pow(2.0f, (SBR_NOISE_FLOOR_OFFSET - ptr_noise_lvl_right[i]));
170 
171     ptr_noise_lvl_right[i] -= ptr_noise_lvl_left[i];
172     ptr_noise_lvl_left[i] =
173         (FLOAT32)(SBR_NOISE_FLOOR_OFFSET - log((pow_left * pow_right) / 2) * SBR_INV_LOG_2);
174     i++;
175   }
176 }
177 
ixheaace_calculate_sbr_envelope(FLOAT32 ** ptr_y_buf_left,FLOAT32 ** ptr_y_buf_right,const ixheaace_str_frame_info_sbr * pstr_const_frame_info,WORD32 * ptr_sfb_ene_l,WORD32 * ptr_sfb_ene_r,ixheaace_pstr_sbr_config_data pstr_sbr_cfg,ixheaace_pstr_enc_channel pstr_sbr,ixheaace_sbr_stereo_mode stereo_mode,WORD32 * ptr_max_quant_err)178 static IA_ERRORCODE ixheaace_calculate_sbr_envelope(
179     FLOAT32 **ptr_y_buf_left, FLOAT32 **ptr_y_buf_right,
180     const ixheaace_str_frame_info_sbr *pstr_const_frame_info, WORD32 *ptr_sfb_ene_l,
181     WORD32 *ptr_sfb_ene_r, ixheaace_pstr_sbr_config_data pstr_sbr_cfg,
182     ixheaace_pstr_enc_channel pstr_sbr, ixheaace_sbr_stereo_mode stereo_mode,
183     WORD32 *ptr_max_quant_err) {
184   WORD32 i, j, k, l, count, m = 0;
185   WORD32 num_bands, start_pos, stop_pos, li, ui;
186   ixheaace_freq_res freq_res;
187 
188   WORD32 ca = 2 - pstr_sbr->enc_env_data.init_sbr_amp_res;
189   WORD32 n_envelopes = pstr_const_frame_info->n_envelopes;
190   WORD32 short_env = pstr_const_frame_info->short_env - 1;
191   WORD32 time_step = pstr_sbr->str_sbr_extract_env.time_step;
192   WORD32 missing_harmonic = 0;
193 
194   if ((ca != 1) && (ca != 2)) {
195     return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_AMP_RES;
196   }
197 
198   if (stereo_mode == SBR_COUPLING) {
199     *ptr_max_quant_err = 0;
200   }
201 
202   i = 0;
203   while (i < n_envelopes) {
204     start_pos = time_step * pstr_const_frame_info->borders[i];
205     stop_pos = time_step * pstr_const_frame_info->borders[i + 1];
206     freq_res = pstr_const_frame_info->freq_res[i];
207     num_bands = pstr_sbr_cfg->num_scf[freq_res];
208 
209     if (i == short_env) {
210       if (pstr_sbr_cfg->is_ld_sbr) {
211         WORD32 temp = 2;
212         if (temp < time_step) {
213           temp = time_step;
214         }
215         if (stop_pos - start_pos > temp) {
216           stop_pos = stop_pos - temp;
217         }
218       } else {
219         stop_pos = stop_pos - time_step;
220       }
221     }
222     for (j = 0; j < num_bands; j++) {
223       FLOAT32 energy_left = 0, energy_right = 0, tmp_ene_l = 0, tmp_ene_r = 0;
224       li = pstr_sbr_cfg->ptr_freq_band_tab[freq_res][j];
225       ui = pstr_sbr_cfg->ptr_freq_band_tab[freq_res][j + 1];
226 
227       if ((freq_res == FREQ_RES_HIGH) && (j == 0 && ui - li > 1)) {
228         li++;
229       } else {
230         if (j == 0 && ui - li > 2) {
231           li++;
232         }
233       }
234 
235       missing_harmonic = 0;
236 
237       if (pstr_sbr->enc_env_data.add_harmonic_flag) {
238         if (freq_res == FREQ_RES_HIGH) {
239           if (pstr_sbr->enc_env_data.add_harmonic[j]) {
240             missing_harmonic = 1;
241           }
242         } else {
243           WORD32 band;
244           WORD32 start_band_high = 0;
245           WORD32 stop_band_high = 0;
246 
247           while (pstr_sbr_cfg->ptr_freq_band_tab[FREQ_RES_HIGH][start_band_high] <
248                  pstr_sbr_cfg->ptr_freq_band_tab[FREQ_RES_LOW][j]) {
249             start_band_high++;
250           }
251 
252           while (pstr_sbr_cfg->ptr_freq_band_tab[FREQ_RES_HIGH][stop_band_high] <
253                  pstr_sbr_cfg->ptr_freq_band_tab[FREQ_RES_LOW][j + 1]) {
254             stop_band_high++;
255           }
256 
257           for (band = start_band_high; band < stop_band_high; band++) {
258             if (pstr_sbr->enc_env_data.add_harmonic[band]) {
259               missing_harmonic = 1;
260             }
261           }
262         }
263       }
264 
265       if (missing_harmonic) {
266         count = stop_pos - start_pos;
267         for (l = start_pos; l < stop_pos; l++) {
268           energy_left += ptr_y_buf_left[l / 2][li];
269         }
270 
271         k = li + 1;
272         while (k < ui) {
273           tmp_ene_l = 0.0f;
274           for (l = start_pos; l < stop_pos; l++) {
275             tmp_ene_l += ptr_y_buf_left[l / 2][k];
276           }
277 
278           if (tmp_ene_l > energy_left) {
279             energy_left = tmp_ene_l;
280           }
281           k++;
282         }
283 
284         if (ui - li > 2) {
285           energy_left = energy_left * 0.398107267f;
286         } else {
287           if (ui - li > 1) {
288             energy_left = energy_left * 0.5f;
289           }
290         }
291 
292         if (stereo_mode == SBR_COUPLING) {
293           for (l = start_pos; l < stop_pos; l++) {
294             energy_right += ptr_y_buf_right[l / 2][li];
295           }
296 
297           k = li + 1;
298           while (k < ui) {
299             tmp_ene_r = 0.0f;
300             for (l = start_pos; l < stop_pos; l++) {
301               tmp_ene_r += ptr_y_buf_right[l / 2][k];
302             }
303 
304             if (tmp_ene_r > energy_right) {
305               energy_right = tmp_ene_r;
306             }
307             k++;
308           }
309 
310           if (ui - li > 2) {
311             energy_right = energy_right * 0.398107267f;
312           } else {
313             if (ui - li > 1) {
314               energy_right = energy_right * 0.5f;
315             }
316           }
317 
318           tmp_ene_l = energy_left;
319           energy_left = (energy_left + energy_right) * 0.5f;
320           energy_right = (tmp_ene_l + 1) / (energy_right + 1);
321         }
322       } else {
323         count = (stop_pos - start_pos) * (ui - li);
324 
325         k = li;
326         while (k < ui) {
327           for (l = start_pos; l < stop_pos; l++) {
328             if (pstr_sbr_cfg->is_ld_sbr) {
329               energy_left += ptr_y_buf_left[l][k];
330             } else {
331               energy_left += ptr_y_buf_left[l / 2][k];
332             }
333           }
334           k++;
335         }
336 
337         if (stereo_mode == SBR_COUPLING) {
338           k = li;
339           while (k < ui) {
340             for (l = start_pos; l < stop_pos; l++) {
341               energy_right += ptr_y_buf_right[l / 2][k];
342             }
343             k++;
344           }
345           tmp_ene_l = energy_left;
346           energy_left = (energy_left + energy_right) * 0.5f;
347           energy_right = (tmp_ene_l + 1) / (energy_right + 1);
348         }
349       }
350 
351       energy_left = (FLOAT32)(log(energy_left / (count * 64) + EPS) * SBR_INV_LOG_2);
352 
353       if (energy_left < 0.0f) {
354         energy_left = 0.0f;
355       }
356 
357       ptr_sfb_ene_l[m] = (WORD32)(ca * energy_left + 0.5);
358 
359       if (stereo_mode == SBR_COUPLING) {
360         WORD32 quant_err;
361         energy_right = (FLOAT32)(log(energy_right) * SBR_INV_LOG_2);
362         ptr_sfb_ene_r[m] =
363             ixheaace_map_panorama((WORD32)((FLOAT32)ca * energy_right),
364                                   pstr_sbr->enc_env_data.init_sbr_amp_res, &quant_err);
365         if (quant_err > *ptr_max_quant_err) {
366           *ptr_max_quant_err = quant_err;
367         }
368       }
369       m++;
370     }
371 
372     if (pstr_sbr_cfg->use_parametric_coding) {
373       m -= num_bands;
374 
375       for (j = 0; j < num_bands; j++) {
376         if (freq_res == FREQ_RES_HIGH && pstr_sbr->str_sbr_extract_env.envelope_compensation[j]) {
377           ptr_sfb_ene_l[m] -= (WORD32)(
378               ca * ixheaac_abs32(pstr_sbr->str_sbr_extract_env.envelope_compensation[j]));
379         }
380 
381         if (ptr_sfb_ene_l[m] < 0) {
382           ptr_sfb_ene_l[m] = 0;
383         }
384         m++;
385       }
386     }
387     i++;
388   }
389   return IA_NO_ERROR;
390 }
ixheaace_get_pitch_bin_deint(FLOAT32 * ptr_fft_data_real,FLOAT32 * ptr_fft_data_im,const WORD32 * ptr_sfb_tab,WORD32 is_4_1)391 static WORD32 ixheaace_get_pitch_bin_deint(FLOAT32 *ptr_fft_data_real, FLOAT32 *ptr_fft_data_im,
392                                            const WORD32 *ptr_sfb_tab, WORD32 is_4_1) {
393   WORD32 i, j = 0, k = 0;
394   WORD32 bin = -1;
395   FLOAT32 tmp, prev_val = 0.0f;
396 
397   while (ptr_sfb_tab[j] != -1) {
398     WORD32 size = ptr_sfb_tab[j];
399     tmp = 0;
400 
401     for (i = 0; i < size; i++) {
402       tmp += ptr_fft_data_real[k / 2] * ptr_fft_data_real[k / 2];
403       tmp += ptr_fft_data_im[k / 2] * ptr_fft_data_im[k / 2];
404       k += 2;
405     }
406 
407     tmp = (FLOAT32)log(max(MIN_FLT_VAL, (tmp / (FLOAT32)size)));
408     if (j != 0) {
409       if (fabs(tmp - prev_val) >= 3.0f) {
410         if (1 == is_4_1) {
411           bin = ((k - (ptr_sfb_tab[j] * 2)) * 3) / 8;
412         } else {
413           bin = ((k - (ptr_sfb_tab[j] * 2)) * 3) / 4;
414         }
415         if (bin > 127) {
416           bin = -1;
417         }
418         break;
419       }
420     }
421     prev_val = tmp;
422     j++;
423   }
424 
425   return bin;
426 }
ixheaace_get_pitch_bin(FLOAT32 * fft_data,const WORD32 * ptr_sfb_tab,WORD32 is_4_1)427 static WORD32 ixheaace_get_pitch_bin(FLOAT32 *fft_data, const WORD32 *ptr_sfb_tab,
428                                      WORD32 is_4_1) {
429   WORD32 i, j = 0, k = 0;
430   WORD32 bin = -1;
431   FLOAT32 tmp, prev_val = 0;
432 
433   while (ptr_sfb_tab[j] != -1) {
434     WORD32 size = ptr_sfb_tab[j];
435     tmp = 0;
436 
437     for (i = 0; i < size; i++) {
438       tmp += fft_data[k] * fft_data[k];
439       tmp += fft_data[k + 1] * fft_data[k + 1];
440       k += 2;
441     }
442 
443     tmp = (FLOAT32)log(MAX(MIN_FLT_VAL, (tmp / (FLOAT32)size)));
444     if (j != 0) {
445       if (fabs(tmp - prev_val) >= 3.0f) {
446         if (1 == is_4_1) {
447           bin = ((k - (ptr_sfb_tab[j] * 2)) * 3) / 8;
448         } else {
449           bin = ((k - (ptr_sfb_tab[j] * 2)) * 3) / 4;
450         }
451         if (bin > 127) {
452           bin = -1;
453         }
454         break;
455       }
456     }
457     prev_val = tmp;
458     j++;
459   }
460 
461   return bin;
462 }
ixheaace_hbe_get_pitch_bins(FLOAT32 * ptr_time_in,ixheaace_pstr_sbr_config_data pstr_sbr_cfg,FLOAT32 * ptr_esbr_scr,ixheaace_str_sbr_tabs * ptr_sbr_tab,WORD32 time_sn_stride,WORD32 num_samples,WORD32 * bin1,WORD32 * bin2)463 static IA_ERRORCODE ixheaace_hbe_get_pitch_bins(FLOAT32 *ptr_time_in,
464                                                 ixheaace_pstr_sbr_config_data pstr_sbr_cfg,
465                                                 FLOAT32 *ptr_esbr_scr,
466                                                 ixheaace_str_sbr_tabs *ptr_sbr_tab,
467                                                 WORD32 time_sn_stride, WORD32 num_samples,
468                                                 WORD32 *bin1, WORD32 *bin2) {
469   const WORD32 *ptr_sbr_table = NULL;
470   FLOAT32 *ptr_esbr_inp = ptr_esbr_scr;
471   ptr_esbr_scr += num_samples * 2;
472   FLOAT32 *ptr_esbr_inp_i = ptr_esbr_inp + num_samples;
473   FLOAT32 *ptr_scratch_fft = ptr_esbr_scr;
474   WORD32 idx, sf, is_4_1 = 0;
475 
476   sf = pstr_sbr_cfg->sample_freq;
477   if (IXHEAACE_MAX_NUM_SAMPLES == num_samples) {
478     sf = sf >> 1;
479     is_4_1 = 1;
480   }
481 
482   switch (sf) {
483     case 16000:
484       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_8k;
485       break;
486     case 22050:
487       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_11k;
488       break;
489     case 24000:
490       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_12k;
491       break;
492     case 32000:
493       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_16k;
494       break;
495     case 44100:
496       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_22k;
497       break;
498     case 48000:
499       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_24k;
500       break;
501     default:
502       return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_SAMP_FREQ;
503   }
504   if (1 == pstr_sbr_cfg->num_ch) {
505     if (num_samples == 2048) {
506       for (idx = 0; idx < num_samples; idx += 2) {
507         ptr_esbr_inp[idx] = ptr_time_in[time_sn_stride * idx];
508         ptr_esbr_inp[idx + 1] = 0;
509         ptr_esbr_inp[num_samples + idx] = ptr_time_in[time_sn_stride * (idx + 1)];
510         ptr_esbr_inp[num_samples + idx + 1] = 0;
511       }
512       iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft);
513       *bin1 = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, is_4_1);
514     } else if (num_samples == IXHEAACE_MAX_NUM_SAMPLES) {
515       memset(ptr_esbr_inp_i, 0, num_samples * sizeof(ptr_esbr_inp_i[0]));
516       for (idx = 0; idx < num_samples; idx += 2) {
517         ptr_esbr_inp[idx / 2] = ptr_time_in[time_sn_stride * idx];
518         ptr_esbr_inp[(num_samples + idx) / 2] = ptr_time_in[time_sn_stride * (idx + 1)];
519       }
520       iusace_complex_fft_4096(ptr_esbr_inp, ptr_esbr_inp_i, ptr_scratch_fft);
521       *bin1 = ixheaace_get_pitch_bin_deint(ptr_esbr_inp, ptr_esbr_inp_i, ptr_sbr_table, is_4_1);
522     }
523   } else {
524     if (num_samples == 2048) {
525       for (idx = 0; idx < num_samples; idx += 2) {
526         ptr_esbr_inp[idx] = ptr_time_in[2 * idx];
527         ptr_esbr_inp[idx + 1] = 0;
528         ptr_esbr_inp[num_samples + idx] = ptr_time_in[2 * idx + 2];
529         ptr_esbr_inp[num_samples + idx + 1] = 0;
530       }
531       iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft);
532       *bin1 = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, is_4_1);
533 
534       for (idx = 0; idx < num_samples; idx += 2) {
535         ptr_esbr_inp[idx] = ptr_time_in[2 * idx + 1];
536         ptr_esbr_inp[idx + 1] = 0;
537         ptr_esbr_inp[num_samples + idx] = ptr_time_in[2 * idx + 3];
538         ptr_esbr_inp[num_samples + idx + 1] = 0;
539       }
540       iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft);
541       *bin2 = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, is_4_1);
542     } else if (num_samples == IXHEAACE_MAX_NUM_SAMPLES) {
543       memset(ptr_esbr_inp_i, 0, num_samples * sizeof(ptr_esbr_inp_i[0]));
544       for (idx = 0; idx < num_samples; idx += 2) {
545         ptr_esbr_inp[idx / 2] = ptr_time_in[2 * idx];
546         ptr_esbr_inp[(num_samples + idx) / 2] = ptr_time_in[2 * idx + 2];
547       }
548       iusace_complex_fft_4096(ptr_esbr_inp, ptr_esbr_inp_i, ptr_scratch_fft);
549       *bin1 = ixheaace_get_pitch_bin_deint(ptr_esbr_inp, ptr_esbr_inp_i, ptr_sbr_table, is_4_1);
550 
551       memset(ptr_esbr_inp_i, 0, num_samples * sizeof(ptr_esbr_inp_i[0]));
552       for (idx = 0; idx < num_samples; idx += 2) {
553         ptr_esbr_inp[idx / 2] = ptr_time_in[2 * idx + 1];
554         ptr_esbr_inp[(num_samples + idx) / 2] = ptr_time_in[2 * idx + 3];
555       }
556       iusace_complex_fft_4096(ptr_esbr_inp, ptr_esbr_inp_i, ptr_scratch_fft);
557       *bin2 = ixheaace_get_pitch_bin_deint(ptr_esbr_inp, ptr_esbr_inp_i, ptr_sbr_table, is_4_1);
558     }
559   }
560   return IA_NO_ERROR;
561 }
ixheaace_update_esbr_ext_data(FLOAT32 * ptr_time_in,ixheaace_pstr_sbr_config_data pstr_sbr_cfg,FLOAT32 * ptr_esbr_scr,ixheaace_str_esbr_bs_data * pstr_esbr,WORD32 transient_info[][3],ixheaace_str_sbr_tabs * ptr_sbr_tab,WORD32 coupling,WORD32 time_sn_stride,WORD32 num_samples)562 static IA_ERRORCODE ixheaace_update_esbr_ext_data(
563     FLOAT32 *ptr_time_in, ixheaace_pstr_sbr_config_data pstr_sbr_cfg, FLOAT32 *ptr_esbr_scr,
564     ixheaace_str_esbr_bs_data *pstr_esbr, WORD32 transient_info[][3],
565     ixheaace_str_sbr_tabs *ptr_sbr_tab, WORD32 coupling, WORD32 time_sn_stride,
566     WORD32 num_samples) {
567   WORD32 bin, bin1;
568   const WORD32 *ptr_sbr_table = NULL;
569   FLOAT32 *ptr_esbr_inp = ptr_esbr_scr;
570   ptr_esbr_scr += num_samples * 2;
571   FLOAT32 *ptr_scratch_fft = ptr_esbr_scr;
572   WORD32 idx;
573   switch (pstr_sbr_cfg->sample_freq) {
574     case 16000:
575       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_8k;
576       break;
577     case 22050:
578       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_11k;
579       break;
580     case 24000:
581       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_12k;
582       break;
583     case 32000:
584       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_16k;
585       break;
586     case 44100:
587       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_22k;
588       break;
589     case 48000:
590       ptr_sbr_table = ptr_sbr_tab->ptr_esbr_sfb_tab->sfb_bins_24k;
591       break;
592     default:
593       return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_SAMP_FREQ;
594   }
595   if (1 == pstr_sbr_cfg->num_ch) {
596     for (idx = 0; idx < num_samples; idx += 2) {
597       ptr_esbr_inp[idx] = ptr_time_in[time_sn_stride * idx];
598       ptr_esbr_inp[idx + 1] = 0;
599       ptr_esbr_inp[num_samples + idx] = ptr_time_in[time_sn_stride * (idx + 1)];
600       ptr_esbr_inp[num_samples + idx + 1] = 0;
601     }
602     iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft);
603     bin = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, 0);
604     pstr_esbr->sbr_num_chan = 1;
605     if (transient_info[0][1] != 0) {
606       pstr_esbr->sbr_preprocessing = 1;
607     } else {
608       pstr_esbr->sbr_preprocessing = 0;
609     }
610 
611     if (transient_info[0][1] != 0 && bin != -1) {
612       pstr_esbr->sbr_oversampling_flag[0] = 1;
613       pstr_esbr->sbr_patching_mode[0] = 0;
614       pstr_esbr->sbr_pitchin_flags[0] = 1;
615       pstr_esbr->sbr_pitchin_bins[0] = (UWORD8)MIN(bin, 127);
616     } else if (bin != -1) {
617       pstr_esbr->sbr_oversampling_flag[0] = 0;
618       pstr_esbr->sbr_patching_mode[0] = 0;
619       pstr_esbr->sbr_pitchin_flags[0] = 1;
620       pstr_esbr->sbr_pitchin_bins[0] = (UWORD8)MIN(bin, 127);
621     } else if (transient_info[0][1] != 0) {
622       pstr_esbr->sbr_oversampling_flag[0] = 1;
623       pstr_esbr->sbr_patching_mode[0] = 0;
624       pstr_esbr->sbr_pitchin_flags[0] = 0;
625     } else {
626       pstr_esbr->sbr_patching_mode[0] = 1;
627     }
628   } else {
629     pstr_esbr->sbr_num_chan = 2;
630     pstr_esbr->sbr_coupling = coupling;
631     for (idx = 0; idx < num_samples; idx += 2) {
632       ptr_esbr_inp[idx] = ptr_time_in[2 * idx];
633       ptr_esbr_inp[idx + 1] = 0;
634       ptr_esbr_inp[num_samples + idx] = ptr_time_in[2 * idx + 2];
635       ptr_esbr_inp[num_samples + idx + 1] = 0;
636     }
637     iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft);
638     bin = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, 0);
639     for (idx = 0; idx < num_samples; idx += 2) {
640       ptr_esbr_inp[idx] = ptr_time_in[2 * idx + 1];
641       ptr_esbr_inp[idx + 1] = 0;
642       ptr_esbr_inp[num_samples + idx] = ptr_time_in[2 * idx + 3];
643       ptr_esbr_inp[num_samples + idx + 1] = 0;
644     }
645     iusace_complex_fft_2048(ptr_esbr_inp, ptr_scratch_fft);
646     bin1 = ixheaace_get_pitch_bin(ptr_esbr_inp, ptr_sbr_table, 0);
647 
648     if (coupling) {
649       if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) {
650         pstr_esbr->sbr_preprocessing = 1;
651       } else {
652         pstr_esbr->sbr_preprocessing = 0;
653       }
654       if ((transient_info[0][1] != 0 || transient_info[1][1] != 0) && bin != -1) {
655         pstr_esbr->sbr_oversampling_flag[0] = 1;
656         pstr_esbr->sbr_patching_mode[0] = 0;
657         pstr_esbr->sbr_pitchin_flags[0] = 1;
658         bin = MIN(bin, bin1);
659         pstr_esbr->sbr_pitchin_bins[0] = (UWORD8)MIN(bin, 127);
660       } else if (bin != -1) {
661         pstr_esbr->sbr_oversampling_flag[0] = 0;
662         pstr_esbr->sbr_patching_mode[0] = 0;
663         pstr_esbr->sbr_pitchin_flags[0] = 1;
664         bin = MIN(bin, bin1);
665         pstr_esbr->sbr_pitchin_bins[0] = (UWORD8)MIN(bin, 127);
666       } else if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) {
667         pstr_esbr->sbr_oversampling_flag[0] = 1;
668         pstr_esbr->sbr_patching_mode[0] = 0;
669         pstr_esbr->sbr_pitchin_flags[0] = 0;
670       } else {
671         pstr_esbr->sbr_patching_mode[0] = 1;
672       }
673     } else {
674       pstr_esbr->sbr_preprocessing = 0;
675       if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) {
676         pstr_esbr->sbr_preprocessing = 1;
677       }
678 
679       if (transient_info[0][1] != 0 && bin != -1) {
680         pstr_esbr->sbr_oversampling_flag[0] = 1;
681         pstr_esbr->sbr_patching_mode[0] = 0;
682         pstr_esbr->sbr_pitchin_flags[0] = 1;
683         bin = MIN(bin, bin1);
684         pstr_esbr->sbr_pitchin_bins[0] = (UWORD8)MIN(bin, 127);
685       } else if (bin != -1) {
686         pstr_esbr->sbr_oversampling_flag[0] = 0;
687         pstr_esbr->sbr_patching_mode[0] = 0;
688         pstr_esbr->sbr_pitchin_flags[0] = 1;
689         pstr_esbr->sbr_pitchin_bins[0] = (UWORD8)MIN(bin, 127);
690       } else if (transient_info[0][1] != 0) {
691         pstr_esbr->sbr_oversampling_flag[0] = 1;
692         pstr_esbr->sbr_patching_mode[0] = 0;
693         pstr_esbr->sbr_pitchin_flags[0] = 0;
694       } else {
695         pstr_esbr->sbr_patching_mode[0] = 1;
696       }
697 
698       if (transient_info[1][1] != 0 && bin1 != -1) {
699         pstr_esbr->sbr_oversampling_flag[1] = 1;
700         pstr_esbr->sbr_patching_mode[1] = 0;
701         pstr_esbr->sbr_pitchin_flags[1] = 1;
702         pstr_esbr->sbr_pitchin_bins[1] = (UWORD8)MIN(bin1, 127);
703       } else if (bin1 != -1) {
704         pstr_esbr->sbr_oversampling_flag[1] = 0;
705         pstr_esbr->sbr_patching_mode[1] = 0;
706         pstr_esbr->sbr_pitchin_flags[1] = 1;
707         pstr_esbr->sbr_pitchin_bins[1] = (UWORD8)MIN(bin1, 127);
708       } else if (transient_info[1][1] != 0) {
709         pstr_esbr->sbr_oversampling_flag[1] = 1;
710         pstr_esbr->sbr_patching_mode[1] = 0;
711         pstr_esbr->sbr_pitchin_flags[1] = 0;
712       } else {
713         pstr_esbr->sbr_patching_mode[1] = 1;
714       }
715     }
716   }
717   return IA_NO_ERROR;
718 }
719 
ixheaace_update_harmonic_sbr_data(WORD32 transient_info[][3],WORD32 coupling,ixheaace_pstr_enc_channel * pstr_enc_ch,WORD32 num_channels)720 static VOID ixheaace_update_harmonic_sbr_data(
721     WORD32 transient_info[][3], WORD32 coupling,
722     ixheaace_pstr_enc_channel *pstr_enc_ch, WORD32 num_channels) {
723   WORD32 bin, bin1;
724   struct ixheaace_str_sbr_env_data *pstr_sbr_env_left = NULL;
725   struct ixheaace_str_sbr_env_data *pstr_sbr_env_right = NULL;
726   if (1 == num_channels) {
727     pstr_sbr_env_left = &pstr_enc_ch[0]->enc_env_data;
728     bin = pstr_sbr_env_left->sbr_pitchin_bins;
729     if (transient_info[0][1] != 0) {
730       pstr_sbr_env_left->sbr_preprocessing = 1;
731     } else {
732       pstr_sbr_env_left->sbr_preprocessing = 0;
733     }
734 
735     if (transient_info[0][1] != 0 && bin != -1) {
736       pstr_sbr_env_left->sbr_oversampling_flag = 1;
737       pstr_sbr_env_left->sbr_patching_mode = 0;
738       pstr_sbr_env_left->sbr_pitchin_bins_flag = 1;
739       pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127);
740     } else if (bin != -1) {
741       pstr_sbr_env_left->sbr_oversampling_flag = 0;
742       pstr_sbr_env_left->sbr_patching_mode = 0;
743       pstr_sbr_env_left->sbr_pitchin_bins_flag = 1;
744       pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127);
745     } else if (transient_info[0][1] != 0) {
746       pstr_sbr_env_left->sbr_oversampling_flag = 1;
747       pstr_sbr_env_left->sbr_patching_mode = 0;
748       pstr_sbr_env_left->sbr_pitchin_bins = 0;
749     } else {
750       pstr_sbr_env_left->sbr_patching_mode = 1;
751     }
752   } else {
753     pstr_sbr_env_left = &pstr_enc_ch[0]->enc_env_data;
754     pstr_sbr_env_right = &pstr_enc_ch[1]->enc_env_data;
755     pstr_sbr_env_left->sbr_coupling = coupling;
756     pstr_sbr_env_right->sbr_coupling = coupling;
757     bin = pstr_sbr_env_left->sbr_pitchin_bins;
758 
759     bin1 = pstr_sbr_env_right->sbr_pitchin_bins;
760 
761     if (coupling) {
762       pstr_sbr_env_right->sbr_preprocessing = 1;
763       if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) {
764         pstr_sbr_env_left->sbr_preprocessing = 1;
765       } else {
766         pstr_sbr_env_left->sbr_preprocessing = 0;
767       }
768       if ((transient_info[0][1] != 0 || transient_info[1][1] != 0) && bin != -1) {
769         pstr_sbr_env_left->sbr_oversampling_flag = 1;
770         pstr_sbr_env_left->sbr_patching_mode = 0;
771         pstr_sbr_env_left->sbr_pitchin_bins_flag = 1;
772         bin = min(bin, bin1);
773         pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127);
774       } else if (bin != -1) {
775         pstr_sbr_env_left->sbr_oversampling_flag = 0;
776         pstr_sbr_env_left->sbr_patching_mode = 0;
777         pstr_sbr_env_left->sbr_pitchin_bins_flag = 1;
778         bin = min(bin, bin1);
779         pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127);
780       } else if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) {
781         pstr_sbr_env_left->sbr_oversampling_flag = 1;
782         pstr_sbr_env_left->sbr_patching_mode = 0;
783         pstr_sbr_env_left->sbr_pitchin_bins_flag = 0;
784       } else {
785         pstr_sbr_env_left->sbr_patching_mode = 1;
786       }
787     } else {
788       pstr_sbr_env_left->sbr_preprocessing = 0;
789       pstr_sbr_env_right->sbr_preprocessing = 0;
790       if ((transient_info[0][1] != 0 || transient_info[1][1] != 0)) {
791         pstr_sbr_env_left->sbr_preprocessing = 1;
792         pstr_sbr_env_right->sbr_preprocessing = 1;
793       }
794 
795       if (transient_info[0][1] != 0 && bin != -1) {
796         pstr_sbr_env_left->sbr_oversampling_flag = 1;
797         pstr_sbr_env_left->sbr_patching_mode = 0;
798         pstr_sbr_env_left->sbr_pitchin_bins_flag = 1;
799         bin = min(bin, bin1);
800         pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127);
801       } else if (bin != -1) {
802         pstr_sbr_env_left->sbr_oversampling_flag = 0;
803         pstr_sbr_env_left->sbr_patching_mode = 0;
804         pstr_sbr_env_left->sbr_pitchin_bins_flag = 1;
805         pstr_sbr_env_left->sbr_pitchin_bins = min(bin, 127);
806       } else if (transient_info[0][1] != 0) {
807         pstr_sbr_env_left->sbr_oversampling_flag = 1;
808         pstr_sbr_env_left->sbr_patching_mode = 0;
809         pstr_sbr_env_left->sbr_pitchin_bins_flag = 0;
810       } else {
811         pstr_sbr_env_left->sbr_patching_mode = 1;
812       }
813 
814       if (transient_info[1][1] != 0 && bin1 != -1) {
815         pstr_sbr_env_right->sbr_oversampling_flag = 1;
816         pstr_sbr_env_right->sbr_patching_mode = 0;
817         pstr_sbr_env_right->sbr_pitchin_bins_flag = 1;
818         pstr_sbr_env_right->sbr_pitchin_bins = bin1 < 127 ? bin1 : 127;
819       } else if (bin1 != -1) {
820         pstr_sbr_env_right->sbr_oversampling_flag = 0;
821         pstr_sbr_env_right->sbr_patching_mode = 0;
822         pstr_sbr_env_right->sbr_pitchin_bins_flag = 1;
823         pstr_sbr_env_right->sbr_pitchin_bins = bin1 < 127 ? bin1 : 127;
824       } else if (transient_info[1][1] != 0) {
825         pstr_sbr_env_right->sbr_oversampling_flag = 1;
826         pstr_sbr_env_right->sbr_patching_mode = 0;
827         pstr_sbr_env_right->sbr_pitchin_bins_flag = 0;
828       } else {
829         pstr_sbr_env_right->sbr_patching_mode = 1;
830       }
831     }
832   }
833 }
834 
ixheaace_esbr_qmf_init(ia_sbr_qmf_filter_bank_struct * pstr_codec_qmf_bank,WORD32 sbr_ratio_idx,WORD32 output_frame_size)835 VOID ixheaace_esbr_qmf_init(ia_sbr_qmf_filter_bank_struct *pstr_codec_qmf_bank,
836                             WORD32 sbr_ratio_idx, WORD32 output_frame_size) {
837   pstr_codec_qmf_bank->pstr_qmf_dec_tabs =
838       (ixheaace_str_qmf_dec_tabs_struct *)&ixheaace_str_aac_qmf_tabs;
839   memset(
840       pstr_codec_qmf_bank->anal_filter_states_32, 0,
841       sizeof(pstr_codec_qmf_bank->anal_filter_states_32[0]) * IXHEAACE_QMF_FILTER_STATE_ANA_SIZE);
842   pstr_codec_qmf_bank->num_time_slots = (WORD16)(output_frame_size / 64);
843   pstr_codec_qmf_bank->ptr_filter_pos_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c;
844   pstr_codec_qmf_bank->ptr_state_new_samples_pos_low_32 =
845       pstr_codec_qmf_bank->anal_filter_states_32;
846   pstr_codec_qmf_bank->ptr_ana_win_coeff_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c;
847 
848   switch (sbr_ratio_idx) {
849     case USAC_SBR_RATIO_INDEX_2_1:
850       pstr_codec_qmf_bank->no_channels = 32;
851       pstr_codec_qmf_bank->ptr_esbr_cos_twiddle =
852           ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l32;
853       pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle =
854           ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l32;
855       pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l32;
856       break;
857     case USAC_SBR_RATIO_INDEX_8_3:
858       pstr_codec_qmf_bank->no_channels = 24;
859       pstr_codec_qmf_bank->ptr_filter_pos_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c_24;
860       pstr_codec_qmf_bank->ptr_ana_win_coeff_32 = ixheaace_str_aac_qmf_tabs.esbr_qmf_c_24;
861       pstr_codec_qmf_bank->ptr_esbr_cos_twiddle =
862           ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l24;
863       pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle =
864           ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l24;
865       pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l24;
866       break;
867     case USAC_SBR_RATIO_INDEX_4_1:
868       pstr_codec_qmf_bank->no_channels = 16;
869       pstr_codec_qmf_bank->ptr_esbr_cos_twiddle =
870           ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l16;
871       pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle =
872           ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l16;
873       pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l16;
874       break;
875     default:
876       pstr_codec_qmf_bank->no_channels = 32;
877       pstr_codec_qmf_bank->ptr_esbr_cos_twiddle =
878           ixheaace_str_aac_qmf_tabs.esbr_sin_cos_twiddle_l32;
879       pstr_codec_qmf_bank->ptr_esbr_alt_sin_twiddle =
880           ixheaace_str_aac_qmf_tabs.esbr_alt_sin_twiddle_l32;
881       pstr_codec_qmf_bank->ptr_esbr_t_cos = ixheaace_str_aac_qmf_tabs.esbr_t_cos_sin_l32;
882       break;
883   }
884 }
ixheaace_esbr_qmfanal32_winadd(FLOAT32 * ptr_inp1,FLOAT32 * ptr_inp2,FLOAT32 * ptr_qmf1,FLOAT32 * ptr_qmf2,FLOAT32 * ptr_out,WORD32 num_band_anal_qmf)885 VOID ixheaace_esbr_qmfanal32_winadd(FLOAT32 *ptr_inp1, FLOAT32 *ptr_inp2, FLOAT32 *ptr_qmf1,
886                                     FLOAT32 *ptr_qmf2, FLOAT32 *ptr_out,
887                                     WORD32 num_band_anal_qmf) {
888   WORD32 n;
889   FLOAT32 accu;
890 
891   switch (num_band_anal_qmf) {
892     case 32: {
893       n = 0;
894       while (n < num_band_anal_qmf) {
895         accu = (ptr_inp1[n + 0] * ptr_qmf1[2 * (n + 0)]);
896         accu += (ptr_inp1[n + 2 * num_band_anal_qmf] * ptr_qmf1[2 * (n + 2 * num_band_anal_qmf)]);
897         accu += (ptr_inp1[n + 4 * num_band_anal_qmf] * ptr_qmf1[2 * (n + 4 * num_band_anal_qmf)]);
898         accu += (ptr_inp1[n + 6 * num_band_anal_qmf] * ptr_qmf1[2 * (n + 6 * num_band_anal_qmf)]);
899         accu += (ptr_inp1[n + 8 * num_band_anal_qmf] * ptr_qmf1[2 * (n + 8 * num_band_anal_qmf)]);
900         ptr_out[n] = 2 * accu;
901 
902         accu = (ptr_inp1[n + 1 + 0] * ptr_qmf1[2 * (n + 1 + 0)]);
903         accu += (ptr_inp1[n + 1 + 2 * num_band_anal_qmf] *
904                  ptr_qmf1[2 * (n + 1 + 2 * num_band_anal_qmf)]);
905         accu += (ptr_inp1[n + 1 + 4 * num_band_anal_qmf] *
906                  ptr_qmf1[2 * (n + 1 + 4 * num_band_anal_qmf)]);
907         accu += (ptr_inp1[n + 1 + 6 * num_band_anal_qmf] *
908                  ptr_qmf1[2 * (n + 1 + 6 * num_band_anal_qmf)]);
909         accu += (ptr_inp1[n + 1 + 8 * num_band_anal_qmf] *
910                  ptr_qmf1[2 * (n + 1 + 8 * num_band_anal_qmf)]);
911         ptr_out[n + 1] = 2 * accu;
912 
913         accu = (ptr_inp2[n + 0] * ptr_qmf2[2 * (n + 0)]);
914         accu += (ptr_inp2[n + 2 * num_band_anal_qmf] * ptr_qmf2[2 * (n + 2 * num_band_anal_qmf)]);
915         accu += (ptr_inp2[n + 4 * num_band_anal_qmf] * ptr_qmf2[2 * (n + 4 * num_band_anal_qmf)]);
916         accu += (ptr_inp2[n + 6 * num_band_anal_qmf] * ptr_qmf2[2 * (n + 6 * num_band_anal_qmf)]);
917         accu += (ptr_inp2[n + 8 * num_band_anal_qmf] * ptr_qmf2[2 * (n + 8 * num_band_anal_qmf)]);
918         ptr_out[n + num_band_anal_qmf] = 2 * accu;
919 
920         accu = (ptr_inp2[n + 1 + 0] * ptr_qmf2[2 * (n + 1 + 0)]);
921         accu += (ptr_inp2[n + 1 + 2 * num_band_anal_qmf] *
922                  ptr_qmf2[2 * (n + 1 + 2 * num_band_anal_qmf)]);
923         accu += (ptr_inp2[n + 1 + 4 * num_band_anal_qmf] *
924                  ptr_qmf2[2 * (n + 1 + 4 * num_band_anal_qmf)]);
925         accu += (ptr_inp2[n + 1 + 6 * num_band_anal_qmf] *
926                  ptr_qmf2[2 * (n + 1 + 6 * num_band_anal_qmf)]);
927         accu += (ptr_inp2[n + 1 + 8 * num_band_anal_qmf] *
928                  ptr_qmf2[2 * (n + 1 + 8 * num_band_anal_qmf)]);
929         ptr_out[n + 1 + num_band_anal_qmf] = 2 * accu;
930 
931         n += 2;
932       }
933       break;
934     }
935     case 24: {
936       n = 0;
937       while (n < num_band_anal_qmf) {
938         accu = (ptr_inp1[n + 0] * ptr_qmf1[(n + 0)]);
939         accu += (ptr_inp1[n + 2 * num_band_anal_qmf] * ptr_qmf1[(n + 2 * num_band_anal_qmf)]);
940         accu += (ptr_inp1[n + 4 * num_band_anal_qmf] * ptr_qmf1[(n + 4 * num_band_anal_qmf)]);
941         accu += (ptr_inp1[n + 6 * num_band_anal_qmf] * ptr_qmf1[(n + 6 * num_band_anal_qmf)]);
942         accu += (ptr_inp1[n + 8 * num_band_anal_qmf] * ptr_qmf1[(n + 8 * num_band_anal_qmf)]);
943         ptr_out[n] = 2 * accu;
944 
945         accu = (ptr_inp1[n + 1 + 0] * ptr_qmf1[(n + 1 + 0)]);
946         accu +=
947             (ptr_inp1[n + 1 + 2 * num_band_anal_qmf] * ptr_qmf1[(n + 1 + 2 * num_band_anal_qmf)]);
948         accu +=
949             (ptr_inp1[n + 1 + 4 * num_band_anal_qmf] * ptr_qmf1[(n + 1 + 4 * num_band_anal_qmf)]);
950         accu +=
951             (ptr_inp1[n + 1 + 6 * num_band_anal_qmf] * ptr_qmf1[(n + 1 + 6 * num_band_anal_qmf)]);
952         accu +=
953             (ptr_inp1[n + 1 + 8 * num_band_anal_qmf] * ptr_qmf1[(n + 1 + 8 * num_band_anal_qmf)]);
954         ptr_out[n + 1] = 2 * accu;
955 
956         accu = (ptr_inp2[n + 0] * ptr_qmf2[(n + 0)]);
957         accu += (ptr_inp2[n + 2 * num_band_anal_qmf] * ptr_qmf2[(n + 2 * num_band_anal_qmf)]);
958         accu += (ptr_inp2[n + 4 * num_band_anal_qmf] * ptr_qmf2[(n + 4 * num_band_anal_qmf)]);
959         accu += (ptr_inp2[n + 6 * num_band_anal_qmf] * ptr_qmf2[(n + 6 * num_band_anal_qmf)]);
960         accu += (ptr_inp2[n + 8 * num_band_anal_qmf] * ptr_qmf2[(n + 8 * num_band_anal_qmf)]);
961         ptr_out[n + num_band_anal_qmf] = 2 * accu;
962 
963         accu = (ptr_inp2[n + 1 + 0] * ptr_qmf2[(n + 1 + 0)]);
964         accu +=
965             (ptr_inp2[n + 1 + 2 * num_band_anal_qmf] * ptr_qmf2[(n + 1 + 2 * num_band_anal_qmf)]);
966         accu +=
967             (ptr_inp2[n + 1 + 4 * num_band_anal_qmf] * ptr_qmf2[(n + 1 + 4 * num_band_anal_qmf)]);
968         accu +=
969             (ptr_inp2[n + 1 + 6 * num_band_anal_qmf] * ptr_qmf2[(n + 1 + 6 * num_band_anal_qmf)]);
970         accu +=
971             (ptr_inp2[n + 1 + 8 * num_band_anal_qmf] * ptr_qmf2[(n + 1 + 8 * num_band_anal_qmf)]);
972         ptr_out[n + 1 + num_band_anal_qmf] = 2 * accu;
973         n += 2;
974       }
975       break;
976     }
977     default: {
978       n = 0;
979       while (n < num_band_anal_qmf) {
980         accu = (ptr_inp1[n + 0] * ptr_qmf1[4 * (n + 0)]);
981         accu += (ptr_inp1[n + 2 * num_band_anal_qmf] * ptr_qmf1[4 * (n + 2 * num_band_anal_qmf)]);
982         accu += (ptr_inp1[n + 4 * num_band_anal_qmf] * ptr_qmf1[4 * (n + 4 * num_band_anal_qmf)]);
983         accu += (ptr_inp1[n + 6 * num_band_anal_qmf] * ptr_qmf1[4 * (n + 6 * num_band_anal_qmf)]);
984         accu += (ptr_inp1[n + 8 * num_band_anal_qmf] * ptr_qmf1[4 * (n + 8 * num_band_anal_qmf)]);
985         ptr_out[n] = 2 * accu;
986 
987         accu = (ptr_inp1[n + 1 + 0] * ptr_qmf1[4 * (n + 1 + 0)]);
988         accu += (ptr_inp1[n + 1 + 2 * num_band_anal_qmf] *
989                  ptr_qmf1[4 * (n + 1 + 2 * num_band_anal_qmf)]);
990         accu += (ptr_inp1[n + 1 + 4 * num_band_anal_qmf] *
991                  ptr_qmf1[4 * (n + 1 + 4 * num_band_anal_qmf)]);
992         accu += (ptr_inp1[n + 1 + 6 * num_band_anal_qmf] *
993                  ptr_qmf1[4 * (n + 1 + 6 * num_band_anal_qmf)]);
994         accu += (ptr_inp1[n + 1 + 8 * num_band_anal_qmf] *
995                  ptr_qmf1[4 * (n + 1 + 8 * num_band_anal_qmf)]);
996         ptr_out[n + 1] = 2 * accu;
997 
998         accu = (ptr_inp2[n + 0] * ptr_qmf2[4 * (n + 0)]);
999         accu += (ptr_inp2[n + 2 * num_band_anal_qmf] * ptr_qmf2[4 * (n + 2 * num_band_anal_qmf)]);
1000         accu += (ptr_inp2[n + 4 * num_band_anal_qmf] * ptr_qmf2[4 * (n + 4 * num_band_anal_qmf)]);
1001         accu += (ptr_inp2[n + 6 * num_band_anal_qmf] * ptr_qmf2[4 * (n + 6 * num_band_anal_qmf)]);
1002         accu += (ptr_inp2[n + 8 * num_band_anal_qmf] * ptr_qmf2[4 * (n + 8 * num_band_anal_qmf)]);
1003         ptr_out[n + num_band_anal_qmf] = 2 * accu;
1004 
1005         accu = (ptr_inp2[n + 1 + 0] * ptr_qmf2[4 * (n + 1 + 0)]);
1006         accu += (ptr_inp2[n + 1 + 2 * num_band_anal_qmf] *
1007                  ptr_qmf2[4 * (n + 1 + 2 * num_band_anal_qmf)]);
1008         accu += (ptr_inp2[n + 1 + 4 * num_band_anal_qmf] *
1009                  ptr_qmf2[4 * (n + 1 + 4 * num_band_anal_qmf)]);
1010         accu += (ptr_inp2[n + 1 + 6 * num_band_anal_qmf] *
1011                  ptr_qmf2[4 * (n + 1 + 6 * num_band_anal_qmf)]);
1012         accu += (ptr_inp2[n + 1 + 8 * num_band_anal_qmf] *
1013                  ptr_qmf2[4 * (n + 1 + 8 * num_band_anal_qmf)]);
1014         ptr_out[n + 1 + num_band_anal_qmf] = 2 * accu;
1015         n += 2;
1016       }
1017       break;
1018     }
1019   }
1020 }
1021 
ixheaace_esbr_radix4bfly(const FLOAT32 * ptr_w_in,FLOAT32 * ptr_x,WORD32 index1,WORD32 index)1022 VOID ixheaace_esbr_radix4bfly(const FLOAT32 *ptr_w_in, FLOAT32 *ptr_x, WORD32 index1,
1023                               WORD32 index) {
1024   int i;
1025   WORD32 l1, l2, h2, fft_jmp;
1026   FLOAT32 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0;
1027   FLOAT32 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0;
1028   FLOAT32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1;
1029   FLOAT32 x_h2_0, x_h2_1;
1030   FLOAT32 si10, si20, si30, co10, co20, co30;
1031 
1032   FLOAT32 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6;
1033   FLOAT32 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12;
1034 
1035   const FLOAT32 *ptr_w = ptr_w_in;
1036   WORD32 i1;
1037 
1038   h2 = index << 1;
1039   l1 = index << 2;
1040   l2 = (index << 2) + (index << 1);
1041 
1042   fft_jmp = 6 * (index);
1043 
1044   i1 = 0;
1045   while (i1 < index1) {
1046     for (i = 0; i < index; i++) {
1047       si10 = (*ptr_w++);
1048       co10 = (*ptr_w++);
1049       si20 = (*ptr_w++);
1050       co20 = (*ptr_w++);
1051       si30 = (*ptr_w++);
1052       co30 = (*ptr_w++);
1053 
1054       x_0 = ptr_x[0];
1055       x_h2_0 = ptr_x[h2];
1056       x_l1_0 = ptr_x[l1];
1057       x_l2_0 = ptr_x[l2];
1058 
1059       xh0_0 = (x_0 + x_l1_0);
1060       xl0_0 = (x_0 - x_l1_0);
1061 
1062       xh20_0 = (x_h2_0 + x_l2_0);
1063       xl20_0 = (x_h2_0 - x_l2_0);
1064 
1065       ptr_x[0] = (xh0_0 + xh20_0);
1066       xt0_0 = (xh0_0 - xh20_0);
1067 
1068       x_1 = ptr_x[1];
1069       x_h2_1 = ptr_x[h2 + 1];
1070       x_l1_1 = ptr_x[l1 + 1];
1071       x_l2_1 = ptr_x[l2 + 1];
1072 
1073       xh1_0 = (x_1 + x_l1_1);
1074       xl1_0 = (x_1 - x_l1_1);
1075 
1076       xh21_0 = (x_h2_1 + x_l2_1);
1077       xl21_0 = (x_h2_1 - x_l2_1);
1078 
1079       ptr_x[1] = (xh1_0 + xh21_0);
1080       yt0_0 = (xh1_0 - xh21_0);
1081 
1082       xt1_0 = (xl0_0 + xl21_0);
1083       xt2_0 = (xl0_0 - xl21_0);
1084 
1085       yt2_0 = (xl1_0 + xl20_0);
1086       yt1_0 = (xl1_0 - xl20_0);
1087 
1088       mul_11 = (xt2_0 * co30);
1089       mul_3 = (yt2_0 * si30);
1090       ptr_x[l2] = 2 * (mul_3 + mul_11);
1091 
1092       mul_5 = (xt2_0 * si30);
1093       mul_9 = (yt2_0 * co30);
1094       ptr_x[l2 + 1] = 2 * (mul_9 - mul_5);
1095 
1096       mul_12 = (xt0_0 * co20);
1097       mul_2 = (yt0_0 * si20);
1098       ptr_x[l1] = 2 * (mul_2 + mul_12);
1099 
1100       mul_6 = (xt0_0 * si20);
1101       mul_8 = (yt0_0 * co20);
1102       ptr_x[l1 + 1] = 2 * (mul_8 - mul_6);
1103 
1104       mul_4 = (xt1_0 * co10);
1105       mul_1 = (yt1_0 * si10);
1106       ptr_x[h2] = 2 * (mul_1 + mul_4);
1107 
1108       mul_10 = (xt1_0 * si10);
1109       mul_7 = (yt1_0 * co10);
1110       ptr_x[h2 + 1] = 2 * (mul_7 - mul_10);
1111 
1112       ptr_x += 2;
1113     }
1114     ptr_x += fft_jmp;
1115     ptr_w = ptr_w - fft_jmp;
1116     i1++;
1117   }
1118 }
1119 
ixheaace_esbr_postradixcompute2(FLOAT32 * ptr_y,FLOAT32 * ptr_x,const FLOAT32 * ptr_dig_rev_tbl,WORD32 npoints)1120 VOID ixheaace_esbr_postradixcompute2(FLOAT32 *ptr_y, FLOAT32 *ptr_x,
1121                                      const FLOAT32 *ptr_dig_rev_tbl, WORD32 npoints) {
1122   WORD32 i, k;
1123   WORD32 h2;
1124   FLOAT32 x_0, x_1, x_2, x_3;
1125   FLOAT32 x_4, x_5, x_6, x_7;
1126   FLOAT32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f;
1127   FLOAT32 n00, n10, n20, n30, n01, n11, n21, n31;
1128   FLOAT32 n02, n12, n22, n32, n03, n13, n23, n33;
1129 
1130   FLOAT32 *ptr_x2, *ptr_x0;
1131   FLOAT32 *ptr_y0, *ptr_y1, *ptr_y2, *ptr_y3;
1132 
1133   ptr_y0 = ptr_y;
1134   ptr_y2 = ptr_y + (WORD32)npoints;
1135   ptr_x0 = ptr_x;
1136   ptr_x2 = ptr_x + (WORD32)(npoints >> 1);
1137 
1138   ptr_y1 = ptr_y0 + (WORD32)(npoints >> 2);
1139   ptr_y3 = ptr_y2 + (WORD32)(npoints >> 2);
1140 
1141   for (k = 0; k < 2; k++) {
1142     for (i = 0; i<npoints>> 1; i += 8) {
1143       h2 = (WORD32)*ptr_dig_rev_tbl++ / 4;
1144 
1145       x_0 = *ptr_x0++;
1146       x_1 = *ptr_x0++;
1147       x_2 = *ptr_x0++;
1148       x_3 = *ptr_x0++;
1149       x_4 = *ptr_x0++;
1150       x_5 = *ptr_x0++;
1151       x_6 = *ptr_x0++;
1152       x_7 = *ptr_x0++;
1153 
1154       n00 = (x_0 + x_2);
1155       n01 = (x_1 + x_3);
1156 
1157       n20 = (x_0 - x_2);
1158       n21 = (x_1 - x_3);
1159 
1160       n10 = (x_4 + x_6);
1161       n11 = (x_5 + x_7);
1162 
1163       n30 = (x_4 - x_6);
1164       n31 = (x_5 - x_7);
1165 
1166       ptr_y0[h2] = n00;
1167       ptr_y0[h2 + 1] = n01;
1168       ptr_y1[h2] = n10;
1169       ptr_y1[h2 + 1] = n11;
1170       ptr_y2[h2] = n20;
1171       ptr_y2[h2 + 1] = n21;
1172       ptr_y3[h2] = n30;
1173       ptr_y3[h2 + 1] = n31;
1174 
1175       x_8 = *ptr_x2++;
1176       x_9 = *ptr_x2++;
1177       x_a = *ptr_x2++;
1178       x_b = *ptr_x2++;
1179       x_c = *ptr_x2++;
1180       x_d = *ptr_x2++;
1181       x_e = *ptr_x2++;
1182       x_f = *ptr_x2++;
1183 
1184       n02 = (x_8 + x_a);
1185       n03 = (x_9 + x_b);
1186 
1187       n22 = (x_8 - x_a);
1188       n23 = (x_9 - x_b);
1189 
1190       n12 = (x_c + x_e);
1191       n13 = (x_d + x_f);
1192 
1193       n32 = (x_c - x_e);
1194       n33 = (x_d - x_f);
1195 
1196       ptr_y0[h2 + 2] = n02;
1197       ptr_y0[h2 + 3] = n03;
1198       ptr_y1[h2 + 2] = n12;
1199       ptr_y1[h2 + 3] = n13;
1200       ptr_y2[h2 + 2] = n22;
1201       ptr_y2[h2 + 3] = n23;
1202       ptr_y3[h2 + 2] = n32;
1203       ptr_y3[h2 + 3] = n33;
1204     }
1205     ptr_x0 += (WORD32)npoints >> 1;
1206     ptr_x2 += (WORD32)npoints >> 1;
1207   }
1208 }
1209 
ixheaace_esbr_postradixcompute4(FLOAT32 * ptr_y,FLOAT32 * ptr_x,const FLOAT32 * ptr_dig_rev_tbl,WORD32 npoints)1210 VOID ixheaace_esbr_postradixcompute4(FLOAT32 *ptr_y, FLOAT32 *ptr_x,
1211                                      const FLOAT32 *ptr_dig_rev_tbl, WORD32 npoints) {
1212   WORD32 i, k;
1213   WORD32 h2;
1214   FLOAT32 xh0_0, xh1_0, xl0_0, xl1_0;
1215   FLOAT32 xh0_1, xh1_1, xl0_1, xl1_1;
1216   FLOAT32 x_0, x_1, x_2, x_3;
1217   FLOAT32 xh0_2, xh1_2, xl0_2, xl1_2, xh0_3, xh1_3, xl0_3, xl1_3;
1218   FLOAT32 x_4, x_5, x_6, x_7;
1219   FLOAT32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f;
1220   FLOAT32 n00, n10, n20, n30, n01, n11, n21, n31;
1221   FLOAT32 n02, n12, n22, n32, n03, n13, n23, n33;
1222 
1223   FLOAT32 *ptr_x2, *ptr_x0;
1224   FLOAT32 *ptr_y0, *ptr_y1, *ptr_y2, *ptr_y3;
1225 
1226   ptr_y0 = ptr_y;
1227   ptr_y2 = ptr_y + npoints;
1228   ptr_x0 = ptr_x;
1229   ptr_x2 = ptr_x + (WORD32)(npoints >> 1);
1230 
1231   ptr_y1 = ptr_y0 + (WORD32)(npoints >> 1);
1232   ptr_y3 = ptr_y2 + (WORD32)(npoints >> 1);
1233 
1234   for (k = 0; k < 2; k++) {
1235     for (i = 0; i<npoints>> 1; i += 8) {
1236       h2 = (WORD32)*ptr_dig_rev_tbl++ / 4;
1237       x_0 = *ptr_x0++;
1238       x_1 = *ptr_x0++;
1239       x_2 = *ptr_x0++;
1240       x_3 = *ptr_x0++;
1241       x_4 = *ptr_x0++;
1242       x_5 = *ptr_x0++;
1243       x_6 = *ptr_x0++;
1244       x_7 = *ptr_x0++;
1245 
1246       xh0_0 = (x_0 + x_4);
1247       xh1_0 = (x_1 + x_5);
1248 
1249       xl0_0 = (x_0 - x_4);
1250       xl1_0 = (x_1 - x_5);
1251 
1252       xh0_1 = (x_2 + x_6);
1253       xh1_1 = (x_3 + x_7);
1254 
1255       xl0_1 = (x_2 - x_6);
1256       xl1_1 = (x_3 - x_7);
1257 
1258       n00 = (xh0_0 + xh0_1);
1259       n01 = (xh1_0 + xh1_1);
1260       n10 = (xl0_0 + xl1_1);
1261 
1262       n11 = (xl1_0 - xl0_1);
1263       n20 = (xh0_0 - xh0_1);
1264       n21 = (xh1_0 - xh1_1);
1265       n30 = (xl0_0 - xl1_1);
1266 
1267       n31 = (xl1_0 + xl0_1);
1268 
1269       ptr_y0[h2] = n00;
1270       ptr_y0[h2 + 1] = n01;
1271       ptr_y1[h2] = n10;
1272       ptr_y1[h2 + 1] = n11;
1273       ptr_y2[h2] = n20;
1274       ptr_y2[h2 + 1] = n21;
1275       ptr_y3[h2] = n30;
1276       ptr_y3[h2 + 1] = n31;
1277 
1278       x_8 = *ptr_x2++;
1279       x_9 = *ptr_x2++;
1280       x_a = *ptr_x2++;
1281       x_b = *ptr_x2++;
1282       x_c = *ptr_x2++;
1283       x_d = *ptr_x2++;
1284       x_e = *ptr_x2++;
1285       x_f = *ptr_x2++;
1286 
1287       xh0_2 = (x_8 + x_c);
1288       xh1_2 = (x_9 + x_d);
1289 
1290       xl0_2 = (x_8 - x_c);
1291       xl1_2 = (x_9 - x_d);
1292 
1293       xh0_3 = (x_a + x_e);
1294       xh1_3 = (x_b + x_f);
1295 
1296       xl0_3 = (x_a - x_e);
1297       xl1_3 = (x_b - x_f);
1298 
1299       n02 = (xh0_2 + xh0_3);
1300       n03 = (xh1_2 + xh1_3);
1301       n12 = (xl0_2 + xl1_3);
1302 
1303       n13 = (xl1_2 - xl0_3);
1304       n22 = (xh0_2 - xh0_3);
1305       n23 = (xh1_2 - xh1_3);
1306       n32 = (xl0_2 - xl1_3);
1307 
1308       n33 = (xl1_2 + xl0_3);
1309 
1310       ptr_y0[h2 + 2] = n02;
1311       ptr_y0[h2 + 3] = n03;
1312       ptr_y1[h2 + 2] = n12;
1313       ptr_y1[h2 + 3] = n13;
1314       ptr_y2[h2 + 2] = n22;
1315       ptr_y2[h2 + 3] = n23;
1316       ptr_y3[h2 + 2] = n32;
1317       ptr_y3[h2 + 3] = n33;
1318     }
1319     ptr_x0 += (WORD32)npoints >> 1;
1320     ptr_x2 += (WORD32)npoints >> 1;
1321   }
1322 }
1323 
ixheaace_esbr_cos_sin_mod(FLOAT32 * subband,ia_sbr_qmf_filter_bank_struct * pstr_qmf_bank,FLOAT32 * ptr_twiddle,FLOAT32 * ptr_dig_rev_tbl)1324 VOID ixheaace_esbr_cos_sin_mod(FLOAT32 *subband, ia_sbr_qmf_filter_bank_struct *pstr_qmf_bank,
1325                                FLOAT32 *ptr_twiddle, FLOAT32 *ptr_dig_rev_tbl) {
1326   WORD32 z;
1327   FLOAT32 temp[128] = {0};
1328 
1329   FLOAT32 re2, re3;
1330   FLOAT32 wim, wre;
1331 
1332   WORD32 i, M_2;
1333   WORD32 M = pstr_qmf_bank->no_channels / 2;
1334 
1335   const FLOAT32 *ptr_sin;
1336   const FLOAT32 *ptr_sin_cos;
1337 
1338   FLOAT32 subband_tmp[128] = {0};
1339   FLOAT32 re;
1340   FLOAT32 im;
1341   FLOAT32 *ptr_subband, *ptr_subband1;
1342   FLOAT32 *ptr_subband_t, *ptr_subband1_t;
1343   FLOAT32 *ptr_subband2, *ptr_subband12;
1344   FLOAT32 *ptr_subband_t2, *ptr_subband1_t2;
1345 
1346   M_2 = M / 2;
1347 
1348   ptr_sin_cos = pstr_qmf_bank->ptr_esbr_cos_twiddle;
1349 
1350   ptr_subband = &subband[0];
1351   ptr_subband1 = &subband[2 * M - 1];
1352   ptr_subband_t = subband_tmp;
1353   ptr_subband1_t = &subband_tmp[2 * M - 1];
1354 
1355   ptr_subband2 = &subband[64];
1356   ptr_subband12 = &subband[2 * M - 1 + 64];
1357   ptr_subband_t2 = &subband_tmp[64];
1358   ptr_subband1_t2 = &subband_tmp[2 * M - 1 + 64];
1359 
1360   i = (M_2 >> 1) - 1;
1361   while (i >= 0) {
1362     re = *ptr_subband++;
1363     im = *ptr_subband1--;
1364 
1365     wim = *ptr_sin_cos++;
1366     wre = *ptr_sin_cos++;
1367 
1368     *ptr_subband_t++ = (re * wre) + (im * wim);
1369     *ptr_subband_t++ = (im * wre) - (re * wim);
1370 
1371     re = *ptr_subband2++;
1372     im = *ptr_subband12--;
1373 
1374     *ptr_subband_t2++ = (im * wim) - (re * wre);
1375     *ptr_subband_t2++ = (re * wim) + (im * wre);
1376 
1377     re = *ptr_subband1--;
1378     im = *ptr_subband++;
1379 
1380     wim = *ptr_sin_cos++;
1381     wre = *ptr_sin_cos++;
1382 
1383     *ptr_subband1_t-- = (im * wre) - (re * wim);
1384     *ptr_subband1_t-- = (re * wre) + (im * wim);
1385 
1386     re = *ptr_subband12--;
1387     im = *ptr_subband2++;
1388 
1389     *ptr_subband1_t2-- = (re * wim) + (im * wre);
1390     *ptr_subband1_t2-- = (im * wim) - (re * wre);
1391 
1392     re = *ptr_subband++;
1393     im = *ptr_subband1--;
1394 
1395     wim = *ptr_sin_cos++;
1396     wre = *ptr_sin_cos++;
1397 
1398     *ptr_subband_t++ = (re * wre) + (im * wim);
1399     *ptr_subband_t++ = (im * wre) - (re * wim);
1400 
1401     re = *ptr_subband2++;
1402     im = *ptr_subband12--;
1403 
1404     *ptr_subband_t2++ = (im * wim) - (re * wre);
1405     *ptr_subband_t2++ = (re * wim) + (im * wre);
1406 
1407     re = *ptr_subband1--;
1408     im = *ptr_subband++;
1409 
1410     wim = *ptr_sin_cos++;
1411     wre = *ptr_sin_cos++;
1412 
1413     *ptr_subband1_t-- = (im * wre) - (re * wim);
1414     *ptr_subband1_t-- = (re * wre) + (im * wim);
1415 
1416     re = *ptr_subband12--;
1417     im = *ptr_subband2++;
1418 
1419     *ptr_subband1_t2-- = (re * wim) + (im * wre);
1420     *ptr_subband1_t2-- = (im * wim) - (re * wre);
1421 
1422     i--;
1423   }
1424 
1425   switch (M) {
1426     case M_32:
1427       ixheaace_esbr_radix4bfly(ptr_twiddle, subband_tmp, 1, 8);
1428       ixheaace_esbr_radix4bfly(ptr_twiddle + 48, subband_tmp, 4, 2);
1429       ixheaace_esbr_postradixcompute2(subband, subband_tmp, ptr_dig_rev_tbl, 32);
1430 
1431       ixheaace_esbr_radix4bfly(ptr_twiddle, &subband_tmp[64], 1, 8);
1432       ixheaace_esbr_radix4bfly(ptr_twiddle + 48, &subband_tmp[64], 4, 2);
1433       ixheaace_esbr_postradixcompute2(&subband[64], &subband_tmp[64], ptr_dig_rev_tbl, 32);
1434       break;
1435 
1436     case M_16:
1437       ixheaace_esbr_radix4bfly(ptr_twiddle, subband_tmp, 1, 4);
1438       ixheaace_esbr_postradixcompute4(subband, subband_tmp, ptr_dig_rev_tbl, 16);
1439 
1440       ixheaace_esbr_radix4bfly(ptr_twiddle, &subband_tmp[64], 1, 4);
1441       ixheaace_esbr_postradixcompute4(&subband[64], &subband_tmp[64], ptr_dig_rev_tbl, 16);
1442       break;
1443 
1444     case M_12:
1445 
1446       for (z = 0; z < (pstr_qmf_bank->no_channels >> 1); z++) {
1447         temp[z] = subband_tmp[2 * z];
1448         temp[12 + z] = subband_tmp[2 * z + 1];
1449       }
1450 
1451       // convert re and im data to interleave
1452       FLOAT32 intermediate[24];
1453       WORD32 cnt = 0;
1454       while (cnt < M_12) {
1455         intermediate[2 * cnt] = temp[cnt];
1456         intermediate[2 * cnt + 1] = temp[12 + cnt];
1457         cnt++;
1458       }
1459 
1460       iusace_complex_fft_p3_no_scratch(intermediate, 12);
1461       // de-interleave
1462       for (cnt = 0; cnt < 12; cnt++) {
1463         temp[cnt] = intermediate[2 * cnt];
1464         temp[12 + cnt] = intermediate[2 * cnt + 1];
1465       }
1466 
1467       z = 0;
1468       while (z < (pstr_qmf_bank->no_channels >> 1)) {
1469         subband[2 * z] = temp[z];
1470         subband[2 * z + 1] = temp[z + 12];
1471         z++;
1472       }
1473 
1474       z = 0;
1475       while (z < (pstr_qmf_bank->no_channels >> 1)) {
1476         temp[z] = subband_tmp[64 + 2 * z];
1477         temp[12 + z] = subband_tmp[64 + 2 * z + 1];
1478         z++;
1479       }
1480 
1481       // convert re and im data to interleave
1482       cnt = 0;
1483       while (cnt < 12) {
1484         intermediate[2 * cnt] = temp[cnt];
1485         intermediate[2 * cnt + 1] = temp[12 + cnt];
1486         cnt++;
1487       }
1488       iusace_complex_fft_p3_no_scratch(intermediate, 12);
1489       // de-interleave
1490 
1491       cnt = 0;
1492       while (cnt < 12) {
1493         temp[cnt] = intermediate[2 * cnt];
1494         temp[12 + cnt] = intermediate[2 * cnt + 1];
1495         cnt++;
1496       }
1497 
1498       z = 0;
1499       while (z < (pstr_qmf_bank->no_channels >> 1)) {
1500         subband[64 + 2 * z] = temp[z];
1501         subband[64 + 2 * z + 1] = temp[z + 12];
1502         z++;
1503       }
1504       break;
1505 
1506     default:
1507       z = 0;
1508       while (z < (pstr_qmf_bank->no_channels >> 1)) {
1509         temp[z] = subband_tmp[2 * z];
1510         temp[8 + z] = subband_tmp[2 * z + 1];
1511         z++;
1512       }
1513 
1514       FLOAT32 scratch[1024];
1515       cnt = 0;
1516       while (cnt < 8) {
1517         intermediate[2 * cnt] = temp[cnt];
1518         intermediate[2 * cnt + 1] = temp[8 + cnt];
1519         cnt++;
1520       }
1521 
1522       iusace_complex_fft_p2(intermediate, 8, scratch);
1523       // de-interleave
1524       cnt = 0;
1525       while (cnt < 8) {
1526         temp[cnt] = intermediate[2 * cnt];
1527         temp[8 + cnt] = intermediate[2 * cnt + 1];
1528         cnt++;
1529       }
1530 
1531       z = 0;
1532       while (z < (pstr_qmf_bank->no_channels >> 1)) {
1533         subband[2 * z] = temp[z];
1534         subband[2 * z + 1] = temp[z + 8];
1535         z++;
1536       }
1537       z = 0;
1538       while (z < (pstr_qmf_bank->no_channels >> 1)) {
1539         temp[z] = subband_tmp[64 + 2 * z];
1540         temp[8 + z] = subband_tmp[64 + 2 * z + 1];
1541         z++;
1542       }
1543 
1544       // convert re and im data to interleave
1545       cnt = 0;
1546       while (cnt < 8) {
1547         intermediate[2 * cnt] = temp[cnt];
1548         intermediate[2 * cnt + 1] = temp[8 + cnt];
1549         cnt++;
1550       }
1551 
1552       iusace_complex_fft_p2(intermediate, 8, scratch);
1553 
1554       // de-interleave
1555       cnt = 0;
1556       while (cnt < 8) {
1557         temp[cnt] = intermediate[2 * cnt];
1558         temp[8 + cnt] = intermediate[2 * cnt + 1];
1559         cnt++;
1560       }
1561 
1562       z = 0;
1563       while (z < (pstr_qmf_bank->no_channels >> 1)) {
1564         subband[64 + 2 * z] = temp[z];
1565         subband[64 + 2 * z + 1] = temp[8 + z];
1566         z++;
1567       }
1568       break;
1569   }
1570 
1571   ptr_subband = &subband[0];
1572   ptr_subband1 = &subband[2 * M - 1];
1573 
1574   re = *ptr_subband1;
1575 
1576   *ptr_subband = *ptr_subband / 2;
1577   ptr_subband++;
1578   *ptr_subband1 = -(*ptr_subband / 2);
1579   ptr_subband1--;
1580 
1581   ptr_sin = pstr_qmf_bank->ptr_esbr_alt_sin_twiddle;
1582 
1583   wim = *ptr_sin++;
1584   wre = *ptr_sin++;
1585 
1586   im = *ptr_subband1;
1587 
1588   *ptr_subband1-- = (re * wre) + (im * wim);
1589   *ptr_subband++ = (im * wre) - (re * wim);
1590 
1591   ptr_subband2 = &subband[64];
1592   ptr_subband12 = &subband[2 * M - 1 + 64];
1593 
1594   re = *ptr_subband12;
1595 
1596   *ptr_subband12-- = -(*ptr_subband2 / 2);
1597 
1598   *ptr_subband2 = ptr_subband2[1] / 2;
1599 
1600   ptr_subband2++;
1601 
1602   im = *ptr_subband12;
1603 
1604   *ptr_subband2++ = -((re * wre) + (im * wim));
1605   *ptr_subband12-- = (re * wim) - (im * wre);
1606 
1607   i = (M_2 - 2);
1608   while (i >= 0) {
1609     im = ptr_subband[0];
1610 
1611     re = ptr_subband[1];
1612 
1613     re2 = *ptr_subband1;
1614 
1615     *ptr_subband++ = (re * wim) + (im * wre);
1616     *ptr_subband1-- = (im * wim) - (re * wre);
1617 
1618     im = ptr_subband2[0];
1619 
1620     re = ptr_subband2[1];
1621 
1622     re3 = *ptr_subband12;
1623 
1624     *ptr_subband12-- = -((re * wim) + (im * wre));
1625     *ptr_subband2++ = (re * wre) - (im * wim);
1626 
1627     wim = *ptr_sin++;
1628     wre = *ptr_sin++;
1629     im = ptr_subband1[0];
1630 
1631     *ptr_subband1-- = (re2 * wre) + (im * wim);
1632     *ptr_subband++ = (im * wre) - (re2 * wim);
1633 
1634     im = ptr_subband12[0];
1635 
1636     *ptr_subband2++ = -((re3 * wre) + (im * wim));
1637     *ptr_subband12-- = (re3 * wim) - (im * wre);
1638     i--;
1639   }
1640 }
1641 
ixheaace_esbr_fwd_modulation(const FLOAT32 * ptr_time_sample_buf,FLOAT32 * ptr_in_real_subband,FLOAT32 * ptr_in_imag_subband,ia_sbr_qmf_filter_bank_struct * pstr_qmf_bank,ixheaace_str_qmf_dec_tabs_struct * pstr_qmf_dec_tabs)1642 static VOID ixheaace_esbr_fwd_modulation(const FLOAT32 *ptr_time_sample_buf,
1643                                          FLOAT32 *ptr_in_real_subband,
1644                                          FLOAT32 *ptr_in_imag_subband,
1645                                          ia_sbr_qmf_filter_bank_struct *pstr_qmf_bank,
1646                                          ixheaace_str_qmf_dec_tabs_struct *pstr_qmf_dec_tabs) {
1647   WORD32 i;
1648   const FLOAT32 *ptr_time_sample_buf1 = &ptr_time_sample_buf[2 * pstr_qmf_bank->no_channels - 1];
1649   FLOAT32 temp1, temp2;
1650   FLOAT32 *ptr_real_subband = ptr_in_real_subband;
1651   FLOAT32 *ptr_imag_subband = ptr_in_imag_subband;
1652   const FLOAT32 *ptr_cos;
1653 
1654   for (i = pstr_qmf_bank->no_channels - 1; i >= 0; i--) {
1655     temp1 = *ptr_time_sample_buf++ / 16.0f;
1656     temp2 = *ptr_time_sample_buf1-- / 16.0f;
1657     *ptr_real_subband++ = (temp1 - temp2);
1658     *ptr_imag_subband++ = (temp1 + temp2);
1659   }
1660 
1661   ixheaace_esbr_cos_sin_mod(ptr_in_real_subband, pstr_qmf_bank, pstr_qmf_dec_tabs->esbr_w_16,
1662                             pstr_qmf_dec_tabs->dig_rev_tab_4_16);
1663 
1664   ptr_cos = pstr_qmf_bank->ptr_esbr_t_cos;
1665 
1666   i = (pstr_qmf_bank->usb - pstr_qmf_bank->lsb - 1);
1667   while (i >= 0) {
1668     FLOAT32 cosh, sinh;
1669     FLOAT32 re, im;
1670 
1671     re = *ptr_in_real_subband;
1672     im = *ptr_in_imag_subband;
1673     cosh = *ptr_cos++;
1674     sinh = *ptr_cos++;
1675     *ptr_in_real_subband++ = 2 * ((re * cosh) + (im * sinh));
1676     *ptr_in_imag_subband++ = 2 * ((im * cosh) - (re * sinh));
1677     i--;
1678   }
1679 }
1680 
ixheaace_esbr_analysis_filt_block(ia_sbr_qmf_filter_bank_struct * pstr_codec_qmf_bank,ixheaace_str_qmf_dec_tabs_struct * pstr_qmf_dec_tabs,FLOAT32 * ptr_core_coder_samples,FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE+2* 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS],FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE+2* 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS],WORD32 op_delay)1681 VOID ixheaace_esbr_analysis_filt_block(
1682     ia_sbr_qmf_filter_bank_struct *pstr_codec_qmf_bank,
1683     ixheaace_str_qmf_dec_tabs_struct *pstr_qmf_dec_tabs, FLOAT32 *ptr_core_coder_samples,
1684     FLOAT32 qmf_buf_real[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS],
1685     FLOAT32 qmf_buf_imag[IXHEAACE_TIMESLOT_BUFFER_SIZE + 2 * 32][IXHEAACE_NUM_QMF_SYNTH_CHANNELS],
1686     WORD32 op_delay) {
1687   FLOAT32 *ptr_filt_states;
1688   FLOAT32 *ptr_filt_states_1;
1689   FLOAT32 *ptr_filt_states_2;
1690   FLOAT32 *ptr_temp;
1691   FLOAT32 *ptr_win_coeffs_1;
1692   FLOAT32 *ptr_win_coeffs_2;
1693   FLOAT32 *ptr_win_coeffs;
1694   FLOAT32 *ptr_loc_qmf_buf_real;
1695   FLOAT32 *ptr_loc_qmf_buf_imag;
1696   FLOAT32 local_qmf_buffer[128] = {0};
1697   FLOAT32 anal_buf[2 * 32] = {0};
1698   WORD32 idx, z;
1699   WORD32 core_syn_ch_index;
1700   FLOAT32 gain;
1701   WORD32 filt_offset;
1702   WORD32 num_columns;
1703 
1704   ia_sbr_qmf_filter_bank_struct *pstr_qmf_anal_bank = pstr_codec_qmf_bank;
1705   ptr_filt_states = pstr_qmf_anal_bank->ptr_state_new_samples_pos_low_32;
1706   ptr_win_coeffs_1 = (FLOAT32 *)pstr_qmf_anal_bank->ptr_filter_pos_32;
1707   num_columns = pstr_qmf_anal_bank->no_channels;
1708 
1709   switch (num_columns) {
1710     case 16:
1711       ptr_win_coeffs_2 = ptr_win_coeffs_1 + 64;
1712       gain = 128.0f;
1713       filt_offset = 64;
1714       break;
1715     case 24:
1716       ptr_win_coeffs_2 = ptr_win_coeffs_1 + 24;
1717       gain = 12.0f;
1718       filt_offset = 24;
1719       break;
1720     case 32:
1721       ptr_win_coeffs_2 = ptr_win_coeffs_1 + 64;
1722       gain = 256.0f;
1723       filt_offset = 64;
1724       break;
1725     default:
1726       ptr_win_coeffs_2 = ptr_win_coeffs_1 + 64;
1727       gain = 256.0f;
1728       filt_offset = 64;
1729       break;
1730   }
1731   gain = 1.0f / gain;
1732 
1733   pstr_qmf_anal_bank->usb = (WORD16)num_columns;
1734 
1735   ptr_loc_qmf_buf_real = &local_qmf_buffer[0];
1736   ptr_loc_qmf_buf_imag = &local_qmf_buffer[64];
1737 
1738   ptr_filt_states_1 = pstr_qmf_anal_bank->anal_filter_states_32;
1739   ptr_filt_states_2 = pstr_qmf_anal_bank->anal_filter_states_32 + num_columns;
1740 
1741   idx = 0;
1742   while (idx < pstr_codec_qmf_bank->num_time_slots) {
1743     for (z = 0; z < num_columns; z++) {
1744       ptr_filt_states[num_columns - 1 - z] = ptr_core_coder_samples[z];
1745     }
1746 
1747     ixheaace_esbr_qmfanal32_winadd(ptr_filt_states_1, ptr_filt_states_2, ptr_win_coeffs_1,
1748                                    ptr_win_coeffs_2, anal_buf, num_columns);
1749 
1750     ptr_core_coder_samples += num_columns;
1751 
1752     ptr_filt_states -= num_columns;
1753     if (ptr_filt_states < pstr_qmf_anal_bank->anal_filter_states_32) {
1754       ptr_filt_states =
1755           pstr_qmf_anal_bank->anal_filter_states_32 + 10 * num_columns - num_columns;
1756     }
1757 
1758     ptr_temp = ptr_filt_states_1;
1759     ptr_filt_states_1 = ptr_filt_states_2;
1760     ptr_filt_states_2 = ptr_temp;
1761 
1762     ptr_win_coeffs_1 += filt_offset;
1763     ptr_win_coeffs_2 += filt_offset;
1764 
1765     ptr_win_coeffs = ptr_win_coeffs_1;
1766     ptr_win_coeffs_1 = ptr_win_coeffs_2;
1767     ptr_win_coeffs_2 = ptr_win_coeffs;
1768 
1769     if (ptr_win_coeffs_2 > (pstr_qmf_anal_bank->ptr_ana_win_coeff_32 + filt_offset * 10)) {
1770       ptr_win_coeffs_1 = (FLOAT32 *)pstr_qmf_anal_bank->ptr_ana_win_coeff_32;
1771       ptr_win_coeffs_2 = (FLOAT32 *)pstr_qmf_anal_bank->ptr_ana_win_coeff_32 + filt_offset;
1772     }
1773 
1774     ixheaace_esbr_fwd_modulation(anal_buf, &ptr_loc_qmf_buf_real[0], &ptr_loc_qmf_buf_imag[0],
1775                                  pstr_qmf_anal_bank, pstr_qmf_dec_tabs);
1776 
1777     core_syn_ch_index = num_columns;
1778 
1779     for (z = 0; z < core_syn_ch_index; z++) {
1780       qmf_buf_real[op_delay + idx][z] = ((FLOAT32)ptr_loc_qmf_buf_real[z] * gain);
1781       qmf_buf_imag[op_delay + idx][z] = ((FLOAT32)ptr_loc_qmf_buf_imag[z] * gain);
1782     }
1783 
1784     idx++;
1785   }
1786 
1787   pstr_qmf_anal_bank->ptr_filter_pos_32 = ptr_win_coeffs_1;
1788   pstr_qmf_anal_bank->ptr_state_new_samples_pos_low_32 = ptr_filt_states;
1789 }
ixheaace_extract_sbr_envelope(FLOAT32 * ptr_in_time,FLOAT32 * ptr_core_buf,UWORD32 time_sn_stride,ixheaace_pstr_sbr_enc pstr_env_enc,ixheaace_str_sbr_tabs * ptr_sbr_tab,ixheaace_comm_tables * pstr_com_tab,WORD32 flag_framelength_small)1790 IA_ERRORCODE ixheaace_extract_sbr_envelope(FLOAT32 *ptr_in_time, FLOAT32 *ptr_core_buf,
1791                                            UWORD32 time_sn_stride,
1792                                            ixheaace_pstr_sbr_enc pstr_env_enc,
1793                                            ixheaace_str_sbr_tabs *ptr_sbr_tab,
1794                                            ixheaace_comm_tables *pstr_com_tab,
1795                                            WORD32 flag_framelength_small) {
1796   IA_ERRORCODE err_code = IA_NO_ERROR;
1797   WORD32 ch, i, j, c;
1798   WORD32 n_envelopes[IXHEAACE_MAX_CH_IN_BS_ELE];
1799   WORD32 transient_info[IXHEAACE_MAX_CH_IN_BS_ELE][3];
1800   const ixheaace_str_frame_info_sbr *pstr_const_frame_info[IXHEAACE_MAX_CH_IN_BS_ELE];
1801   ixheaace_str_frame_info_sbr *pstr_frame_info = NULL;
1802 
1803   ixheaace_pstr_sbr_config_data pstr_sbr_cfg = &pstr_env_enc->str_sbr_cfg;
1804   ixheaace_pstr_sbr_hdr_data pstr_sbr_hdr = &pstr_env_enc->str_sbr_hdr;
1805   ixheaace_pstr_sbr_bitstream_data pstr_sbr_bs = &pstr_env_enc->str_sbr_bs;
1806   struct ixheaace_ps_enc *pstr_ps_enc = pstr_env_enc->pstr_ps_enc;
1807   ixheaace_pstr_sbr_qmf_filter_bank pstr_synthesis_qmf_bank =
1808       pstr_env_enc->pstr_synthesis_qmf_bank;
1809   ixheaace_pstr_common_data pstr_com_data = &pstr_env_enc->str_cmon_data;
1810   WORD8 *ptr_sbr_scratch = pstr_env_enc->ptr_sbr_enc_scr->sbr_scratch;
1811   ixheaace_pstr_enc_channel pstr_env_ch[IXHEAACE_MAX_CH_IN_BS_ELE];
1812   pstr_env_ch[0] = pstr_env_enc->pstr_env_channel[0];
1813   pstr_env_ch[1] = pstr_env_enc->pstr_env_channel[1];
1814 
1815   WORD32 num_channels = pstr_sbr_cfg->num_ch;
1816   WORD32 n_in_channels = (pstr_ps_enc) ? 2 : num_channels;
1817 
1818   ixheaace_sbr_stereo_mode stereo_mode = pstr_sbr_cfg->stereo_mode;
1819   struct ixheaace_str_sbr_env_data *pstr_env_0 = &(pstr_env_ch[0]->enc_env_data);
1820   struct ixheaace_str_sbr_env_data *pstr_env_1 = NULL;
1821 
1822   if (num_channels > 1) {
1823     pstr_env_1 = &(pstr_env_ch[1]->enc_env_data);
1824   }
1825   ixheaace_freq_res res[MAXIMUM_NUM_NOISE_VALUES];
1826   WORD32 *ptr_v_tuning;
1827   WORD32 v_tuning_lc_sbr[6] = {0, 2, 4, 0, 0, 0};
1828   WORD32 v_tuning_ld_sbr[6] = {0, 2, 3, 0, 0, 0};
1829   if (pstr_sbr_cfg->is_ld_sbr) {
1830     ptr_v_tuning = v_tuning_ld_sbr;
1831   } else {
1832     ptr_v_tuning = v_tuning_lc_sbr;
1833   }
1834   FLOAT32 *ptr_noise_floor[IXHEAACE_MAX_CH_IN_BS_ELE] = {NULL};
1835   WORD32 *ptr_scale_factor_band_nrg[IXHEAACE_MAX_CH_IN_BS_ELE] = {NULL};
1836   WORD32 *ptr_noise_level[IXHEAACE_MAX_CH_IN_BS_ELE] = {NULL};
1837 
1838   WORD32 *ptr_sfb_nrg_coupling[IXHEAACE_MAX_CH_IN_BS_ELE];
1839   WORD32 *ptr_noise_lvl_coupling[IXHEAACE_MAX_CH_IN_BS_ELE];
1840   WORD32 *ptr_frame_splitter_scratch =
1841       (WORD32 *)pstr_env_ch[0]->str_sbr_extract_env.ptr_r_buffer[0];
1842 
1843   WORD32 max_quant_error;
1844   ixheaace_str_esbr_bs_data str_esbr = {0};
1845   WORD32 samp_ratio_fac = DOWNSAMPLE_FAC_2_1;
1846   if ((pstr_env_enc->str_sbr_cfg.sbr_codec == USAC_SBR) &&
1847       (pstr_env_enc->str_sbr_cfg.sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1)) {
1848     samp_ratio_fac = DOWNSAMPLE_FAC_4_1;
1849   }
1850   if ((n_in_channels > IXHEAACE_MAX_CH_IN_BS_ELE) || (n_in_channels < num_channels) ||
1851       (n_in_channels <= 0) || (num_channels <= 0)) {
1852     return IA_EXHEAACE_EXE_FATAL_SBR_INVALID_IN_CHANNELS;
1853   }
1854   ch = 0;
1855   while (ch < n_in_channels) {
1856     ptr_sfb_nrg_coupling[ch] = (WORD32 *)pstr_env_ch[ch]->str_sbr_extract_env.ptr_r_buffer[0];
1857     ptr_noise_lvl_coupling[ch] = (WORD32 *)pstr_env_ch[ch]->str_sbr_extract_env.ptr_i_buffer[0];
1858     ptr_scale_factor_band_nrg[ch] =
1859         (WORD32 *)pstr_env_ch[ch]->str_sbr_extract_env.ptr_r_buffer[0] +
1860         IXHEAACE_MAX_CH_IN_BS_ELE * MAXIMUM_NUM_ENVELOPE_VALUES;
1861     ptr_noise_level[ch] = (WORD32 *)pstr_env_ch[ch]->str_sbr_extract_env.ptr_i_buffer[0] +
1862                           IXHEAACE_MAX_CH_IN_BS_ELE * MAXIMUM_NUM_ENVELOPE_VALUES;
1863     ptr_noise_floor[ch] = pstr_env_ch[ch]->str_sbr_extract_env.ptr_i_buffer[0] +
1864                           IXHEAACE_MAX_CH_IN_BS_ELE * MAXIMUM_NUM_ENVELOPE_VALUES * 2;
1865     ch++;
1866   }
1867   if ((pstr_sbr_cfg->sbr_codec == USAC_SBR) && (pstr_sbr_hdr->sbr_harmonic)) {
1868     WORD32 num_sbr_samples = 2048;
1869     if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) {
1870       num_sbr_samples = IXHEAACE_MAX_NUM_SAMPLES;
1871     }
1872     err_code = ixheaace_hbe_get_pitch_bins(
1873         ptr_in_time, pstr_sbr_cfg, pstr_env_ch[0]->str_sbr_extract_env.ptr_r_buffer[0],
1874         ptr_sbr_tab, time_sn_stride, num_sbr_samples, &pstr_env_0->sbr_pitchin_bins,
1875         n_in_channels == 1 ? NULL : &pstr_env_1->sbr_pitchin_bins);
1876     if (err_code) return err_code;
1877 
1878     WORD32 op_delay, codec_x_delay, num_time_slots;
1879     op_delay = IXHEAACE_OP_DELAY_OFFSET;
1880     codec_x_delay = IXHEAACE_ESBR_HBE_DELAY_OFFSET;
1881     if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) {
1882       op_delay = 2 * op_delay;
1883       codec_x_delay = 2 * codec_x_delay;
1884     }
1885 
1886     WORD32 eff_offset = op_delay + IXHEAACE_SBR_HF_ADJ_OFFSET;
1887     WORD32 memmove_sz1 = (eff_offset + codec_x_delay) *
1888                          sizeof(pstr_env_ch[0]->pstr_hbe_enc->qmf_buf_real[0][0]) *
1889                          MAX_QMF_TIME_SLOTS;
1890     WORD32 memmove_sz2 = eff_offset *
1891                          sizeof(pstr_env_ch[0]->pstr_hbe_enc->ph_vocod_qmf_real[0][0]) *
1892                          MAX_QMF_TIME_SLOTS;
1893 
1894     for (ch = 0; ch < n_in_channels; ch++) {
1895       ixheaace_str_hbe_enc *pstr_hbe_enc = pstr_env_ch[ch]->pstr_hbe_enc;
1896       num_time_slots =
1897           pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate;
1898 
1899       memmove(pstr_hbe_enc->qmf_buf_real[0], pstr_hbe_enc->qmf_buf_real[num_time_slots],
1900               memmove_sz1);
1901       memmove(pstr_hbe_enc->qmf_buf_imag[0], pstr_hbe_enc->qmf_buf_imag[num_time_slots],
1902               memmove_sz1);
1903       memmove(pstr_hbe_enc->ph_vocod_qmf_real[0], pstr_hbe_enc->ph_vocod_qmf_real[num_time_slots],
1904               memmove_sz2);
1905       memmove(pstr_hbe_enc->ph_vocod_qmf_imag, pstr_hbe_enc->ph_vocod_qmf_imag + num_time_slots,
1906               memmove_sz2);
1907     }
1908   }
1909   i = 0;
1910   while (i < MAXIMUM_NUM_NOISE_VALUES) {
1911     res[i] = FREQ_RES_HIGH;
1912     i++;
1913   }
1914 
1915   memset(transient_info, 0, sizeof(transient_info));
1916 
1917   ch = 0;
1918   while (ch < n_in_channels) {
1919     ixheaace_str_sbr_extr_env *pstr_sbr_extract_env = &(pstr_env_ch[ch]->str_sbr_extract_env);
1920 
1921     ixheaace_sbr_analysis_filtering(
1922         ptr_in_time ? ptr_in_time + ch : NULL, time_sn_stride,
1923         pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer,
1924         &pstr_env_ch[ch]->str_sbr_qmf, ptr_sbr_tab->ptr_qmf_tab,
1925         pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate,
1926         pstr_sbr_cfg->is_ld_sbr, (FLOAT32 *)ptr_sbr_scratch,
1927         (pstr_ps_enc != NULL && flag_framelength_small));
1928 
1929     if ((1 == n_in_channels) && (USAC_SBR == pstr_sbr_cfg->sbr_codec) &&
1930         (pstr_sbr_hdr->sbr_pvc_active)) {
1931       ixheaace_pvc_scratch *pstr_pvc_scr = (ixheaace_pvc_scratch *)ptr_sbr_scratch;
1932       WORD32 ts, bd;
1933       FLOAT32 nrg_0, nrg_1;
1934       FLOAT32 *ptr_r_0, *ptr_r_1, *ptr_i_0, *ptr_i_1;
1935       FLOAT32 *ptr_r_2, *ptr_r_3, *ptr_i_2, *ptr_i_3, nrg_2, nrg_3;
1936       WORD32 pvc_rate = pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_rate;
1937 
1938       // update header_active to send SBR header when previous PVC mode is different from
1939       // current frame's
1940       if (pstr_env_enc->str_sbr_hdr.sbr_pvc_mode !=
1941           pstr_env_enc->pstr_pvc_enc->pvc_param.pvc_mode) {
1942         pstr_sbr_bs->header_active = 1;
1943       }
1944 
1945       switch (pvc_rate) {
1946         case 2: {
1947           for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) {
1948             ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts];
1949             ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1];
1950             ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts];
1951             ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1];
1952 
1953             for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) {
1954               nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd];
1955               nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd];
1956               pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] =
1957                   (nrg_0 + nrg_1) / 2.0f;
1958             }
1959             WORD32 num_low_bands = MAX_QMF_TIME_SLOTS >> 1;
1960             for (bd = 0; bd < num_low_bands; bd++) {
1961               pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] =
1962                   pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd];
1963             }
1964           }
1965           break;
1966         }
1967         case 4: {
1968           for (ts = 0; ts < IXHEAACE_ESBR_PVC_NUM_TS; ts++) {
1969             ptr_r_0 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts];
1970             ptr_r_1 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 1];
1971             ptr_r_2 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 2];
1972             ptr_r_3 = pstr_sbr_extract_env->ptr_r_buffer[pvc_rate * ts + 3];
1973             ptr_i_0 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts];
1974             ptr_i_1 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 1];
1975             ptr_i_2 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 2];
1976             ptr_i_3 = pstr_sbr_extract_env->ptr_i_buffer[pvc_rate * ts + 3];
1977 
1978             for (bd = 0; bd < MAX_QMF_TIME_SLOTS; bd++) {
1979               nrg_0 = ptr_r_0[bd] * ptr_r_0[bd] + ptr_i_0[bd] * ptr_i_0[bd];
1980               nrg_1 = ptr_r_1[bd] * ptr_r_1[bd] + ptr_i_1[bd] * ptr_i_1[bd];
1981               nrg_2 = ptr_r_2[bd] * ptr_r_2[bd] + ptr_i_2[bd] * ptr_i_2[bd];
1982               nrg_3 = ptr_r_3[bd] * ptr_r_3[bd] + ptr_i_3[bd] * ptr_i_3[bd];
1983               pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd] =
1984                   (nrg_0 + nrg_1 + nrg_2 + nrg_3) / 4.0f;
1985             }
1986             WORD32 num_low_bands = (MAX_QMF_TIME_SLOTS >> 2);
1987             for (bd = 0; bd < num_low_bands; bd++) {
1988               pstr_pvc_scr->pvc_qmf_low[ts * num_low_bands + bd] =
1989                   pstr_pvc_scr->pvc_qmf_high[ts * IXHEAACE_ESBR_PVC_NUM_QMF_BANDS + bd];
1990             }
1991           }
1992           break;
1993         }
1994       }
1995       pstr_env_enc->pstr_pvc_enc->pvc_param.usac_indep_flag = pstr_sbr_bs->usac_indep_flag;
1996       err_code = ixheaace_pvc_encode_frame(
1997           pstr_env_enc->pstr_pvc_enc, (UWORD8)pstr_env_enc->str_sbr_hdr.sbr_pvc_mode,
1998           pstr_pvc_scr->pvc_qmf_low, pstr_pvc_scr->pvc_qmf_high,
1999           pstr_sbr_cfg->ptr_v_k_master[0],
2000           pstr_sbr_cfg->ptr_v_k_master[pstr_sbr_cfg->num_master] - 1);
2001       if (err_code) {
2002         return err_code;
2003       }
2004 
2005       memcpy(&pstr_env_ch[ch]->enc_env_data.pvc_info, &pstr_env_enc->pstr_pvc_enc->pvc_bs_info,
2006              sizeof(ixheaace_pvc_bs_info));
2007     }
2008 
2009     // COPY generated spectrum for inter-TES encoder
2010     if ((USAC_SBR == pstr_sbr_cfg->sbr_codec) && (1 == pstr_sbr_hdr->sbr_inter_tes_active)) {
2011       WORD32 ts, num_ts, delay;
2012       num_ts = pstr_env_ch[ch]->str_sbr_qmf.num_time_slots;
2013 
2014       ixheaace_str_inter_tes_params *pstr_tes_enc = &pstr_env_ch[ch]->str_inter_tes_enc;
2015       delay = pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET;
2016       ts = 0;
2017       while (ts < num_ts) {
2018         memcpy(pstr_tes_enc->qmf_buf_real[delay + ts], pstr_sbr_extract_env->ptr_r_buffer[ts],
2019                IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0]));
2020         memcpy(pstr_tes_enc->qmf_buf_imag[delay + ts], pstr_sbr_extract_env->ptr_i_buffer[ts],
2021                IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_imag[0][0]));
2022         ts++;
2023       }
2024     }
2025 
2026     ch++;
2027   }
2028   if ((pstr_sbr_cfg->sbr_codec == USAC_SBR) && (pstr_sbr_hdr->sbr_harmonic)) {
2029     WORD32 dft_hbe_flag = 0;
2030     WORD32 op_delay, codec_x_delay, num_time_slots;
2031     WORD32 esbr_hbe_delay_offsets = IXHEAACE_ESBR_HBE_DELAY_OFFSET;
2032     WORD32 oversampling_flag = 0;
2033     op_delay = IXHEAACE_OP_DELAY_OFFSET;
2034     codec_x_delay = IXHEAACE_ESBR_HBE_DELAY_OFFSET;
2035     if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) {
2036       op_delay = 2 * IXHEAACE_OP_DELAY_OFFSET;
2037       codec_x_delay = 2 * codec_x_delay;
2038       oversampling_flag = 1;
2039     }
2040     WORD32 eff_offset = op_delay + IXHEAACE_SBR_HF_ADJ_OFFSET;
2041     dft_hbe_flag = pstr_sbr_hdr->hq_esbr;
2042     ch = 0;
2043     while (ch < n_in_channels) {
2044       ixheaace_str_hbe_enc *pstr_hbe_enc = pstr_env_ch[ch]->pstr_hbe_enc;
2045       pstr_hbe_enc->pstr_hbe_txposer->oversampling_flag = oversampling_flag;
2046       num_time_slots =
2047           pstr_env_ch[ch]->str_sbr_qmf.num_time_slots * pstr_env_ch[ch]->str_sbr_qmf.rate;
2048 
2049       if (dft_hbe_flag == 1) {
2050         err_code = ixheaace_dft_hbe_apply(
2051             pstr_hbe_enc->pstr_hbe_txposer,
2052             pstr_hbe_enc->qmf_buf_real + eff_offset + esbr_hbe_delay_offsets,
2053             pstr_hbe_enc->qmf_buf_imag + eff_offset + esbr_hbe_delay_offsets, num_time_slots,
2054             pstr_hbe_enc->ph_vocod_qmf_real + eff_offset,
2055             pstr_hbe_enc->ph_vocod_qmf_imag + eff_offset,
2056             pstr_env_ch[ch]->enc_env_data.sbr_pitchin_bins, (FLOAT32 *)ptr_sbr_scratch);
2057         if (err_code) {
2058           return err_code;
2059         }
2060       } else {
2061         // size 4096 samples
2062         FLOAT32 *ptr_time_data = (FLOAT32 *)ptr_sbr_scratch;
2063         int cnt = 0;
2064         if (0 == ch) {
2065           while (cnt < IXHEAACE_MAX_NUM_SAMPLES) {
2066             ptr_time_data[cnt] = pstr_env_enc->ptr_hbe_resample_buf[2 * cnt];
2067             cnt++;
2068           }
2069         } else {
2070           while (cnt < IXHEAACE_MAX_NUM_SAMPLES) {
2071             ptr_time_data[cnt] = pstr_env_enc->ptr_hbe_resample_buf[2 * cnt + 1];
2072             cnt++;
2073           }
2074         }
2075 
2076         ixheaace_esbr_analysis_filt_block(&(pstr_hbe_enc->str_codec_qmf_bank),
2077                                           pstr_hbe_enc->str_codec_qmf_bank.pstr_qmf_dec_tabs,
2078                                           ptr_time_data, pstr_hbe_enc->qmf_buf_real,
2079                                           pstr_hbe_enc->qmf_buf_imag,
2080                                           op_delay + codec_x_delay + IXHEAACE_SBR_HF_ADJ_OFFSET);
2081 
2082         err_code = ixheaace_qmf_hbe_apply(
2083             pstr_hbe_enc->pstr_hbe_txposer,
2084             pstr_hbe_enc->qmf_buf_real + eff_offset + esbr_hbe_delay_offsets,
2085             pstr_hbe_enc->qmf_buf_imag + eff_offset + esbr_hbe_delay_offsets, num_time_slots,
2086             pstr_hbe_enc->ph_vocod_qmf_real + eff_offset,
2087             pstr_hbe_enc->ph_vocod_qmf_imag + eff_offset,
2088             pstr_env_ch[ch]->enc_env_data.sbr_pitchin_bins);
2089         if (err_code) {
2090           return err_code;
2091         }
2092 
2093         if (pstr_sbr_cfg->sbr_ratio_idx == USAC_SBR_RATIO_INDEX_4_1) {
2094           ixheaace_hbe_repl_spec(&pstr_hbe_enc->pstr_hbe_txposer->x_over_qmf[0],
2095                                  pstr_hbe_enc->ph_vocod_qmf_real + eff_offset,
2096                                  pstr_hbe_enc->ph_vocod_qmf_imag + eff_offset, num_time_slots,
2097                                  pstr_hbe_enc->pstr_hbe_txposer->max_stretch);
2098         }
2099       }
2100       ch++;
2101     }
2102   }
2103   if (pstr_ps_enc && pstr_synthesis_qmf_bank) {
2104     err_code = ixheaace_encode_ps_frame(
2105         pstr_ps_enc, pstr_env_ch[0]->str_sbr_extract_env.ptr_i_buffer,
2106         pstr_env_ch[0]->str_sbr_extract_env.ptr_r_buffer,
2107         pstr_env_ch[1]->str_sbr_extract_env.ptr_i_buffer,
2108         pstr_env_ch[1]->str_sbr_extract_env.ptr_r_buffer, ptr_sbr_tab->ptr_ps_tab, pstr_com_tab);
2109     if (err_code) {
2110       return err_code;
2111     }
2112     ixheaace_enc_synthesis_qmf_filtering(
2113         pstr_env_ch[0]->str_sbr_extract_env.ptr_r_buffer,
2114         pstr_env_ch[0]->str_sbr_extract_env.ptr_i_buffer, ptr_core_buf,
2115         (ixheaace_pstr_sbr_qmf_filter_bank)pstr_synthesis_qmf_bank);
2116   }
2117 
2118   ch = 0;
2119   while (ch < num_channels) {
2120     ixheaace_str_hbe_enc *pstr_hbe_enc = pstr_env_ch[ch]->pstr_hbe_enc;
2121     ixheaace_str_sbr_extr_env *pstr_sbr_extract_env = &(pstr_env_ch[ch]->str_sbr_extract_env);
2122 
2123     ixheaace_get_energy_from_cplx_qmf(
2124         pstr_sbr_extract_env->ptr_y_buffer + pstr_sbr_extract_env->y_buffer_write_offset,
2125         pstr_sbr_extract_env->ptr_r_buffer, pstr_sbr_extract_env->ptr_i_buffer,
2126         pstr_sbr_cfg->is_ld_sbr, pstr_env_ch[ch]->str_sbr_qmf.num_time_slots, samp_ratio_fac,
2127         pstr_hbe_enc, (IXHEAACE_OP_DELAY_OFFSET + IXHEAACE_ESBR_HBE_DELAY_OFFSET +
2128         IXHEAACE_SBR_HF_ADJ_OFFSET), pstr_sbr_hdr->sbr_harmonic);
2129 
2130     ixheaace_calculate_tonality_quotas(
2131         &pstr_env_ch[ch]->str_ton_corr, pstr_sbr_extract_env->ptr_r_buffer,
2132         pstr_sbr_extract_env->ptr_i_buffer,
2133         pstr_sbr_cfg->ptr_freq_band_tab[HI][pstr_sbr_cfg->num_scf[HI]],
2134         pstr_env_ch[ch]->str_sbr_qmf.num_time_slots, pstr_sbr_cfg->is_ld_sbr);
2135     if (pstr_sbr_cfg->is_ld_sbr) {
2136       ixheaace_detect_transient_eld(pstr_sbr_extract_env->ptr_y_buffer,
2137                                     &pstr_env_ch[ch]->str_sbr_trans_detector, transient_info[ch]);
2138     } else {
2139       ixheaace_detect_transient(pstr_sbr_extract_env->ptr_y_buffer,
2140                                 &pstr_env_ch[ch]->str_sbr_trans_detector, transient_info[ch],
2141                                 pstr_sbr_extract_env->time_step, pstr_sbr_cfg->sbr_codec);
2142     }
2143     if (transient_info[ch][1] == 0) {
2144       if (pstr_sbr_cfg->is_ld_sbr) {
2145         err_code = ixheaace_frame_splitter(
2146             pstr_sbr_extract_env->ptr_y_buffer, &pstr_env_ch[ch]->str_sbr_trans_detector,
2147             pstr_sbr_cfg->ptr_freq_band_tab[1], pstr_sbr_cfg->num_scf[1],
2148             pstr_sbr_extract_env->time_step, pstr_sbr_extract_env->time_slots, transient_info[ch],
2149             (FLOAT32 *)ptr_frame_splitter_scratch, pstr_sbr_cfg->is_ld_sbr);
2150       } else {
2151         err_code = ixheaace_frame_splitter(
2152             pstr_sbr_extract_env->ptr_y_buffer, &pstr_env_ch[ch]->str_sbr_trans_detector,
2153             pstr_sbr_cfg->ptr_freq_band_tab[1], pstr_sbr_cfg->num_scf[1],
2154             pstr_sbr_extract_env->time_step, pstr_sbr_extract_env->no_cols, transient_info[ch],
2155             (FLOAT32 *)ptr_frame_splitter_scratch, pstr_sbr_cfg->is_ld_sbr);
2156       }
2157       if (err_code) {
2158         return err_code;
2159       }
2160     }
2161     ch++;
2162   }
2163 
2164   if (stereo_mode == SBR_COUPLING) {
2165     if (transient_info[0][1] && transient_info[1][1]) {
2166       transient_info[0][0] = ixheaac_min32(transient_info[1][0], transient_info[0][0]);
2167 
2168       transient_info[1][0] = transient_info[0][0];
2169     } else if (transient_info[0][1] && !transient_info[1][1]) {
2170       transient_info[1][0] = transient_info[0][0];
2171     } else if (!transient_info[0][1] && transient_info[1][1]) {
2172       transient_info[0][0] = transient_info[1][0];
2173     } else {
2174       transient_info[0][0] = ixheaac_max32(transient_info[1][0], transient_info[0][0]);
2175 
2176       transient_info[1][0] = transient_info[0][0];
2177     }
2178   }
2179 
2180   err_code = ixheaace_frame_info_generator(
2181       &pstr_env_ch[0]->str_sbr_env_frame, pstr_env_ch[0]->str_sbr_extract_env.pre_transient_info,
2182       transient_info[0], ptr_v_tuning, ptr_sbr_tab->ptr_qmf_tab,
2183       pstr_env_ch[0]->str_sbr_qmf.num_time_slots, pstr_sbr_cfg->is_ld_sbr, &pstr_frame_info,
2184       flag_framelength_small);
2185   if (pstr_sbr_cfg->is_ld_sbr && transient_info[0][2]) {
2186     pstr_frame_info->short_env = pstr_frame_info->n_envelopes;
2187   }
2188   pstr_const_frame_info[0] = pstr_frame_info;
2189   if (err_code) {
2190     return err_code;
2191   }
2192 
2193   pstr_env_0->pstr_sbr_bs_grid = &pstr_env_ch[0]->str_sbr_env_frame.sbr_grid;
2194 
2195   for (ch = 0; ch < num_channels; ch++) {
2196     memset(
2197         ptr_noise_floor[ch], 0,
2198         IXHEAACE_MAX_CH_IN_BS_ELE * MAXIMUM_NUM_ENVELOPE_VALUES * sizeof(ptr_noise_floor[0][0]));
2199   }
2200 
2201   switch (stereo_mode) {
2202     case IXHEAACE_SBR_MODE_LEFT_RIGHT:
2203     case IXHEAACE_SBR_MODE_SWITCH_LRC:
2204 
2205       err_code = ixheaace_frame_info_generator(
2206           &pstr_env_ch[1]->str_sbr_env_frame,
2207           pstr_env_ch[1]->str_sbr_extract_env.pre_transient_info, transient_info[1], ptr_v_tuning,
2208           ptr_sbr_tab->ptr_qmf_tab, pstr_env_ch[1]->str_sbr_qmf.num_time_slots,
2209           pstr_sbr_cfg->is_ld_sbr, &pstr_frame_info, flag_framelength_small);
2210 
2211       if (pstr_sbr_cfg->is_ld_sbr && transient_info[1][2]) {
2212         pstr_frame_info->short_env = pstr_frame_info->n_envelopes;
2213       }
2214       pstr_const_frame_info[1] = pstr_frame_info;
2215       if (err_code) {
2216         return err_code;
2217       }
2218 
2219       pstr_env_1->pstr_sbr_bs_grid = &pstr_env_ch[1]->str_sbr_env_frame.sbr_grid;
2220 
2221       if (pstr_const_frame_info[0]->n_envelopes != pstr_const_frame_info[1]->n_envelopes) {
2222         stereo_mode = IXHEAACE_SBR_MODE_LEFT_RIGHT;
2223       } else {
2224         for (i = 0; i < pstr_const_frame_info[0]->n_envelopes + 1; i++) {
2225           if (pstr_const_frame_info[0]->borders[i] != pstr_const_frame_info[1]->borders[i]) {
2226             stereo_mode = IXHEAACE_SBR_MODE_LEFT_RIGHT;
2227             break;
2228           }
2229         }
2230 
2231         for (i = 0; i < pstr_const_frame_info[0]->n_envelopes; i++) {
2232           if (pstr_const_frame_info[0]->freq_res[i] != pstr_const_frame_info[1]->freq_res[i]) {
2233             stereo_mode = IXHEAACE_SBR_MODE_LEFT_RIGHT;
2234             break;
2235           }
2236         }
2237 
2238         if (pstr_const_frame_info[0]->short_env != pstr_const_frame_info[1]->short_env) {
2239           stereo_mode = IXHEAACE_SBR_MODE_LEFT_RIGHT;
2240         }
2241       }
2242       break;
2243     case SBR_COUPLING:
2244 
2245       pstr_const_frame_info[1] = pstr_const_frame_info[0];
2246 
2247       pstr_env_1->pstr_sbr_bs_grid = &pstr_env_ch[0]->str_sbr_env_frame.sbr_grid;
2248       break;
2249     case IXHEAACE_SBR_MODE_MONO:
2250       break;
2251   }
2252 
2253   for (ch = 0; ch < num_channels; ch++) {
2254     ixheaace_str_sbr_extr_env *pstr_sbr_extract_env = &(pstr_env_ch[ch]->str_sbr_extract_env);
2255 
2256     pstr_sbr_extract_env->pre_transient_info[0] = transient_info[ch][0];
2257     pstr_sbr_extract_env->pre_transient_info[1] = transient_info[ch][1];
2258     pstr_env_ch[ch]->enc_env_data.no_of_envelopes = n_envelopes[ch] =
2259         pstr_const_frame_info[ch]->n_envelopes;
2260 
2261     for (i = 0; i < n_envelopes[ch]; i++) {
2262       pstr_env_ch[ch]->enc_env_data.no_scf_bands[i] =
2263           (pstr_const_frame_info[ch]->freq_res[i] == FREQ_RES_HIGH
2264                ? pstr_sbr_cfg->num_scf[FREQ_RES_HIGH]
2265                : pstr_sbr_cfg->num_scf[FREQ_RES_LOW]);
2266     }
2267 
2268     if ((pstr_env_ch[ch]->enc_env_data.pstr_sbr_bs_grid->frame_type == IXHEAACE_FIXFIX) &&
2269         (n_envelopes[ch] == 1)) {
2270       if (pstr_sbr_cfg->is_ld_sbr) {
2271         pstr_env_ch[ch]->enc_env_data.curr_sbr_amp_res = IXHEAACE_SBR_AMP_RES_3_0;
2272       } else {
2273         pstr_env_ch[ch]->enc_env_data.curr_sbr_amp_res = IXHEAACE_SBR_AMP_RES_1_5;
2274       }
2275       if (pstr_env_ch[ch]->enc_env_data.init_sbr_amp_res !=
2276           pstr_env_ch[ch]->enc_env_data.curr_sbr_amp_res) {
2277         err_code = ixheaace_init_sbr_huffman_tabs(
2278             &pstr_env_ch[ch]->enc_env_data, &pstr_env_ch[ch]->str_sbr_code_env,
2279             &pstr_env_ch[ch]->str_sbr_code_noise_floor, IXHEAACE_SBR_AMP_RES_1_5,
2280             ptr_sbr_tab->ptr_sbr_huff_tab);
2281         if (err_code) {
2282           return err_code;
2283         }
2284         pstr_env_ch[ch]->sbr_amp_res_init = IXHEAACE_SBR_AMP_RES_1_5;
2285       }
2286     } else {
2287       if (pstr_sbr_hdr->sbr_amp_res != pstr_env_ch[ch]->enc_env_data.init_sbr_amp_res) {
2288         err_code = ixheaace_init_sbr_huffman_tabs(
2289             &pstr_env_ch[ch]->enc_env_data, &pstr_env_ch[ch]->str_sbr_code_env,
2290             &pstr_env_ch[ch]->str_sbr_code_noise_floor, pstr_sbr_hdr->sbr_amp_res,
2291             ptr_sbr_tab->ptr_sbr_huff_tab);
2292         if (err_code) {
2293           return err_code;
2294         }
2295         pstr_env_ch[ch]->sbr_amp_res_init = pstr_sbr_hdr->sbr_amp_res;
2296       }
2297     }
2298 
2299     ixheaace_ton_corr_param_extr(
2300         &pstr_env_ch[ch]->str_ton_corr, pstr_env_ch[ch]->enc_env_data.sbr_invf_mode_vec,
2301         ptr_noise_floor[ch], &pstr_env_ch[ch]->enc_env_data.add_harmonic_flag,
2302         pstr_env_ch[ch]->enc_env_data.add_harmonic, pstr_sbr_extract_env->envelope_compensation,
2303         pstr_const_frame_info[ch], transient_info[ch], pstr_sbr_cfg->ptr_freq_band_tab[HI],
2304         pstr_sbr_cfg->num_scf[HI], pstr_env_ch[ch]->enc_env_data.sbr_xpos_mode, ptr_sbr_scratch,
2305         pstr_sbr_cfg->is_ld_sbr);
2306 
2307     pstr_env_ch[ch]->enc_env_data.sbr_invf_mode =
2308         pstr_env_ch[ch]->enc_env_data.sbr_invf_mode_vec[0];
2309     pstr_env_ch[ch]->enc_env_data.noise_band_count =
2310         pstr_env_ch[ch]->str_ton_corr.sbr_noise_floor_est.num_of_noise_bands;
2311   }
2312 
2313   switch (stereo_mode) {
2314     case IXHEAACE_SBR_MODE_MONO:
2315       err_code = ixheaace_calculate_sbr_envelope(pstr_env_ch[0]->str_sbr_extract_env.ptr_y_buffer,
2316                                                  NULL, pstr_const_frame_info[0],
2317                                                  ptr_scale_factor_band_nrg[0], NULL, pstr_sbr_cfg,
2318                                                  pstr_env_ch[0], IXHEAACE_SBR_MODE_MONO, NULL);
2319 
2320       if (err_code) {
2321         return err_code;
2322       }
2323       break;
2324 
2325     case IXHEAACE_SBR_MODE_LEFT_RIGHT:
2326 
2327       err_code = ixheaace_calculate_sbr_envelope(pstr_env_ch[0]->str_sbr_extract_env.ptr_y_buffer,
2328                                                  NULL, pstr_const_frame_info[0],
2329                                                  ptr_scale_factor_band_nrg[0], NULL, pstr_sbr_cfg,
2330                                                  pstr_env_ch[0], IXHEAACE_SBR_MODE_MONO, NULL);
2331       if (err_code) {
2332         return err_code;
2333       }
2334 
2335       err_code = ixheaace_calculate_sbr_envelope(pstr_env_ch[1]->str_sbr_extract_env.ptr_y_buffer,
2336                                                  NULL, pstr_const_frame_info[1],
2337                                                  ptr_scale_factor_band_nrg[1], NULL, pstr_sbr_cfg,
2338                                                  pstr_env_ch[1], IXHEAACE_SBR_MODE_MONO, NULL);
2339 
2340       if (err_code) {
2341         return err_code;
2342       }
2343 
2344       break;
2345 
2346     case SBR_COUPLING:
2347 
2348       err_code = ixheaace_calculate_sbr_envelope(
2349           pstr_env_ch[0]->str_sbr_extract_env.ptr_y_buffer,
2350           pstr_env_ch[1]->str_sbr_extract_env.ptr_y_buffer, pstr_const_frame_info[0],
2351           ptr_scale_factor_band_nrg[0], ptr_scale_factor_band_nrg[1], pstr_sbr_cfg,
2352           pstr_env_ch[0], SBR_COUPLING, &max_quant_error);
2353       if (err_code) {
2354         return err_code;
2355       }
2356       break;
2357 
2358     case IXHEAACE_SBR_MODE_SWITCH_LRC:
2359       err_code = ixheaace_calculate_sbr_envelope(pstr_env_ch[0]->str_sbr_extract_env.ptr_y_buffer,
2360                                                  NULL, pstr_const_frame_info[0],
2361                                                  ptr_scale_factor_band_nrg[0], NULL, pstr_sbr_cfg,
2362                                                  pstr_env_ch[0], IXHEAACE_SBR_MODE_MONO, NULL);
2363       if (err_code) {
2364         return err_code;
2365       }
2366 
2367       err_code = ixheaace_calculate_sbr_envelope(pstr_env_ch[1]->str_sbr_extract_env.ptr_y_buffer,
2368                                                  NULL, pstr_const_frame_info[1],
2369                                                  ptr_scale_factor_band_nrg[1], NULL, pstr_sbr_cfg,
2370                                                  pstr_env_ch[1], IXHEAACE_SBR_MODE_MONO, NULL);
2371       if (err_code) {
2372         return err_code;
2373       }
2374 
2375       err_code = ixheaace_calculate_sbr_envelope(
2376           pstr_env_ch[0]->str_sbr_extract_env.ptr_y_buffer,
2377           pstr_env_ch[1]->str_sbr_extract_env.ptr_y_buffer, pstr_const_frame_info[0],
2378           ptr_sfb_nrg_coupling[0], ptr_sfb_nrg_coupling[1], pstr_sbr_cfg, pstr_env_ch[0],
2379           SBR_COUPLING, &max_quant_error);
2380       if (err_code) {
2381         return err_code;
2382       }
2383       break;
2384   }
2385 
2386   switch (stereo_mode) {
2387     case IXHEAACE_SBR_MODE_MONO:
2388 
2389       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_level[0], ptr_noise_floor[0], 0);
2390 
2391       err_code = ixheaace_code_envelope(
2392           ptr_noise_level[0], res, &pstr_env_ch[0]->str_sbr_code_noise_floor,
2393           pstr_env_0->domain_vec_noise, 0, (pstr_const_frame_info[0]->n_envelopes > 1 ? 2 : 1), 0,
2394           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2395       if (err_code) {
2396         return err_code;
2397       }
2398 
2399       break;
2400 
2401     case IXHEAACE_SBR_MODE_LEFT_RIGHT:
2402       // We have a error checks for Number of channels to ensure memory is assigned to
2403       // ptr_noise_floor[]. However, MSVS static analysis is marking this as a potential error.
2404       // So, suppressed this in source
2405       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_level[0], ptr_noise_floor[0], 0);
2406 
2407       err_code = ixheaace_code_envelope(
2408           ptr_noise_level[0], res, &pstr_env_ch[0]->str_sbr_code_noise_floor,
2409           pstr_env_0->domain_vec_noise, 0, (pstr_const_frame_info[0]->n_envelopes > 1 ? 2 : 1), 0,
2410           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2411       if (err_code) {
2412         return err_code;
2413       }
2414 
2415       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_level[1], ptr_noise_floor[1], 0);
2416 
2417       err_code = ixheaace_code_envelope(
2418           ptr_noise_level[1], res, &pstr_env_ch[1]->str_sbr_code_noise_floor,
2419           pstr_env_1->domain_vec_noise, 0, (pstr_const_frame_info[1]->n_envelopes > 1 ? 2 : 1), 0,
2420           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2421       if (err_code) {
2422         return err_code;
2423       }
2424 
2425       break;
2426 
2427     case SBR_COUPLING:
2428       ixheaace_couple_noise_floor(ptr_noise_floor[0], ptr_noise_floor[1]);
2429 
2430       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_level[0], ptr_noise_floor[0], 0);
2431 
2432       err_code = ixheaace_code_envelope(
2433           ptr_noise_level[0], res, &pstr_env_ch[0]->str_sbr_code_noise_floor,
2434           pstr_env_0->domain_vec_noise, 1, (pstr_const_frame_info[0]->n_envelopes > 1 ? 2 : 1), 0,
2435           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2436       if (err_code) {
2437         return err_code;
2438       }
2439 
2440       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_level[1], ptr_noise_floor[1], 1);
2441 
2442       err_code = ixheaace_code_envelope(
2443           ptr_noise_level[1], res, &pstr_env_ch[1]->str_sbr_code_noise_floor,
2444           pstr_env_1->domain_vec_noise, 1, (pstr_const_frame_info[1]->n_envelopes > 1 ? 2 : 1), 1,
2445           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2446       if (err_code) {
2447         return err_code;
2448       }
2449 
2450       break;
2451 
2452     case IXHEAACE_SBR_MODE_SWITCH_LRC:
2453 
2454       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_level[0], ptr_noise_floor[0], 0);
2455 
2456       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_level[1], ptr_noise_floor[1], 0);
2457 
2458       ixheaace_couple_noise_floor(ptr_noise_floor[0], ptr_noise_floor[1]);
2459 
2460       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_lvl_coupling[0], ptr_noise_floor[0],
2461                                                    0);
2462 
2463       ixheaace_sbr_noise_floor_levels_quantisation(ptr_noise_lvl_coupling[1], ptr_noise_floor[1],
2464                                                    1);
2465       break;
2466   }
2467 
2468   switch (stereo_mode) {
2469     case IXHEAACE_SBR_MODE_MONO:
2470 
2471       pstr_sbr_hdr->coupling = 0;
2472       pstr_env_0->balance = 0;
2473 
2474       err_code = ixheaace_code_envelope(
2475           ptr_scale_factor_band_nrg[0], pstr_const_frame_info[0]->freq_res,
2476           &pstr_env_ch[0]->str_sbr_code_env, pstr_env_0->domain_vec, pstr_sbr_hdr->coupling,
2477           pstr_const_frame_info[0]->n_envelopes, 0, pstr_sbr_bs->header_active,
2478           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2479       if (err_code) {
2480         return err_code;
2481       }
2482       break;
2483 
2484     case IXHEAACE_SBR_MODE_LEFT_RIGHT:
2485 
2486       pstr_sbr_hdr->coupling = 0;
2487 
2488       pstr_env_0->balance = 0;
2489       pstr_env_1->balance = 0;
2490 
2491       err_code = ixheaace_code_envelope(
2492           ptr_scale_factor_band_nrg[0], pstr_const_frame_info[0]->freq_res,
2493           &pstr_env_ch[0]->str_sbr_code_env, pstr_env_0->domain_vec, pstr_sbr_hdr->coupling,
2494           pstr_const_frame_info[0]->n_envelopes, 0, pstr_sbr_bs->header_active,
2495           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2496       if (err_code) {
2497         return err_code;
2498       }
2499 
2500       err_code = ixheaace_code_envelope(
2501           ptr_scale_factor_band_nrg[1], pstr_const_frame_info[1]->freq_res,
2502           &pstr_env_ch[1]->str_sbr_code_env, pstr_env_1->domain_vec, pstr_sbr_hdr->coupling,
2503           pstr_const_frame_info[1]->n_envelopes, 0, pstr_sbr_bs->header_active,
2504           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2505       if (err_code) {
2506         return err_code;
2507       }
2508       break;
2509 
2510     case SBR_COUPLING:
2511 
2512       pstr_sbr_hdr->coupling = 1;
2513       pstr_env_0->balance = 0;
2514       pstr_env_1->balance = 1;
2515 
2516       err_code = ixheaace_code_envelope(
2517           ptr_scale_factor_band_nrg[0], pstr_const_frame_info[0]->freq_res,
2518           &pstr_env_ch[0]->str_sbr_code_env, pstr_env_0->domain_vec, pstr_sbr_hdr->coupling,
2519           pstr_const_frame_info[0]->n_envelopes, 0, pstr_sbr_bs->header_active,
2520           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2521       if (err_code) {
2522         return err_code;
2523       }
2524 
2525       err_code = ixheaace_code_envelope(
2526           ptr_scale_factor_band_nrg[1], pstr_const_frame_info[1]->freq_res,
2527           &pstr_env_ch[1]->str_sbr_code_env, pstr_env_1->domain_vec, pstr_sbr_hdr->coupling,
2528           pstr_const_frame_info[1]->n_envelopes, 1, pstr_sbr_bs->header_active,
2529           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2530       if (err_code) {
2531         return err_code;
2532       }
2533       break;
2534 
2535     case IXHEAACE_SBR_MODE_SWITCH_LRC: {
2536       WORD32 payloadbits_lr;
2537       WORD32 payloadbits_coupling;
2538 
2539       WORD32 scale_factor_band_nrg_prev_temp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_FREQ_COEFFS];
2540       WORD32 noise_prev_temp[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_NUM_NOISE_COEFFS];
2541       WORD32 up_date_nrg_temp[IXHEAACE_MAX_CH_IN_BS_ELE];
2542       WORD32 up_date_noise_temp[IXHEAACE_MAX_CH_IN_BS_ELE];
2543       WORD32 domain_vec_temp[IXHEAACE_MAX_CH_IN_BS_ELE][IXHEAACE_MAX_ENV];
2544       WORD32 domain_vec_noise_temp[IXHEAACE_MAX_CH_IN_BS_ELE][IXHEAACE_MAX_ENV];
2545 
2546       WORD32 temp_flag_right = 0;
2547       WORD32 temp_flag_left = 0;
2548 
2549       ch = 0;
2550       while (ch < num_channels) {
2551         memcpy(scale_factor_band_nrg_prev_temp[ch],
2552                pstr_env_ch[ch]->str_sbr_code_env.sfb_nrg_prev,
2553                MAXIMUM_FREQ_COEFFS * sizeof(scale_factor_band_nrg_prev_temp[0][0]));
2554 
2555         memcpy(noise_prev_temp[ch], pstr_env_ch[ch]->str_sbr_code_noise_floor.sfb_nrg_prev,
2556                MAXIMUM_NUM_NOISE_COEFFS * sizeof(noise_prev_temp[0][0]));
2557 
2558         up_date_nrg_temp[ch] = pstr_env_ch[ch]->str_sbr_code_env.update;
2559         up_date_noise_temp[ch] = pstr_env_ch[ch]->str_sbr_code_noise_floor.update;
2560 
2561         if (pstr_sbr_hdr->prev_coupling) {
2562           pstr_env_ch[ch]->str_sbr_code_env.update = 0;
2563           pstr_env_ch[ch]->str_sbr_code_noise_floor.update = 0;
2564         }
2565         ch++;
2566       }
2567 
2568       err_code = ixheaace_code_envelope(
2569           ptr_scale_factor_band_nrg[0], pstr_const_frame_info[0]->freq_res,
2570           &pstr_env_ch[0]->str_sbr_code_env, pstr_env_0->domain_vec, 0,
2571           pstr_const_frame_info[0]->n_envelopes, 0, pstr_sbr_bs->header_active,
2572           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2573       if (err_code) {
2574         return err_code;
2575       }
2576 
2577       err_code = ixheaace_code_envelope(
2578           ptr_scale_factor_band_nrg[1], pstr_const_frame_info[1]->freq_res,
2579           &pstr_env_ch[1]->str_sbr_code_env, pstr_env_1->domain_vec, 0,
2580           pstr_const_frame_info[1]->n_envelopes, 0, pstr_sbr_bs->header_active,
2581           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2582       if (err_code) {
2583         return err_code;
2584       }
2585 
2586       c = 0;
2587       i = 0;
2588       while (i < n_envelopes[0]) {
2589         for (j = 0; j < pstr_env_0->no_scf_bands[i]; j++) {
2590           pstr_env_0->ienvelope[i][j] = ptr_scale_factor_band_nrg[0][c];
2591           pstr_env_1->ienvelope[i][j] = ptr_scale_factor_band_nrg[1][c];
2592 
2593           c++;
2594         }
2595         i++;
2596       }
2597 
2598       err_code = ixheaace_code_envelope(
2599           ptr_noise_level[0], res, &pstr_env_ch[0]->str_sbr_code_noise_floor,
2600           pstr_env_0->domain_vec_noise, 0, (pstr_const_frame_info[0]->n_envelopes > 1 ? 2 : 1), 0,
2601           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2602       if (err_code) {
2603         return err_code;
2604       }
2605 
2606       i = 0;
2607       while (i < MAXIMUM_NUM_NOISE_VALUES) {
2608         pstr_env_0->noise_level[i] = ptr_noise_level[0][i];
2609         i++;
2610       }
2611 
2612       err_code = ixheaace_code_envelope(
2613           ptr_noise_level[1], res, &pstr_env_ch[1]->str_sbr_code_noise_floor,
2614           pstr_env_1->domain_vec_noise, 0, (pstr_const_frame_info[1]->n_envelopes > 1 ? 2 : 1), 0,
2615           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2616       if (err_code) {
2617         return err_code;
2618       }
2619 
2620       i = 0;
2621       while (i < MAXIMUM_NUM_NOISE_VALUES) {
2622         pstr_env_1->noise_level[i] = ptr_noise_level[1][i];
2623         i++;
2624       }
2625 
2626       pstr_sbr_hdr->coupling = 0;
2627       pstr_env_0->balance = 0;
2628       pstr_env_1->balance = 0;
2629 
2630       err_code = ixheaace_count_sbr_channel_pair_element(
2631           pstr_sbr_hdr, pstr_sbr_bs, &pstr_env_ch[0]->enc_env_data, &pstr_env_ch[1]->enc_env_data,
2632           pstr_com_data, ptr_sbr_tab, pstr_sbr_cfg->sbr_codec, pstr_sbr_cfg->is_esbr, &str_esbr,
2633           &payloadbits_lr);
2634       if (err_code) {
2635         return err_code;
2636       }
2637 
2638       for (ch = 0; ch < num_channels; ch++) {
2639         WORD32 itmp;
2640 
2641         for (i = 0; i < MAXIMUM_FREQ_COEFFS; i++) {
2642           itmp = pstr_env_ch[ch]->str_sbr_code_env.sfb_nrg_prev[i];
2643           pstr_env_ch[ch]->str_sbr_code_env.sfb_nrg_prev[i] =
2644               scale_factor_band_nrg_prev_temp[ch][i];
2645           scale_factor_band_nrg_prev_temp[ch][i] = itmp;
2646         }
2647 
2648         for (i = 0; i < MAXIMUM_NUM_NOISE_COEFFS; i++) {
2649           itmp = pstr_env_ch[ch]->str_sbr_code_noise_floor.sfb_nrg_prev[i];
2650           pstr_env_ch[ch]->str_sbr_code_noise_floor.sfb_nrg_prev[i] = noise_prev_temp[ch][i];
2651           noise_prev_temp[ch][i] = itmp;
2652         }
2653 
2654         itmp = pstr_env_ch[ch]->str_sbr_code_env.update;
2655         pstr_env_ch[ch]->str_sbr_code_env.update = up_date_nrg_temp[ch];
2656         up_date_nrg_temp[ch] = itmp;
2657 
2658         itmp = pstr_env_ch[ch]->str_sbr_code_noise_floor.update;
2659         pstr_env_ch[ch]->str_sbr_code_noise_floor.update = up_date_noise_temp[ch];
2660         up_date_noise_temp[ch] = itmp;
2661 
2662         memcpy(domain_vec_temp[ch], pstr_env_ch[ch]->enc_env_data.domain_vec,
2663                sizeof(domain_vec_temp[0][0]) * IXHEAACE_MAX_ENV);
2664 
2665         memcpy(domain_vec_noise_temp[ch], pstr_env_ch[ch]->enc_env_data.domain_vec_noise,
2666                sizeof(domain_vec_noise_temp[0][0]) * IXHEAACE_MAX_ENV);
2667 
2668         if (!pstr_sbr_hdr->prev_coupling) {
2669           pstr_env_ch[ch]->str_sbr_code_env.update = 0;
2670           pstr_env_ch[ch]->str_sbr_code_noise_floor.update = 0;
2671         }
2672       }
2673 
2674       err_code = ixheaace_code_envelope(
2675           ptr_sfb_nrg_coupling[0], pstr_const_frame_info[0]->freq_res,
2676           &pstr_env_ch[0]->str_sbr_code_env, pstr_env_0->domain_vec, 1,
2677           pstr_const_frame_info[0]->n_envelopes, 0, pstr_sbr_bs->header_active,
2678           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2679       if (err_code) {
2680         return err_code;
2681       }
2682 
2683       err_code = ixheaace_code_envelope(
2684           ptr_sfb_nrg_coupling[1], pstr_const_frame_info[1]->freq_res,
2685           &pstr_env_ch[1]->str_sbr_code_env, pstr_env_1->domain_vec, 1,
2686           pstr_const_frame_info[1]->n_envelopes, 1, pstr_sbr_bs->header_active,
2687           pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2688       if (err_code) {
2689         return err_code;
2690       }
2691 
2692       c = 0;
2693       i = 0;
2694       while (i < n_envelopes[0]) {
2695         for (j = 0; j < pstr_env_0->no_scf_bands[i]; j++) {
2696           pstr_env_0->ienvelope[i][j] = ptr_sfb_nrg_coupling[0][c];
2697           pstr_env_1->ienvelope[i][j] = ptr_sfb_nrg_coupling[1][c];
2698           c++;
2699         }
2700         i++;
2701       }
2702 
2703       err_code = ixheaace_code_envelope(
2704           ptr_noise_lvl_coupling[0], res, &pstr_env_ch[0]->str_sbr_code_noise_floor,
2705           pstr_env_0->domain_vec_noise, 1, (pstr_const_frame_info[0]->n_envelopes > 1 ? 2 : 1), 0,
2706           pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2707       if (err_code) {
2708         return err_code;
2709       }
2710 
2711       for (i = 0; i < MAXIMUM_NUM_NOISE_VALUES; i++) {
2712         pstr_env_0->noise_level[i] = ptr_noise_lvl_coupling[0][i];
2713       }
2714 
2715       err_code = ixheaace_code_envelope(
2716           ptr_noise_lvl_coupling[1], res, &pstr_env_ch[1]->str_sbr_code_noise_floor,
2717           pstr_env_1->domain_vec_noise, 1, ((pstr_const_frame_info[1]->n_envelopes > 1) ? 2 : 1),
2718           1, pstr_sbr_bs->header_active, pstr_sbr_bs->usac_indep_flag, pstr_sbr_cfg->is_ld_sbr);
2719       if (err_code) {
2720         return err_code;
2721       }
2722 
2723       for (i = 0; i < MAXIMUM_NUM_NOISE_VALUES; i++) {
2724         pstr_env_1->noise_level[i] = ptr_noise_lvl_coupling[1][i];
2725       }
2726 
2727       pstr_sbr_hdr->coupling = 1;
2728 
2729       pstr_env_0->balance = 0;
2730       pstr_env_1->balance = 1;
2731 
2732       temp_flag_left = pstr_env_0->add_harmonic_flag;
2733       temp_flag_right = pstr_env_1->add_harmonic_flag;
2734 
2735       err_code = ixheaace_count_sbr_channel_pair_element(
2736           pstr_sbr_hdr, pstr_sbr_bs, &pstr_env_ch[0]->enc_env_data, &pstr_env_ch[1]->enc_env_data,
2737           pstr_com_data, ptr_sbr_tab, pstr_sbr_cfg->sbr_codec, pstr_sbr_cfg->is_esbr, &str_esbr,
2738           &payloadbits_coupling);
2739       if (err_code) {
2740         return err_code;
2741       }
2742 
2743       pstr_env_0->add_harmonic_flag = temp_flag_left;
2744       pstr_env_1->add_harmonic_flag = temp_flag_right;
2745 
2746       if (payloadbits_coupling < payloadbits_lr) {
2747         ch = 0;
2748         while (ch < num_channels) {
2749           memcpy(ptr_scale_factor_band_nrg[ch], ptr_sfb_nrg_coupling[ch],
2750                  MAXIMUM_NUM_ENVELOPE_VALUES * sizeof(ptr_scale_factor_band_nrg[0][0]));
2751 
2752           memcpy(ptr_noise_level[ch], ptr_noise_lvl_coupling[ch],
2753                  MAXIMUM_NUM_NOISE_VALUES * sizeof(ptr_noise_level[0][0]));
2754           ch++;
2755         }
2756 
2757         pstr_sbr_hdr->coupling = 1;
2758         pstr_env_0->balance = 0;
2759         pstr_env_1->balance = 1;
2760       } else {
2761         ch = 0;
2762         while (ch < num_channels) {
2763           memcpy(pstr_env_ch[ch]->str_sbr_code_env.sfb_nrg_prev,
2764                  scale_factor_band_nrg_prev_temp[ch],
2765                  MAXIMUM_FREQ_COEFFS * sizeof(scale_factor_band_nrg_prev_temp[0][0]));
2766 
2767           pstr_env_ch[ch]->str_sbr_code_env.update = up_date_nrg_temp[ch];
2768 
2769           memcpy(pstr_env_ch[ch]->str_sbr_code_noise_floor.sfb_nrg_prev, noise_prev_temp[ch],
2770                  MAXIMUM_NUM_NOISE_COEFFS * sizeof(noise_prev_temp[0][0]));
2771 
2772           memcpy(pstr_env_ch[ch]->enc_env_data.domain_vec, domain_vec_temp[ch],
2773                  sizeof(domain_vec_temp[0][0]) * IXHEAACE_MAX_ENV);
2774 
2775           memcpy(pstr_env_ch[ch]->enc_env_data.domain_vec_noise, domain_vec_noise_temp[ch],
2776                  sizeof(domain_vec_noise_temp[0][0]) * IXHEAACE_MAX_ENV);
2777 
2778           pstr_env_ch[ch]->str_sbr_code_noise_floor.update = up_date_noise_temp[ch];
2779           ch++;
2780         }
2781 
2782         pstr_sbr_hdr->coupling = 0;
2783         pstr_env_0->balance = 0;
2784         pstr_env_1->balance = 0;
2785       }
2786     } break;
2787   }
2788 
2789   if (num_channels == 1) {
2790     if (pstr_env_0->domain_vec[0] == TIME) {
2791       pstr_env_ch[0]->str_sbr_code_env.df_edge_incr_fac++;
2792     } else {
2793       pstr_env_ch[0]->str_sbr_code_env.df_edge_incr_fac = 0;
2794     }
2795   } else {
2796     if (pstr_env_0->domain_vec[0] == TIME || pstr_env_1->domain_vec[0] == TIME) {
2797       pstr_env_ch[0]->str_sbr_code_env.df_edge_incr_fac++;
2798       pstr_env_ch[1]->str_sbr_code_env.df_edge_incr_fac++;
2799     } else {
2800       pstr_env_ch[0]->str_sbr_code_env.df_edge_incr_fac = 0;
2801       pstr_env_ch[1]->str_sbr_code_env.df_edge_incr_fac = 0;
2802     }
2803   }
2804 
2805   for (ch = 0; ch < num_channels; ch++) {
2806     c = 0;
2807     i = 0;
2808 
2809     while (i < n_envelopes[ch]) {
2810       for (j = 0; j < pstr_env_ch[ch]->enc_env_data.no_scf_bands[i]; j++) {
2811         pstr_env_ch[ch]->enc_env_data.ienvelope[i][j] = ptr_scale_factor_band_nrg[ch][c];
2812         c++;
2813       }
2814       i++;
2815     }
2816 
2817     i = 0;
2818     while (i < MAXIMUM_NUM_NOISE_VALUES) {
2819       pstr_env_ch[ch]->enc_env_data.noise_level[i] = ptr_noise_level[ch][i];
2820       i++;
2821     }
2822   }
2823   if ((USAC_SBR == pstr_sbr_cfg->sbr_codec) && (1 == pstr_sbr_hdr->sbr_inter_tes_active)) {
2824     // inter-TES encoder
2825     WORD32 idx;
2826     for (ch = 0; ch < num_channels; ch++) {
2827       ixheaace_str_inter_tes_params *pstr_tes_enc = &pstr_env_ch[ch]->str_inter_tes_enc;
2828 
2829       pstr_tes_enc->num_if_bands = pstr_env_ch[ch]->enc_env_data.noise_band_count;
2830       pstr_tes_enc->sub_band_start = pstr_sbr_cfg->ptr_freq_band_tab[LO][0];
2831       pstr_tes_enc->sub_band_end = pstr_sbr_cfg->ptr_freq_band_tab[LO][pstr_sbr_cfg->num_scf[LO]];
2832       pstr_tes_enc->num_mf_bands = pstr_sbr_cfg->num_master;
2833       pstr_tes_enc->out_fs = pstr_sbr_cfg->sample_freq;
2834       pstr_tes_enc->num_env = pstr_env_ch[ch]->str_sbr_env_frame.sbr_grid.bs_num_env;
2835 
2836       for (idx = 0; idx < (IXHEAACE_MAX_ENV + 1); idx++) {
2837         pstr_tes_enc->border_vec[idx] = (WORD16)pstr_const_frame_info[ch]->borders[idx];
2838       }
2839 
2840       for (idx = 0; idx < (MAXIMUM_FREQ_COEFFS + 1); idx++) {
2841         pstr_tes_enc->f_master_tbl[idx] = (WORD16)((UWORD16)pstr_sbr_cfg->ptr_v_k_master[idx]);
2842       }
2843 
2844       for (idx = 0; idx < MAXIMUM_NUM_NOISE_VALUES; idx++) {
2845         pstr_tes_enc->inv_filt_mode[idx] =
2846             (WORD32)pstr_env_ch[ch]->enc_env_data.sbr_invf_mode_vec[idx];
2847         pstr_tes_enc->invf_band_tbl[idx] =
2848             (WORD16)pstr_env_ch[ch]->str_ton_corr.sbr_noise_floor_est.s_freq_qmf_band_tbl[idx];
2849       }
2850       pstr_tes_enc->invf_band_tbl[MAXIMUM_NUM_NOISE_VALUES] =
2851           (WORD16)pstr_env_ch[ch]
2852               ->str_ton_corr.sbr_noise_floor_est.s_freq_qmf_band_tbl[MAXIMUM_NUM_NOISE_VALUES];
2853 
2854       err_code = ixheaace_process_inter_tes(pstr_tes_enc, ptr_sbr_scratch);
2855       if (err_code) {
2856         return err_code;
2857       }
2858 
2859       WORD32 ts, num_ts, delay;
2860       num_ts = pstr_env_ch[ch]->str_sbr_qmf.num_time_slots;
2861 
2862       delay = pstr_tes_enc->op_delay + pstr_tes_enc->codec_delay + IXHEAACE_SBR_HF_ADJ_OFFSET;
2863 
2864       for (ts = 0; ts < delay; ts++) {
2865         memcpy(pstr_tes_enc->qmf_buf_real[ts], pstr_tes_enc->qmf_buf_real[num_ts + ts],
2866                IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_real[0][0]));
2867         memcpy(pstr_tes_enc->qmf_buf_imag[ts], pstr_tes_enc->qmf_buf_imag[num_ts + ts],
2868                IXHEAACE_QMF_CHANNELS * sizeof(pstr_tes_enc->qmf_buf_imag[0][0]));
2869       }
2870     }
2871   }
2872   // Pitch detection, pre-processing detection and oversampling decision making
2873   if ((1 == pstr_sbr_cfg->is_esbr) && (pstr_sbr_cfg->sbr_codec == HEAAC_SBR)) {
2874     err_code = ixheaace_update_esbr_ext_data(
2875         ptr_in_time, pstr_sbr_cfg, pstr_env_ch[0]->str_sbr_extract_env.ptr_r_buffer[0], &str_esbr,
2876         transient_info, ptr_sbr_tab, pstr_sbr_hdr->coupling, time_sn_stride, 2048);
2877     if (err_code) return err_code;
2878   }
2879 
2880   if ((pstr_sbr_cfg->sbr_codec == USAC_SBR) && (pstr_sbr_hdr->sbr_harmonic)) {
2881     ixheaace_update_harmonic_sbr_data(transient_info, pstr_sbr_hdr->coupling,
2882                                       &pstr_env_ch[0], num_channels);
2883   }
2884   if (num_channels == 2) {
2885     WORD32 num_bits;
2886     pstr_env_0->usac_indep_flag = pstr_sbr_bs->usac_indep_flag;
2887     pstr_env_1->usac_indep_flag = pstr_sbr_bs->usac_indep_flag;
2888     err_code = ixheaace_write_env_channel_pair_element(
2889         pstr_sbr_hdr, pstr_sbr_bs, &pstr_env_ch[0]->enc_env_data, &pstr_env_ch[1]->enc_env_data,
2890         pstr_com_data, ptr_sbr_tab, pstr_sbr_cfg->sbr_codec, pstr_sbr_cfg->is_esbr, &str_esbr,
2891         &num_bits);
2892     if (err_code) {
2893       return err_code;
2894     }
2895   } else {
2896     WORD32 num_bits;
2897     pstr_env_0->sbr_pvc_mode = pstr_sbr_hdr->sbr_pvc_mode;
2898     pstr_env_0->sbr_sinusoidal_pos_flag = 0;
2899     pstr_env_0->usac_indep_flag = pstr_sbr_bs->usac_indep_flag;
2900 
2901     err_code = ixheaace_write_env_single_channel_element(
2902         pstr_sbr_hdr, pstr_sbr_bs, &pstr_env_ch[0]->enc_env_data, pstr_ps_enc, pstr_com_data,
2903         ptr_sbr_tab, pstr_sbr_cfg->sbr_codec, pstr_sbr_cfg->is_esbr, &str_esbr, &num_bits);
2904     if (err_code) {
2905       return err_code;
2906     }
2907   }
2908 
2909   ch = 0;
2910   while (ch < num_channels) {
2911     ixheaace_str_sbr_extr_env *pstr_sbr_extract_env = &(pstr_env_ch[ch]->str_sbr_extract_env);
2912     for (i = 0; i < pstr_sbr_extract_env->y_buffer_write_offset; i++) {
2913       FLOAT32 *ptr_tmp;
2914       ptr_tmp = pstr_sbr_extract_env->ptr_y_buffer[i];
2915       pstr_sbr_extract_env->ptr_y_buffer[i] =
2916           pstr_sbr_extract_env->ptr_y_buffer[i + (pstr_sbr_extract_env->no_cols >> 1)];
2917       pstr_sbr_extract_env->ptr_y_buffer[i + (pstr_sbr_extract_env->no_cols >> 1)] = ptr_tmp;
2918     }
2919 
2920     pstr_sbr_extract_env->buffer_flag ^= 1;
2921     ch++;
2922   }
2923 
2924   pstr_sbr_hdr->prev_coupling = pstr_sbr_hdr->coupling;
2925 
2926   return err_code;
2927 }
2928