Coverage Report

Created: 2025-10-13 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_multichannel.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 <string.h>
21
22
#include "ixheaac_type_def.h"
23
#include "ixheaacd_sbr_common.h"
24
25
#include "ixheaac_constants.h"
26
#include "ixheaac_basic_ops32.h"
27
#include "ixheaac_basic_ops16.h"
28
#include "ixheaac_basic_ops40.h"
29
#include "ixheaac_basic_ops.h"
30
31
#include "ixheaacd_bitbuffer.h"
32
33
#include "ixheaacd_audioobjtypes.h"
34
#include "ixheaacd_sbrdecsettings.h"
35
#include "ixheaacd_memory_standards.h"
36
#include "ixheaacd_error_codes.h"
37
38
#include "ixheaacd_defines.h"
39
#include "ixheaacd_aac_rom.h"
40
#include "ixheaacd_pns.h"
41
42
#include "ixheaacd_pulsedata.h"
43
#include "ixheaacd_drc_data_struct.h"
44
45
#include "ixheaacd_lt_predict.h"
46
#include "ixheaacd_cnst.h"
47
#include "ixheaacd_ec_defines.h"
48
#include "ixheaacd_ec_struct_def.h"
49
#include "ixheaacd_channelinfo.h"
50
#include "ixheaacd_drc_dec.h"
51
52
#include "ixheaacd_sbrdecoder.h"
53
#include "ixheaacd_sbr_scale.h"
54
#include "ixheaacd_lpp_tran.h"
55
#include "ixheaacd_env_extr_part.h"
56
#include "ixheaacd_sbr_rom.h"
57
58
#include "ixheaacd_hybrid.h"
59
#include "ixheaacd_ps_dec.h"
60
#include "ixheaacd_ps_bitdec.h"
61
62
#include "ixheaacd_pulsedata.h"
63
64
#include "ixheaacd_pns.h"
65
66
#include "ixheaacd_env_extr.h"
67
#include "ixheaacd_common_rom.h"
68
#include "ixheaacd_block.h"
69
#include "ixheaacd_channel.h"
70
#include "ixheaacd_audioobjtypes.h"
71
#include "ixheaacd_latmdemux.h"
72
#include "ixheaacd_aacdec.h"
73
#include "ixheaacd_config.h"
74
#include "ixheaacd_hybrid.h"
75
#include "ixheaacd_ps_dec.h"
76
#include "ixheaacd_qmf_dec.h"
77
#include "ixheaacd_mps_polyphase.h"
78
#include "ixheaacd_mps_macro_def.h"
79
#include "ixheaacd_mps_struct_def.h"
80
#include "ixheaacd_mps_res_rom.h"
81
#include "ixheaacd_mps_aac_struct.h"
82
#include "ixheaacd_mps_dec.h"
83
#include "ixheaacd_mps_interface.h"
84
#include "ixheaacd_struct_def.h"
85
#include "ixheaacd_headerdecode.h"
86
87
#include "ixheaacd_multichannel.h"
88
#include "ixheaac_basic_op.h"
89
90
WORD cblock_decode_huff_symbol(UWORD8 *ptr_read_next, WORD32 bit_pos,
91
                               const UWORD16 *huff_ori, WORD16 *input,
92
                               WORD32 *readword)
