xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_ps_enc.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 
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_error_standards.h"
26 #include "ixheaace_sbr_def.h"
27 #include "ixheaace_resampler.h"
28 #include "ixheaace_sbr_rom.h"
29 #include "ixheaace_common_rom.h"
30 #include "ixheaace_bitbuffer.h"
31 #include "ixheaace_sbr_hybrid.h"
32 #include "ixheaace_sbr_ps_enc.h"
33 #include "ixheaac_constants.h"
34 #include "ixheaace_aac_constants.h"
35 
ixheaace_memcpy(void * dest,const void * src,WORD32 count)36 static VOID ixheaace_memcpy(void *dest, const void *src, WORD32 count) {
37   memcpy(dest, src, count);
38 }
39 
ia_enhaacplus_enc_downmix_to_mono(ixheaace_pstr_ps_enc pms,FLOAT32 ** qmf_left_real,FLOAT32 ** qmf_left_imag,FLOAT32 ** qmf_right_real,FLOAT32 ** qmf_right_imag,ixheaace_str_ps_tab * ps_tables)40 static VOID ia_enhaacplus_enc_downmix_to_mono(ixheaace_pstr_ps_enc pms, FLOAT32 **qmf_left_real,
41                                               FLOAT32 **qmf_left_imag, FLOAT32 **qmf_right_real,
42                                               FLOAT32 **qmf_right_imag,
43                                               ixheaace_str_ps_tab *ps_tables) {
44   WORD32 i;
45   WORD32 group;
46   WORD32 subband;
47   WORD32 max_subband;
48   WORD32 subband_grp;
49 
50   FLOAT32 temp_left_real;
51   FLOAT32 temp_left_imag;
52   FLOAT32 temp_right_real;
53   FLOAT32 temp_right_imag;
54   FLOAT32 temp, temp2;
55 
56   for (i = 0; i < IXHEAACE_HYBRID_FILTER_DELAY; i++) {
57     ixheaace_memcpy(pms->temp_qmf_left_real[i],
58                     qmf_left_real[NUMBER_OF_SUBSAMPLES - IXHEAACE_HYBRID_FILTER_DELAY + i],
59                     NUMBER_OF_QMF_BANDS * sizeof(**qmf_left_real));
60     ixheaace_memcpy(pms->temp_qmf_left_imag[i],
61                     qmf_left_imag[NUMBER_OF_SUBSAMPLES - IXHEAACE_HYBRID_FILTER_DELAY + i],
62                     NUMBER_OF_QMF_BANDS * sizeof(**qmf_left_imag));
63   }
64 
65   {
66     FLOAT32 *hybrid_left_real_init, *hybrid_right_real_init;
67     hybrid_left_real_init = pms->m_hybrid_real_left[0];
68     hybrid_right_real_init = pms->m_hybrid_real_right[0];
69 
70     for (group = 0; group < SUBQMF_GROUPS_MIX; group++) {
71       FLOAT32 *hybrid_left_real, *hybrid_right_real;
72 
73       subband = ps_tables->grp_borders_mix[group];
74       hybrid_left_real = hybrid_left_real_init + subband;
75       hybrid_right_real = hybrid_right_real_init + subband;
76 
77       for (i = NUMBER_OF_SUBSAMPLES; i != 0; i--) {
78         FLOAT32 temp_left_real_1, temp_left_imag_1;
79 
80         temp_left_real = hybrid_left_real[0];
81         hybrid_left_real += 32;
82         temp_left_imag = hybrid_left_real[-16];
83         temp_right_real = hybrid_right_real[0];
84         hybrid_right_real += 32;
85         temp_right_imag = hybrid_right_real[-16];
86 
87         temp_left_real_1 = temp_right_real + temp_left_real;
88         temp_left_imag_1 = temp_right_imag + temp_left_imag;
89 
90         temp2 = temp_left_real_1 * temp_left_real_1;
91         temp2 += temp_left_imag_1 * temp_left_imag_1;
92         temp2 /= 2.0f;
93 
94         temp = temp_left_real * temp_right_real;
95         temp += temp_left_imag * temp_right_imag;
96 
97         temp = temp2 - temp;
98 
99         if ((temp / 8.0f) >= temp2) {
100           temp_left_real = temp_left_real_1 * 2.0f;
101           temp_left_imag = temp_left_imag_1 * 2.0f;
102         } else {
103           temp = (FLOAT32)sqrt(temp / (temp2 * 2.0f));
104           temp_left_real = temp_left_real_1 * temp;
105           temp_left_imag = temp_left_imag_1 * temp;
106         }
107 
108         hybrid_left_real[-32] = temp_left_real;
109         hybrid_left_real[-16] = temp_left_imag;
110       }
111     }
112   }
113 
114   for (; group < NUMBER_OF_IPD_GROUPS; group++) {
115     FLOAT32 *hybrid_left_real;
116     FLOAT32 *qmf_lre = qmf_left_real[NUMBER_OF_SUBSAMPLES - 1];
117 
118     subband_grp = ps_tables->grp_borders_mix[group];
119     max_subband = ps_tables->grp_borders_mix[group + 1];
120 
121     hybrid_left_real =
122         (qmf_left_real - IXHEAACE_HYBRID_FILTER_DELAY)[NUMBER_OF_SUBSAMPLES - 1] + 0X1000;
123     hybrid_left_real += subband_grp;
124     qmf_lre += subband_grp;
125 
126     for (i = NUMBER_OF_SUBSAMPLES - 1; i >= IXHEAACE_HYBRID_FILTER_DELAY; i--) {
127       for (subband = max_subband - subband_grp; subband != 0; subband--) {
128         FLOAT32 temp_left_real_1, temp_left_imag_1;
129 
130         temp_left_real = hybrid_left_real[-0X1000];
131         temp_left_imag = hybrid_left_real[0];
132         temp_right_real = hybrid_left_real[-0X800];
133         temp_right_imag = hybrid_left_real[0X800];
134 
135         hybrid_left_real += 1;
136 
137         temp_left_real_1 = temp_right_real + temp_left_real;
138         temp_left_imag_1 = temp_right_imag + temp_left_imag;
139 
140         temp2 = temp_left_real_1 * temp_left_real_1;
141         temp2 += temp_left_imag_1 * temp_left_imag_1;
142         temp2 /= 2.0f;
143 
144         temp = temp_left_real * temp_right_real;
145         temp += temp_left_imag * temp_right_imag;
146 
147         temp = temp2 - temp;
148 
149         if ((temp / 8.0f) >= temp2) {
150           temp_left_real = temp_left_real_1 * 2.0f;
151           temp_left_imag = temp_left_imag_1 * 2.0f;
152         } else {
153           temp = (FLOAT32)sqrt(temp / (2.0f * temp2));
154           temp_left_real = temp_left_real_1 * temp;
155           temp_left_imag = temp_left_imag_1 * temp;
156         }
157 
158         qmf_lre[0] = temp_left_real;
159         qmf_lre[0 + 0x1000] = temp_left_imag;
160         qmf_lre += 1;
161       }
162 
163       hybrid_left_real -= max_subband - subband_grp;
164       qmf_lre -= max_subband - subband_grp;
165       qmf_lre -= 64;
166       hybrid_left_real -= 64;
167     }
168 
169     hybrid_left_real = pms->hist_qmf_left_real[IXHEAACE_HYBRID_FILTER_DELAY - 1];
170     hybrid_left_real += subband_grp;
171 
172     for (i = IXHEAACE_HYBRID_FILTER_DELAY - 1; i >= 0; i--) {
173       for (subband = max_subband - subband_grp; subband != 0; subband--) {
174         FLOAT32 temp_left_real_1, temp_left_imag_1;
175 
176         temp_left_real = hybrid_left_real[0];
177         temp_left_imag = hybrid_left_real[0 + 0x40];
178         temp_right_real = hybrid_left_real[0 + 0x80];
179         temp_right_imag = hybrid_left_real[0 + 0xc0];
180 
181         temp_left_real_1 = temp_right_real + temp_left_real;
182         temp_left_imag_1 = temp_right_imag + temp_left_imag;
183 
184         temp2 = temp_left_real_1 * temp_left_real_1;
185         temp2 += temp_left_imag_1 * temp_left_imag_1;
186         temp2 /= 2.0f;
187 
188         temp = temp_left_real * temp_right_real;
189         temp += temp_left_imag * temp_right_imag;
190 
191         temp = temp2 - temp;
192 
193         if ((temp / 8.0f) >= temp2) {
194           temp_left_real = temp_left_real_1 * 2.0f;
195           temp_left_imag = temp_left_imag_1 * 2.0f;
196         } else {
197           temp = (FLOAT32)sqrt(temp / (2.0f * temp2));
198           temp_left_real = temp_left_real_1 * temp;
199           temp_left_imag = temp_left_imag_1 * temp;
200         }
201 
202         qmf_lre[0] = temp_left_real;
203         qmf_lre[0x1000] = temp_left_imag;
204         qmf_lre += 1;
205         hybrid_left_real += 1;
206       }
207       qmf_lre -= max_subband - subband_grp;
208       hybrid_left_real -= max_subband - subband_grp;
209       qmf_lre -= 64;
210       hybrid_left_real -= 0x100;
211     }
212   }
213 
214   for (i = 0; i < IXHEAACE_HYBRID_FILTER_DELAY; i++) {
215     ixheaace_memcpy(pms->hist_qmf_left_real[i], pms->temp_qmf_left_real[i],
216                     NUMBER_OF_QMF_BANDS * sizeof(**qmf_left_real));
217     ixheaace_memcpy(pms->hist_qmf_left_imag[i], pms->temp_qmf_left_imag[i],
218                     NUMBER_OF_QMF_BANDS * sizeof(**qmf_left_imag));
219     ixheaace_memcpy(pms->hist_qmf_right_real[i],
220                     qmf_right_real[NUMBER_OF_SUBSAMPLES - IXHEAACE_HYBRID_FILTER_DELAY + i],
221                     NUMBER_OF_QMF_BANDS * sizeof(**qmf_right_real));
222     ixheaace_memcpy(pms->hist_qmf_right_imag[i],
223                     qmf_right_imag[NUMBER_OF_SUBSAMPLES - IXHEAACE_HYBRID_FILTER_DELAY + i],
224                     NUMBER_OF_QMF_BANDS * sizeof(**qmf_right_imag));
225   }
226 
227   ixheaace_hybrid_synthesis((const FLOAT32 **)pms->m_hybrid_real_left,
228                             (const FLOAT32 **)pms->m_hybrid_imag_left, qmf_left_real,
229                             qmf_left_imag, ps_tables->a_hyb_res);
230 }
231 
ixheaace_encode_ps_frame(ixheaace_pstr_ps_enc pms,FLOAT32 ** i_buffer_left,FLOAT32 ** r_buffer_left,FLOAT32 ** i_buffer_right,FLOAT32 ** r_buffer_right,ixheaace_str_ps_tab * ps_tables,ixheaace_comm_tables * common_tab)232 IA_ERRORCODE ixheaace_encode_ps_frame(ixheaace_pstr_ps_enc pms, FLOAT32 **i_buffer_left,
233                                       FLOAT32 **r_buffer_left, FLOAT32 **i_buffer_right,
234                                       FLOAT32 **r_buffer_right, ixheaace_str_ps_tab *ps_tables,
235                                       ixheaace_comm_tables *common_tab) {
236   IA_ERRORCODE err_code;
237   WORD32 i;
238   WORD32 bin;
239   WORD32 subband, max_subband;
240 
241   FLOAT32 band_hist_power_left;
242   FLOAT32 band_hist_power_right;
243   FLOAT32 band_hist_power_corr_real;
244   FLOAT32 band_hist_power_corr_imag;
245 
246   FLOAT32 band_power_left_env1;
247   FLOAT32 band_power_right_env1;
248   FLOAT32 band_power_corr_real_env1;
249   FLOAT32 band_power_corr_imag_env1;
250   FLOAT32 scratch_power_left_right_env2[2 * NUMBER_OF_BINS];
251   FLOAT32 scratch_power_corr_real_imag_env2[2 * NUMBER_OF_BINS];
252 
253   FLOAT32 **hybrid_left_imag_env1;
254   FLOAT32 **hybrid_left_real_env1;
255   FLOAT32 **hybrid_right_imag_env1;
256   FLOAT32 **hybrid_right_real_env1;
257 
258   FLOAT32 **hybrid_left_imag_env2;
259   FLOAT32 **hybrid_left_real_env2;
260   FLOAT32 **hybr_right_imag_env2;
261   FLOAT32 **hybr_right_real_env2;
262 
263   FLOAT32 **hist_left_imag;
264   FLOAT32 **hist_left_real;
265   FLOAT32 **hist_right_imag;
266   FLOAT32 **hist_right_real;
267 
268   FLOAT32 temp1;
269   FLOAT32 temp2;
270 
271   FLOAT32 temp_hist_pow_left;
272   FLOAT32 temp_hist_pow_right;
273   FLOAT32 temp_hist_pow_corr_real;
274   FLOAT32 temp_hist_pow_corr_imag;
275 
276   FLOAT32 temp_power_left_env1;
277   FLOAT32 temp_power_right_env1;
278   FLOAT32 temp_power_corr_real_env1;
279   FLOAT32 temp_power_corr_imag_env1;
280 
281   FLOAT32 temp_power_left_env2;
282   FLOAT32 temp_power_right_env2;
283   FLOAT32 temp_power_corr_real_env2;
284   FLOAT32 temp_power_corr_imag_env2;
285 
286   err_code = ixheaace_hybrid_analysis((const FLOAT32 **)(r_buffer_left),
287                                       (const FLOAT32 **)(i_buffer_left), pms->m_hybrid_real_left,
288                                       pms->m_hybrid_imag_left, pms->ptr_hybrid_left, ps_tables,
289                                       common_tab->pstr_common_tab);
290   if (err_code != IA_NO_ERROR) {
291     return err_code;
292   }
293 
294   err_code = ixheaace_hybrid_analysis(
295       (const FLOAT32 **)(r_buffer_right), (const FLOAT32 **)(i_buffer_right),
296       pms->m_hybrid_real_right, pms->m_hybrid_imag_right, pms->ptr_hybrid_right, ps_tables,
297       common_tab->pstr_common_tab);
298   if (err_code != IA_NO_ERROR) {
299     return err_code;
300   }
301 
302   {
303     hybrid_left_real_env1 = pms->m_hybrid_real_left;
304     hybrid_left_imag_env1 = pms->m_hybrid_imag_left;
305     hybrid_right_real_env1 = pms->m_hybrid_real_right;
306     hybrid_right_imag_env1 = pms->m_hybrid_imag_right;
307 
308     hybrid_left_real_env2 = &(pms->m_hybrid_real_left[NUMBER_OF_SUBSAMPLES / 2]);
309     hybrid_left_imag_env2 = &(pms->m_hybrid_imag_left[NUMBER_OF_SUBSAMPLES / 2]);
310     hybr_right_real_env2 = &(pms->m_hybrid_real_right[NUMBER_OF_SUBSAMPLES / 2]);
311     hybr_right_imag_env2 = &(pms->m_hybrid_imag_right[NUMBER_OF_SUBSAMPLES / 2]);
312 
313     for (bin = 0; bin < SUBQMF_BINS_ENERGY; bin++) {
314       band_power_left_env1 = 0;
315       band_power_right_env1 = 0;
316       band_power_corr_real_env1 = 0;
317       band_power_corr_imag_env1 = 0;
318 
319       temp_power_left_env2 = 0;
320       temp_power_right_env2 = 0;
321       temp_power_corr_real_env2 = 0;
322       temp_power_corr_imag_env2 = 0;
323 
324       max_subband = ps_tables->hi_res_band_borders[bin] + 1;
325       for (subband = ps_tables->hi_res_band_borders[bin]; subband < max_subband; subband++) {
326         FLOAT32 t_left_real, t_left_imag, t_right_real, t_right_imag;
327 
328         for (i = 0; i < NUMBER_OF_SUBSAMPLES / 2; i++) {
329           // Envelope 1
330           t_left_real = hybrid_left_real_env1[i][subband];
331           t_right_real = hybrid_right_real_env1[i][subband];
332           t_left_imag = hybrid_left_imag_env1[i][subband];
333           t_right_imag = hybrid_right_imag_env1[i][subband];
334 
335           temp1 = t_left_real * t_left_real;
336           temp2 = t_left_imag * t_left_imag;
337           band_power_left_env1 += (temp1 + temp2);
338 
339           temp1 = t_right_real * t_right_real;
340           temp2 = t_right_imag * t_right_imag;
341           band_power_right_env1 += (temp1 + temp2);
342 
343           temp1 = t_left_real * t_right_real;
344           temp2 = t_left_imag * t_right_imag;
345           band_power_corr_real_env1 += (temp1 + temp2);
346 
347           temp1 = t_left_imag * t_right_real;
348           temp2 = t_left_real * t_right_imag;
349           band_power_corr_imag_env1 += (temp1 - temp2);
350 
351           // Envelope 2
352           t_left_real = hybrid_left_real_env2[i][subband];
353           t_right_real = hybr_right_real_env2[i][subband];
354           t_left_imag = hybrid_left_imag_env2[i][subband];
355           t_right_imag = hybr_right_imag_env2[i][subband];
356 
357           temp1 = t_left_real * t_left_real;
358           temp2 = t_left_imag * t_left_imag;
359           temp_power_left_env2 += (temp1 + temp2);
360 
361           temp1 = t_right_real * t_right_real;
362           temp2 = t_right_imag * t_right_imag;
363           temp_power_right_env2 += (temp1 + temp2);
364 
365           temp1 = t_left_real * t_right_real;
366           temp2 = t_left_imag * t_right_imag;
367           temp_power_corr_real_env2 += (temp1 + temp2);
368 
369           temp1 = t_left_imag * t_right_real;
370           temp2 = t_left_real * t_right_imag;
371           temp_power_corr_imag_env2 += (temp1 - temp2);
372         }
373       }
374 
375       scratch_power_left_right_env2[2 * bin] = temp_power_left_env2;
376       scratch_power_left_right_env2[2 * bin + 1] = temp_power_right_env2;
377       scratch_power_corr_real_imag_env2[2 * bin] = temp_power_corr_real_env2;
378       scratch_power_corr_real_imag_env2[2 * bin + 1] = temp_power_corr_imag_env2;
379 
380       pms->pow_left_right[2 * bin] = pms->pow_left_right[2 * bin] + band_power_left_env1;
381       pms->pow_left_right[2 * bin + 1] = pms->pow_left_right[2 * bin + 1] + band_power_right_env1;
382       pms->pow_corr_real_imag[2 * bin] =
383           pms->pow_corr_real_imag[2 * bin] + band_power_corr_real_env1;
384       pms->pow_corr_real_imag[2 * bin + 1] =
385           pms->pow_corr_real_imag[2 * bin + 1] + band_power_corr_imag_env1;
386     }
387 
388     hist_left_real = pms->hist_qmf_left_real;
389     hist_left_imag = pms->hist_qmf_left_imag;
390     hist_right_real = pms->hist_qmf_right_real;
391     hist_right_imag = pms->hist_qmf_right_imag;
392 
393     hybrid_left_real_env1 = r_buffer_left;
394     hybrid_left_imag_env1 = i_buffer_left;
395     hybrid_right_real_env1 = r_buffer_right;
396     hybrid_right_imag_env1 = i_buffer_right;
397 
398     hybrid_left_real_env2 =
399         &r_buffer_left[NUMBER_OF_SUBSAMPLES / 2 - IXHEAACE_HYBRID_FILTER_DELAY];
400     hybrid_left_imag_env2 =
401         &i_buffer_left[NUMBER_OF_SUBSAMPLES / 2 - IXHEAACE_HYBRID_FILTER_DELAY];
402     hybr_right_real_env2 =
403         &r_buffer_right[NUMBER_OF_SUBSAMPLES / 2 - IXHEAACE_HYBRID_FILTER_DELAY];
404     hybr_right_imag_env2 =
405         &i_buffer_right[NUMBER_OF_SUBSAMPLES / 2 - IXHEAACE_HYBRID_FILTER_DELAY];
406 
407     for (bin = SUBQMF_BINS_ENERGY; bin < NUMBER_OF_BINS; bin++) {
408       band_power_left_env1 = 0;
409       band_power_right_env1 = 0;
410       band_power_corr_real_env1 = 0;
411       band_power_corr_imag_env1 = 0;
412 
413       scratch_power_left_right_env2[2 * bin] = 0;
414       scratch_power_left_right_env2[2 * bin + 1] = 0;
415       scratch_power_corr_real_imag_env2[2 * bin] = 0;
416       scratch_power_corr_real_imag_env2[2 * bin + 1] = 0;
417 
418       band_hist_power_left = 0;
419       band_hist_power_right = 0;
420       band_hist_power_corr_real = 0;
421       band_hist_power_corr_imag = 0;
422 
423       for (subband = ps_tables->hi_res_band_borders[bin];
424            subband < ps_tables->hi_res_band_borders[bin + 1]; subband++) {
425         FLOAT32 t_left_real, t_left_imag, t_right_real, t_right_imag;
426         temp_hist_pow_left = 0;
427         temp_hist_pow_right = 0;
428         temp_hist_pow_corr_real = 0;
429         temp_hist_pow_corr_imag = 0;
430 
431         temp_power_left_env1 = 0;
432         temp_power_right_env1 = 0;
433         temp_power_corr_real_env1 = 0;
434         temp_power_corr_imag_env1 = 0;
435 
436         temp_power_left_env2 = 0;
437         temp_power_right_env2 = 0;
438         temp_power_corr_real_env2 = 0;
439         temp_power_corr_imag_env2 = 0;
440 
441         for (i = 0; i < 6; i++) {
442           t_left_real = hist_left_real[i][subband];
443           t_left_imag = hist_left_imag[i][subband];
444           t_right_real = hist_right_real[i][subband];
445           t_right_imag = hist_right_imag[i][subband];
446 
447           temp1 = t_left_real * t_left_real;
448           temp2 = t_left_imag * t_left_imag;
449           temp_hist_pow_left += (temp1 + temp2);
450 
451           temp1 = t_right_real * t_right_real;
452           temp2 = t_right_imag * t_right_imag;
453           temp_hist_pow_right += (temp1 + temp2);
454 
455           temp1 = t_left_real * t_right_real;
456           temp2 = t_left_imag * t_right_imag;
457           temp_hist_pow_corr_real += (temp1 + temp2);
458 
459           temp1 = t_left_imag * t_right_real;
460           temp2 = t_left_real * t_right_imag;
461           temp_hist_pow_corr_imag += (temp1 - temp2);
462 
463           t_left_real = hybrid_left_real_env1[i][subband];
464           t_left_imag = hybrid_left_imag_env1[i][subband];
465           t_right_real = hybrid_right_real_env1[i][subband];
466           t_right_imag = hybrid_right_imag_env1[i][subband];
467 
468           temp1 = t_left_real * t_left_real;
469           temp2 = t_left_imag * t_left_imag;
470           temp_power_left_env1 += (temp1 + temp2);
471 
472           temp1 = t_right_real * t_right_real;
473           temp2 = t_right_imag * t_right_imag;
474           temp_power_right_env1 += (temp1 + temp2);
475 
476           temp1 = t_left_real * t_right_real;
477           temp2 = t_left_imag * t_right_imag;
478           temp_power_corr_real_env1 += (temp1 + temp2);
479 
480           temp1 = t_left_imag * t_right_real;
481           temp2 = t_left_real * t_right_imag;
482           temp_power_corr_imag_env1 += (temp1 - temp2);
483 
484           t_left_real = hybrid_left_real_env2[i][subband];
485           t_left_imag = hybrid_left_imag_env2[i][subband];
486           t_right_real = hybr_right_real_env2[i][subband];
487           t_right_imag = hybr_right_imag_env2[i][subband];
488 
489           temp1 = t_left_real * t_left_real;
490           temp2 = t_left_imag * t_left_imag;
491           temp_power_left_env2 += (temp1 + temp2);
492 
493           temp1 = t_right_real * t_right_real;
494           temp2 = t_right_imag * t_right_imag;
495           temp_power_right_env2 += (temp1 + temp2);
496 
497           temp1 = t_left_real * t_right_real;
498           temp2 = t_left_imag * t_right_imag;
499           temp_power_corr_real_env2 += (temp1 + temp2);
500 
501           temp1 = t_left_imag * t_right_real;
502           temp2 = t_left_real * t_right_imag;
503           temp_power_corr_imag_env2 += (temp1 - temp2);
504         }
505 
506         for (i = 6; i < 10; i++) {
507           t_left_real = hybrid_left_real_env1[i][subband];
508           t_left_imag = hybrid_left_imag_env1[i][subband];
509           t_right_real = hybrid_right_real_env1[i][subband];
510           t_right_imag = hybrid_right_imag_env1[i][subband];
511 
512           temp1 = t_left_real * t_left_real;
513           temp2 = t_left_imag * t_left_imag;
514           temp_power_left_env1 += (temp1 + temp2);
515 
516           temp1 = t_right_real * t_right_real;
517           temp2 = t_right_imag * t_right_imag;
518           temp_power_right_env1 += (temp1 + temp2);
519 
520           temp1 = t_left_real * t_right_real;
521           temp2 = t_left_imag * t_right_imag;
522           temp_power_corr_real_env1 += (temp1 + temp2);
523 
524           temp1 = t_left_imag * t_right_real;
525           temp2 = t_left_real * t_right_imag;
526           temp_power_corr_imag_env1 += (temp1 - temp2);
527 
528           t_left_real = hybrid_left_real_env2[i][subband];
529           t_left_imag = hybrid_left_imag_env2[i][subband];
530           t_right_real = hybr_right_real_env2[i][subband];
531           t_right_imag = hybr_right_imag_env2[i][subband];
532 
533           temp1 = t_left_real * t_left_real;
534           temp2 = t_left_imag * t_left_imag;
535           temp_power_left_env2 += (temp1 + temp2);
536 
537           temp1 = t_right_real * t_right_real;
538           temp2 = t_right_imag * t_right_imag;
539           temp_power_right_env2 += (temp1 + temp2);
540 
541           temp1 = t_left_real * t_right_real;
542           temp2 = t_left_imag * t_right_imag;
543           temp_power_corr_real_env2 += (temp1 + temp2);
544 
545           temp1 = t_left_imag * t_right_real;
546           temp2 = t_left_real * t_right_imag;
547           temp_power_corr_imag_env2 += (temp1 - temp2);
548         }
549 
550         for (i = 10; i < 16; i++) {
551           t_left_real = hybrid_left_real_env2[i][subband];
552           t_left_imag = hybrid_left_imag_env2[i][subband];
553           t_right_real = hybr_right_real_env2[i][subband];
554           t_right_imag = hybr_right_imag_env2[i][subband];
555 
556           temp1 = t_left_real * t_left_real;
557           temp2 = t_left_imag * t_left_imag;
558           temp_power_left_env2 += (temp1 + temp2);
559 
560           temp1 = t_right_real * t_right_real;
561           temp2 = t_right_imag * t_right_imag;
562           temp_power_right_env2 += (temp1 + temp2);
563 
564           temp1 = t_left_real * t_right_real;
565           temp2 = t_left_imag * t_right_imag;
566           temp_power_corr_real_env2 += (temp1 + temp2);
567 
568           temp1 = t_left_imag * t_right_real;
569           temp2 = t_left_real * t_right_imag;
570           temp_power_corr_imag_env2 += (temp1 - temp2);
571         }
572 
573         scratch_power_left_right_env2[2 * bin] =
574             scratch_power_left_right_env2[2 * bin] + temp_power_left_env2;
575         scratch_power_left_right_env2[2 * bin + 1] =
576             scratch_power_left_right_env2[2 * bin + 1] + temp_power_right_env2;
577         scratch_power_corr_real_imag_env2[2 * bin] =
578             scratch_power_corr_real_imag_env2[2 * bin] + temp_power_corr_real_env2;
579         scratch_power_corr_real_imag_env2[2 * bin + 1] =
580             scratch_power_corr_real_imag_env2[2 * bin + 1] + temp_power_corr_imag_env2;
581 
582         band_power_left_env1 = band_power_left_env1 + temp_power_left_env1;
583         band_power_right_env1 = band_power_right_env1 + temp_power_right_env1;
584         band_power_corr_real_env1 = band_power_corr_real_env1 + temp_power_corr_real_env1;
585         band_power_corr_imag_env1 = band_power_corr_imag_env1 + temp_power_corr_imag_env1;
586 
587         band_hist_power_left = band_hist_power_left + temp_hist_pow_left;
588         band_hist_power_right = band_hist_power_right + temp_hist_pow_right;
589         band_hist_power_corr_real = band_hist_power_corr_real + temp_hist_pow_corr_real;
590         band_hist_power_corr_imag = band_hist_power_corr_imag + temp_hist_pow_corr_imag;
591       }
592 
593       pms->pow_left_right[2 * bin] += (band_power_left_env1 + band_hist_power_left);
594       pms->pow_left_right[2 * bin + 1] += (band_power_right_env1 + band_hist_power_right);
595       pms->pow_corr_real_imag[2 * bin] += (band_power_corr_real_env1 + band_hist_power_corr_real);
596       pms->pow_corr_real_imag[2 * bin + 1] +=
597           (band_power_corr_imag_env1 + band_hist_power_corr_imag);
598     }
599   }
600 
601   {
602     FLOAT32 temp_left;
603     FLOAT32 temp_right;
604     FLOAT32 temp_corr_re;
605     FLOAT32 temp_corr_im;
606 
607     for (bin = 0; bin < pms->iid_icc_bins; bin++) {
608       if (pms->b_hi_freq_res_iid_icc) {
609         temp_left = pms->pow_left_right[2 * bin];
610         temp_right = pms->pow_left_right[2 * bin + 1];
611         temp_corr_re = pms->pow_corr_real_imag[2 * bin];
612         temp_corr_im = pms->pow_corr_real_imag[2 * bin + 1];
613       } else {
614         temp_left = pms->pow_left_right[2 * 2 * bin] + pms->pow_left_right[2 * 2 * bin + 2];
615         temp_right =
616             pms->pow_left_right[2 * 2 * bin + 1] + pms->pow_left_right[2 * (2 * bin + 1) + 1];
617         temp_corr_re =
618             pms->pow_corr_real_imag[2 * 2 * bin] + pms->pow_corr_real_imag[2 * 2 * bin + 2];
619         temp_corr_im = pms->pow_corr_real_imag[2 * 2 * bin + 1] +
620                        pms->pow_corr_real_imag[2 * (2 * bin + 1) + 1];
621       }
622 
623       if (temp_left == 0) {
624         temp_left = 0.0625f;
625       }
626       if (temp_right == 0) {
627         temp_right = 0.0625f;
628       }
629       if (temp_corr_re == 0) {
630         temp_corr_re = 0.0625f;
631       }
632       if (temp_corr_im == 0) {
633         temp_corr_im = 0.0625f;
634       }
635 
636       pms->aaa_ICC_data_buf[bin][1] = pms->aaa_ICC_data_buf[bin][0];
637       if (bin > NUMBER_OF_IPD_BINS) {
638         temp1 = temp_corr_re * temp_corr_re;
639         temp2 = temp_corr_im * temp_corr_im;
640         temp_corr_re = temp1 + temp2;
641 
642         temp1 = temp_left * temp_right;
643         pms->aaa_ICC_data_buf[bin][0] = (FLOAT32)sqrt(temp_corr_re / temp1);
644       } else {
645         temp1 = temp_left * temp_right;
646         pms->aaa_ICC_data_buf[bin][0] = temp_corr_re / (FLOAT32)sqrt(temp1);
647       }
648       if (pms->aaa_ICC_data_buf[bin][0] > 1.0f) {
649         pms->aaa_ICC_data_buf[bin][0] = 0;
650       } else {
651         pms->aaa_ICC_data_buf[bin][0] =
652             (FLOAT32)sqrt(0.5f - (pms->aaa_ICC_data_buf[bin][0] / 2.0f));
653       }
654       temp1 = temp_left / temp_right;
655       temp1 = (FLOAT32)sqrt(temp1);
656       pms->aaa_IID_data_buf[bin][1] = pms->aaa_IID_data_buf[bin][0];
657       pms->aaa_IID_data_buf[bin][0] = SBR_INV_LOG_2 * (FLOAT32)log(temp1);
658     }
659   }
660   {
661     FLOAT32 *pow_left = &pms->pow_left_right[0];
662     FLOAT32 *corr_real = &pms->pow_corr_real_imag[0];
663 
664     memcpy(pow_left, scratch_power_left_right_env2, 2 * NUMBER_OF_BINS * sizeof(FLOAT32));
665     memcpy(corr_real, scratch_power_corr_real_imag_env2, 2 * NUMBER_OF_BINS * sizeof(FLOAT32));
666   }
667 
668   ia_enhaacplus_enc_downmix_to_mono(pms, r_buffer_left, i_buffer_left, r_buffer_right,
669                                     i_buffer_right, ps_tables);
670   return IA_NO_ERROR;
671 }
672