Coverage Report

Created: 2026-09-01 06:32

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_hybrid.c
Line
Count
Source
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2023 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
21
#include <string.h>
22
23
#include "ixheaac_type_def.h"
24
#include "ixheaac_error_standards.h"
25
#include "ixheaace_error_codes.h"
26
#include "ixheaace_common_rom.h"
27
#include "ixheaace_sbr_def.h"
28
#include "ixheaace_resampler.h"
29
#include "ixheaace_sbr_rom.h"
30
#include "ixheaace_sbr_hybrid.h"
31
32
#include "ixheaace_aac_constants.h"
33
34
VOID ia_enhaacplus_enc_fft(complex *out, WORD32 N, ixheaace_common_tables *);
35
36
static VOID ixheaace_four_chan_filtering(const FLOAT32 *ptr_qmf_real, const FLOAT32 *ptr_qmf_imag,
37
                                         FLOAT32 **ptr_hyb_real, FLOAT32 **ptr_hyb_imag,
38
                                         WORD32 ch_offset, const FLOAT32 *ptr_p4_13,
39
78.8k
                                         ixheaace_common_tables *pstr_common_tab) {
40
78.8k
  WORD32 i, k, n;
41
78.8k
  WORD32 mid_tap = IXHEAACE_HYBRID_FILTER_DELAY;
42
43
78.8k
  FLOAT32 cum[8], *ptr_cum;
44
78.8k
  FLOAT32 tmp1, tmp2, tmp_p4;
45
78.8k
  FLOAT32 real, imag;
46
78.8k
  const FLOAT32 *ptr_re, *ptr_im;
47
78.8k
  FLOAT32 *ptr_hy_im, *ptr_hy_re;
48
78.8k
  ptr_re = &ptr_qmf_real[0];
49
78.8k
  ptr_im = &ptr_qmf_imag[0];
50
78.8k
  ptr_hy_re = &ptr_hyb_real[0][ch_offset];
51
78.8k
  ptr_hy_im = &ptr_hyb_imag[0][ch_offset];
52
53
2.60M
  for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) {
54
2.52M
    real = imag = 0;
55
12.6M
    for (k = 0; k < 16; k += 4) {
56
10.0M
      tmp_p4 = ptr_p4_13[k];
57
10.0M
      tmp1 = ptr_re[k];
58
10.0M
      tmp2 = ptr_im[k];
59
60
10.0M
      tmp1 = tmp_p4 * tmp1;
61
10.0M
      real = real - tmp1;
62
63
10.0M
      tmp1 = tmp_p4 * tmp2;
64
10.0M
      imag = imag + tmp1;
65
10.0M
    }
66
67
2.52M
    cum[3] = imag;
68
2.52M
    cum[2] = real;
69
2.52M
    real = imag = 0;
70
71
10.0M
    for (k = 3; k < 15; k += 4) {
72
7.56M
      tmp_p4 = ptr_p4_13[k];
73
7.56M
      tmp1 = ptr_re[k];
74
7.56M
      tmp2 = ptr_im[k];
75
7.56M
      tmp1 = tmp_p4 * tmp1;
76
7.56M
      real = real + tmp1;
77
7.56M
      tmp1 = tmp_p4 * tmp2;
78
7.56M
      imag = imag + tmp1;
79
7.56M
    }
80
81
2.52M
    tmp1 = imag + real;
82
2.52M
    cum[7] = tmp1 * IXHEAACE_COS_PI_BY_4;
83
2.52M
    tmp1 = imag - real;
84
2.52M
    cum[6] = tmp1 * IXHEAACE_COS_PI_BY_4;
85
86
2.52M
    cum[1] = ptr_p4_13[mid_tap] * ptr_re[mid_tap];
87
2.52M
    cum[0] = ptr_p4_13[mid_tap] * ptr_im[mid_tap];
88
89
2.52M
    real = imag = 0;
90
91
10.0M
    for (k = 1; k < 13; k += 4) {
92
7.56M
      tmp_p4 = ptr_p4_13[k];
93
7.56M
      tmp1 = ptr_re[k];
94
7.56M
      tmp2 = ptr_im[k];
95
7.56M
      tmp1 = tmp_p4 * tmp1;
96
7.56M
      real = real + tmp1;
97
7.56M
      tmp1 = tmp_p4 * tmp2;
98
7.56M
      imag = imag + tmp1;
99
7.56M
    }
100
101
2.52M
    tmp1 = real - imag;
102
2.52M
    cum[5] = tmp1 * IXHEAACE_COS_PI_BY_4;
103
2.52M
    tmp1 = real + imag;
104
2.52M
    cum[4] = tmp1 * IXHEAACE_COS_PI_BY_4;
105
106
2.52M
    ia_enhaacplus_enc_fft((complex *)cum, 4, pstr_common_tab);
107
108
2.52M
    ptr_cum = &cum[0];
109
110
12.6M
    for (n = 3; n >= 0; n--) {
111
10.0M
      tmp1 = *ptr_cum++;
112
10.0M
      tmp2 = *ptr_cum++;
113
10.0M
      *ptr_hy_im++ = tmp1;
114
10.0M
      *ptr_hy_re++ = tmp2;
115
10.0M
    }
116
2.52M
    ptr_re++;
117
2.52M
    ptr_im++;
118
2.52M
    ptr_hy_re += IXHEAACE_QMF_TIME_SLOTS - 4;
119
2.52M
    ptr_hy_im += IXHEAACE_QMF_TIME_SLOTS - 4;
120
2.52M
  }
