Coverage Report

Created: 2026-02-07 06:17

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_acelp_mdct.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 <stdlib.h>
21
#include <math.h>
22
23
#include "ixheaac_type_def.h"
24
25
#include "ixheaacd_bitbuffer.h"
26
#include "ixheaacd_interface.h"
27
28
#include "ixheaacd_tns_usac.h"
29
#include "ixheaacd_cnst.h"
30
31
#include "ixheaacd_acelp_info.h"
32
33
#include "ixheaacd_td_mdct.h"
34
35
#include "ixheaacd_sbrdecsettings.h"
36
#include "ixheaacd_info.h"
37
#include "ixheaacd_sbr_common.h"
38
#include "ixheaacd_drc_data_struct.h"
39
#include "ixheaacd_drc_dec.h"
40
#include "ixheaacd_sbrdecoder.h"
41
#include "ixheaacd_mps_polyphase.h"
42
#include "ixheaac_sbr_const.h"
43
44
#include "ixheaacd_ec_defines.h"
45
#include "ixheaacd_ec_struct_def.h"
46
#include "ixheaacd_main.h"
47
#include "ixheaacd_arith_dec.h"
48
49
#include "ixheaacd_func_def.h"
50
#include "ixheaac_constants.h"
51
#include "ixheaac_basic_ops32.h"
52
#include "ixheaac_basic_ops40.h"
53
54
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_512[4][512];
55
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_384[4][384];
56
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_256[4][256];
57
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_192[4][192];
58
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_128[4][128];
59
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_96[4][96];
60
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_64[4][64];
61
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_48[4][48];
62
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_32[4][32];
63
extern const WORD32 ixheaacd_pre_post_twid_cos_sin_24[4][24];
64
65
static PLATFORM_INLINE WORD32 ixheaacd_mul_sub64_sat_32(WORD32 a, WORD32 b,
66
52.9M
                                                        WORD32 c, WORD32 d) {
67
52.9M
  WORD64 diff;
68
52.9M
  WORD64 temp_result1;
69
52.9M
  WORD64 temp_result2;
70
71
52.9M
  temp_result1 = (WORD64)a * (WORD64)c;
72
52.9M
  temp_result2 = (WORD64)b * (WORD64)d;
73
74
52.9M
  diff = (temp_result1 - temp_result2) >> 32;
75
76
52.9M
  if (diff >= 2147483647)
77
0
    diff = 2147483647;
78
52.9M
  else if (diff <= -2147483647 - 1)
79
0
    diff = -2147483647 - 1;
80
81
52.9M
  return ((WORD32)diff);
82
52.9M
}
83
84
static PLATFORM_INLINE WORD32 ixheaacd_mul_add64_sat_32(WORD32 a, WORD32 b,
85
52.9M
                                                        WORD32 c, WORD32 d) {
86
52.9M
  WORD64 sum;
87
52.9M
  WORD64 temp_result1;
88
52.9M
  WORD64 temp_result2;
89
90
52.9M
  temp_result1 = (WORD64)a * (WORD64)c;
91
52.9M
  temp_result2 = (WORD64)b * (WORD64)d;
92
93
52.9M
  sum = (temp_result1 + temp_result2) >> 32;
94
95
52.9M
  if (sum >= 2147483647)
96
0
    sum = 2147483647;
97
52.9M
  else if (sum <= -2147483647 - 1)
98
0
    sum = -2147483647 - 1;
99
100
52.9M
  return ((WORD32)sum);
101
52.9M
}
102
103
static void ixheaacd_pre_twid(WORD32 *in, WORD32 *r_ptr, WORD32 *i_ptr,
104
296k
                              WORD32 nlength, const WORD32 *ptr_pre_cos_sin) {
105
296k
  WORD32 i;
106
107
296k
  const WORD32 *cos_ptr = &ptr_pre_cos_sin[0];
108
296k
  const WORD32 *sin_ptr = &ptr_pre_cos_sin[nlength];
109
110
6.92M
  for (i = 0; i < nlength; i += 4) {
111
6.62M
    *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i], in[nlength + i], cos_ptr[i],
112
6.62M
                                         sin_ptr[i]);
113
6.62M
    *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i], in[nlength + i], sin_ptr[i],
114
6.62M
                                         cos_ptr[i]);
115
116
6.62M
    *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i + 1], in[nlength + i + 1],
117
6.62M
                                         cos_ptr[i + 1], sin_ptr[i + 1]);
118
6.62M
    *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i + 1], in[nlength + i + 1],
119
6.62M
                                         sin_ptr[i + 1], cos_ptr[i + 1]);
120
121
6.62M
    *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i + 2], in[nlength + i + 2],
122
6.62M
                                         cos_ptr[i + 2], sin_ptr[i + 2]);
123
6.62M
    *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i + 2], in[nlength + i + 2],
124
6.62M
                                         sin_ptr[i + 2], cos_ptr[i + 2]);
125
126
6.62M
    *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i + 3], in[nlength + i + 3],
127
6.62M
                                         cos_ptr[i + 3], sin_ptr[i + 3]);
128
6.62M
    *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i + 3], in[nlength + i + 3],
129
6.62M
                                         sin_ptr[i + 3], cos_ptr[i + 3]);
130
6.62M
  }
