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