93
94
0
{
95
0
  const UWORD16 *h;
96
0
  WORD tot_bits;
97
0
  {
98
0
    UWORD16 first_offset;
99
0
    WORD16 sign_ret_val;
100
0
    UWORD32 read_word1;
101
102
0
    read_word1 = *readword << bit_pos;
103
104
0
    h = (UWORD16 *)(huff_ori);
105
0
    first_offset = 7;
106
107
0
    h += (read_word1) >> (32 - first_offset);
108
0
    sign_ret_val = *h;
109
0
    tot_bits = 0;
110
111
0
    while (sign_ret_val > 0) {
112
0
      tot_bits += first_offset;
113
0
      bit_pos += first_offset;
114
115
0
      if ((bit_pos -= 8) >= 0) {
116
0
        *readword = (*readword << 8) | *ptr_read_next;
117
0
        ptr_read_next++;
118
0
      } else {
119
0
        bit_pos += 8;
120
0
      }
121
122
0
      read_word1 = (read_word1) << (first_offset);
123
124
0
      first_offset = (sign_ret_val >> 11);
125
0
      h += sign_ret_val & (0x07FF);
126
127
0
      h += (read_word1) >> (32 - first_offset);
128
0
      sign_ret_val = *h;
129
0
    }
130
131
0
    tot_bits += ((sign_ret_val & 0x7fff) >> 11);
132
0
    bit_pos += ((sign_ret_val & 0x7fff) >> 11);
133
0
    if ((bit_pos - 8) >= 0) {
134
0
      *readword = (*readword << 8) | *ptr_read_next;
135
0
    }
136
137
0
    *input = (sign_ret_val & (0x07FF)) - 60;
138
0
  }
139
140
0
  return tot_bits;
141
0
}
142
143
IA_ERRORCODE ixheaacd_dec_coupling_channel_element(
144
    ia_bit_buf_struct *it_bit_buf, ia_aac_decoder_struct *aac_handle,
145
    WORD32 samp_rate_idx, ia_aac_dec_tables_struct *ptr_aac_tables,
146
    ixheaacd_misc_tables *common_tables_ptr, WORD *element_index_order,
147
    ia_enhaacplus_dec_ind_cc *ind_channel_info, WORD32 total_channels,
148
    WORD32 frame_size, WORD32 audio_object_type,
149
970
    ia_eld_specific_config_struct eld_specific_config, WORD32 ele_type) {
150
970
  WORD32 element_instance_tag;
151
970
  LOOPIDX c;
152
153
970
  WORD ind_sw_cce_flag, num_coupled_elements;
154
155
970
  WORD num_gain_element_lists = 0;
156
970
  WORD gain_element_scale;
157
158
970
  const UWORD16 *hcod_sf =
159
970
      ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl;
160
970
  const UWORD32 *table_idx =
161
970
      ptr_aac_tables->pstr_huffmann_tables->huffman_code_book_scl_index;
162
970
  WORD16 index, length;
163
164
970
  IA_ERRORCODE error_status = IA_NO_ERROR;
165
166
970
  element_instance_tag = ixheaacd_read_bits_buf(it_bit_buf, 4);
167
970
  element_index_order[0] = element_instance_tag;
168
169
970
  ind_sw_cce_flag = ixheaacd_read_bits_buf(it_bit_buf, 1);
170
970
  num_coupled_elements = ixheaacd_read_bits_buf(it_bit_buf, 3);
171
172
10.5k
  for (c = 0; c < MAX_BS_ELEMENT; c++)
173
9.58k
    ind_channel_info->elements_coupled[c] = -1;
174
175
970
  ind_channel_info->num_coupled_elements = num_coupled_elements;
176
177
4.95k
  for (c = 0; c < (num_coupled_elements + 1); c++) {
178
3.98k
    num_gain_element_lists++;
179
180
3.98k
    ind_channel_info->cc_target_is_cpe[c] = ixheaacd_read_bits_buf(it_bit_buf, 1);
181
3.98k
    ind_channel_info->cc_target_tag_select[c] = ixheaacd_read_bits_buf(it_bit_buf, 4);
182
3.98k
    if (ind_channel_info->cc_target_is_cpe[c]) {
183
1.53k
      ind_channel_info->cc_l[c] = ixheaacd_read_bits_buf(it_bit_buf, 1);
184
1.53k
      ind_channel_info->cc_r[c] = ixheaacd_read_bits_buf(it_bit_buf, 1);
185
1.53k
      if (ind_channel_info->cc_l[c] && ind_channel_info->cc_r[c])
186
620
        num_gain_element_lists++;
187
1.53k
      ind_channel_info->elements_coupled[c] = 1;
188
1.53k
    } else
189
2.44k
      ind_channel_info->elements_coupled[c] = 0;
190
3.98k
  }
191
970
  if ((ind_sw_cce_flag == 0) && (num_gain_element_lists > MAX_BS_ELEMENT)) {
192
2
    return IA_FATAL_ERROR;
193
2
  }
194
968
  ixheaacd_read_bits_buf(it_bit_buf, 1);/*cc_domain*/
195
968
  ixheaacd_read_bits_buf(it_bit_buf, 1);/*gain_element_sign*/
196
968
  gain_element_scale = ixheaacd_read_bits_buf(it_bit_buf, 2);
197
198
968
  aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.num_swb_window = 0;
199
968
  aac_handle->pstr_aac_dec_ch_info[0]->str_ics_info.sampling_rate_index =
200
968
      samp_rate_idx;
201
202
968
  aac_handle->pstr_aac_dec_ch_info[0]->common_window = 0;
203
204
968
  error_status = ixheaacd_individual_ch_stream(
205
968
      it_bit_buf, aac_handle, 1, frame_size, total_channels, audio_object_type,
206
968
      eld_specific_config, ele_type);
207
208
968
  if (error_status) return error_status;
209
210
938
  ind_channel_info->cc_gain[0] = 1 << 29;
211
4.42k
  for (c = 1; c < num_gain_element_lists; c++) {
212
3.49k
    WORD cge;
213
3.49k
    WORD common_gain_element_present[MAX_BS_ELEMENT];
214
3.49k
    WORD16 norm_value;
215
216
3.49k
    if (ind_sw_cce_flag)
217
3.48k
      cge = 1;
218
9
    else {
219
9
      common_gain_element_present[c] = ixheaacd_read_bits_buf(it_bit_buf, 1);
220
9
      cge = common_gain_element_present[c];
221
9
      return IA_XHEAAC_DEC_EXE_FATAL_UNIMPLEMENTED_CCE;
222
9
    }
223
3.48k
    if (cge) {
224
3.48k
      UWORD8 *ptr_read_next = it_bit_buf->ptr_read_next;
225
3.48k
      WORD32 bit_pos = 7 - it_bit_buf->bit_pos;
226
3.48k
      WORD32 read_word =
227
3.48k
          ixheaacd_aac_showbits_32(it_bit_buf->ptr_read_next, it_bit_buf->cnt_bits, NULL);
228
3.48k
      UWORD32 read_word1;
229
230
3.48k
      read_word1 = read_word << bit_pos;
231
3.48k
      ixheaacd_huffman_decode(read_word1, &index, &length, hcod_sf, table_idx);
232
233
3.48k
      bit_pos += length;
234
235
3.48k
      ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word);
236
3.64k
      while (bit_pos > 8)
237
154
        ixheaacd_aac_read_byte(&ptr_read_next, &bit_pos, &read_word);
238
239
3.48k
      it_bit_buf->ptr_read_next = ptr_read_next;
240
3.48k
      it_bit_buf->bit_pos = 7 - bit_pos;
241
3.48k
      it_bit_buf->cnt_bits -= length;
242
243
3.48k
      norm_value = index - 60;
244
3.48k
      if (norm_value == -1)
245
68
        ind_channel_info->cc_gain[c] =
246
68
            common_tables_ptr->cc_gain_scale[gain_element_scale];
247
3.41k
      else {
248
3.41k
        int i;
249
3.41k
        ind_channel_info->cc_gain[c] =
250
3.41k
            common_tables_ptr->cc_gain_scale[gain_element_scale];
251
8.57k
        for (i = 0; i < (-norm_value) - 1; i++) {
252
5.15k
          ind_channel_info->cc_gain[c] = ixheaac_mul32_sh(
253
5.15k
              ind_channel_info->cc_gain[c],
254
5.15k
              common_tables_ptr->cc_gain_scale[gain_element_scale], 29);
255
5.15k
        }
256
3.41k
      }
257
3.48k
    } else {
258
0
      return IA_XHEAAC_DEC_EXE_FATAL_UNIMPLEMENTED_CCE;
259
0
    }
260
3.48k
  }