121
78.8k
}
122
123
static VOID ixheaace_eight_chan_filtering(const FLOAT32 *ptr_qmf_real,
124
                                          const FLOAT32 *ptr_qmf_imag, FLOAT32 **ptr_hyb_real,
125
                                          FLOAT32 **ptr_hyb_imag, const FLOAT32 *ptr_p8_13,
126
                                          ixheaace_common_tables *pstr_common_tab)
127
128
39.4k
{
129
39.4k
  LOOPINDEX i, n;
130
39.4k
  LOOPINDEX mid_tap = IXHEAACE_HYBRID_FILTER_DELAY;
131
39.4k
  FLOAT32 real, imag;
132
39.4k
  FLOAT32 cum[16], *ptr_cum;
133
39.4k
  FLOAT32 tmp1, tmp2, tmp3;
134
39.4k
  const FLOAT32 *ptr_re, *ptr_im;
135
39.4k
  FLOAT32 *ptr_hy_re, *ptr_hy_im;
136
39.4k
  ptr_re = &ptr_qmf_real[0];
137
39.4k
  ptr_im = &ptr_qmf_imag[0];
138
39.4k
  ptr_hy_re = &ptr_hyb_real[0][0];
139
39.4k
  ptr_hy_im = &ptr_hyb_imag[0][0];
140
141
1.30M
  for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) {
142
1.26M
    tmp1 = ptr_p8_13[4] * ptr_re[4];
143
1.26M
    tmp2 = ptr_p8_13[12] * ptr_re[12];
144
145
1.26M
    tmp3 = ptr_im[4];
146
1.26M
    real = tmp1 + tmp2;
147
1.26M
    tmp2 = ptr_im[12];
148
1.26M
    tmp1 = ptr_p8_13[4] * tmp3;
149
1.26M
    tmp2 = ptr_p8_13[12] * tmp2;
150
1.26M
    imag = tmp1 + tmp2;
151
152
1.26M
    tmp1 = imag - real;
153
1.26M
    cum[5] = tmp1 * IXHEAACE_COS_PI_BY_4;
154
155
1.26M
    tmp1 = imag + real;
156
1.26M
    tmp3 = ptr_re[3];
157
1.26M
    cum[4] = -tmp1 * IXHEAACE_COS_PI_BY_4;
158
1.26M
    tmp2 = ptr_re[11];
159
1.26M
    tmp1 = ptr_p8_13[3] * tmp3;
160
1.26M
    tmp2 = ptr_p8_13[11] * tmp2;
161
1.26M
    tmp3 = ptr_im[3];
162
1.26M
    real = tmp1 + tmp2;
163
1.26M
    tmp2 = ptr_im[11];
164
1.26M
    tmp1 = ptr_p8_13[3] * tmp3;
165
1.26M
    tmp2 = ptr_p8_13[11] * tmp2;
166
1.26M
    imag = tmp1 + tmp2;
167
168
1.26M
    tmp1 = imag * IXHEAACE_COS_PI_BY_8;
169
1.26M
    tmp2 = real * IXHEAACE_SIN_PI_BY_8;
170
1.26M
    cum[13] = tmp1 - tmp2;
171
172
1.26M
    tmp1 = imag * IXHEAACE_SIN_PI_BY_8;
173
1.26M
    tmp2 = real * IXHEAACE_COS_PI_BY_8;
174
1.26M
    tmp3 = ptr_re[2];
175
1.26M
    cum[12] = -tmp1 - tmp2;
176
1.26M
    tmp2 = ptr_re[10];
177
1.26M
    tmp1 = ptr_p8_13[2] * tmp3;
178
1.26M
    tmp2 = ptr_p8_13[10] * tmp2;
179
1.26M
    tmp3 = ptr_im[2];
180
1.26M
    cum[2] = -tmp1 - tmp2;
181
1.26M
    tmp2 = ptr_im[10];
182
1.26M
    tmp1 = ptr_p8_13[2] * tmp3;
183
1.26M
    tmp2 = ptr_p8_13[10] * tmp2;
184
1.26M
    cum[3] = tmp1 + tmp2;
185
186
1.26M
    tmp1 = ptr_p8_13[1] * ptr_re[1];
187
1.26M
    tmp2 = ptr_p8_13[9] * ptr_re[9];
188
1.26M
    real = tmp1 + tmp2;
189
190
1.26M
    tmp1 = ptr_p8_13[1] * ptr_im[1];
191
1.26M
    tmp2 = ptr_p8_13[9] * ptr_im[9];
192
1.26M
    imag = tmp1 + tmp2;
193
194
1.26M
    tmp1 = imag * IXHEAACE_COS_PI_BY_8;
195
1.26M
    tmp2 = real * IXHEAACE_SIN_PI_BY_8;
196
1.26M
    cum[11] = tmp1 + tmp2;
197
198
1.26M
    tmp1 = imag * IXHEAACE_SIN_PI_BY_8;
199
1.26M
    tmp2 = real * IXHEAACE_COS_PI_BY_8;
200
1.26M
    cum[10] = tmp1 - tmp2;
201
202
1.26M
    tmp1 = ptr_p8_13[0] * ptr_re[0];
203
1.26M
    tmp2 = ptr_p8_13[8] * ptr_re[8];
204
1.26M
    real = tmp1 + tmp2;
205
206
1.26M
    tmp1 = ptr_p8_13[0] * ptr_im[0];
207
1.26M
    tmp2 = ptr_p8_13[8] * ptr_im[8];
208
1.26M
    imag = tmp1 + tmp2;
209
210
1.26M
    tmp1 = imag + real;
211
1.26M
    cum[7] = tmp1 * IXHEAACE_COS_PI_BY_4;
212
213
1.26M
    tmp1 = imag - real;
214
1.26M
    cum[6] = tmp1 * IXHEAACE_COS_PI_BY_4;
215
216
1.26M
    real = ptr_p8_13[7] * ptr_re[7];
217
1.26M
    imag = ptr_p8_13[7] * ptr_im[7];
218
219
1.26M
    tmp1 = imag * IXHEAACE_SIN_PI_BY_8;
220
1.26M
    tmp2 = real * IXHEAACE_COS_PI_BY_8;
221
1.26M
    cum[15] = tmp1 + tmp2;
222
223
1.26M
    tmp1 = imag * IXHEAACE_COS_PI_BY_8;
224
1.26M
    tmp2 = real * IXHEAACE_SIN_PI_BY_8;
225
1.26M
    cum[14] = tmp1 - tmp2;
226
227
1.26M
    cum[1] = ptr_p8_13[mid_tap] * ptr_re[mid_tap];
228
1.26M
    cum[0] = ptr_p8_13[mid_tap] * ptr_im[mid_tap];
229
230
1.26M
    real = ptr_p8_13[5] * ptr_re[5];
231
1.26M
    imag = ptr_p8_13[5] * ptr_im[5];
232
233
1.26M
    tmp1 = real * IXHEAACE_COS_PI_BY_8;
234
1.26M
    tmp2 = imag * IXHEAACE_SIN_PI_BY_8;
235
1.26M
    cum[9] = tmp1 - tmp2;
236
237
1.26M
    tmp1 = real * IXHEAACE_SIN_PI_BY_8;
238
1.26M
    tmp2 = imag * IXHEAACE_COS_PI_BY_8;
239
1.26M
    cum[8] = tmp1 + tmp2;
240
241
1.26M
    ia_enhaacplus_enc_fft((complex *)cum, 8, pstr_common_tab);
242
243
1.26M
    ptr_cum = &cum[0];
244
245
11.3M
    for (n = 7; n >= 0; n--) {
246
10.0M
      tmp1 = *ptr_cum++;
247
10.0M
      tmp2 = *ptr_cum++;
248
10.0M
      *ptr_hy_im++ = tmp1;
249
10.0M
      *ptr_hy_re++ = tmp2;
250
10.0M
    }
251
1.26M
    ptr_re++;
252
1.26M
    ptr_im++;
253
1.26M
    ptr_hy_re += IXHEAACE_QMF_TIME_SLOTS - 8;
254
1.26M
    ptr_hy_im += IXHEAACE_QMF_TIME_SLOTS - 8;
255
1.26M
  }
