/src/libxaac/decoder/ixheaacd_basic_funcs.c
Line | Count | Source |
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 "ixheaac_type_def.h" |
22 | | |
23 | | #include "ixheaac_constants.h" |
24 | | #include "ixheaac_basic_ops32.h" |
25 | | #include "ixheaac_basic_ops16.h" |
26 | | #include "ixheaac_basic_ops40.h" |
27 | | #include "ixheaac_basic_op.h" |
28 | | #include "ixheaac_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) ixheaac_sat16(a) |
34 | | |
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 | 631k | WORD16 *ptr_result_exp) { |
38 | 631k | WORD32 new_mant; |
39 | 631k | WORD32 new_exp; |
40 | 631k | new_exp = op1_exp - op2_exp; |
41 | 631k | if (new_exp < 0) { |
42 | 347k | if (new_exp < -31) { |
43 | 13.6k | new_exp = -31; |
44 | 13.6k | } |
45 | 347k | op1_mant = op1_mant >> (-new_exp); |
46 | 347k | new_exp = op2_exp; |
47 | 347k | } else { |
48 | 284k | if (new_exp > 31) { |
49 | 72.4k | new_exp = 31; |
50 | 72.4k | } |
51 | 284k | op2_mant = op2_mant >> new_exp; |
52 | 284k | new_exp = op1_exp; |
53 | 284k | } |
54 | | |
55 | 631k | new_mant = op1_mant + op2_mant; |
56 | | |
57 | 631k | if (ixheaac_abs32(new_mant) >= 0x8000) { |
58 | 4.61k | new_mant = new_mant >> 1; |
59 | 4.61k | new_exp++; |
60 | 4.61k | } |
61 | | |
62 | 631k | *ptr_result_mant = new_mant; |
63 | 631k | *ptr_result_exp = (WORD16)(new_exp); |
64 | 631k | } |
65 | | |
66 | | WORD32 ixheaacd_fix_mant_div(WORD16 op1_mant, WORD16 op2_mant, |
67 | | WORD16 *ptr_result_mant, |
68 | | ixheaacd_misc_tables *pstr_common_tables) |
69 | | |
70 | 4.71M | { |
71 | 4.71M | WORD32 pre_shift_val, post_shift_val; |
72 | 4.71M | WORD32 index; |
73 | 4.71M | WORD16 one_by_op2_mant; |
74 | | |
75 | 4.71M | pre_shift_val = ixheaac_norm32(op2_mant) - 16; |
76 | | |
77 | 4.71M | index = (op2_mant << pre_shift_val) >> (SHORT_BITS - 3 - 8); |
78 | | |
79 | 4.71M | index &= (1 << (8 + 1)) - 1; |
80 | | |
81 | 4.71M | if (index == 0) { |
82 | 1.34M | post_shift_val = ixheaac_norm32(op1_mant) - 16; |
83 | | |
84 | 1.34M | *ptr_result_mant = (op1_mant << post_shift_val); |
85 | 3.36M | } else { |
86 | 3.36M | WORD32 ratio_m; |
87 | | |
88 | 3.36M | index = ((index - 1) >> 1); |
89 | | |
90 | 3.36M | one_by_op2_mant = pstr_common_tables->inv_table[index]; |
91 | | |
92 | 3.36M | ratio_m = ixheaac_mult16x16in32(one_by_op2_mant, op1_mant); |
93 | | |
94 | 3.36M | post_shift_val = ixheaac_norm32(ratio_m) - 1; |
95 | | |
96 | 3.36M | *ptr_result_mant = (WORD16)((ratio_m << post_shift_val) >> 15); |
97 | 3.36M | } |
98 | 4.71M | return (pre_shift_val - post_shift_val); |
99 | 4.71M | } |
100 | | |
101 | 5.07M | VOID ixheaacd_fix_mant_exp_sqrt(WORD16 *ptr_in_out, WORD16 *sqrt_table) { |
102 | 5.07M | WORD32 index; |
103 | 5.07M | WORD32 pre_shift_val; |
104 | 5.07M | WORD32 op_mant = *ptr_in_out; |
105 | 5.07M | WORD32 op_exp = *(ptr_in_out + 1); |
106 | 5.07M | WORD32 result_m; |
107 | 5.07M | WORD32 result_e; |
108 | | |
109 | 5.07M | if (op_mant > 0) { |
110 | 3.38M | pre_shift_val = (ixheaac_norm32((WORD16)op_mant) - 16); |
111 | 3.38M | op_exp = (op_exp - pre_shift_val); |
112 | 3.38M | index = (op_mant << pre_shift_val) >> (SHORT_BITS - 3 - 8); |
113 | 3.38M | index &= (1 << (8 + 1)) - 1; |
114 | 3.38M | result_m = sqrt_table[index >> 1]; |
115 | 3.38M | if ((op_exp & 1) != 0) { |
116 | 1.70M | result_m = (result_m * 0x5a82) >> 16; |
117 | 1.70M | op_exp += 3; |
118 | 1.70M | } |
119 | 3.38M | result_e = (op_exp >> 1); |
120 | | |
121 | 3.38M | } else { |
122 | 1.68M | result_m = 0; |
123 | 1.68M | result_e = -SHORT_BITS; |
124 | 1.68M | } |
125 | | |
126 | 5.07M | *ptr_in_out++ = (WORD16)result_m; |
127 | 5.07M | *ptr_in_out = (WORD16)result_e; |
128 | 5.07M | } |
129 | | |
130 | 955k | WORD32 ixheaacd_fix_div_dec(WORD32 op1, WORD32 op2) { |
131 | 955k | WORD32 quotient = 0; |
132 | 955k | UWORD32 abs_num, abs_den; |
133 | 955k | WORD32 k; |
134 | 955k | WORD32 sign; |
135 | | |
136 | 955k | abs_num = ixheaac_abs32(op1 >> 1); |
137 | 955k | abs_den = ixheaac_abs32(op2 >> 1); |
138 | 955k | sign = op1 ^ op2; |
139 | | |
140 | 955k | if (abs_num != 0) { |
141 | 15.2M | for (k = 15; k > 0; k--) { |
142 | 14.3M | quotient = (quotient << 1); |
143 | 14.3M | abs_num = (abs_num << 1); |
144 | 14.3M | if (abs_num >= abs_den) { |
145 | 7.53M | abs_num -= abs_den; |
146 | 7.53M | quotient++; |
147 | 7.53M | } |
148 | 14.3M | } |
149 | 955k | } |
150 | 955k | if (sign < 0) quotient = -(quotient); |
151 | | |
152 | 955k | return quotient; |
153 | 955k | } |
154 | | |
155 | 1.68M | #define ONE_IN_Q30 0x40000000 |
156 | | |
157 | 561k | static PLATFORM_INLINE WORD32 ixheaacd_one_by_sqrt_calc(WORD32 op) { |
158 | 561k | WORD32 a = ixheaac_add32_sat(0x900ebee0, |
159 | 561k | ixheaac_mult32x16in32_shl_sat(op, 0x39d9)); |
160 | 561k | WORD32 iy = |
161 | 561k | ixheaac_add32_sat(0x573b645a, ixheaac_mult32x16h_in32_shl_sat(op, a)); |
162 | | |
163 | 561k | iy = ixheaac_shl32_dir_sat_limit(iy, 1); |
164 | | |
165 | 561k | a = ixheaac_mult32_shl_sat(op, iy); |
166 | 561k | a = ixheaac_sub32_sat(ONE_IN_Q30, ixheaac_shl32_dir_sat_limit( |
167 | 561k | ixheaac_mult32_shl_sat(a, iy), 1)); |
168 | 561k | iy = ixheaac_add32_sat(iy, ixheaac_mult32_shl_sat(a, iy)); |
169 | | |
170 | 561k | a = ixheaac_mult32_shl_sat(op, iy); |
171 | 561k | a = ixheaac_sub32_sat(ONE_IN_Q30, ixheaac_shl32_dir_sat_limit( |
172 | 561k | ixheaac_mult32_shl_sat(a, iy), 1)); |
173 | 561k | iy = ixheaac_add32_sat(iy, ixheaac_mult32_shl_sat(a, iy)); |
174 | | |
175 | 561k | a = ixheaac_mult32_shl_sat(op, iy); |
176 | 561k | a = ixheaac_sub32_sat(ONE_IN_Q30, ixheaac_shl32_dir_sat_limit( |
177 | 561k | ixheaac_mult32_shl_sat(a, iy), 1)); |
178 | 561k | iy = ixheaac_add32_sat(iy, ixheaac_mult32_shl_sat(a, iy)); |
179 | | |
180 | 561k | return iy; |
181 | 561k | } |
182 | | |
183 | 561k | WORD32 ixheaacd_sqrt(WORD32 op) { |
184 | 561k | WORD32 result = 0; |
185 | 561k | WORD16 shift; |
186 | | |
187 | 561k | if (op != 0) { |
188 | 561k | shift = (WORD16)(ixheaac_norm32(op) & ~1); |
189 | 561k | op = ixheaac_shl32_dir_sat_limit(op, shift); |
190 | 561k | shift = ixheaac_shr32_dir_sat_limit(shift, 1); |
191 | 561k | op = ixheaac_mult32_shl_sat(ixheaacd_one_by_sqrt_calc(op), op); |
192 | 561k | result = ixheaac_shr32_dir_sat_limit(op, ixheaac_sat16(shift - 1)); |
193 | 561k | } |
194 | | |
195 | 561k | return result; |
196 | 561k | } |