261
929
  if (it_bit_buf->cnt_bits < 0) {
262
18
    return IA_XHEAAC_DEC_EXE_NONFATAL_INSUFFICIENT_INPUT_BYTES;
263
18
  }
264
911
  return error_status;
265
929
}
266
267
void ixheaacd_dec_couple_channel(WORD32 *p_time_data, WORD32 *out_samp_cc,
268
                                 WORD16 frame_size, WORD total_channels,
269
                                 WORD16 gain_cc)
270
271
408
{
272
408
  WORD i;
273
408
  WORD32 out_cc;
274
408
  WORD32 *ptr_out_samp = &out_samp_cc[0];
275
360k
  for (i = frame_size - 1; i >= 0; i--) {
276
359k
    out_cc = (ixheaac_shl32_sat(
277
359k
        ixheaac_mult32x16in32(*ptr_out_samp++, gain_cc), 3));
278
359k
    *p_time_data = ixheaac_add32_sat(out_cc, *p_time_data);
279
359k
    p_time_data += total_channels;
280
359k
  }
281
408
}
282
283
IA_ERRORCODE ixheaacd_dec_ind_coupling(
284
    ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD32 *coup_ch_output,
285
    WORD16 frame_size, WORD total_channels, VOID *ptr_time_data_tmp)
