• 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 <string.h>
21 #include "ixheaacd_sbr_common.h"
22 #include <ixheaacd_type_def.h>
23 
24 #include "ixheaacd_constants.h"
25 #include <ixheaacd_basic_ops32.h>
26 #include <ixheaacd_basic_ops16.h>
27 #include <ixheaacd_basic_ops40.h>
28 #include "ixheaacd_basic_ops.h"
29 
30 #include <ixheaacd_basic_op.h>
31 #include "ixheaacd_intrinsics.h"
32 #include "ixheaacd_common_rom.h"
33 #include "ixheaacd_basic_funcs.h"
34 
35 #include "ixheaacd_bitbuffer.h"
36 #include "ixheaacd_sbrdecsettings.h"
37 #include "ixheaacd_sbr_scale.h"
38 #include "ixheaacd_lpp_tran.h"
39 #include "ixheaacd_env_extr_part.h"
40 #include <ixheaacd_sbr_rom.h>
41 #include "ixheaacd_hybrid.h"
42 
43 #include "ixheaacd_ps_dec.h"
44 
45 #include "ixheaacd_env_extr.h"
46 
47 #include "ixheaacd_dsp_fft32x32s.h"
48 
49 #include "ixheaacd_function_selector.h"
50 
ixheaacd_filt_2_ch(const WORD32 * ptr_qmf,WORD32 * ptr_hybrid,ia_sbr_tables_struct * ptr_sbr_tables)51 static VOID ixheaacd_filt_2_ch(const WORD32 *ptr_qmf, WORD32 *ptr_hybrid,
52                                ia_sbr_tables_struct *ptr_sbr_tables) {
53   WORD32 cum0, cum1, cum00, cum11;
54   WORD16 *p2_6 = ptr_sbr_tables->ps_tables_ptr->p2_6;
55 
56   cum0 = ptr_qmf[HYBRID_FILTER_DELAY] >> 1;
57   cum00 = ptr_qmf[HYBRID_FILTER_DELAY + 16] >> 1;
58   cum1 = 0L;
59   cum11 = 0L;
60 
61   {
62     cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[1], *p2_6));
63     cum11 =
64         ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[17], *p2_6++));
65 
66     cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[3], *p2_6));
67     cum11 =
68         ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[19], *p2_6++));
69 
70     cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[5], *p2_6));
71     cum11 =
72         ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[21], *p2_6++));
73 
74     cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[7], *p2_6));
75     cum11 =
76         ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[23], *p2_6++));
77 
78     cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[9], *p2_6));
79     cum11 =
80         ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[25], *p2_6++));
81 
82     cum1 = ixheaacd_add32_sat(cum1, ixheaacd_mult32x16in32(ptr_qmf[11], *p2_6));
83     cum11 =
84         ixheaacd_add32_sat(cum11, ixheaacd_mult32x16in32(ptr_qmf[27], *p2_6++));
85   }
86   cum1 = ixheaacd_shl32(cum1, 1);
87   cum11 = ixheaacd_shl32(cum11, 1);
88 
89   ptr_hybrid[0] = ixheaacd_add32_sat(cum0, cum1);
90   ptr_hybrid[1] = ixheaacd_sub32_sat(cum0, cum1);
91 
92   ptr_hybrid[16] = ixheaacd_add32_sat(cum00, cum11);
93   ptr_hybrid[17] = ixheaacd_sub32_sat(cum00, cum11);
94 }
95 
ixheaacd_filt_8_ch(const WORD32 * ptr_qmf_real,const WORD32 * ptr_qmf_imag,WORD32 * ptr_hyb_real,WORD32 * ptr_hyb_imag,ia_sbr_tables_struct * ptr_sbr_tables)96 static VOID ixheaacd_filt_8_ch(const WORD32 *ptr_qmf_real,
97                                const WORD32 *ptr_qmf_imag, WORD32 *ptr_hyb_real,
98                                WORD32 *ptr_hyb_imag,
99                                ia_sbr_tables_struct *ptr_sbr_tables) {
100   const WORD16 tcos = 0x7642;
101   const WORD16 tsin = 0x30fc;
102   const WORD16 tcom = 0x5a82;
103   WORD32 real, imag;
104   WORD32 cum[16];
105   const WORD16 *p8_13 = ptr_sbr_tables->ps_tables_ptr->p8_13;
106   const WORD16 *p8_13_8 = ptr_sbr_tables->ps_tables_ptr->p8_13 + 8;
107 
108   real = ixheaacd_shl32(
109       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[0], *p8_13),
110                          ixheaacd_mult32x16in32(ptr_qmf_real[8], *p8_13_8)),
111       1);
112   imag = ixheaacd_shl32(
113       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[0], *p8_13++),
114                          ixheaacd_mult32x16in32(ptr_qmf_imag[8], *p8_13_8++)),
115       1);
116 
117   cum[12] = ixheaacd_shl32(
118       ixheaacd_mult32x16in32(ixheaacd_add32_sat(imag, real), tcom), 1);
119   cum[13] = ixheaacd_shl32(
120       ixheaacd_mult32x16in32(ixheaacd_sub32_sat(imag, real), tcom), 1);
121 
122   real = ixheaacd_shl32(
123       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[1], *p8_13),
124                          ixheaacd_mult32x16in32(ptr_qmf_real[9], *p8_13_8)),
125       1);
126   imag = ixheaacd_shl32(
127       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[1], *p8_13++),
128                          ixheaacd_mult32x16in32(ptr_qmf_imag[9], *p8_13_8++)),
129       1);
130 
131   cum[10] =
132       ixheaacd_shl32(ixheaacd_add32_sat(ixheaacd_mult32x16in32(imag, tcos),
133                                         ixheaacd_mult32x16in32(real, tsin)),
134                      1);
135   cum[11] =
136       ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(imag, tsin),
137                                         ixheaacd_mult32x16in32(real, tcos)),
138                      1);
139   cum[9] = ixheaacd_shl32(
140       ixheaacd_mult32x16in32(
141           ixheaacd_sub32_sat(ptr_qmf_real[2], ptr_qmf_real[10]), *p8_13_8++),
142       1);
143   cum[8] = ixheaacd_shl32(
144       ixheaacd_mult32x16in32(
145           ixheaacd_sub32_sat(ptr_qmf_imag[2], ptr_qmf_imag[10]), *p8_13++),
146       1);
147 
148   real = ixheaacd_shl32(
149       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[3], *p8_13),
150                          ixheaacd_mult32x16in32(ptr_qmf_real[11], *p8_13_8)),
151       1);
152   imag = ixheaacd_shl32(
153       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[3], *p8_13++),
154                          ixheaacd_mult32x16in32(ptr_qmf_imag[11], *p8_13_8++)),
155       1);
156 
157   cum[6] =
158       ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(imag, tcos),
159                                         ixheaacd_mult32x16in32(real, tsin)),
160                      1);
161   cum[7] = ixheaacd_shl32(ixheaacd_negate32_sat(ixheaacd_add32_sat(
162                               ixheaacd_mult32x16in32(imag, tsin),
163                               ixheaacd_mult32x16in32(real, tcos))),
164                           1);
165 
166   real = ixheaacd_shl32(
167       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_real[4], *p8_13),
168                          ixheaacd_mult32x16in32(ptr_qmf_real[12], *p8_13_8)),
169       1);
170   imag = ixheaacd_shl32(
171       ixheaacd_add32_sat(ixheaacd_mult32x16in32(ptr_qmf_imag[4], *p8_13++),
172                          ixheaacd_mult32x16in32(ptr_qmf_imag[12], *p8_13_8++)),
173       1);
174 
175   cum[4] = ixheaacd_shl32(
176       ixheaacd_mult32x16in32(ixheaacd_sub32_sat(imag, real), tcom), 1);
177   cum[5] = ixheaacd_shl32(
178       ixheaacd_mult32x16in32(
179           ixheaacd_negate32_sat(ixheaacd_add32_sat(imag, real)), tcom),
180       1);
181 
182   real = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_real[5], *p8_13), 1);
183   imag = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_imag[5], *p8_13++), 1);
184 
185   cum[2] =
186       ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(real, tcos),
187                                         ixheaacd_mult32x16in32(imag, tsin)),
188                      1);
189   cum[3] =
190       ixheaacd_shl32(ixheaacd_add32_sat(ixheaacd_mult32x16in32(real, tsin),
191                                         ixheaacd_mult32x16in32(imag, tcos)),
192                      1);
193 
194   cum[0] = ixheaacd_shl32(
195       ixheaacd_mult32x16in32(ptr_qmf_real[HYBRID_FILTER_DELAY], *p8_13), 1);
196   cum[1] = ixheaacd_shl32(
197       ixheaacd_mult32x16in32(ptr_qmf_imag[HYBRID_FILTER_DELAY], *p8_13++), 1);
198 
199   real = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_real[7], *p8_13), 1);
200   imag = ixheaacd_shl32(ixheaacd_mult32x16in32(ptr_qmf_imag[7], *p8_13++), 1);
201 
202   cum[14] =
203       ixheaacd_shl32(ixheaacd_add32_sat(ixheaacd_mult32x16in32(imag, tsin),
204                                         ixheaacd_mult32x16in32(real, tcos)),
205                      1);
206   cum[15] =
207       ixheaacd_shl32(ixheaacd_sub32_sat(ixheaacd_mult32x16in32(imag, tcos),
208                                         ixheaacd_mult32x16in32(real, tsin)),
209                      1);
210 
211   (*ixheaacd_inv_dit_fft_8pt)(cum, ptr_hyb_real, ptr_hyb_imag);
212 }
213 
ixheaacd_hybrid_analysis(const WORD32 * ptr_qmf_real,WORD32 * ptr_hyb_real,WORD32 * ptr_hyb_imag,ia_hybrid_struct * ptr_hybrid,WORD16 scale,ia_sbr_tables_struct * ptr_sbr_tables)214 VOID ixheaacd_hybrid_analysis(const WORD32 *ptr_qmf_real, WORD32 *ptr_hyb_real,
215                               WORD32 *ptr_hyb_imag,
216                               ia_hybrid_struct *ptr_hybrid, WORD16 scale,
217                               ia_sbr_tables_struct *ptr_sbr_tables)
218 
219 {
220   WORD band, j;
221   WORD chn_offset = 0;
222   WORD32 *ptr_re, *ptr_im;
223   WORD32 *ptr_temp_real, *ptr_temp_imag;
224 
225   for (band = 0; band < NO_QMF_CHANNELS_IN_HYBRID; band++) {
226     ptr_re = ptr_hybrid->ptr_qmf_buf_re[band];
227     ptr_im = ptr_hybrid->ptr_qmf_buf_im[band];
228 
229     ptr_temp_real = &ptr_hybrid->ptr_work_re[0];
230     ptr_temp_imag = &ptr_hybrid->ptr_work_im[0];
231 
232     *ptr_temp_real = *ptr_re;
233     *ptr_temp_imag = *ptr_im;
234 
235     ptr_temp_real++;
236     ptr_re++;
237     ptr_temp_imag++;
238     ptr_im++;
239 
240     for (j = ptr_hybrid->ptr_qmf_buf - 2; j >= 0; j--) {
241       *ptr_temp_real++ = *ptr_re;
242       *(ptr_re - 1) = *ptr_re;
243       ptr_re++;
244       *ptr_temp_imag++ = *ptr_im;
245       *(ptr_im - 1) = *ptr_im;
246       ptr_im++;
247     }
248 
249     {
250       WORD32 temp_re = ptr_qmf_real[band];
251       WORD32 temp_im = ptr_qmf_real[band + 0x40];
252 
253       if (scale < 0) {
254         temp_re = ixheaacd_shl32(temp_re, -scale);
255         temp_im = ixheaacd_shl32(temp_im, -scale);
256       } else {
257         temp_re = ixheaacd_shr32(temp_re, scale);
258         temp_im = ixheaacd_shr32(temp_im, scale);
259       }
260       *ptr_temp_real = temp_re;
261       *--ptr_re = temp_re;
262 
263       *ptr_temp_imag = temp_im;
264       *--ptr_im = temp_im;
265     }
266 
267     switch (ptr_hybrid->ptr_resol[band]) {
268       case NO_HYBRID_CHANNELS_LOW:
269 
270         ixheaacd_filt_2_ch(ptr_hybrid->ptr_work_re, &ptr_hyb_real[chn_offset],
271                            ptr_sbr_tables);
272 
273         chn_offset += 2;
274 
275         break;
276       case NO_HYBRID_CHANNELS_HIGH:
277 
278         ixheaacd_filt_8_ch(ptr_hybrid->ptr_work_re, ptr_hybrid->ptr_work_im,
279                            &ptr_hyb_real[chn_offset], &ptr_hyb_imag[chn_offset],
280                            ptr_sbr_tables);
281 
282         chn_offset += 6;
283     }
284   }
285 }
286