• 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 "ixheaacd_sbr_common.h"
21 #include "ixheaacd_type_def.h"
22 
23 #include "ixheaacd_constants.h"
24 #include "ixheaacd_basic_ops32.h"
25 #include "ixheaacd_basic_ops16.h"
26 #include "ixheaacd_basic_ops40.h"
27 #include "ixheaacd_basic_op.h"
28 #include "ixheaacd_basic_ops.h"
29 #include "ixheaacd_intrinsics.h"
30 #include "ixheaacd_common_rom.h"
31 #include "ixheaacd_basic_funcs.h"
32 
33 #define sat16_m(a) ixheaacd_sat16(a)
34 
ixheaacd_fix_mant_exp_add(WORD16 op1_mant,WORD16 op1_exp,WORD16 op2_mant,WORD16 op2_exp,WORD16 * ptr_result_mant,WORD16 * ptr_result_exp)35 VOID ixheaacd_fix_mant_exp_add(WORD16 op1_mant, WORD16 op1_exp, WORD16 op2_mant,
36                                WORD16 op2_exp, WORD16 *ptr_result_mant,
37                                WORD16 *ptr_result_exp) {
38   WORD32 new_mant;
39   WORD32 new_exp;
40   new_exp = op1_exp - op2_exp;
41   if (new_exp < 0) {
42     op1_mant = op1_mant >> (-new_exp);
43     new_exp = op2_exp;
44   } else {
45     op2_mant = op2_mant >> new_exp;
46     new_exp = op1_exp;
47   }
48 
49   new_mant = op1_mant + op2_mant;
50 
51   if (ixheaacd_abs32(new_mant) >= 0x8000) {
52     new_mant = new_mant >> 1;
53     new_exp++;
54   }
55 
56   *ptr_result_mant = new_mant;
57   *ptr_result_exp = (WORD16)(new_exp);
58 }
59 
ixheaacd_fix_mant_div(WORD16 op1_mant,WORD16 op2_mant,WORD16 * ptr_result_mant,ixheaacd_misc_tables * pstr_common_tables)60 WORD32 ixheaacd_fix_mant_div(WORD16 op1_mant, WORD16 op2_mant,
61                              WORD16 *ptr_result_mant,
62                              ixheaacd_misc_tables *pstr_common_tables)
63 
64 {
65   WORD32 pre_shift_val, post_shift_val;
66   WORD32 index;
67   WORD16 one_by_op2_mant;
68 
69   pre_shift_val = ixheaacd_norm32(op2_mant) - 16;
70 
71   index = (op2_mant << pre_shift_val) >> (SHORT_BITS - 3 - 8);
72 
73   index &= (1 << (8 + 1)) - 1;
74 
75   if (index == 0) {
76     post_shift_val = ixheaacd_norm32(op1_mant) - 16;
77 
78     *ptr_result_mant = (op1_mant << post_shift_val);
79   } else {
80     WORD32 ratio_m;
81 
82     index = ((index - 1) >> 1);
83 
84     one_by_op2_mant = pstr_common_tables->inv_table[index];
85 
86     ratio_m = ixheaacd_mult16x16in32(one_by_op2_mant, op1_mant);
87 
88     post_shift_val = ixheaacd_norm32(ratio_m) - 1;
89 
90     *ptr_result_mant = (WORD16)((ratio_m << post_shift_val) >> 15);
91   }
92   return (pre_shift_val - post_shift_val);
93 }
94 
ixheaacd_fix_mant_exp_sqrt(WORD16 * ptr_in_out,WORD16 * sqrt_table)95 VOID ixheaacd_fix_mant_exp_sqrt(WORD16 *ptr_in_out, WORD16 *sqrt_table) {
96   WORD32 index;
97   WORD32 pre_shift_val;
98   WORD32 op_mant = *ptr_in_out;
99   WORD32 op_exp = *(ptr_in_out + 1);
100   WORD32 result_m;
101   WORD32 result_e;
102 
103   if (op_mant > 0) {
104     pre_shift_val = (ixheaacd_norm32((WORD16)op_mant) - 16);
105     op_exp = (op_exp - pre_shift_val);
106     index = (op_mant << pre_shift_val) >> (SHORT_BITS - 3 - 8);
107     index &= (1 << (8 + 1)) - 1;
108     result_m = sqrt_table[index >> 1];
109     if ((op_exp & 1) != 0) {
110       result_m = (result_m * 0x5a82) >> 16;
111       op_exp += 3;
112     }
113     result_e = (op_exp >> 1);
114 
115   } else {
116     result_m = 0;
117     result_e = -SHORT_BITS;
118   }
119 
120   *ptr_in_out++ = (WORD16)result_m;
121   *ptr_in_out = (WORD16)result_e;
122 }
123 
ixheaacd_fix_div_dec(WORD32 op1,WORD32 op2)124 WORD32 ixheaacd_fix_div_dec(WORD32 op1, WORD32 op2) {
125   WORD32 quotient = 0;
126   UWORD32 abs_num, abs_den;
127   WORD32 k;
128   WORD32 sign;
129 
130   abs_num = ixheaacd_abs32(op1 >> 1);
131   abs_den = ixheaacd_abs32(op2 >> 1);
132   sign = op1 ^ op2;
133 
134   if (abs_num != 0) {
135     for (k = 15; k > 0; k--) {
136       quotient = (quotient << 1);
137       abs_num = (abs_num << 1);
138       if (abs_num >= abs_den) {
139         abs_num -= abs_den;
140         quotient++;
141       }
142     }
143   }
144   if (sign < 0) quotient = -(quotient);
145 
146   return quotient;
147 }
148 
149 #define ONE_IN_Q30 0x40000000
150 
ixheaacd_one_by_sqrt_calc(WORD32 op)151 static PLATFORM_INLINE WORD32 ixheaacd_one_by_sqrt_calc(WORD32 op) {
152   WORD32 a = ixheaacd_add32_sat(0x900ebee0,
153                                 ixheaacd_mult32x16in32_shl_sat(op, 0x39d9));
154   WORD32 iy =
155       ixheaacd_add32_sat(0x573b645a, ixheaacd_mult32x16h_in32_shl_sat(op, a));
156 
157   iy = ixheaacd_shl32_dir_sat_limit(iy, 1);
158 
159   a = ixheaacd_mult32_shl_sat(op, iy);
160   a = ixheaacd_sub32_sat(ONE_IN_Q30, ixheaacd_shl32_dir_sat_limit(
161                                          ixheaacd_mult32_shl_sat(a, iy), 1));
162   iy = ixheaacd_add32_sat(iy, ixheaacd_mult32_shl_sat(a, iy));
163 
164   a = ixheaacd_mult32_shl_sat(op, iy);
165   a = ixheaacd_sub32_sat(ONE_IN_Q30, ixheaacd_shl32_dir_sat_limit(
166                                          ixheaacd_mult32_shl_sat(a, iy), 1));
167   iy = ixheaacd_add32_sat(iy, ixheaacd_mult32_shl_sat(a, iy));
168 
169   a = ixheaacd_mult32_shl_sat(op, iy);
170   a = ixheaacd_sub32_sat(ONE_IN_Q30, ixheaacd_shl32_dir_sat_limit(
171                                          ixheaacd_mult32_shl_sat(a, iy), 1));
172   iy = ixheaacd_add32_sat(iy, ixheaacd_mult32_shl_sat(a, iy));
173 
174   return iy;
175 }
176 
ixheaacd_sqrt(WORD32 op)177 WORD32 ixheaacd_sqrt(WORD32 op) {
178   WORD32 result = 0;
179   WORD16 shift;
180 
181   if (op != 0) {
182     shift = (WORD16)(ixheaacd_norm32(op) & ~1);
183     op = ixheaacd_shl32_dir_sat_limit(op, shift);
184     shift = ixheaacd_shr32_dir_sat_limit(shift, 1);
185     op = ixheaacd_mult32_shl_sat(ixheaacd_one_by_sqrt_calc(op), op);
186     result = ixheaacd_shr32_dir_sat_limit(op, ixheaacd_sat16(shift - 1));
187   }
188 
189   return result;
190 }
191