• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <stdio.h>
21 #include <string.h>
22 #include "ixheaacd_sbr_common.h"
23 #include "ixheaacd_type_def.h"
24 
25 #include "ixheaacd_constants.h"
26 #include "ixheaacd_basic_ops32.h"
27 #include "ixheaacd_basic_ops16.h"
28 #include "ixheaacd_basic_ops40.h"
29 #include "ixheaacd_basic_ops.h"
30 
31 #include "ixheaacd_basic_op.h"
32 #include "ixheaacd_intrinsics.h"
33 #include "ixheaacd_common_rom.h"
34 #include "ixheaacd_basic_funcs.h"
35 #include "ixheaacd_sbr_scale.h"
36 #include "ixheaacd_sbrdecsettings.h"
37 #include "ixheaacd_lpp_tran.h"
38 #include "ixheaacd_bitbuffer.h"
39 #include "ixheaacd_defines.h"
40 
41 #include "ixheaacd_pns.h"
42 
43 #include "ixheaacd_aac_rom.h"
44 #include "ixheaacd_pulsedata.h"
45 
46 #include "ixheaacd_drc_data_struct.h"
47 
48 #include "ixheaacd_lt_predict.h"
49 
50 #include "ixheaacd_channelinfo.h"
51 #include "ixheaacd_drc_dec.h"
52 
53 #include "ixheaacd_sbrdecoder.h"
54 #include "ixheaacd_sbr_scale.h"
55 #include "ixheaacd_lpp_tran.h"
56 #include "ixheaacd_env_extr_part.h"
57 #include "ixheaacd_sbr_rom.h"
58 #include "ixheaacd_hybrid.h"
59 #include "ixheaacd_ps_dec.h"
60 #include "ixheaacd_env_extr.h"
61 
62 #include "ixheaacd_intrinsics.h"
63 #include "ixheaacd_basic_funcs.h"
64 
65 #include "ixheaacd_qmf_dec.h"
66 #include "ixheaacd_env_calc.h"
67 #include "ixheaacd_sbr_const.h"
68 
69 #include "ixheaacd_pvc_dec.h"
70 #include "ixheaacd_sbr_dec.h"
71 #include "ixheaacd_function_selector.h"
72 
73 #include "ixheaacd_audioobjtypes.h"
74 
75 #define LPC_SCALE_FACTOR 2
76 
77 #define SHIFT 5
78 
ixheaacd_mult32x16hin32(WORD32 a,WORD32 b)79 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16hin32(WORD32 a, WORD32 b) {
80   WORD32 result;
81   WORD64 temp_result;
82 
83   temp_result = (WORD64)(a) * (WORD64)(b >> 16);
84   result = (WORD32)(temp_result >> 16);
85 
86   return (result);
87 }
88 
ixheaacd_mac32x16hin32(WORD32 a,WORD32 b,WORD32 c)89 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16hin32(WORD32 a, WORD32 b,
90                                                      WORD32 c) {
91   WORD32 result;
92 
93   result = a + ixheaacd_mult32x16hin32(b, c);
94 
95   return (result);
96 }
97 
ixheaacd_macn32x16hin32(WORD32 a,WORD32 b,WORD32 c)98 static PLATFORM_INLINE WORD32 ixheaacd_macn32x16hin32(WORD32 a, WORD32 b,
99                                                       WORD32 c) {
100   WORD32 result;
101 
102   result = a - ixheaacd_mult32x16hin32(b, c);
103 
104   return (result);
105 }
106 
ixheaacd_filterstep3(WORD16 a0r,WORD16 a0i,WORD16 a1r,WORD16 a1i,WORD32 start_indx,WORD32 stop_idx,WORD32 low_band,WORD32 high_band,WORD32 * qmf_buffer)107 VOID ixheaacd_filterstep3(WORD16 a0r, WORD16 a0i, WORD16 a1r, WORD16 a1i,
108                           WORD32 start_indx, WORD32 stop_idx, WORD32 low_band,
109                           WORD32 high_band, WORD32 *qmf_buffer) {
110   WORD32 i;
111   WORD32 prev1r, prev1i;
112   WORD32 prev2r, prev2i;
113   WORD16 coef1r = (a0r);
114   WORD16 coef1i = (a0i);
115   WORD16 coef2r = (a1r);
116   WORD16 coef2i = (a1i);
117   WORD32 *p_src, *p_dst;
118   WORD32 qmf_real, qmf_imag;
119 
120   WORD32 curr, curi;
121   p_src = qmf_buffer + low_band + ((start_indx) << 7);
122   prev2r = *p_src;
123   p_src += 64;
124 
125   prev2i = *p_src;
126   p_src += 64;
127 
128   prev1r = *p_src;
129   p_src += 64;
130 
131   prev1i = *p_src;
132   p_src += 64;
133 
134   p_dst = qmf_buffer + high_band + ((start_indx + 2) << 7);
135 
136   for (i = stop_idx - start_indx; i != 0; i--) {
137     WORD32 accu;
138 
139     curr = *p_src;
140     p_src += 64;
141 
142     curi = *p_src;
143     p_src += 64;
144 
145     qmf_real = (curr >> LPC_SCALE_FACTOR);
146     qmf_imag = (curi >> LPC_SCALE_FACTOR);
147 
148     accu = ixheaacd_sub32(
149         ixheaacd_add32(ixheaacd_sub32(ixheaacd_mult32x16in32(prev1r, coef1r),
150                                       ixheaacd_mult32x16in32(prev1i, coef1i)),
151                        ixheaacd_mult32x16in32(prev2r, coef2r)),
152         ixheaacd_mult32x16in32(prev2i, coef2i));
153 
154     *p_dst = ixheaacd_add32(qmf_real, (accu << 1));
155     p_dst += 64;
156 
157     accu = ixheaacd_add32(
158         ixheaacd_add32_sat(
159             ixheaacd_add32_sat(ixheaacd_mult32x16in32(prev1r, coef1i),
160                                ixheaacd_mult32x16in32(prev1i, coef1r)),
161             ixheaacd_mult32x16in32(prev2r, coef2i)),
162         ixheaacd_mult32x16in32(prev2i, coef2r));
163 
164     *p_dst = ixheaacd_add32(qmf_imag, (accu << 1));
165     p_dst += 64;
166 
167     prev2r = prev1r;
168     prev1r = curr;
169     prev2i = prev1i;
170     prev1i = curi;
171   }
172 }
173 
ixheaacd_covariance_matrix_calc_dec(WORD32 * sub_sign_xlow,ixheaacd_lpp_trans_cov_matrix * cov_matrix,WORD32 count)174 VOID ixheaacd_covariance_matrix_calc_dec(
175     WORD32 *sub_sign_xlow, ixheaacd_lpp_trans_cov_matrix *cov_matrix,
176     WORD32 count) {
177   WORD32 j, k;
178   WORD32 ixheaacd_drc_offset = 2;
179   WORD32 len = 38;
180   WORD32 factor;
181   WORD32 max_val, q_factor;
182   WORD32 temp1, temp2, temp3, temp4;
183   WORD32 *temp_buf_ptr = sub_sign_xlow;
184 
185   for (k = count; k > 0; k--) {
186     WORD32 t_phi_01 = 0, t_phi_02 = 0, t_phi_11 = 0;
187     WORD32 t_phi_12 = 0, t_phi_22 = 0;
188 
189     factor = -3;
190     j = ixheaacd_drc_offset;
191     sub_sign_xlow = temp_buf_ptr;
192 
193     temp1 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
194     sub_sign_xlow += 64;
195 
196     temp2 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
197     sub_sign_xlow += 64;
198 
199     for (; (j = j + 3) < ixheaacd_drc_offset + len;) {
200       temp3 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
201       sub_sign_xlow += 64;
202 
203       t_phi_01 += ixheaacd_mult32x16hin32(temp3, temp2);
204       t_phi_02 += ixheaacd_mult32x16hin32(temp3, temp1);
205       t_phi_11 += ixheaacd_mult32x16hin32(temp2, temp2);
206 
207       temp1 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
208       sub_sign_xlow += 64;
209 
210       t_phi_01 += ixheaacd_mult32x16hin32(temp1, temp3);
211       t_phi_02 += ixheaacd_mult32x16hin32(temp1, temp2);
212       t_phi_11 += ixheaacd_mult32x16hin32(temp3, temp3);
213 
214       temp2 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
215       sub_sign_xlow += 64;
216 
217       t_phi_01 += ixheaacd_mult32x16hin32(temp2, temp1);
218       t_phi_02 += ixheaacd_mult32x16hin32(temp2, temp3);
219       t_phi_11 += ixheaacd_mult32x16hin32(temp1, temp1);
220     }
221 
222     temp3 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
223     sub_sign_xlow += 64;
224 
225     t_phi_01 += ixheaacd_mult32x16hin32(temp3, temp2);
226     t_phi_02 += ixheaacd_mult32x16hin32(temp3, temp1);
227     t_phi_11 += ixheaacd_mult32x16hin32(temp2, temp2);
228 
229     temp1 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
230     sub_sign_xlow += 64;
231 
232     t_phi_01 += ixheaacd_mult32x16hin32(temp1, temp3);
233     t_phi_02 += ixheaacd_mult32x16hin32(temp1, temp2);
234     t_phi_11 += ixheaacd_mult32x16hin32(temp3, temp3);
235 
236     temp2 = ixheaacd_shl32_dir(*temp_buf_ptr, factor);
237     temp4 = ixheaacd_shl32_dir(*(temp_buf_ptr + 64), factor);
238 
239     t_phi_12 = (t_phi_01 - ixheaacd_mult32x16hin32(temp1, temp3) +
240                 ixheaacd_mult32x16hin32(temp4, temp2));
241 
242     t_phi_22 = (t_phi_11 - ixheaacd_mult32x16hin32(temp3, temp3) +
243                 ixheaacd_mult32x16hin32(temp2, temp2));
244 
245     max_val = ixheaacd_abs32_nrm(t_phi_01);
246     max_val = max_val | ixheaacd_abs32_nrm(t_phi_02);
247     max_val = max_val | ixheaacd_abs32_nrm(t_phi_12);
248     max_val = max_val | (t_phi_11);
249     max_val = max_val | (t_phi_22);
250 
251     q_factor = ixheaacd_pnorm32(max_val);
252 
253     cov_matrix->phi_11 = (t_phi_11 << q_factor);
254     cov_matrix->phi_22 = (t_phi_22 << q_factor);
255     cov_matrix->phi_01 = (t_phi_01 << q_factor);
256     cov_matrix->phi_02 = (t_phi_02 << q_factor);
257     cov_matrix->phi_12 = (t_phi_12 << q_factor);
258 
259     cov_matrix->d = ixheaacd_sub32_sat(
260         ixheaacd_mult32(cov_matrix->phi_22, cov_matrix->phi_11),
261         ixheaacd_mult32(cov_matrix->phi_12, cov_matrix->phi_12));
262 
263     cov_matrix++;
264     temp_buf_ptr++;
265   }
266 
267   return;
268 }
269 
ixheaacd_covariance_matrix_calc_2_dec(ixheaacd_lpp_trans_cov_matrix * cov_matrix,WORD32 * real_buffer,WORD32 num_bands,WORD16 slots)270 VOID ixheaacd_covariance_matrix_calc_2_dec(
271     ixheaacd_lpp_trans_cov_matrix *cov_matrix,
272 
273     WORD32 *real_buffer, WORD32 num_bands, WORD16 slots) {
274   WORD32 k;
275   WORD32 *img_buffer;
276   WORD32 *ptr_real = real_buffer;
277   ixheaacd_lpp_trans_cov_matrix *pac_arr = cov_matrix;
278 
279   for (k = 0; k < num_bands; k++) {
280     WORD32 t_phi_11 = 0, t_phi_01 = 0, t_phi_01_i = 0;
281     WORD32 prev_real, prev_imag, curr_real, curr_imag;
282 
283     real_buffer = ptr_real;
284     img_buffer = real_buffer + 64;
285     cov_matrix = pac_arr;
286 
287     prev_real = real_buffer[-128];
288     prev_imag = img_buffer[-128];
289 
290     curr_real = real_buffer[0];
291     curr_imag = img_buffer[0];
292 
293     curr_real = ixheaacd_shr32(curr_real, 3);
294     curr_imag = ixheaacd_shr32(curr_imag, 3);
295     prev_real = ixheaacd_shr32(prev_real, 3);
296     prev_imag = ixheaacd_shr32(prev_imag, 3);
297 
298     t_phi_01 = ixheaacd_mult32x16hin32(curr_real, prev_real);
299     t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_imag, prev_imag);
300 
301     t_phi_01_i = ixheaacd_mult32x16hin32(curr_imag, prev_real);
302     t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, curr_real, prev_imag);
303 
304     t_phi_11 = ixheaacd_mult32x16hin32(prev_real, prev_real);
305     t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_imag, prev_imag);
306 
307     {
308       WORD n;
309       WORD32 *real1 = &real_buffer[128];
310       WORD32 *imag1 = &img_buffer[128];
311 
312       prev_real = curr_real;
313       prev_imag = curr_imag;
314 
315       for (n = ((slots - 2) >> 1); n; n--) {
316         curr_real = *real1;
317         real1 += 128;
318         curr_imag = *imag1;
319         imag1 += 128;
320 
321         curr_real = ixheaacd_shr32(curr_real, 3);
322         curr_imag = ixheaacd_shr32(curr_imag, 3);
323 
324         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_real, prev_real);
325         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_imag, prev_imag);
326 
327         t_phi_01_i = ixheaacd_mac32x16hin32(t_phi_01_i, curr_imag, prev_real);
328         t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, curr_real, prev_imag);
329 
330         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_real, prev_real);
331         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_imag, prev_imag);
332 
333         prev_real = *real1;
334         real1 += 128;
335         prev_imag = *imag1;
336         imag1 += 128;
337 
338         prev_real = ixheaacd_shr32(prev_real, 3);
339         prev_imag = ixheaacd_shr32(prev_imag, 3);
340 
341         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, prev_real, curr_real);
342         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, prev_imag, curr_imag);
343 
344         t_phi_01_i = ixheaacd_mac32x16hin32(t_phi_01_i, prev_imag, curr_real);
345         t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, prev_real, curr_imag);
346 
347         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_real, curr_real);
348         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_imag, curr_imag);
349       }
350 
351       if (slots & 0x01) {
352         curr_real = *real1;
353         curr_imag = *imag1;
354 
355         curr_real = ixheaacd_shr32(curr_real, 3);
356         curr_imag = ixheaacd_shr32(curr_imag, 3);
357 
358         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_real, prev_real);
359         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_imag, prev_imag);
360 
361         t_phi_01_i = ixheaacd_mac32x16hin32(t_phi_01_i, curr_imag, prev_real);
362         t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, curr_real, prev_imag);
363 
364         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_real, prev_real);
365         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_imag, prev_imag);
366       }
367     }
368 
369     {
370       WORD32 t_phi_22 = t_phi_11;
371       WORD32 curr_real = real_buffer[-2 * 128];
372       WORD32 curr_imag = img_buffer[-2 * 128];
373 
374       curr_real = ixheaacd_shr32(curr_real, 3);
375       curr_imag = ixheaacd_shr32(curr_imag, 3);
376 
377       t_phi_22 = ixheaacd_mac32x16hin32(t_phi_22, curr_real, curr_real);
378       t_phi_22 = ixheaacd_mac32x16hin32(t_phi_22, curr_imag, curr_imag);
379 
380       curr_real = real_buffer[(slots - 2) * 128];
381       curr_imag = img_buffer[(slots - 2) * 128];
382 
383       curr_real = ixheaacd_shr32(curr_real, 3);
384       curr_imag = ixheaacd_shr32(curr_imag, 3);
385 
386       t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_real, curr_real);
387       t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_imag, curr_imag);
388 
389       cov_matrix->phi_11 = t_phi_11;
390       cov_matrix->phi_22 = t_phi_22;
391     }
392 
393     {
394       WORD32 t_phi_12 = t_phi_01;
395 
396       t_phi_12 = ixheaacd_mac32x16hin32(t_phi_12, real_buffer[-128] >> 3,
397                                         real_buffer[-2 * 128] >> 3);
398       t_phi_12 = ixheaacd_mac32x16hin32(t_phi_12, img_buffer[-128] >> 3,
399                                         img_buffer[-2 * 128] >> 3);
400       t_phi_01 =
401           ixheaacd_mac32x16hin32(t_phi_01, real_buffer[(slots - 1) * 128] >> 3,
402                                  real_buffer[(slots - 2) * 128] >> 3);
403       t_phi_01 =
404           ixheaacd_mac32x16hin32(t_phi_01, img_buffer[(slots - 1) * 128] >> 3,
405                                  img_buffer[(slots - 2) * 128] >> 3);
406 
407       cov_matrix->phi_01 = t_phi_01;
408       cov_matrix->phi_12 = t_phi_12;
409     }
410 
411     {
412       WORD32 t_phi_12_i = t_phi_01_i;
413 
414       t_phi_12_i = ixheaacd_mac32x16hin32(t_phi_12_i, img_buffer[-128] >> 3,
415                                           real_buffer[-2 * 128] >> 3);
416       t_phi_12_i = ixheaacd_macn32x16hin32(t_phi_12_i, real_buffer[-128] >> 3,
417                                            img_buffer[-2 * 128] >> 3);
418       t_phi_01_i =
419           ixheaacd_mac32x16hin32(t_phi_01_i, img_buffer[(slots - 1) * 128] >> 3,
420                                  real_buffer[(slots - 2) * 128] >> 3);
421       t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i,
422                                            real_buffer[(slots - 1) * 128] >> 3,
423                                            img_buffer[(slots - 2) * 128] >> 3);
424 
425       cov_matrix->phi_01_im = t_phi_01_i;
426       cov_matrix->phi_12_im = t_phi_12_i;
427     }
428 
429     {
430       WORD16 n, len_by_4, p;
431       WORD32 t_phi_02 = 0x00, t_phi_02_i = 0x00;
432 
433       len_by_4 = (slots >> 2);
434       p = 0;
435       for (n = 0; n < len_by_4; n++) {
436         WORD32 real1, real2, imag1, imag2;
437         real1 = real_buffer[p * 128];
438         real2 = real_buffer[(p - 2) * 128];
439         imag1 = img_buffer[p * 128];
440         imag2 = img_buffer[(p - 2) * 128];
441 
442         real1 = ixheaacd_shr32(real1, 3);
443         real2 = ixheaacd_shr32(real2, 3);
444         imag1 = ixheaacd_shr32(imag1, 3);
445         imag2 = ixheaacd_shr32(imag2, 3);
446 
447         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
448         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
449         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
450         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
451 
452         real1 = real_buffer[(p + 1) * 128];
453         real2 = real_buffer[(p - 1) * 128];
454         imag1 = img_buffer[(p + 1) * 128];
455         imag2 = img_buffer[(p - 1) * 128];
456 
457         real1 = ixheaacd_shr32(real1, 3);
458         real2 = ixheaacd_shr32(real2, 3);
459         imag1 = ixheaacd_shr32(imag1, 3);
460         imag2 = ixheaacd_shr32(imag2, 3);
461 
462         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
463         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
464         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
465         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
466 
467         real1 = real_buffer[(p + 2) * 128];
468         real2 = real_buffer[p * 128];
469         imag1 = img_buffer[(p + 2) * 128];
470         imag2 = img_buffer[p * 128];
471 
472         real1 = ixheaacd_shr32(real1, 3);
473         real2 = ixheaacd_shr32(real2, 3);
474         imag1 = ixheaacd_shr32(imag1, 3);
475         imag2 = ixheaacd_shr32(imag2, 3);
476 
477         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
478         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
479         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
480         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
481 
482         real1 = real_buffer[(p + 3) * 128];
483         real2 = real_buffer[(p + 1) * 128];
484         imag1 = img_buffer[(p + 3) * 128];
485         imag2 = img_buffer[(p + 1) * 128];
486 
487         real1 = ixheaacd_shr32(real1, 3);
488         real2 = ixheaacd_shr32(real2, 3);
489         imag1 = ixheaacd_shr32(imag1, 3);
490         imag2 = ixheaacd_shr32(imag2, 3);
491 
492         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
493         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
494         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
495         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
496         p += 4;
497       }
498       n = ixheaacd_shl16(len_by_4, 2);
499       for (; n < slots; n++) {
500         WORD32 real1, real2, imag1, imag2;
501         real1 = real_buffer[(n * 128)];
502         real2 = real_buffer[(n - 2) * 128];
503         imag1 = img_buffer[n * 128];
504         imag2 = img_buffer[(n - 2) * 128];
505 
506         real1 = ixheaacd_shr32(real1, 3);
507         real2 = ixheaacd_shr32(real2, 3);
508         imag1 = ixheaacd_shr32(imag1, 3);
509         imag2 = ixheaacd_shr32(imag2, 3);
510 
511         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
512         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
513         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
514         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
515       }
516 
517       cov_matrix->phi_02 = t_phi_02;
518       cov_matrix->phi_02_im = t_phi_02_i;
519     }
520     ptr_real++;
521     pac_arr++;
522   }
523 }
524 
ixheaacd_filt_step3_lp(WORD len,WORD32 coef1,WORD32 coef2,WORD32 * pqmf_real_low,WORD32 * pqmf_real_high)525 static PLATFORM_INLINE VOID ixheaacd_filt_step3_lp(WORD len, WORD32 coef1,
526                                                    WORD32 coef2,
527                                                    WORD32 *pqmf_real_low,
528                                                    WORD32 *pqmf_real_high) {
529   WORD32 prev1;
530   WORD32 prev2;
531   WORD32 i;
532 
533   prev2 = *pqmf_real_low;
534   pqmf_real_low += 64;
535 
536   prev1 = *pqmf_real_low;
537   pqmf_real_low += 64;
538 
539   for (i = len; i >= 0; i -= 2) {
540     WORD32 curr = *pqmf_real_low;
541     WORD32 temp = ixheaacd_mult32x16hin32(prev2, coef2);
542     pqmf_real_low += 64;
543 
544     *pqmf_real_high = ixheaacd_add32_sat(
545         (curr >> LPC_SCALE_FACTOR),
546         (ixheaacd_shl32_sat(ixheaacd_mac32x16hin32(temp, prev1, coef1), 1)));
547     pqmf_real_high += 64;
548 
549     prev2 = *pqmf_real_low;
550     temp = ixheaacd_mult32x16hin32(prev1, coef2);
551     pqmf_real_low += 64;
552 
553     *pqmf_real_high = ixheaacd_add32_sat(
554         (prev2 >> LPC_SCALE_FACTOR),
555         (ixheaacd_shl32_sat(ixheaacd_mac32x16hin32(temp, curr, coef1), 1)));
556     pqmf_real_high += 64;
557 
558     prev1 = prev2;
559     prev2 = curr;
560   }
561 }
562 
ixheaacd_filter1_lp(ia_sbr_hf_generator_struct * hf_generator,ixheaacd_lpp_trans_cov_matrix * cov_matrix_seq,WORD32 * bw_array,WORD16 * degree_alias,WORD32 start_idx,WORD32 stop_idx,WORD32 max_qmf_subband,WORD32 start_patch,WORD32 stop_patch,WORD32 * sub_sig_x)563 VOID ixheaacd_filter1_lp(ia_sbr_hf_generator_struct *hf_generator,
564                          ixheaacd_lpp_trans_cov_matrix *cov_matrix_seq,
565                          WORD32 *bw_array, WORD16 *degree_alias,
566                          WORD32 start_idx, WORD32 stop_idx,
567                          WORD32 max_qmf_subband, WORD32 start_patch,
568                          WORD32 stop_patch, WORD32 *sub_sig_x) {
569   WORD16 k1, k1_below = 0, k1_below2 = 0;
570   WORD32 i;
571   WORD16 alpha_real[LPC_ORDER];
572   WORD32 low_band, high_band;
573   WORD32 patch;
574   WORD16 bw = 0;
575   WORD32 a0r, a1r;
576 
577   WORD num_patches = hf_generator->pstr_settings->num_patches;
578   ia_patch_param_struct *patch_param =
579       hf_generator->pstr_settings->str_patch_param;
580   WORD32 bw_index[MAX_NUM_PATCHES];
581 
582   memset(bw_index, 0, sizeof(WORD32) * num_patches);
583 
584   for (low_band = start_patch; low_band < stop_patch; low_band++) {
585     ixheaacd_lpp_trans_cov_matrix *p_cov_matrix = &cov_matrix_seq[low_band];
586 
587     alpha_real[1] = 0;
588     alpha_real[0] = 0;
589 
590     if (p_cov_matrix->d != 0) {
591       WORD32 tmp_r, temp_real, modulus_d;
592       WORD16 inverse_d;
593       WORD32 norm_d;
594 
595       norm_d = ixheaacd_norm32(p_cov_matrix->d);
596 
597       inverse_d =
598           (WORD16)(*ixheaacd_fix_div)(0x40000000, (p_cov_matrix->d << norm_d));
599       modulus_d = ixheaacd_abs32(p_cov_matrix->d);
600 
601       tmp_r =
602           (ixheaacd_sub32_sat(
603                ixheaacd_mult32(p_cov_matrix->phi_01, p_cov_matrix->phi_12),
604                ixheaacd_mult32(p_cov_matrix->phi_02, p_cov_matrix->phi_11)) >>
605            LPC_SCALE_FACTOR);
606       temp_real = ixheaacd_abs32(tmp_r);
607 
608       if (temp_real < modulus_d) {
609         alpha_real[1] = (WORD16)(
610             (ixheaacd_mult32x16in32_shl_sat(tmp_r, inverse_d) << norm_d) >> 15);
611       }
612 
613       tmp_r =
614           (ixheaacd_sub32_sat(
615                ixheaacd_mult32(p_cov_matrix->phi_02, p_cov_matrix->phi_12),
616                ixheaacd_mult32(p_cov_matrix->phi_01, p_cov_matrix->phi_22)) >>
617            LPC_SCALE_FACTOR);
618       temp_real = ixheaacd_abs32(tmp_r);
619 
620       if (temp_real < modulus_d) {
621         alpha_real[0] = (WORD16)(
622             (ixheaacd_mult32x16in32_shl_sat(tmp_r, inverse_d) << norm_d) >> 15);
623       }
624     }
625 
626     if (p_cov_matrix->phi_11 == 0) {
627       k1 = 0;
628     } else {
629       if (ixheaacd_abs32_sat(p_cov_matrix->phi_01) >= p_cov_matrix->phi_11) {
630         if (p_cov_matrix->phi_01 < 0) {
631           k1 = 0x7fff;
632         } else {
633           k1 = (WORD16)-0x8000;
634         }
635       } else {
636         k1 = -((WORD16)(
637             (*ixheaacd_fix_div)(p_cov_matrix->phi_01, p_cov_matrix->phi_11)));
638       }
639     }
640 
641     if (low_band > 1) {
642       WORD16 deg = ixheaacd_sub16_sat(
643           0x7fff, ixheaacd_mult16_shl_sat(k1_below, k1_below));
644       degree_alias[low_band] = 0;
645 
646       if (((low_band & 1) == 0) && (k1 < 0)) {
647         if (k1_below < 0) {
648           degree_alias[low_band] = 0x7fff;
649 
650           if (k1_below2 > 0) {
651             degree_alias[low_band - 1] = deg;
652           }
653         } else {
654           if (k1_below2 > 0) {
655             degree_alias[low_band] = deg;
656           }
657         }
658       }
659 
660       if (((low_band & 1) != 0) && (k1 > 0)) {
661         if (k1_below > 0) {
662           degree_alias[low_band] = 0x7fff;
663 
664           if (k1_below2 < 0) {
665             degree_alias[low_band - 1] = deg;
666           }
667         } else {
668           if (k1_below2 < 0) {
669             degree_alias[low_band] = deg;
670           }
671         }
672       }
673     }
674 
675     k1_below2 = k1_below;
676     k1_below = k1;
677 
678     patch = 0;
679     while (patch < num_patches) {
680       ia_patch_param_struct *p_loc_patch_param = &patch_param[patch];
681       WORD32 bw_vec, bw_idx;
682       WORD16 alpha1, alpha2;
683 
684       high_band = (((low_band + p_loc_patch_param->dst_end_band) << 8) >> 8);
685 
686       if ((low_band < p_loc_patch_param->src_start_band) ||
687           (low_band >= p_loc_patch_param->src_end_band) ||
688           (high_band < max_qmf_subband)) {
689         patch++;
690         continue;
691       }
692 
693       bw_idx = bw_index[patch];
694       while (high_band >= hf_generator->pstr_settings->bw_borders[bw_idx]) {
695         bw_idx++;
696         bw_index[patch] = bw_idx;
697       }
698 
699       bw_vec = bw_array[bw_idx];
700       alpha1 = alpha_real[0];
701       alpha2 = alpha_real[1];
702 
703       bw = ixheaacd_extract16h(bw_vec);
704       a0r = ixheaacd_mult16x16in32_shl(bw, alpha1);
705       bw = ixheaacd_mult16_shl_sat(bw, bw);
706       a1r = ixheaacd_mult16x16in32_shl(bw, alpha2);
707 
708       {
709         WORD32 *p_sub_signal_xlow = sub_sig_x + low_band + ((start_idx) << 6);
710         WORD32 *p_sub_signal_xhigh =
711             sub_sig_x + high_band + ((start_idx + 2) << 6);
712         WORD32 len = stop_idx - start_idx - 1;
713 
714         if (bw > 0) {
715           ixheaacd_filt_step3_lp(len, a0r, a1r, p_sub_signal_xlow,
716                                  p_sub_signal_xhigh);
717 
718         } else {
719           p_sub_signal_xlow += 128;
720           for (i = len; i >= 0; i--) {
721             *p_sub_signal_xhigh = *p_sub_signal_xlow >> LPC_SCALE_FACTOR;
722             p_sub_signal_xlow += 64;
723             p_sub_signal_xhigh += 64;
724           }
725         }
726       }
727 
728       patch++;
729     }
730   }
731 }
732 
ixheaacd_clr_subsamples(WORD32 * ptr_qmf_buf,WORD32 num,WORD32 size)733 VOID ixheaacd_clr_subsamples(WORD32 *ptr_qmf_buf, WORD32 num, WORD32 size) {
734   WORD32 i;
735   for (i = num; i >= 0; i--) {
736     memset(ptr_qmf_buf, 0, sizeof(WORD32) * (size));
737     ptr_qmf_buf += 64;
738   }
739 }
740 
ixheaacd_low_pow_hf_generator(ia_sbr_hf_generator_struct * hf_generator,WORD32 ** qmf_real,WORD16 * degree_alias,WORD32 start_idx,WORD32 stop_idx,WORD32 num_if_bands,WORD32 max_qmf_subband,WORD32 * sbr_invf_mode,WORD32 * sbr_invf_mode_prev,WORD32 norm_max,WORD32 * sub_sig_x)741 VOID ixheaacd_low_pow_hf_generator(ia_sbr_hf_generator_struct *hf_generator,
742                                    WORD32 **qmf_real, WORD16 *degree_alias,
743                                    WORD32 start_idx, WORD32 stop_idx,
744                                    WORD32 num_if_bands, WORD32 max_qmf_subband,
745                                    WORD32 *sbr_invf_mode,
746                                    WORD32 *sbr_invf_mode_prev, WORD32 norm_max,
747                                    WORD32 *sub_sig_x) {
748   WORD32 bw_array[MAX_NUM_PATCHES];
749   WORD32 i;
750   WORD32 start_patch, stop_patch, low_band, high_band;
751   ia_patch_param_struct *patch_param =
752       hf_generator->pstr_settings->str_patch_param;
753   WORD32 patch;
754   ixheaacd_lpp_trans_cov_matrix cov_matrix_seq[MAX_COLS];
755 
756   WORD32 actual_stop_band;
757   WORD32 num_patches = hf_generator->pstr_settings->num_patches;
758 
759   stop_idx = (hf_generator->pstr_settings->num_columns + stop_idx);
760 
761   ixheaacd_invfilt_level_emphasis(hf_generator, num_if_bands, sbr_invf_mode,
762                                   sbr_invf_mode_prev, bw_array);
763 
764   actual_stop_band =
765       ixheaacd_add16(patch_param[num_patches - 1].dst_start_band,
766                      patch_param[num_patches - 1].num_bands_in_patch);
767 
768   {
769     WORD32 *p_qmf_real;
770     WORD32 len = 6, num;
771 
772     if (len > stop_idx) len = stop_idx;
773 
774     p_qmf_real = &qmf_real[start_idx][actual_stop_band];
775     num = (len - start_idx - 1);
776     ixheaacd_clr_subsamples(p_qmf_real, num,
777                             (NO_SYNTHESIS_CHANNELS - actual_stop_band));
778 
779     if (actual_stop_band < 32) {
780       num = (stop_idx - len - 1);
781       p_qmf_real = &qmf_real[len][actual_stop_band];
782       ixheaacd_clr_subsamples(p_qmf_real, num,
783                               (NO_ANALYSIS_CHANNELS - actual_stop_band));
784     }
785   }
786 
787   start_patch = ixheaacd_max16(
788       1, ixheaacd_sub16(hf_generator->pstr_settings->start_patch, 2));
789   stop_patch = patch_param[0].dst_start_band;
790 
791   {
792     WORD32 *ptr = &sub_sig_x[0];
793     WORD32 *plpc_filt_states_real = &hf_generator->lpc_filt_states_real[0][0];
794     for (i = LPC_ORDER; i != 0; i--) {
795       memcpy(ptr, plpc_filt_states_real, sizeof(WORD32) * (stop_patch));
796       ptr += NO_SYNTHESIS_CHANNELS;
797       plpc_filt_states_real += 32;
798     }
799   }
800   if (norm_max != 30) {
801     (*ixheaacd_covariance_matrix_calc)(sub_sig_x + start_patch,
802                                        &cov_matrix_seq[start_patch],
803                                        (stop_patch - start_patch));
804 
805   } else {
806     memset(&cov_matrix_seq[0], 0,
807            sizeof(ixheaacd_lpp_trans_cov_matrix) * stop_patch);
808   }
809 
810   ixheaacd_filter1_lp(hf_generator, cov_matrix_seq, bw_array, degree_alias,
811                       start_idx, stop_idx, max_qmf_subband, start_patch,
812                       stop_patch, sub_sig_x);
813 
814   start_patch = hf_generator->pstr_settings->start_patch;
815   stop_patch = hf_generator->pstr_settings->stop_patch;
816 
817   for (low_band = start_patch; low_band < stop_patch; low_band++) {
818     WORD32 src_start_band, src_end_band, dst_start_band, dst_end_band;
819     patch = 0;
820 
821     while (patch < num_patches) {
822       ia_patch_param_struct *ptr_loc_patch_param = &patch_param[patch];
823 
824       src_start_band = ptr_loc_patch_param->src_start_band;
825       src_end_band = ptr_loc_patch_param->src_end_band;
826       dst_start_band = ptr_loc_patch_param->dst_start_band;
827       dst_end_band = ptr_loc_patch_param->dst_end_band;
828 
829       high_band = (low_band + ptr_loc_patch_param->dst_end_band);
830 
831       if ((low_band < src_start_band) || (low_band >= src_end_band) ||
832           (high_band >= NO_SYNTHESIS_CHANNELS)) {
833         patch++;
834         continue;
835       }
836 
837       if ((high_band != dst_start_band)) {
838         degree_alias[high_band] = degree_alias[low_band];
839       }
840 
841       patch++;
842     }
843   }
844 
845   memcpy(hf_generator->bw_array_prev, bw_array, sizeof(WORD32) * num_if_bands);
846 }
847 
ixheaacd_hf_generator(ia_sbr_hf_generator_struct * hf_generator,ia_sbr_scale_fact_struct * scale_factor,WORD32 ** qmf_real,WORD32 ** qmf_imag,WORD32 factor,WORD32 start_idx,WORD32 stop_idx,WORD32 num_if_bands,WORD32 max_qmf_subband,WORD32 * sbr_invf_mode,WORD32 * sbr_invf_mode_prev,WORD32 * sub_sig_x,WORD audio_object_type)848 VOID ixheaacd_hf_generator(ia_sbr_hf_generator_struct *hf_generator,
849                            ia_sbr_scale_fact_struct *scale_factor,
850                            WORD32 **qmf_real, WORD32 **qmf_imag, WORD32 factor,
851                            WORD32 start_idx, WORD32 stop_idx,
852                            WORD32 num_if_bands, WORD32 max_qmf_subband,
853                            WORD32 *sbr_invf_mode, WORD32 *sbr_invf_mode_prev,
854                            WORD32 *sub_sig_x, WORD audio_object_type) {
855   WORD32 bw_index[MAX_NUM_PATCHES];
856   WORD32 bw_array[MAX_NUM_PATCHES];
857 
858   WORD32 i, j;
859   WORD32 start_patch, stop_patch, low_band, high_band;
860   ia_patch_param_struct *patch_param =
861       hf_generator->pstr_settings->str_patch_param;
862   WORD32 patch;
863 
864   WORD16 alpha_real[LPC_ORDER];
865   WORD16 a0r, a1r;
866   WORD16 alpha_imag[LPC_ORDER];
867   WORD16 a0i = 0, a1i = 0;
868 
869   WORD16 bw = 0;
870 
871   ixheaacd_lpp_trans_cov_matrix cov_matrix;
872   ixheaacd_lpp_trans_cov_matrix cov_matrix_seq[MAX_COLS];
873 
874   WORD32 common_scale;
875   WORD32 actual_stop_band;
876   WORD32 num_patches = hf_generator->pstr_settings->num_patches;
877 
878   start_idx = (start_idx * factor);
879 
880   stop_idx = (hf_generator->pstr_settings->num_columns + (stop_idx * factor));
881 
882   ixheaacd_invfilt_level_emphasis(hf_generator, num_if_bands, sbr_invf_mode,
883                                   sbr_invf_mode_prev, bw_array);
884 
885   actual_stop_band =
886       ixheaacd_add16(patch_param[num_patches - 1].dst_start_band,
887                      patch_param[num_patches - 1].num_bands_in_patch);
888 
889   for (i = start_idx; i < stop_idx; i++) {
890     WORD32 *p_qmf_real = &qmf_real[i][actual_stop_band];
891     WORD32 *p_qmf_imag = &qmf_imag[i][actual_stop_band];
892 
893     for (j = NO_SYNTHESIS_CHANNELS - actual_stop_band; j != 0; j--) {
894       *p_qmf_real++ = 0;
895       *p_qmf_imag++ = 0;
896     }
897   }
898 
899   memset(bw_index, 0, sizeof(WORD32) * num_patches);
900 
901   common_scale =
902       ixheaacd_min32(scale_factor->ov_lb_scale, scale_factor->lb_scale);
903 
904   start_patch = hf_generator->pstr_settings->start_patch;
905   stop_patch = hf_generator->pstr_settings->stop_patch;
906 
907   {
908     WORD32 *ptr;
909     for (i = 0; i < LPC_ORDER; i++) {
910       ptr = sub_sig_x + (start_patch) + i * 128;
911       memcpy(ptr, &hf_generator->lpc_filt_states_real[i][start_patch],
912              sizeof(WORD32) * (stop_patch - start_patch));
913       memcpy(ptr + 64, &hf_generator->lpc_filt_states_imag[i][start_patch],
914              sizeof(WORD32) * (stop_patch - start_patch));
915     }
916   }
917   if (audio_object_type != AOT_ER_AAC_ELD &&
918       audio_object_type != AOT_ER_AAC_LD) {
919     (*ixheaacd_covariance_matrix_calc_2)(
920         &cov_matrix_seq[start_patch],
921         (sub_sig_x + start_patch + LPC_ORDER * 128), (stop_patch - start_patch),
922         38);
923   } else {
924     (*ixheaacd_covariance_matrix_calc_2)(
925         &cov_matrix_seq[start_patch],
926         (sub_sig_x + start_patch + LPC_ORDER * 128), (stop_patch - start_patch),
927         16);
928   }
929 
930   for (low_band = start_patch; low_band < stop_patch; low_band++) {
931     FLAG reset_lpc_coeff = 0;
932     WORD32 max_val;
933     WORD32 q_shift;
934     WORD32 v;
935     max_val = ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_01);
936     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_02);
937     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_12);
938 
939     max_val = max_val | (cov_matrix_seq[low_band].phi_11);
940     max_val = max_val | (cov_matrix_seq[low_band].phi_22);
941     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_01_im);
942     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_02_im);
943     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_12_im);
944 
945     q_shift = ixheaacd_pnorm32(max_val);
946 
947     cov_matrix.phi_11 = (cov_matrix_seq[low_band].phi_11 << q_shift);
948     cov_matrix.phi_22 = (cov_matrix_seq[low_band].phi_22 << q_shift);
949     cov_matrix.phi_01 = (cov_matrix_seq[low_band].phi_01 << q_shift);
950     cov_matrix.phi_02 = (cov_matrix_seq[low_band].phi_02 << q_shift);
951     cov_matrix.phi_12 = (cov_matrix_seq[low_band].phi_12 << q_shift);
952     cov_matrix.phi_01_im = (cov_matrix_seq[low_band].phi_01_im << q_shift);
953     cov_matrix.phi_02_im = (cov_matrix_seq[low_band].phi_02_im << q_shift);
954     cov_matrix.phi_12_im = (cov_matrix_seq[low_band].phi_12_im << q_shift);
955 
956     max_val = ixheaacd_mult32(cov_matrix.phi_12, cov_matrix.phi_12);
957     max_val = ixheaacd_add32_sat(
958         max_val, ixheaacd_mult32(cov_matrix.phi_12_im, cov_matrix.phi_12_im));
959 
960     v = ixheaacd_sub32_sat(
961             ixheaacd_mult32(cov_matrix.phi_11, cov_matrix.phi_22), max_val)
962         << 1;
963     cov_matrix.d = v;
964 
965     alpha_real[1] = 0;
966     alpha_imag[1] = 0;
967 
968     if (cov_matrix.d != 0) {
969       WORD32 tmp_r, temp_real, modulus_d;
970       WORD32 tmp_i, temp_imag;
971       WORD16 inverse_d;
972       WORD32 norm_d;
973 
974       norm_d = ixheaacd_norm32(cov_matrix.d);
975 
976       inverse_d =
977           (WORD16)(*ixheaacd_fix_div)(0x40000000, (cov_matrix.d << norm_d));
978 
979       modulus_d = ixheaacd_abs32_sat(cov_matrix.d);
980       tmp_r =
981           (ixheaacd_sub32_sat(
982               ixheaacd_sub32_sat(
983                   ixheaacd_mult32(cov_matrix.phi_01, cov_matrix.phi_12),
984                   ixheaacd_mult32(cov_matrix.phi_01_im, cov_matrix.phi_12_im)),
985               ixheaacd_mult32(cov_matrix.phi_02, cov_matrix.phi_11))) >>
986           (LPC_SCALE_FACTOR - 1);
987       tmp_i = (ixheaacd_sub32_sat(
988                   ixheaacd_add32_sat(
989                       ixheaacd_mult32(cov_matrix.phi_01_im, cov_matrix.phi_12),
990                       ixheaacd_mult32(cov_matrix.phi_01, cov_matrix.phi_12_im)),
991                   ixheaacd_mult32(cov_matrix.phi_02_im, cov_matrix.phi_11))) >>
992               (LPC_SCALE_FACTOR - 1);
993       temp_imag = ixheaacd_abs32(tmp_i);
994       temp_real = ixheaacd_abs32(tmp_r);
995 
996       if (temp_real >= modulus_d) {
997         reset_lpc_coeff = 1;
998       } else {
999         alpha_real[1] = (WORD16)(
1000             (ixheaacd_mult32x16in32(tmp_r, inverse_d) << (norm_d + 1)) >> 15);
1001       }
1002 
1003       if (temp_imag >= modulus_d) {
1004         reset_lpc_coeff = 1;
1005       } else {
1006         alpha_imag[1] = (WORD16)(
1007             (ixheaacd_mult32x16in32(tmp_i, inverse_d) << (norm_d + 1)) >> 15);
1008       }
1009     }
1010 
1011     alpha_real[0] = 0;
1012     alpha_imag[0] = 0;
1013 
1014     if (cov_matrix.phi_11 != 0) {
1015       WORD32 tmp_r, temp_real;
1016       WORD32 tmp_i = 0, temp_imag = 0;
1017       WORD16 inverse_r11;
1018       WORD32 norm_r11;
1019 
1020       norm_r11 = ixheaacd_norm32(cov_matrix.phi_11);
1021 
1022       inverse_r11 = (WORD16)(*ixheaacd_fix_div)(
1023           0x40000000, (cov_matrix.phi_11 << norm_r11));
1024 
1025       tmp_r = ixheaacd_add32_sat(
1026           ixheaacd_add32(
1027               (cov_matrix.phi_01 >> (LPC_SCALE_FACTOR + 1)),
1028               ixheaacd_mult32x16in32(cov_matrix.phi_12, alpha_real[1])),
1029           ixheaacd_mult32x16in32(cov_matrix.phi_12_im, alpha_imag[1]));
1030       tmp_i = ixheaacd_sub32_sat(
1031           ixheaacd_add32(
1032               (cov_matrix.phi_01_im >> (LPC_SCALE_FACTOR + 1)),
1033               ixheaacd_mult32x16in32(cov_matrix.phi_12, alpha_imag[1])),
1034           ixheaacd_mult32x16in32(cov_matrix.phi_12_im, alpha_real[1]));
1035 
1036       tmp_r = tmp_r << 1;
1037       tmp_i = tmp_i << 1;
1038 
1039       temp_imag = ixheaacd_abs32(tmp_i);
1040       temp_real = ixheaacd_abs32(tmp_r);
1041 
1042       if (temp_real >= cov_matrix.phi_11) {
1043         reset_lpc_coeff = 1;
1044       } else {
1045         alpha_real[0] = (WORD16)(
1046             (ixheaacd_mult32x16in32(ixheaacd_sub32_sat(0, tmp_r), inverse_r11)
1047              << (norm_r11 + 1)) >>
1048             15);
1049       }
1050 
1051       if (temp_imag >= cov_matrix.phi_11) {
1052         reset_lpc_coeff = 1;
1053       } else {
1054         alpha_imag[0] = (WORD16)(
1055             (ixheaacd_mult32x16in32(ixheaacd_sub32_sat(0, tmp_i), inverse_r11)
1056              << (norm_r11 + 1)) >>
1057             15);
1058       }
1059     }
1060 
1061     if (ixheaacd_add32_sat((alpha_real[0] * alpha_real[0]),
1062                            (alpha_imag[0] * alpha_imag[0])) >= 0x40000000L) {
1063       reset_lpc_coeff = 1;
1064     }
1065 
1066     if (ixheaacd_add32_sat((alpha_real[1] * alpha_real[1]),
1067                            (alpha_imag[1] * alpha_imag[1])) >= 0x40000000L) {
1068       reset_lpc_coeff = 1;
1069     }
1070 
1071     if (reset_lpc_coeff) {
1072       alpha_real[0] = 0;
1073       alpha_real[1] = 0;
1074       alpha_imag[0] = 0;
1075       alpha_imag[1] = 0;
1076     }
1077 
1078     patch = 0;
1079 
1080     while (patch < num_patches) {
1081       high_band = (low_band + patch_param[patch].dst_end_band);
1082 
1083       if ((low_band < patch_param[patch].src_start_band) ||
1084           (low_band >= patch_param[patch].src_end_band)) {
1085         patch++;
1086         continue;
1087       }
1088 
1089       if (high_band < max_qmf_subband) {
1090         patch++;
1091         continue;
1092       }
1093 
1094       while ((bw_index[patch] < MAX_NUM_PATCHES - 1) &&
1095              (bw_index[patch] < MAX_NUM_NOISE_VALUES) &&
1096              (high_band >=
1097               hf_generator->pstr_settings->bw_borders[bw_index[patch]])) {
1098         bw_index[patch]++;
1099       }
1100 
1101       bw = ixheaacd_extract16h(bw_array[bw_index[patch]]);
1102       a0r = ixheaacd_mult16_shl_sat(bw, alpha_real[0]);
1103       a0i = ixheaacd_mult16_shl_sat(bw, alpha_imag[0]);
1104       bw = ixheaacd_mult16_shl_sat(bw, bw);
1105       a1r = ixheaacd_mult16_shl_sat(bw, alpha_real[1]);
1106       a1i = ixheaacd_mult16_shl_sat(bw, alpha_imag[1]);
1107 
1108       if (bw > 0) {
1109         ixheaacd_filterstep3(a0r, a0i, a1r, a1i, start_idx, stop_idx, low_band,
1110                              high_band, sub_sig_x);
1111 
1112       } else {
1113         WORD32 *p_src = sub_sig_x + low_band + ((start_idx + 2) << 7);
1114         WORD32 *p_dst = sub_sig_x + high_band + ((start_idx + 2) << 7);
1115 
1116         for (i = stop_idx - start_idx; i != 0; i--) {
1117           *(p_dst) = *(p_src) >> LPC_SCALE_FACTOR;
1118           p_src += 64;
1119           p_dst += 64;
1120           *(p_dst) = *(p_src) >> LPC_SCALE_FACTOR;
1121           p_src += 64;
1122           p_dst += 64;
1123         }
1124       }
1125 
1126       patch++;
1127     }
1128   }
1129 
1130   memcpy(hf_generator->bw_array_prev, bw_array, sizeof(WORD32) * num_if_bands);
1131 
1132   scale_factor->hb_scale = (WORD16)(common_scale - LPC_SCALE_FACTOR);
1133 }
1134