Coverage Report

Created: 2025-07-12 06:52

/src/libxaac/decoder/ixheaacd_hybrid.c
Line
Count
Source (jump to first uncovered line)
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 <string.h>
21
#include "ixheaacd_sbr_common.h"
22
#include "ixheaac_type_def.h"
23
24
#include "ixheaac_constants.h"
25
#include "ixheaac_basic_ops32.h"
26
#include "ixheaac_basic_ops16.h"
27
#include "ixheaac_basic_ops40.h"
28
#include "ixheaac_basic_ops.h"
29
30
#include "ixheaac_basic_op.h"
31
#include "ixheaacd_intrinsics.h"
32
#include "ixheaacd_common_rom.h"
33
#include "ixheaacd_basic_funcs.h"
34
35
#include "ixheaacd_bitbuffer.h"
36
#include "ixheaacd_sbrdecsettings.h"
37
#include "ixheaacd_sbr_scale.h"
38
#include "ixheaacd_lpp_tran.h"
39
#include "ixheaacd_env_extr_part.h"
40
#include "ixheaacd_sbr_rom.h"
41
#include "ixheaacd_hybrid.h"
42
43
#include "ixheaacd_ps_dec.h"
44
45
#include "ixheaacd_env_extr.h"
46
47
#include "ixheaacd_dsp_fft32x32s.h"
48
49
#include "ixheaacd_function_selector.h"
50
51
static VOID ixheaacd_filt_2_ch(const WORD32 *ptr_qmf, WORD32 *ptr_hybrid,
52
0
                               ia_sbr_tables_struct *ptr_sbr_tables) {
53
0
  WORD32 cum0, cum1, cum00, cum11;
54
0
  WORD16 *p2_6 = ptr_sbr_tables->ps_tables_ptr->p2_6;
55
56
0
  cum0 = ptr_qmf[HYBRID_FILTER_DELAY] >> 1;
57
0
  cum00 = ptr_qmf[HYBRID_FILTER_DELAY + 16] >> 1;
58
0
  cum1 = 0L;
59
0
  cum11 = 0L;
60
61
0
  {
62
0
    cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[1], *p2_6));
63
0
    cum11 =
64
0
        ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[17], *p2_6++));
65
66
0
    cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[3], *p2_6));
67
0
    cum11 =
68
0
        ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[19], *p2_6++));
69
70
0
    cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[5], *p2_6));
71
0
    cum11 =
72
0
        ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[21], *p2_6++));
73
74
0
    cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[7], *p2_6));
75
0
    cum11 =
76
0
        ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[23], *p2_6++));
77
78
0
    cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[9], *p2_6));
79
0
    cum11 =
80
0
        ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[25], *p2_6++));
81
82
0
    cum1 = ixheaac_add32_sat(cum1, ixheaac_mult32x16in32(ptr_qmf[11], *p2_6));
83
0
    cum11 =
84
0
        ixheaac_add32_sat(cum11, ixheaac_mult32x16in32(ptr_qmf[27], *p2_6++));
85
0
  }
86
0
  cum1 = ixheaac_shl32(cum1, 1);
87
0
  cum11 = ixheaac_shl32(cum11, 1);
88
89
0
  ptr_hybrid[0] = ixheaac_add32_sat(cum0, cum1);
90
0
  ptr_hybrid[1] = ixheaac_sub32_sat(cum0, cum1);
91
92
0
  ptr_hybrid[16] = ixheaac_add32_sat(cum00, cum11);
93
0
  ptr_hybrid[17] = ixheaac_sub32_sat(cum00, cum11);
94
0
}
95
96
static VOID ixheaacd_filt_8_ch(const WORD32 *ptr_qmf_real,
97
                               const WORD32 *ptr_qmf_imag, WORD32 *ptr_hyb_real,
98
                               WORD32 *ptr_hyb_imag,
99
0
                               ia_sbr_tables_struct *ptr_sbr_tables) {
100
0
  const WORD16 tcos = 0x7642;
101
0
  const WORD16 tsin = 0x30fc;
102
0
  const WORD16 tcom = 0x5a82;
103
0
  WORD32 real, imag;
104
0
  WORD32 cum[16];
105
0
  const WORD16 *p8_13 = ptr_sbr_tables->ps_tables_ptr->p8_13;
106
0
  const WORD16 *p8_13_8 = ptr_sbr_tables->ps_tables_ptr->p8_13 + 8;
107
108
0
  real = ixheaac_shl32(
109
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[0], *p8_13),
110
0
                         ixheaac_mult32x16in32(ptr_qmf_real[8], *p8_13_8)),