131
296k
}
132
133
static void ixheaacd_post_twid(WORD32 *data_re, WORD32 *data_im, WORD32 *out,
134
296k
                               WORD32 nlength, const WORD32 *ptr_post_cos_sin) {
135
296k
  WORD32 i;
136
137
296k
  const WORD32 *cos_ptr = &ptr_post_cos_sin[nlength * 2];
138
296k
  const WORD32 *sin_ptr = &ptr_post_cos_sin[nlength * 3];
139
140
296k
  WORD32 *out_ptr = &out[2 * nlength - 1];
141
6.92M
  for (i = 0; i < nlength; i += 4) {
142
6.62M
    out[0] = ixheaacd_mul_sub64_sat_32(data_re[i], data_im[i], cos_ptr[i],
143
6.62M
                                       sin_ptr[i]);
144
6.62M
    out_ptr[0] = -ixheaacd_mul_add64_sat_32(data_re[i], data_im[i], sin_ptr[i],
145
6.62M
                                            cos_ptr[i]);
146
147
6.62M
    out[2] = ixheaacd_mul_sub64_sat_32(data_re[i + 1], data_im[i + 1],
148
6.62M
                                       cos_ptr[i + 1], sin_ptr[i + 1]);
149
6.62M
    out_ptr[-2] = -ixheaacd_mul_add64_sat_32(data_re[i + 1], data_im[i + 1],
150
6.62M
                                             sin_ptr[i + 1], cos_ptr[i + 1]);
151
152
6.62M
    out[4] = ixheaacd_mul_sub64_sat_32(data_re[i + 2], data_im[i + 2],
153
6.62M
                                       cos_ptr[i + 2], sin_ptr[i + 2]);
154
6.62M
    out_ptr[-4] = -ixheaacd_mul_add64_sat_32(data_re[i + 2], data_im[i + 2],
155
6.62M
                                             sin_ptr[i + 2], cos_ptr[i + 2]);
156
157
6.62M
    out[6] = ixheaacd_mul_sub64_sat_32(data_re[i + 3], data_im[i + 3],
158
6.62M
                                       cos_ptr[i + 3], sin_ptr[i + 3]);
159
6.62M
    out_ptr[-6] = -ixheaacd_mul_add64_sat_32(data_re[i + 3], data_im[i + 3],
160
6.62M
                                             sin_ptr[i + 3], cos_ptr[i + 3]);
161
6.62M
    out += 8;
162
6.62M
    out_ptr -= 8;
163
6.62M
  }
164
296k
}
165
166
VOID ixheaacd_acelp_mdct(WORD32 *ptr_in, WORD32 *ptr_out, WORD32 *preshift, WORD32 length,
167
296k
                         WORD32 *ptr_scratch) {
168
296k
  WORD32 *ptr_data_r = ptr_scratch;
169
296k
  WORD32 *ptr_data_i = ptr_scratch + 512;
170
296k
  const WORD32 *ptr_pre_post_twid;
171
172
296k
  switch (length) {
173
218
    case 1024:
174
218
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_512[0][0];
175
218
      break;
176
142
    case 768:
177
142
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_384[0][0];
178
142
      break;
179
16.4k
    case 512:
180
16.4k
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_256[0][0];
181
16.4k
      break;
182
10.8k
    case 384:
183
10.8k
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_192[0][0];
184
10.8k
      break;
185
47.0k
    case 256:
186
47.0k
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_128[0][0];
187
47.0k
      break;
188
21.8k
    case 192:
189
21.8k
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_96[0][0];
190
21.8k
      break;
191
151k
    case 128:
192
151k
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_64[0][0];
193
151k
      break;
194
42.3k
    case 96:
195
42.3k
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_48[0][0];
196
42.3k
      break;
197
5.96k
    case 64:
198
5.96k
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_32[0][0];
199
5.96k
      break;
200
562
    case 48:
201
562
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_24[0][0];
202
562
      break;
203
0
    default:
204
0
      ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_24[0][0];
205
0
      break;
206
296k
  }
207
208
296k
  ixheaacd_pre_twid(ptr_in, ptr_data_r, ptr_data_i, length / 2,
209
296k
                    ptr_pre_post_twid);
210
211
296k
  ixheaacd_complex_fft(ptr_data_r, ptr_data_i, length / 2, -1, preshift);
212
296k
  *preshift += 1;
213
214
296k
  ixheaacd_post_twid(ptr_data_r, ptr_data_i, ptr_out, length / 2,
215
296k
                     ptr_pre_post_twid);
216
296k
  *preshift += 1;
217
296k
  return;
218
296k
}
219
220
VOID ixheaacd_acelp_mdct_main(ia_usac_data_struct *usac_data, WORD32 *in, WORD32 *out, WORD32 l,
221
96.5k
                              WORD32 m, WORD32 *preshift) {
222
96.5k
  WORD32 i;
223
96.5k
  WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
224
96.5k
  WORD32 *output_buffer = &usac_data->x_ac_dec[0];
225
226
96.5k
  ixheaacd_acelp_mdct(in, output_buffer, preshift, l + m, ptr_scratch);
227
228
3.36M
  for (i = 0; i < m / 2; i++) {
229
3.26M
    out[l + m / 2 - 1 - i] = -output_buffer[m / 2 + l / 2 + i];
230
3.26M
  }
231
11.4M
  for (i = 0; i < l / 2; i++) {
232
11.3M
    out[i] = output_buffer[m + l / 2 + i];
233
11.3M
    out[l - 1 - i] = -output_buffer[m + l / 2 + i];
234
11.3M
  }
235
3.36M
  for (i = 0; i < m / 2; i++) {
236
3.26M
    out[l + m / 2 + i] = -output_buffer[m / 2 + l / 2 - 1 - i];
237
3.26M
  }
238
11.4M
  for (i = 0; i < l / 2; i++) {
239
11.3M
    out[l + m + i] = -output_buffer[l / 2 - 1 - i];
240
11.3M
    out[2 * l + m - 1 - i] = -output_buffer[l / 2 - 1 - i];
241
11.3M
  }
242
96.5k
  return;
243
96.5k
}