1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker * *
3*15dc779aSAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker *
5*15dc779aSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker *
9*15dc779aSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker *
11*15dc779aSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker *
17*15dc779aSAndroid Build Coastguard Worker *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker */
20*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
21*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
22*15dc779aSAndroid Build Coastguard Worker
23*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops16.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_op.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_intrinsics.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_common_rom.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_basic_funcs.h"
32*15dc779aSAndroid Build Coastguard Worker
33*15dc779aSAndroid Build Coastguard Worker #define sat16_m(a) ixheaac_sat16(a)
34*15dc779aSAndroid Build Coastguard Worker
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*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_fix_mant_exp_add(WORD16 op1_mant, WORD16 op1_exp, WORD16 op2_mant,
36*15dc779aSAndroid Build Coastguard Worker WORD16 op2_exp, WORD16 *ptr_result_mant,
37*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_result_exp) {
38*15dc779aSAndroid Build Coastguard Worker WORD32 new_mant;
39*15dc779aSAndroid Build Coastguard Worker WORD32 new_exp;
40*15dc779aSAndroid Build Coastguard Worker new_exp = op1_exp - op2_exp;
41*15dc779aSAndroid Build Coastguard Worker if (new_exp < 0) {
42*15dc779aSAndroid Build Coastguard Worker if (new_exp < -31) {
43*15dc779aSAndroid Build Coastguard Worker new_exp = -31;
44*15dc779aSAndroid Build Coastguard Worker }
45*15dc779aSAndroid Build Coastguard Worker op1_mant = op1_mant >> (-new_exp);
46*15dc779aSAndroid Build Coastguard Worker new_exp = op2_exp;
47*15dc779aSAndroid Build Coastguard Worker } else {
48*15dc779aSAndroid Build Coastguard Worker if (new_exp > 31) {
49*15dc779aSAndroid Build Coastguard Worker new_exp = 31;
50*15dc779aSAndroid Build Coastguard Worker }
51*15dc779aSAndroid Build Coastguard Worker op2_mant = op2_mant >> new_exp;
52*15dc779aSAndroid Build Coastguard Worker new_exp = op1_exp;
53*15dc779aSAndroid Build Coastguard Worker }
54*15dc779aSAndroid Build Coastguard Worker
55*15dc779aSAndroid Build Coastguard Worker new_mant = op1_mant + op2_mant;
56*15dc779aSAndroid Build Coastguard Worker
57*15dc779aSAndroid Build Coastguard Worker if (ixheaac_abs32(new_mant) >= 0x8000) {
58*15dc779aSAndroid Build Coastguard Worker new_mant = new_mant >> 1;
59*15dc779aSAndroid Build Coastguard Worker new_exp++;
60*15dc779aSAndroid Build Coastguard Worker }
61*15dc779aSAndroid Build Coastguard Worker
62*15dc779aSAndroid Build Coastguard Worker *ptr_result_mant = new_mant;
63*15dc779aSAndroid Build Coastguard Worker *ptr_result_exp = (WORD16)(new_exp);
64*15dc779aSAndroid Build Coastguard Worker }
65*15dc779aSAndroid Build Coastguard Worker
ixheaacd_fix_mant_div(WORD16 op1_mant,WORD16 op2_mant,WORD16 * ptr_result_mant,ixheaacd_misc_tables * pstr_common_tables)66*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_fix_mant_div(WORD16 op1_mant, WORD16 op2_mant,
67*15dc779aSAndroid Build Coastguard Worker WORD16 *ptr_result_mant,
68*15dc779aSAndroid Build Coastguard Worker ixheaacd_misc_tables *pstr_common_tables)
69*15dc779aSAndroid Build Coastguard Worker
70*15dc779aSAndroid Build Coastguard Worker {
71*15dc779aSAndroid Build Coastguard Worker WORD32 pre_shift_val, post_shift_val;
72*15dc779aSAndroid Build Coastguard Worker WORD32 index;
73*15dc779aSAndroid Build Coastguard Worker WORD16 one_by_op2_mant;
74*15dc779aSAndroid Build Coastguard Worker
75*15dc779aSAndroid Build Coastguard Worker pre_shift_val = ixheaac_norm32(op2_mant) - 16;
76*15dc779aSAndroid Build Coastguard Worker
77*15dc779aSAndroid Build Coastguard Worker index = (op2_mant << pre_shift_val) >> (SHORT_BITS - 3 - 8);
78*15dc779aSAndroid Build Coastguard Worker
79*15dc779aSAndroid Build Coastguard Worker index &= (1 << (8 + 1)) - 1;
80*15dc779aSAndroid Build Coastguard Worker
81*15dc779aSAndroid Build Coastguard Worker if (index == 0) {
82*15dc779aSAndroid Build Coastguard Worker post_shift_val = ixheaac_norm32(op1_mant) - 16;
83*15dc779aSAndroid Build Coastguard Worker
84*15dc779aSAndroid Build Coastguard Worker *ptr_result_mant = (op1_mant << post_shift_val);
85*15dc779aSAndroid Build Coastguard Worker } else {
86*15dc779aSAndroid Build Coastguard Worker WORD32 ratio_m;
87*15dc779aSAndroid Build Coastguard Worker
88*15dc779aSAndroid Build Coastguard Worker index = ((index - 1) >> 1);
89*15dc779aSAndroid Build Coastguard Worker
90*15dc779aSAndroid Build Coastguard Worker one_by_op2_mant = pstr_common_tables->inv_table[index];
91*15dc779aSAndroid Build Coastguard Worker
92*15dc779aSAndroid Build Coastguard Worker ratio_m = ixheaac_mult16x16in32(one_by_op2_mant, op1_mant);
93*15dc779aSAndroid Build Coastguard Worker
94*15dc779aSAndroid Build Coastguard Worker post_shift_val = ixheaac_norm32(ratio_m) - 1;
95*15dc779aSAndroid Build Coastguard Worker
96*15dc779aSAndroid Build Coastguard Worker *ptr_result_mant = (WORD16)((ratio_m << post_shift_val) >> 15);
97*15dc779aSAndroid Build Coastguard Worker }
98*15dc779aSAndroid Build Coastguard Worker return (pre_shift_val - post_shift_val);
99*15dc779aSAndroid Build Coastguard Worker }
100*15dc779aSAndroid Build Coastguard Worker
ixheaacd_fix_mant_exp_sqrt(WORD16 * ptr_in_out,WORD16 * sqrt_table)101*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_fix_mant_exp_sqrt(WORD16 *ptr_in_out, WORD16 *sqrt_table) {
102*15dc779aSAndroid Build Coastguard Worker WORD32 index;
103*15dc779aSAndroid Build Coastguard Worker WORD32 pre_shift_val;
104*15dc779aSAndroid Build Coastguard Worker WORD32 op_mant = *ptr_in_out;
105*15dc779aSAndroid Build Coastguard Worker WORD32 op_exp = *(ptr_in_out + 1);
106*15dc779aSAndroid Build Coastguard Worker WORD32 result_m;
107*15dc779aSAndroid Build Coastguard Worker WORD32 result_e;
108*15dc779aSAndroid Build Coastguard Worker
109*15dc779aSAndroid Build Coastguard Worker if (op_mant > 0) {
110*15dc779aSAndroid Build Coastguard Worker pre_shift_val = (ixheaac_norm32((WORD16)op_mant) - 16);
111*15dc779aSAndroid Build Coastguard Worker op_exp = (op_exp - pre_shift_val);
112*15dc779aSAndroid Build Coastguard Worker index = (op_mant << pre_shift_val) >> (SHORT_BITS - 3 - 8);
113*15dc779aSAndroid Build Coastguard Worker index &= (1 << (8 + 1)) - 1;
114*15dc779aSAndroid Build Coastguard Worker result_m = sqrt_table[index >> 1];
115*15dc779aSAndroid Build Coastguard Worker if ((op_exp & 1) != 0) {
116*15dc779aSAndroid Build Coastguard Worker result_m = (result_m * 0x5a82) >> 16;
117*15dc779aSAndroid Build Coastguard Worker op_exp += 3;
118*15dc779aSAndroid Build Coastguard Worker }
119*15dc779aSAndroid Build Coastguard Worker result_e = (op_exp >> 1);
120*15dc779aSAndroid Build Coastguard Worker
121*15dc779aSAndroid Build Coastguard Worker } else {
122*15dc779aSAndroid Build Coastguard Worker result_m = 0;
123*15dc779aSAndroid Build Coastguard Worker result_e = -SHORT_BITS;
124*15dc779aSAndroid Build Coastguard Worker }
125*15dc779aSAndroid Build Coastguard Worker
126*15dc779aSAndroid Build Coastguard Worker *ptr_in_out++ = (WORD16)result_m;
127*15dc779aSAndroid Build Coastguard Worker *ptr_in_out = (WORD16)result_e;
128*15dc779aSAndroid Build Coastguard Worker }
129*15dc779aSAndroid Build Coastguard Worker
ixheaacd_fix_div_dec(WORD32 op1,WORD32 op2)130*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_fix_div_dec(WORD32 op1, WORD32 op2) {
131*15dc779aSAndroid Build Coastguard Worker WORD32 quotient = 0;
132*15dc779aSAndroid Build Coastguard Worker UWORD32 abs_num, abs_den;
133*15dc779aSAndroid Build Coastguard Worker WORD32 k;
134*15dc779aSAndroid Build Coastguard Worker WORD32 sign;
135*15dc779aSAndroid Build Coastguard Worker
136*15dc779aSAndroid Build Coastguard Worker abs_num = ixheaac_abs32(op1 >> 1);
137*15dc779aSAndroid Build Coastguard Worker abs_den = ixheaac_abs32(op2 >> 1);
138*15dc779aSAndroid Build Coastguard Worker sign = op1 ^ op2;
139*15dc779aSAndroid Build Coastguard Worker
140*15dc779aSAndroid Build Coastguard Worker if (abs_num != 0) {
141*15dc779aSAndroid Build Coastguard Worker for (k = 15; k > 0; k--) {
142*15dc779aSAndroid Build Coastguard Worker quotient = (quotient << 1);
143*15dc779aSAndroid Build Coastguard Worker abs_num = (abs_num << 1);
144*15dc779aSAndroid Build Coastguard Worker if (abs_num >= abs_den) {
145*15dc779aSAndroid Build Coastguard Worker abs_num -= abs_den;
146*15dc779aSAndroid Build Coastguard Worker quotient++;
147*15dc779aSAndroid Build Coastguard Worker }
148*15dc779aSAndroid Build Coastguard Worker }
149*15dc779aSAndroid Build Coastguard Worker }
150*15dc779aSAndroid Build Coastguard Worker if (sign < 0) quotient = -(quotient);
151*15dc779aSAndroid Build Coastguard Worker
152*15dc779aSAndroid Build Coastguard Worker return quotient;
153*15dc779aSAndroid Build Coastguard Worker }
154*15dc779aSAndroid Build Coastguard Worker
155*15dc779aSAndroid Build Coastguard Worker #define ONE_IN_Q30 0x40000000
156*15dc779aSAndroid Build Coastguard Worker
ixheaacd_one_by_sqrt_calc(WORD32 op)157*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaacd_one_by_sqrt_calc(WORD32 op) {
158*15dc779aSAndroid Build Coastguard Worker WORD32 a = ixheaac_add32_sat(0x900ebee0,
159*15dc779aSAndroid Build Coastguard Worker ixheaac_mult32x16in32_shl_sat(op, 0x39d9));
160*15dc779aSAndroid Build Coastguard Worker WORD32 iy =
161*15dc779aSAndroid Build Coastguard Worker ixheaac_add32_sat(0x573b645a, ixheaac_mult32x16h_in32_shl_sat(op, a));
162*15dc779aSAndroid Build Coastguard Worker
163*15dc779aSAndroid Build Coastguard Worker iy = ixheaac_shl32_dir_sat_limit(iy, 1);
164*15dc779aSAndroid Build Coastguard Worker
165*15dc779aSAndroid Build Coastguard Worker a = ixheaac_mult32_shl_sat(op, iy);
166*15dc779aSAndroid Build Coastguard Worker a = ixheaac_sub32_sat(ONE_IN_Q30, ixheaac_shl32_dir_sat_limit(
167*15dc779aSAndroid Build Coastguard Worker ixheaac_mult32_shl_sat(a, iy), 1));
168*15dc779aSAndroid Build Coastguard Worker iy = ixheaac_add32_sat(iy, ixheaac_mult32_shl_sat(a, iy));
169*15dc779aSAndroid Build Coastguard Worker
170*15dc779aSAndroid Build Coastguard Worker a = ixheaac_mult32_shl_sat(op, iy);
171*15dc779aSAndroid Build Coastguard Worker a = ixheaac_sub32_sat(ONE_IN_Q30, ixheaac_shl32_dir_sat_limit(
172*15dc779aSAndroid Build Coastguard Worker ixheaac_mult32_shl_sat(a, iy), 1));
173*15dc779aSAndroid Build Coastguard Worker iy = ixheaac_add32_sat(iy, ixheaac_mult32_shl_sat(a, iy));
174*15dc779aSAndroid Build Coastguard Worker
175*15dc779aSAndroid Build Coastguard Worker a = ixheaac_mult32_shl_sat(op, iy);
176*15dc779aSAndroid Build Coastguard Worker a = ixheaac_sub32_sat(ONE_IN_Q30, ixheaac_shl32_dir_sat_limit(
177*15dc779aSAndroid Build Coastguard Worker ixheaac_mult32_shl_sat(a, iy), 1));
178*15dc779aSAndroid Build Coastguard Worker iy = ixheaac_add32_sat(iy, ixheaac_mult32_shl_sat(a, iy));
179*15dc779aSAndroid Build Coastguard Worker
180*15dc779aSAndroid Build Coastguard Worker return iy;
181*15dc779aSAndroid Build Coastguard Worker }
182*15dc779aSAndroid Build Coastguard Worker
ixheaacd_sqrt(WORD32 op)183*15dc779aSAndroid Build Coastguard Worker WORD32 ixheaacd_sqrt(WORD32 op) {
184*15dc779aSAndroid Build Coastguard Worker WORD32 result = 0;
185*15dc779aSAndroid Build Coastguard Worker WORD16 shift;
186*15dc779aSAndroid Build Coastguard Worker
187*15dc779aSAndroid Build Coastguard Worker if (op != 0) {
188*15dc779aSAndroid Build Coastguard Worker shift = (WORD16)(ixheaac_norm32(op) & ~1);
189*15dc779aSAndroid Build Coastguard Worker op = ixheaac_shl32_dir_sat_limit(op, shift);
190*15dc779aSAndroid Build Coastguard Worker shift = ixheaac_shr32_dir_sat_limit(shift, 1);
191*15dc779aSAndroid Build Coastguard Worker op = ixheaac_mult32_shl_sat(ixheaacd_one_by_sqrt_calc(op), op);
192*15dc779aSAndroid Build Coastguard Worker result = ixheaac_shr32_dir_sat_limit(op, ixheaac_sat16(shift - 1));
193*15dc779aSAndroid Build Coastguard Worker }
194*15dc779aSAndroid Build Coastguard Worker
195*15dc779aSAndroid Build Coastguard Worker return result;
196*15dc779aSAndroid Build Coastguard Worker }
197