111
0
      1);
112
0
  imag = ixheaac_shl32(
113
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[0], *p8_13++),
114
0
                         ixheaac_mult32x16in32(ptr_qmf_imag[8], *p8_13_8++)),
115
0
      1);
116
117
0
  cum[12] = ixheaac_shl32(
118
0
      ixheaac_mult32x16in32(ixheaac_add32_sat(imag, real), tcom), 1);
119
0
  cum[13] = ixheaac_shl32(
120
0
      ixheaac_mult32x16in32(ixheaac_sub32_sat(imag, real), tcom), 1);
121
122
0
  real = ixheaac_shl32(
123
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[1], *p8_13),
124
0
                         ixheaac_mult32x16in32(ptr_qmf_real[9], *p8_13_8)),
125
0
      1);
126
0
  imag = ixheaac_shl32(
127
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[1], *p8_13++),
128
0
                         ixheaac_mult32x16in32(ptr_qmf_imag[9], *p8_13_8++)),
129
0
      1);
130
131
0
  cum[10] =
132
0
      ixheaac_shl32(ixheaac_add32_sat(ixheaac_mult32x16in32(imag, tcos),
133
0
                                        ixheaac_mult32x16in32(real, tsin)),
134
0
                     1);
135
0
  cum[11] =
136
0
      ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(imag, tsin),
137
0
                                        ixheaac_mult32x16in32(real, tcos)),
138
0
                     1);
139
0
  cum[9] = ixheaac_shl32(
140
0
      ixheaac_mult32x16in32(
141
0
          ixheaac_sub32_sat(ptr_qmf_real[2], ptr_qmf_real[10]), *p8_13_8++),
142
0
      1);
143
0
  cum[8] = ixheaac_shl32(
144
0
      ixheaac_mult32x16in32(
145
0
          ixheaac_sub32_sat(ptr_qmf_imag[2], ptr_qmf_imag[10]), *p8_13++),
146
0
      1);
147
148
0
  real = ixheaac_shl32(
149
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[3], *p8_13),
150
0
                         ixheaac_mult32x16in32(ptr_qmf_real[11], *p8_13_8)),
151
0
      1);
152
0
  imag = ixheaac_shl32(
153
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[3], *p8_13++),
154
0
                         ixheaac_mult32x16in32(ptr_qmf_imag[11], *p8_13_8++)),
155
0
      1);
156
157
0
  cum[6] =
158
0
      ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(imag, tcos),
159
0
                                        ixheaac_mult32x16in32(real, tsin)),
160
0
                     1);
161
0
  cum[7] = ixheaac_shl32(ixheaac_negate32_sat(ixheaac_add32_sat(
162
0
                              ixheaac_mult32x16in32(imag, tsin),
163
0
                              ixheaac_mult32x16in32(real, tcos))),
164
0
                          1);
165
166
0
  real = ixheaac_shl32(
167
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_real[4], *p8_13),
168
0
                         ixheaac_mult32x16in32(ptr_qmf_real[12], *p8_13_8)),
169
0
      1);
170
0
  imag = ixheaac_shl32(
171
0
      ixheaac_add32_sat(ixheaac_mult32x16in32(ptr_qmf_imag[4], *p8_13++),
172
0
                         ixheaac_mult32x16in32(ptr_qmf_imag[12], *p8_13_8++)),
173
0
      1);
174
175
0
  cum[4] = ixheaac_shl32(
176
0
      ixheaac_mult32x16in32(ixheaac_sub32_sat(imag, real), tcom), 1);
177
0
  cum[5] = ixheaac_shl32(
178
0
      ixheaac_mult32x16in32(
179
0
          ixheaac_negate32_sat(ixheaac_add32_sat(imag, real)), tcom),
180
0
      1);
181
182
0
  real = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_real[5], *p8_13), 1);
183
0
  imag = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_imag[5], *p8_13++), 1);
184
185
0
  cum[2] =
186
0
      ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(real, tcos),
187
0
                                        ixheaac_mult32x16in32(imag, tsin)),
188
0
                     1);
189
0
  cum[3] =
190
0
      ixheaac_shl32(ixheaac_add32_sat(ixheaac_mult32x16in32(real, tsin),
191
0
                                        ixheaac_mult32x16in32(imag, tcos)),
192
0
                     1);
193
194
0
  cum[0] = ixheaac_shl32(
195
0
      ixheaac_mult32x16in32(ptr_qmf_real[HYBRID_FILTER_DELAY], *p8_13), 1);