286
287
295
{
288
295
  WORD c, j, k;
289
295
  WORD l;
290
295
  WORD32 *out_samp_cc, err = 0;
291
292
295
  ia_enhaacplus_dec_ind_cc *ind_channel_info;
293
294
295
  WORD32 *ptr_time_data = (WORD32 *)ptr_time_data_tmp;
295
296
295
  {
297
295
    ind_channel_info = &p_obj_exhaacplus_dec->p_state_aac->ind_cc_info;
298
299
295
    out_samp_cc = coup_ch_output;
300
301
295
    if (ind_channel_info->num_coupled_elements > 0 && coup_ch_output == NULL) {
302
22
      if (p_obj_exhaacplus_dec->p_state_aac->ec_enable) {
303
0
        ind_channel_info->num_coupled_elements = 0;
304
0
        p_obj_exhaacplus_dec->aac_config.frame_status = 0;
305
22
      } else {
306
22
        return IA_FATAL_ERROR;
307
22
      }
308
22
    }
309
310
273
    j = 0;
311
1.36k
    for (c = 0; c < ind_channel_info->num_coupled_elements + 1; c++) {
312
9.12k
      for (l = 0; l < MAX_BS_ELEMENT; l++) {
313
8.39k
        if (p_obj_exhaacplus_dec->aac_config.element_type[l] ==
314
8.39k
                ind_channel_info->elements_coupled[c] &&
315
1.72k
            p_obj_exhaacplus_dec->aac_config.element_instance_order[l] ==
316
1.72k
                ind_channel_info->cc_target_tag_select[c]) {
317
364
          break;
318
364
        }
319
8.39k
      }
320
1.09k
      if (l == MAX_BS_ELEMENT) {
321
726
        continue;
322
726
      }
323
324
364
      k = p_obj_exhaacplus_dec->aac_config.slot_element[l];
325
326
364
      if (ind_channel_info->cc_target_is_cpe[c] == 0) {
327
266
        WORD32 *p_time_data = &ptr_time_data[k];
328
329
266
        WORD16 gain_cc = ixheaac_round16(ind_channel_info->cc_gain[j]);
330
331
266
        ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
332
266
                                    total_channels, gain_cc);
333
266
      }
334
364
      if (ind_channel_info->cc_target_is_cpe[c] == 1) {
335
98
        if (ind_channel_info->cc_l[c] == 1) {
336
91
          WORD32 *p_time_data = &ptr_time_data[k];
337
338
91
          WORD16 gain_cc = ixheaac_round16(ind_channel_info->cc_gain[j]);
339
340
91
          ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
341
91
                                      total_channels, gain_cc);
342
91
        }
343
344
98
        k = p_obj_exhaacplus_dec->aac_config.slot_element[l];
345
346
98
        if (ind_channel_info->cc_r[c] == 1) {
347
51
          WORD32 *p_time_data = &ptr_time_data[k + 1];
348
51
          WORD16 gain_cc = ixheaac_round16(ind_channel_info->cc_gain[j + 1]);
349
350
51
          ixheaacd_dec_couple_channel(p_time_data, out_samp_cc, frame_size,
351
51
                                      total_channels, gain_cc);
352
51
        }
353
98
      }
354
364
      if (ind_channel_info->cc_target_is_cpe[c] == 1) {
355
98
        j += 2;
356
266
      } else {
357
266
        j += 1;
358
266
      }
359
364
    }
