Coverage Report

Created: 2025-08-03 06:57

/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
}