196
0
  cum[1] = ixheaac_shl32(
197
0
      ixheaac_mult32x16in32(ptr_qmf_imag[HYBRID_FILTER_DELAY], *p8_13++), 1);
198
199
0
  real = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_real[7], *p8_13), 1);
200
0
  imag = ixheaac_shl32(ixheaac_mult32x16in32(ptr_qmf_imag[7], *p8_13++), 1);
201
202
0
  cum[14] =
203
0
      ixheaac_shl32(ixheaac_add32_sat(ixheaac_mult32x16in32(imag, tsin),
204
0
                                        ixheaac_mult32x16in32(real, tcos)),
205
0
                     1);
206
0
  cum[15] =
207
0
      ixheaac_shl32(ixheaac_sub32_sat(ixheaac_mult32x16in32(imag, tcos),
208
0
                                        ixheaac_mult32x16in32(real, tsin)),
209
0
                     1);
210
211
0
  (*ixheaacd_inv_dit_fft_8pt)(cum, ptr_hyb_real, ptr_hyb_imag);
212
0
}
213
214
VOID ixheaacd_hybrid_analysis(const WORD32 *ptr_qmf_real, WORD32 *ptr_hyb_real,
215
                              WORD32 *ptr_hyb_imag,
216
                              ia_hybrid_struct *ptr_hybrid, WORD16 scale,
217
                              ia_sbr_tables_struct *ptr_sbr_tables)
218
219
0
{
220
0
  WORD band, j;
221
0
  WORD chn_offset = 0;
222
0
  WORD32 *ptr_re, *ptr_im;
223
0
  WORD32 *ptr_temp_real, *ptr_temp_imag;
224
225
0
  for (band = 0; band < NO_QMF_CHANNELS_IN_HYBRID; band++) {
226
0
    ptr_re = ptr_hybrid->ptr_qmf_buf_re[band];
227
0
    ptr_im = ptr_hybrid->ptr_qmf_buf_im[band];
228
229
0
    ptr_temp_real = &ptr_hybrid->ptr_work_re[0];
230
0
    ptr_temp_imag = &ptr_hybrid->ptr_work_im[0];
231
232
0
    *ptr_temp_real = *ptr_re;
233
0
    *ptr_temp_imag = *ptr_im;
234
235
0
    ptr_temp_real++;
236
0
    ptr_re++;
237
0
    ptr_temp_imag++;
238
0
    ptr_im++;
239
240
0
    for (j = ptr_hybrid->ptr_qmf_buf - 2; j >= 0; j--) {
241
0
      *ptr_temp_real++ = *ptr_re;
242
0
      *(ptr_re - 1) = *ptr_re;
243
0
      ptr_re++;
244
0
      *ptr_temp_imag++ = *ptr_im;
245
0
      *(ptr_im - 1) = *ptr_im;
246
0
      ptr_im++;
247
0
    }
248
249
0
    {
250
0
      WORD32 temp_re = ptr_qmf_real[band];
251
0
      WORD32 temp_im = ptr_qmf_real[band + 0x40];
252
253
0
      if (scale < 0) {
254
0
        temp_re = ixheaac_shl32(temp_re, -scale);
255
0
        temp_im = ixheaac_shl32(temp_im, -scale);
256
0
      } else {
257
0
        temp_re = ixheaac_shr32(temp_re, scale);
258
0
        temp_im = ixheaac_shr32(temp_im, scale);
259
0
      }
260
0
      *ptr_temp_real = temp_re;
261
0
      *--ptr_re = temp_re;
262
263
0
      *ptr_temp_imag = temp_im;
264
0
      *--ptr_im = temp_im;
265
0
    }
266
267
0
    switch (ptr_hybrid->ptr_resol[band]) {
268
0
      case NO_HYBRID_CHANNELS_LOW:
269
270
0
        ixheaacd_filt_2_ch(ptr_hybrid->ptr_work_re, &ptr_hyb_real[chn_offset],
271
0
                           ptr_sbr_tables);
272
273
0
        chn_offset += 2;
274
275
0
        break;
276
0
      case NO_HYBRID_CHANNELS_HIGH:
277
278
0
        ixheaacd_filt_8_ch(ptr_hybrid->ptr_work_re, ptr_hybrid->ptr_work_im,
279
0
                           &ptr_hyb_real[chn_offset], &ptr_hyb_imag[chn_offset],
280
0
                           ptr_sbr_tables);
281
282
0
        chn_offset += 6;
283
0
    }
284
0
  }
285
0
}