360
273
  }
361
0
  return err;
362
295
}
363
364
void ixheaacd_dec_downmix_to_stereo(
365
    ia_exhaacplus_dec_api_struct *p_obj_exhaacplus_dec, WORD16 frame_size,
366
0
    WORD total_elements, WORD16 *ptr_time_data, WORD total_channels) {
367
0
  LOOPIDX i, j;
368
0
  WORD k = 0;
369
0
  if (5 == total_channels) k = 0;
370
0
  if (6 == total_channels) k = 1;
371
0
  if (7 == total_channels) k = 2;
372
0
  if (8 == total_channels) k = 3;
373
374
0
  for (j = 0; j < frame_size; j++) {
375
0
    WORD16 temp_l = 0, temp_r = 0;
376
0
    for (i = 0; i < total_elements; i++) {
377
0
      if (0 == p_obj_exhaacplus_dec->aac_config.element_type[i] ||
378
0
          3 == p_obj_exhaacplus_dec->aac_config.element_type[i]) {
379
0
        temp_l += (WORD16)(
380
0
            ixheaac_mult32x16in32(
381
0
                p_obj_exhaacplus_dec->common_tables->down_mix_martix
382
0
                    [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
383
0
                ptr_time_data[j * total_channels +
384
0
                              p_obj_exhaacplus_dec->aac_config
385
0
                                  .slot_element[i]]) >>
386
0
            14);
387
388
0
        temp_r += (WORD16)(
389
0
            ixheaac_mult32x16in32(
390
0
                p_obj_exhaacplus_dec->common_tables->down_mix_martix
391
0
                    [k][1][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
392
0
                ptr_time_data[j * total_channels +
393
0
                              p_obj_exhaacplus_dec->aac_config
394
0
                                  .slot_element[i]]) >>
395
0
            14);
396
0
      }
397
0
      if (1 == p_obj_exhaacplus_dec->aac_config.element_type[i]) {
398
0
        temp_l += (WORD16)(
399
0
            ixheaac_mult32x16in32(
400
0
                p_obj_exhaacplus_dec->common_tables->down_mix_martix
401
0
                    [k][0][p_obj_exhaacplus_dec->aac_config.slot_element[i]],
402
0
                ptr_time_data[j * total_channels +
403
0
                              p_obj_exhaacplus_dec->aac_config
404
0
                                  .slot_element[i]]) >>
405
0
            14);
406
407
0
        temp_r += (WORD16)(
408
0
            ixheaac_mult32x16in32(
409
0
                p_obj_exhaacplus_dec->common_tables->down_mix_martix
410
0
                    [k][1]
411
0
                    [p_obj_exhaacplus_dec->aac_config.slot_element[i] + 1],
412
0
                ptr_time_data[j * total_channels +
413
0
                              p_obj_exhaacplus_dec->aac_config.slot_element[i] +
414
0
                              1]) >>
415
0
            14);
416
0
      }
417
0
    }
418
419
0
    ptr_time_data[2 * j] = temp_l;
420
0
    ptr_time_data[2 * j + 1] = temp_r;
421
0
  }
422
0
}