256
39.4k
}
257
258
IA_ERRORCODE ixheaace_hybrid_analysis(const FLOAT32 **ptr_qmf_real_in,
259
                                      const FLOAT32 **ptr_qmf_imag_in, FLOAT32 **ptr_hyb_real_in,
260
                                      FLOAT32 **ptr_hyb_imag_in, ixheaace_pstr_hybrid pstr_hybrid,
261
                                      ixheaace_str_ps_tab *pstr_ps_tab,
262
39.4k
                                      ixheaace_common_tables *pstr_common_tab) {
263
39.4k
  WORD32 band, i;
264
39.4k
  ixheaace_hybrid_res hybrid_res;
265
39.4k
  WORD32 ch_offset = 0;
266
267
39.4k
  FLOAT32 *ptr_re, *ptr_im;
268
39.4k
  const FLOAT32 *ptr_qmf_real, *ptr_qmf_imag;
269
39.4k
  FLOAT32 tmp1, tmp2;
270
271
157k
  for (band = 0; band < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; band++) {
272
118k
    hybrid_res = (ixheaace_hybrid_res)pstr_ps_tab->a_hyb_res[band];
273
274
118k
    memcpy(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_qmf_buf_real[band],
275
118k
           IXHEAACE_QMF_BUFFER_MOVE * sizeof(FLOAT32));
276
118k
    memcpy(pstr_hybrid->ptr_work_imag, pstr_hybrid->ptr_qmf_buf_imag[band],
277
118k
           IXHEAACE_QMF_BUFFER_MOVE * sizeof(FLOAT32));
278
118k
    ptr_re = &pstr_hybrid->ptr_work_real[IXHEAACE_QMF_BUFFER_MOVE];
279
118k
    ptr_im = &pstr_hybrid->ptr_work_imag[IXHEAACE_QMF_BUFFER_MOVE];
280
118k
    ptr_qmf_real = &ptr_qmf_real_in[0][band];
281
118k
    ptr_qmf_imag = &ptr_qmf_imag_in[0][band];
282
283
3.90M
    for (i = IXHEAACE_QMF_TIME_SLOTS - 1; i >= 0; i--) {
284
3.78M
      tmp1 = *ptr_qmf_real;
285
3.78M
      tmp2 = *ptr_qmf_imag;
286
287
3.78M
      ptr_qmf_real += IXHEAACE_QMF_CHANNELS;
288
3.78M
      ptr_qmf_imag += IXHEAACE_QMF_CHANNELS;
289
290
3.78M
      *ptr_im++ = tmp2;
291
3.78M
      *ptr_re++ = tmp1;
292
3.78M
    }
293
294
118k
    ptr_re = &pstr_hybrid->ptr_qmf_buf_real[band][0];
295
118k
    ptr_im = &pstr_hybrid->ptr_qmf_buf_imag[band][0];
296
297
118k
    ptr_qmf_real = &ptr_qmf_real_in[IXHEAACE_QMF_TIME_SLOTS - IXHEAACE_QMF_BUFFER_MOVE][band];
298
118k
    ptr_qmf_imag = &ptr_qmf_imag_in[IXHEAACE_QMF_TIME_SLOTS - IXHEAACE_QMF_BUFFER_MOVE][band];
299
300
1.53M
    for (i = 0; i < IXHEAACE_QMF_BUFFER_MOVE; i++) {
301
1.41M
      tmp1 = *ptr_qmf_real;
302
1.41M
      ptr_qmf_real += IXHEAACE_QMF_CHANNELS;
303
1.41M
      tmp2 = *ptr_qmf_imag;
304
1.41M
      ptr_qmf_imag += IXHEAACE_QMF_CHANNELS;
305
1.41M
      *ptr_re++ = tmp1;
306
1.41M
      *ptr_im++ = tmp2;
307
1.41M
    }
308
309
118k
    switch (hybrid_res) {
310
78.8k
      case IXHEAACE_HYBRID_4_CPLX:
311
78.8k
        ixheaace_four_chan_filtering(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_work_imag,
312
78.8k
                                     ptr_hyb_real_in, ptr_hyb_imag_in, ch_offset,
313
78.8k
                                     pstr_ps_tab->p4_13, pstr_common_tab);
314
78.8k
        break;
315
39.4k
      case IXHEAACE_HYBRID_8_CPLX:
316
39.4k
        ixheaace_eight_chan_filtering(pstr_hybrid->ptr_work_real, pstr_hybrid->ptr_work_imag,
317
39.4k
                                      ptr_hyb_real_in, ptr_hyb_imag_in, pstr_ps_tab->p8_13,
318
39.4k
                                      pstr_common_tab);
319
39.4k
        break;
320
0
      default:
321
0
        return IA_EXHEAACE_EXE_FATAL_PS_INVALID_HYBRID_RES_VAL;
322
0
        break;
323
118k
    }
324
118k
    ch_offset += hybrid_res;
325
118k
  }
326
39.4k
  return IA_NO_ERROR;
327
39.4k
}
328
329
VOID ixheaace_hybrid_synthesis(const FLOAT32 **ptr_hybrid_real_flt,
330
                               const FLOAT32 **ptr_hybrid_imag_flt, FLOAT32 **ptr_qmf_real_flt,
331
19.7k
                               FLOAT32 **ptr_qmf_imag_flt, const WORD32 *ptr_hyb_res) {
332
19.7k
  WORD32 k, n, band;
333
19.7k
  ixheaace_hybrid_res hybrid_res;
334
19.7k
  WORD32 ch_offset = 0;
335
336
19.7k
  FLOAT32 temp1, temp2;
337
19.7k
  FLOAT32 *ptr_qmf_real;
338
19.7k
  FLOAT32 *ptr_qmf_imag;
339
340
78.8k
  for (band = 0; band < IXHEAACE_NUM_QMF_BANDS_IN_HYBRID; band++) {
341
59.1k
    const FLOAT32 *ptr_hybrid_real = &ptr_hybrid_real_flt[0][ch_offset];
342
59.1k
    const FLOAT32 *ptr_hybrid_imag = &ptr_hybrid_imag_flt[0][ch_offset];
343
344
59.1k
    hybrid_res = (ixheaace_hybrid_res)ptr_hyb_res[band];
345
346
59.1k
    ptr_qmf_real = &ptr_qmf_real_flt[0][band];
347
59.1k
    ptr_qmf_imag = &ptr_qmf_imag_flt[0][band];
348
349
1.95M
    for (n = 0; n < IXHEAACE_QMF_TIME_SLOTS; n++) {
350
1.89M
      FLOAT32 temo_real = 0, temo_imag = 0;
351
352
11.9M
      for (k = hybrid_res - 1; k >= 0; k--) {
353
10.0M
        temp1 = *ptr_hybrid_real++;
354
10.0M
        temp2 = *ptr_hybrid_imag++;
355
10.0M
        temo_real += temp1;
356
10.0M
        temo_imag += temp2;
357
10.0M
      }
358
359
1.89M
      ptr_hybrid_real += IXHEAACE_QMF_TIME_SLOTS - hybrid_res;
360
1.89M
      ptr_hybrid_imag += IXHEAACE_QMF_TIME_SLOTS - hybrid_res;
361
362
1.89M
      *ptr_qmf_real = temo_real;
363
1.89M
      ptr_qmf_real += IXHEAACE_QMF_CHANNELS;
364
365
1.89M
      *ptr_qmf_imag = temo_imag;
366
1.89M
      ptr_qmf_imag += IXHEAACE_QMF_CHANNELS;
367
1.89M
    }
368
59.1k
    ch_offset += hybrid_res;
369
59.1k
  }
370
19.7k
}