Coverage Report

Created: 2025-07-12 07:02

/src/libxaac/encoder/ixheaace_mps_bitstream.c
Line
Count
Source (jump to first uncovered line)
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 <stdlib.h>
22
#include <math.h>
23
#include "ixheaac_type_def.h"
24
#include "impd_drc_common_enc.h"
25
#include "impd_drc_uni_drc.h"
26
#include "impd_drc_tables.h"
27
#include "impd_drc_api.h"
28
#include "ixheaace_api.h"
29
#include "ixheaac_error_standards.h"
30
#include "ixheaace_error_codes.h"
31
#include "ixheaace_mps_common_fix.h"
32
#include "ixheaace_mps_defines.h"
33
#include "ixheaace_mps_common_define.h"
34
#include "ixheaace_bitbuffer.h"
35
36
#include "ixheaace_mps_nlc_enc.h"
37
#include "ixheaac_constants.h"
38
#include "ixheaace_aac_constants.h"
39
#include "ixheaace_common_rom.h"
40
41
#include "ixheaace_mps_struct_def.h"
42
#include "ixheaace_mps_sac_polyphase.h"
43
#include "ixheaace_mps_sac_nlc_enc.h"
44
#include "ixheaace_mps_sac_hybfilter.h"
45
#include "ixheaace_mps_bitstream.h"
46
#include "ixheaace_mps_spatial_bitstream.h"
47
#include "ixheaace_mps_param_extract.h"
48
#include "ixheaace_mps_tree.h"
49
#include "ixheaace_mps_rom.h"
50
51
35.4k
static UWORD8 ixheaace_mps_212_get_bs_freq_res_stride(const WORD32 index) {
52
35.4k
  WORD32 freq_res_stride_table_size = 0;
53
35.4k
  const UWORD8 *ptr_freq_res_stride_table = NULL;
54
55
35.4k
  ptr_freq_res_stride_table = freq_res_stride_table_212;
56
35.4k
  freq_res_stride_table_size =
57
35.4k
      sizeof(freq_res_stride_table_212) / sizeof(*freq_res_stride_table_212);
58
59
35.4k
  return (((index >= 0) && (index < freq_res_stride_table_size))
60
35.4k
              ? ptr_freq_res_stride_table[index]
61
35.4k
              : 1);
62
35.4k
}
63
64
static IA_ERRORCODE ixheaace_mps_212_get_bs_freq_res_index(const WORD32 num_bands,
65
                                                           WORD32 *const ptr_bs_freq_res_index,
66
1.66k
                                                           WORD32 aot) {
67
1.66k
  IA_ERRORCODE error = IA_NO_ERROR;
68
1.66k
  WORD32 idx;
69
1.66k
  const UWORD8 *p_freq_res_bin_table;
70
1.66k
  *ptr_bs_freq_res_index = -1;
71
72
1.66k
  if (aot == AOT_AAC_ELD) {
73
335
    p_freq_res_bin_table = freq_res_bin_table_ld;
74
1.32k
  } else {
75
1.32k
    p_freq_res_bin_table = freq_res_bin_table_usac;
76
1.32k
  }
77
3.65k
  for (idx = 0; idx < MAX_FREQ_RES_INDEX; idx++) {
78
3.65k
    if (num_bands == p_freq_res_bin_table[idx]) {
79
1.66k
      *ptr_bs_freq_res_index = idx;
80
1.66k
      break;
81
1.66k
    }
82
3.65k
  }
83
1.66k
  if (*ptr_bs_freq_res_index < 0 || *ptr_bs_freq_res_index >= MAX_FREQ_RES_INDEX) {
84
0
    return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
85
0
  }
86
1.66k
  return error;
87
1.66k
}
88
89
static VOID ixheaace_mps_212_get_sampling_frequency_index(
90
1.66k
    const UWORD32 bs_sampling_frequency, WORD32 *const ptr_bs_sampling_frequency_index) {
91
1.66k
  WORD32 idx;
92
1.66k
  *ptr_bs_sampling_frequency_index = SAMPLING_FREQUENCY_INDEX_ESCAPE;
93
94
7.88k
  for (idx = 0; idx < MAX_SAMPLING_FREQUENCY_INDEX; idx++) {
95
7.88k
    if (bs_sampling_frequency == ia_sampl_freq_table[idx]) {
96
1.66k
      *ptr_bs_sampling_frequency_index = idx;
97
1.66k
      break;
98
1.66k
    }
99
7.88k
  }
100
1.66k
}
101
102
static IA_ERRORCODE ixheaace_mps_212_ec_data(
103
    ixheaace_bit_buf_handle pstr_bit_buf, WORD8 data[MAX_NUM_PARAMS][MAX_NUM_BINS],
104
    WORD8 old_data[MAX_NUM_BINS], UWORD8 quant_coarse_xxx_prev[MAX_NUM_PARAMS],
105
    ixheaace_mps_lossless_data *const pstr_lossless_data, const WORD32 data_type,
106
    const WORD32 param_idx, const WORD32 num_param_sets, const WORD32 independency_flag,
107
189k
    const WORD32 start_band, const WORD32 stop_band, const WORD32 default_value) {
108
189k
  IA_ERRORCODE error;
109
189k
  WORD32 ps, pb, str_offset, pb_stride, i;
110
189k
  WORD16 data_bands;
111
189k
  WORD32 a_strides[MAX_NUM_BINS + 1] = {0};
112
189k
  WORD16 cmp_idx_data[2][MAX_NUM_BINS] = {{0}};
113
189k
  WORD16 cmp_old_data[MAX_NUM_BINS] = {0};
114
115
189k
  if (num_param_sets > MAX_NUM_PARAMS) {
116
0
    return IA_EXHEAACE_EXE_FATAL_MPS_INVALID_NUM_PARAM_SETS;
117
0
  }
118
119
189k
  if (independency_flag || (pstr_lossless_data->bs_quant_coarse_xxx[param_idx][0] !=
120
168k
                            quant_coarse_xxx_prev[param_idx])) {
121
20.5k
    pstr_lossless_data->bs_xxx_data_mode[param_idx][0] = IXHEAACE_MPS_DATA_MODE_FINECOARSE;
122
168k
  } else {
123
168k
    pstr_lossless_data->bs_xxx_data_mode[param_idx][0] = IXHEAACE_MPS_DATA_MODE_KEEP;
124
3.92M
    for (i = start_band; i < stop_band; i++) {
125
3.76M
      if (data[0][i] != old_data[i]) {
126
14.8k
        pstr_lossless_data->bs_xxx_data_mode[param_idx][0] = IXHEAACE_MPS_DATA_MODE_FINECOARSE;
127
14.8k
        break;
128
14.8k
      }
129
3.76M
    }
130
168k
  }
131
132
189k
  ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_xxx_data_mode[param_idx][0], 2);
133
134
189k
  for (ps = 1; ps < num_param_sets; ps++) {
135
0
    if (pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps] !=
136
0
        pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps - 1]) {
137
0
      pstr_lossless_data->bs_xxx_data_mode[param_idx][ps] = IXHEAACE_MPS_DATA_MODE_FINECOARSE;
138
0
    } else {
139
0
      pstr_lossless_data->bs_xxx_data_mode[param_idx][ps] = IXHEAACE_MPS_DATA_MODE_KEEP;
140
0
      for (i = start_band; i < stop_band; i++) {
141
0
        if (data[ps][i] != data[ps - 1][i]) {
142
0
          pstr_lossless_data->bs_xxx_data_mode[param_idx][ps] = IXHEAACE_MPS_DATA_MODE_FINECOARSE;
143
0
          break;
144
0
        }
145
0
      }
146
0
    }
147
148
0
    ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_xxx_data_mode[param_idx][ps], 2);
149
0
  }
150
151
189k
  for (ps = 0; ps < (num_param_sets - 1); ps++) {
152
0
    if (pstr_lossless_data->bs_xxx_data_mode[param_idx][ps] ==
153
0
        IXHEAACE_MPS_DATA_MODE_FINECOARSE) {
154
0
      if (pstr_lossless_data->bs_xxx_data_mode[param_idx][ps + 1] ==
155
0
          IXHEAACE_MPS_DATA_MODE_FINECOARSE) {
156
0
        if ((pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps + 1] ==
157
0
             pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps]) &&
158
0
            (pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][ps + 1] ==
159
0
             pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][ps])) {
160
0
          pstr_lossless_data->bs_data_pair[param_idx][ps] = 1;
161
0
          pstr_lossless_data->bs_data_pair[param_idx][ps + 1] = 1;
162
0
          ps++;
163
0
          continue;
164
0
        }
165
0
      }
166
167
0
      pstr_lossless_data->bs_data_pair[param_idx][ps] = 0;
168
169
0
      pstr_lossless_data->bs_data_pair[param_idx][ps + 1] = 0;
170
0
    } else {
171
0
      pstr_lossless_data->bs_data_pair[param_idx][ps] = 0;
172
0
      pstr_lossless_data->bs_data_pair[param_idx][ps + 1] = 0;
173
0
    }
174
0
  }
175
176
378k
  for (ps = 0; ps < num_param_sets; ps++) {
177
189k
    if (pstr_lossless_data->bs_xxx_data_mode[param_idx][ps] == IXHEAACE_MPS_DATA_MODE_DEFAULT) {
178
0
      for (i = start_band; i < stop_band; i++) {
179
0
        old_data[i] = (WORD8)default_value;
180
0
      }
181
0
      quant_coarse_xxx_prev[param_idx] = 0;
182
0
    }
183
184
189k
    if (pstr_lossless_data->bs_xxx_data_mode[param_idx][ps] ==
185
189k
        IXHEAACE_MPS_DATA_MODE_FINECOARSE) {
186
35.4k
      ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_data_pair[param_idx][ps], 1);
187
35.4k
      ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps],
188
35.4k
                          1);
189
35.4k
      ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][ps],
190
35.4k
                          2);
191
192
35.4k
      if (pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps] !=
193
35.4k
          quant_coarse_xxx_prev[param_idx]) {
194
0
        if (quant_coarse_xxx_prev[param_idx]) {
195
0
          for (i = start_band; i < stop_band; i++) {
196
0
            old_data[i] *= 2;
197
0
          }
198
199
0
          if (data_type == IXHEAACE_MPS_SAC_DATA_TYPE_CLD) {
200
0
            for (i = start_band; i < stop_band; i++) {
201
0
              if (old_data[i] == -14) {
202
0
                old_data[i] = -15;
203
0
              } else if (old_data[i] == 14) {
204
0
                old_data[i] = 15;
205
0
              }
206
0
            }
207
0
          }
208
0
        } else {
209
0
          for (i = start_band; i < stop_band; i++) {
210
0
            old_data[i] /= 2;
211
0
          }
212
0
        }
213
0
      }
214
215
35.4k
      pb_stride = ixheaace_mps_212_get_bs_freq_res_stride(
216
35.4k
          pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][ps]);
217
35.4k
      data_bands = (WORD16)((stop_band - start_band - 1) / pb_stride + 1);
218
219
35.4k
      a_strides[0] = start_band;
220
908k
      for (pb = 1; pb <= data_bands; pb++) {
221
873k
        a_strides[pb] = a_strides[pb - 1] + pb_stride;
222
873k
      }
223
224
35.4k
      str_offset = 0;
225
35.4k
      while (a_strides[data_bands] > stop_band) {
226
0
        if (str_offset < data_bands) {
227
0
          str_offset++;
228
0
        }
229
0
        for (i = str_offset; i <= data_bands; i++) {
230
0
          a_strides[i]--;
231
0
        }
232
0
      }
233
234
908k
      for (pb = 0; pb < data_bands; pb++) {
235
873k
        cmp_old_data[start_band + pb] = old_data[a_strides[pb]];
236
873k
        cmp_idx_data[0][start_band + pb] = data[ps][a_strides[pb]];
237
238
873k
        if (pstr_lossless_data->bs_data_pair[param_idx][ps]) {
239
0
          cmp_idx_data[1][start_band + pb] = data[ps + 1][a_strides[pb]];
240
0
        }
241
873k
      }
242
243
35.4k
      if (pstr_lossless_data->bs_data_pair[param_idx][ps]) {
244
0
        error = ixheaace_mps_212_ec_data_pair_enc(
245
0
            pstr_bit_buf, cmp_idx_data, cmp_old_data, data_type, 0, start_band, data_bands,
246
0
            pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps],
247
0
            independency_flag && (ps == 0));
248
0
        if (error != IA_NO_ERROR) {
249
0
          return error;
250
0
        }
251
35.4k
      } else {
252
35.4k
        error = ixheaace_mps_212_ec_data_single_enc(
253
35.4k
            pstr_bit_buf, cmp_idx_data, cmp_old_data, data_type, 0, start_band, data_bands,
254
35.4k
            pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps],
255
35.4k
            independency_flag && (ps == 0));
256
35.4k
        if (error != IA_NO_ERROR) {
257
0
          return error;
258
0
        }
259
35.4k
      }
260
908k
      for (i = start_band; i < stop_band; i++) {
261
873k
        if (pstr_lossless_data->bs_data_pair[param_idx][ps]) {
262
0
          old_data[i] = data[ps + 1][i];
263
873k
        } else {
264
873k
          old_data[i] = data[ps][i];
265
873k
        }
266
873k
      }
267
268
35.4k
      quant_coarse_xxx_prev[param_idx] = pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps];
269
270
35.4k
      if (pstr_lossless_data->bs_data_pair[param_idx][ps]) {
271
0
        ps++;
272
0
      }
273
35.4k
    }
274
189k
  }
275
189k
  return IA_NO_ERROR;
276
189k
}
277
278
static VOID ixheaace_mps_212_write_smg_data(ixheaace_bit_buf_handle pstr_bit_buf,
279
                                            const ixheaace_mps_smg_data *const pstr_smg_data,
280
                                            const WORD32 num_param_sets,
281
27.4k
                                            const WORD32 data_bands) {
282
27.4k
  WORD32 param, band;
283
284
54.8k
  for (param = 0; param < num_param_sets; param++) {
285
27.4k
    ixheaace_write_bits(pstr_bit_buf, pstr_smg_data->bs_smooth_mode[param], 2);
286
27.4k
    if (pstr_smg_data->bs_smooth_mode[param] >= 2) {
287
0
      ixheaace_write_bits(pstr_bit_buf, pstr_smg_data->bs_smooth_time[param], 2);
288
0
    }
289
27.4k
    if (pstr_smg_data->bs_smooth_mode[param] == 3) {
290
0
      WORD32 stride =
291
0
          ixheaace_mps_212_get_bs_freq_res_stride(pstr_smg_data->bs_freq_res_stride[param]);
292
0
      ixheaace_write_bits(pstr_bit_buf, pstr_smg_data->bs_freq_res_stride[param], 2);
293
0
      for (band = 0; band < data_bands; band += stride) {
294
0
        ixheaace_write_bits(pstr_bit_buf, pstr_smg_data->bs_smg_data[param][band], 1);
295
0
      }
296
0
    }
297
27.4k
  }
298
27.4k
}
299
300
static IA_ERRORCODE ixheaace_mps_212_write_ott_data(
301
    ixheaace_bit_buf_handle pstr_bit_buf, ixheaace_mps_prev_ott_data *const pstr_prev_ott_data,
302
    ixheaace_mps_ott_data *const pstr_ott_data,
303
    const ixheaace_mps_ott_config ott_config[IXHEAACE_MPS_MAX_NUM_BOXES],
304
    ixheaace_mps_lossless_data *const pstr_cld_lossless_data,
305
    ixheaace_mps_lossless_data *const pstr_icc_lossless_data, const WORD32 num_ott_boxes,
306
94.6k
    const WORD32 num_bands, const WORD32 num_param_sets, const WORD32 bs_independency_flag) {
307
94.6k
  IA_ERRORCODE error = IA_NO_ERROR;
308
94.6k
  WORD32 box;
309
189k
  for (box = 0; box < num_ott_boxes; box++) {
310
94.6k
    error = ixheaace_mps_212_ec_data(
311
94.6k
        pstr_bit_buf, pstr_ott_data->cld[box], pstr_prev_ott_data->cld_old[box],
312
94.6k
        pstr_prev_ott_data->quant_coarse_cld_prev[box], pstr_cld_lossless_data,
313
94.6k
        IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets, bs_independency_flag, 0,
314
94.6k
        ott_config[box].bs_ott_bands, 15);
315
94.6k
    if (error != IA_NO_ERROR) {
316
0
      return error;
317
0
    }
318
94.6k
  }
319
189k
  for (box = 0; box < num_ott_boxes; box++) {
320
94.6k
    error = ixheaace_mps_212_ec_data(pstr_bit_buf, pstr_ott_data->icc[box],
321
94.6k
                                     pstr_prev_ott_data->icc_old[box],
322
94.6k
                                     pstr_prev_ott_data->quant_coarse_icc_prev[box],
323
94.6k
                                     pstr_icc_lossless_data, IXHEAACE_MPS_SAC_DATA_TYPE_ICC, box,
324
94.6k
                                     num_param_sets, bs_independency_flag, 0, num_bands, 0);
325
94.6k
    if (error != IA_NO_ERROR) {
326
0
      return error;
327
0
    }
328
94.6k
  }
329
330
94.6k
  return IA_NO_ERROR;
331
94.6k
}
332
333
static VOID ixheaace_mps_212_write_framing_info(
334
    ixheaace_bit_buf_handle pstr_bit_buf,
335
27.4k
    const ixheaace_mps_framing_info *const pstr_framing_info, const WORD32 frame_length) {
336
27.4k
  ixheaace_write_bits(pstr_bit_buf, pstr_framing_info->bs_framing_type, 1);
337
27.4k
  ixheaace_write_bits(pstr_bit_buf, pstr_framing_info->num_param_sets - 1, 1);
338
339
27.4k
  if (pstr_framing_info->bs_framing_type) {
340
0
    WORD32 ps = 0;
341
0
    UWORD8 bits_param_slot = 0;
342
0
    WORD32 num_param_sets = pstr_framing_info->num_param_sets;
343
0
    while ((1 << bits_param_slot) < (frame_length + 1)) {
344
0
      bits_param_slot++;
345
0
    }
346
0
    if (bits_param_slot > 0) {
347
0
      for (ps = 0; ps < num_param_sets; ps++) {
348
0
        ixheaace_write_bits(pstr_bit_buf, pstr_framing_info->bs_param_slots[ps], bits_param_slot);
349
0
      }
350
0
    }
351
0
  }
352
27.4k
}
353
354
static IA_ERRORCODE ixheaace_mps_515_ec_data(ixheaace_bit_buf_handle pstr_bit_buf,
355
                                             WORD32 data[MAX_NUM_PARAMS][MAX_NUM_BINS],
356
                                             WORD32 old_data[MAX_NUM_BINS],
357
                                             ixheaace_mps_sac_lossless_data *pstr_lossless_data,
358
                                             WORD32 data_type, WORD32 param_idx,
359
                                             WORD32 num_param_sets, WORD32 independency_flag,
360
150k
                                             WORD32 start_band, WORD32 stop_band) {
361
150k
  WORD32 param_set, set_idx, pb_stride, data_bands, bin, data_sets;
362
150k
  WORD32 param_set_index[MAX_NUM_PARAMS] = {0};
363
364
300k
  for (param_set = 0; param_set < num_param_sets; param_set++) {
365
150k
    pstr_lossless_data->bs_xxx_data_mode[param_idx][param_set] =
366
150k
        IXHEAACE_MPS_DATA_MODE_FINECOARSE;
367
150k
    ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_xxx_data_mode[param_idx][param_set],
368
150k
                        2);
369
150k
  }
370
371
300k
  for (param_set = 0, set_idx = 0; param_set < num_param_sets; param_set++) {
372
150k
    param_set_index[set_idx] = param_set;
373
150k
    if (param_set != num_param_sets - 1) {
374
0
      pstr_lossless_data->bs_data_pair[param_idx][set_idx] = 1;
375
0
      pstr_lossless_data->bs_data_pair[param_idx][set_idx + 1] = 1;
376
0
      param_set++;
377
0
      set_idx += 2;
378
150k
    } else {
379
150k
      pstr_lossless_data->bs_data_pair[param_idx][set_idx] = 0;
380
150k
      set_idx++;
381
150k
    }
382
150k
  }
383
150k
  data_sets = set_idx;
384
385
300k
  for (set_idx = 0; set_idx < data_sets;) {
386
150k
    ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_data_pair[param_idx][set_idx], 1);
387
150k
    ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_quant_coarse_xxx[param_idx][set_idx],
388
150k
                        1);
389
150k
    ixheaace_write_bits(pstr_bit_buf,
390
150k
                        pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][set_idx], 2);
391
392
150k
    pb_stride =
393
150k
        freq_res_stride_table[pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][set_idx]];
394
150k
    data_bands = (stop_band - start_band - 1) / pb_stride + 1;
395
396
150k
    ixheaace_mps_515_ec_data_pair_enc(
397
150k
        pstr_bit_buf, data, old_data, data_type, param_set_index[set_idx], start_band, data_bands,
398
150k
        pstr_lossless_data->bs_data_pair[param_idx][set_idx],
399
150k
        pstr_lossless_data->bs_quant_coarse_xxx[param_idx][set_idx], independency_flag);
400
401
150k
    if (pstr_lossless_data->bs_data_pair[param_idx][set_idx]) {
402
0
      if (pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][set_idx + 1] !=
403
0
          pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][set_idx]) {
404
0
        return IA_EXHEAACE_EXE_FATAL_MPS_INVALID_RES_STRIDE;
405
0
      }
406
0
      if (pstr_lossless_data->bs_quant_coarse_xxx[param_idx][set_idx + 1] !=
407
0
          pstr_lossless_data->bs_quant_coarse_xxx[param_idx][set_idx]) {
408
0
        return IA_EXHEAACE_EXE_FATAL_MPS_INVALID_QUANT_COARSE;
409
0
      }
410
0
    }
411
412
8.56M
    for (bin = 0; bin < MAX_NUM_BINS; bin++) {
413
8.41M
      old_data[bin] = data[param_set_index[set_idx] +
414
8.41M
                           pstr_lossless_data->bs_data_pair[param_idx][set_idx]][bin];
415
8.41M
    }
416
417
150k
    set_idx += pstr_lossless_data->bs_data_pair[param_idx][set_idx] + 1;
418
150k
  }
419
150k
  return IA_NO_ERROR;
420
150k
}
421
422
1.50M
WORD32 ixheaace_mps_515_icc_quant(FLOAT32 val) {
423
1.50M
  FLOAT32 p_qsteps[7] = {0.9685f, 0.88909f, 0.72105f, 0.48428f, 0.18382f, -0.2945f, -0.7895f};
424
1.50M
  WORD32 i;
425
426
1.50M
  if (val >= p_qsteps[0]) {
427
741k
    return 0;
428
741k
  }
429
3.63M
  for (i = 1; i < 6; i++) {
430
3.57M
    if ((val >= p_qsteps[i]) && (val <= p_qsteps[i - 1])) {
431
701k
      return i;
432
701k
    }
433
3.57M
  }
434
58.2k
  return 7;
435
759k
}
436
437
1.87M
WORD32 ixheaace_mps_515_cld_quant(FLOAT32 val) {
438
1.87M
  FLOAT32 p_qsteps[30] = {-47.5, -42.5, -37.5, -32.5, -27.5, -23.5, -20.5, -17.5, -14.5, -11.5,
439
1.87M
                          -9.0,  -7.0,  -5.0,  -3.0,  -1.0,  1.0,   3.0,   5.0,   7.0,   9.0,
440
1.87M
                          11.5,  14.5,  17.5,  20.5,  23.5,  27.5,  32.5,  37.5,  42.5,  47.5};
441
442
1.87M
  WORD32 i;
443
444
1.87M
  if (val < p_qsteps[0]) {
445
652k
    return 0 - 15;
446
652k
  }
447
21.3M
  for (i = 1; i < 30; i++) {
448
21.3M
    if ((val <= p_qsteps[i]) && (val >= p_qsteps[i - 1])) {
449
1.21M
      return i - 15;
450
1.21M
    }
451
21.3M
  }
452
15.4k
  return 30 - 15;
453
1.22M
}
454
455
VOID ixheaace_mps_515_ttt_box(WORD32 slots, FLOAT32 *ptr_real1, FLOAT32 *ptr_imag1,
456
                              FLOAT32 *ptr_real2, FLOAT32 *ptr_imag2, FLOAT32 *ptr_real3,
457
9.40k
                              FLOAT32 *ptr_imag3, WORD32 *ptr_qclds1, WORD32 *ptr_qclds2) {
458
9.40k
  WORD32 i, j;
459
460
9.40k
  FLOAT32 cld_s1[PARAMETER_BANDS] = {0};
461
9.40k
  FLOAT32 cld_s2[PARAMETER_BANDS] = {0};
462
9.40k
  FLOAT32 p_pow1[MAX_HYBRID_BANDS] = {0};
463
9.40k
  FLOAT32 p_pow2[MAX_HYBRID_BANDS] = {0};
464
9.40k
  FLOAT32 p_pow3[MAX_HYBRID_BANDS] = {0};
465
466
9.40k
  FLOAT32 p_pow_par_band1[PARAMETER_BANDS] = {0};
467
9.40k
  FLOAT32 p_pow_par_band2[PARAMETER_BANDS] = {0};
468
9.40k
  FLOAT32 p_pow_par_band3[PARAMETER_BANDS] = {0};
469
470
156k
  for (i = 0; i < slots; i++) {
471
10.5M
    for (j = 0; j < MAX_HYBRID_BANDS; j++) {
472
10.4M
      p_pow1[j] += ptr_real1[i * MAX_HYBRID_BANDS + j] * ptr_real1[i * MAX_HYBRID_BANDS + j] +
473
10.4M
                   ptr_imag1[i * MAX_HYBRID_BANDS + j] * ptr_imag1[i * MAX_HYBRID_BANDS + j];
474
10.4M
      p_pow2[j] += ptr_real2[i * MAX_HYBRID_BANDS + j] * ptr_real2[i * MAX_HYBRID_BANDS + j] +
475
10.4M
                   ptr_imag2[i * MAX_HYBRID_BANDS + j] * ptr_imag2[i * MAX_HYBRID_BANDS + j];
476
10.4M
      p_pow3[j] += ptr_real3[i * MAX_HYBRID_BANDS + j] * ptr_real3[i * MAX_HYBRID_BANDS + j] +
477
10.4M
                   ptr_imag3[i * MAX_HYBRID_BANDS + j] * ptr_imag3[i * MAX_HYBRID_BANDS + j];
478
479
10.4M
      ptr_real1[i * MAX_HYBRID_BANDS + j] =
480
10.4M
          (ptr_real1[i * MAX_HYBRID_BANDS + j] + ptr_real3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
481
10.4M
      ptr_imag1[i * MAX_HYBRID_BANDS + j] =
482
10.4M
          (ptr_imag1[i * MAX_HYBRID_BANDS + j] + ptr_imag3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
483
484
10.4M
      ptr_real2[i * MAX_HYBRID_BANDS + j] =
485
10.4M
          (ptr_real2[i * MAX_HYBRID_BANDS + j] + ptr_real3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
486
10.4M
      ptr_imag2[i * MAX_HYBRID_BANDS + j] =
487
10.4M
          (ptr_imag2[i * MAX_HYBRID_BANDS + j] + ptr_imag3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
488
10.4M
    }
489
147k
  }
490
677k
  for (i = 0; i < MAX_HYBRID_BANDS; i++) {
491
668k
    p_pow_par_band1[kernels_20[i]] += p_pow1[i];
492
668k
    p_pow_par_band2[kernels_20[i]] += p_pow2[i];
493
668k
    p_pow_par_band3[kernels_20[i]] += p_pow3[i];
494
668k
  }
495
197k
  for (i = 0; i < PARAMETER_BANDS; i++) {
496
188k
    if (p_pow_par_band3[i]) {
497
138k
      cld_s1[i] = ((p_pow_par_band1[i] + p_pow_par_band2[i]) / (p_pow_par_band3[i]));
498
138k
      cld_s1[i] = (FLOAT32)(10.0 * log(cld_s1[i] + 1e-10) / log(10.0));
499
138k
    } else if ((p_pow_par_band1[i] + p_pow_par_band2[i]))
500
2.40k
      cld_s1[i] = 50.0;
501
47.4k
    else
502
47.4k
      cld_s1[i] = -50;
503
188k
    ptr_qclds1[i] = ixheaace_mps_515_cld_quant(cld_s1[i]);
504
505
188k
    if (p_pow_par_band2[i]) {
506
138k
      cld_s2[i] = (p_pow_par_band1[i] / (p_pow_par_band2[i]));
507
138k
      cld_s2[i] = (FLOAT32)(10 * log(cld_s2[i] + 1e-10f) / log(10.0));
508
138k
    } else if (p_pow_par_band1[i])
509
1.41k
      cld_s2[i] = 50.0;
510
48.0k
    else
511
48.0k
      cld_s2[i] = -50;
512
188k
    ptr_qclds2[i] = ixheaace_mps_515_cld_quant(cld_s2[i]);
513
188k
  }
514
9.40k
}
515
516
VOID ixheaace_mps_515_ott_box(WORD32 slots, FLOAT32 *ptr_real1, FLOAT32 *ptr_imag1,
517
                              FLOAT32 *ptr_real2, FLOAT32 *ptr_imag2, WORD32 *ptr_p_qclds,
518
75.0k
                              WORD32 *ptr_qiccs) {
519
75.0k
  WORD32 i, j;
520
521
75.0k
  FLOAT32 clds[PARAMETER_BANDS] = {0};
522
75.0k
  FLOAT32 iccs[PARAMETER_BANDS] = {0};
523
75.0k
  FLOAT32 p_pow1[MAX_HYBRID_BANDS] = {0};
524
75.0k
  FLOAT32 p_pow2[MAX_HYBRID_BANDS] = {0};
525
75.0k
  FLOAT32 p_xcor_real[MAX_HYBRID_BANDS] = {0};
526
527
75.0k
  FLOAT32 p_pow_par_band1[PARAMETER_BANDS] = {0};
528
75.0k
  FLOAT32 p_pow_par_band2[PARAMETER_BANDS] = {0};
529
75.0k
  FLOAT32 p_xcor_par_band[PARAMETER_BANDS] = {0};
530
531
1.23M
  for (i = 0; i < slots; i++) {
532
83.4M
    for (j = 0; j < MAX_HYBRID_BANDS; j++) {
533
82.2M
      p_pow1[j] += ptr_real1[i * MAX_HYBRID_BANDS + j] * ptr_real1[i * MAX_HYBRID_BANDS + j] +
534
82.2M
                   ptr_imag1[i * MAX_HYBRID_BANDS + j] * ptr_imag1[i * MAX_HYBRID_BANDS + j];
535
82.2M
      p_pow2[j] += ptr_real2[i * MAX_HYBRID_BANDS + j] * ptr_real2[i * MAX_HYBRID_BANDS + j] +
536
82.2M
                   ptr_imag2[i * MAX_HYBRID_BANDS + j] * ptr_imag2[i * MAX_HYBRID_BANDS + j];
537
82.2M
      p_xcor_real[j] +=
538
82.2M
          ptr_real1[i * MAX_HYBRID_BANDS + j] * ptr_real2[i * MAX_HYBRID_BANDS + j] +
539
82.2M
          ptr_imag1[i * MAX_HYBRID_BANDS + j] * ptr_imag2[i * MAX_HYBRID_BANDS + j];
540
541
82.2M
      ptr_real1[i * MAX_HYBRID_BANDS + j] =
542
82.2M
          (ptr_real1[i * MAX_HYBRID_BANDS + j] + ptr_real2[i * MAX_HYBRID_BANDS + j]);
543
82.2M
      ptr_imag1[i * MAX_HYBRID_BANDS + j] =
544
82.2M
          (ptr_imag1[i * MAX_HYBRID_BANDS + j] + ptr_imag2[i * MAX_HYBRID_BANDS + j]);
545
82.2M
    }
546
1.15M
  }
547
5.40M
  for (i = 0; i < MAX_HYBRID_BANDS; i++) {
548
5.33M
    p_pow_par_band1[kernels_20[i]] += p_pow1[i];
549
5.33M
    p_pow_par_band2[kernels_20[i]] += p_pow2[i];
550
5.33M
    p_xcor_par_band[kernels_20[i]] += p_xcor_real[i];
551
5.33M
  }
552
1.57M
  for (i = 0; i < PARAMETER_BANDS; i++) {
553
1.50M
    if (p_pow_par_band2[i]) {
554
948k
      clds[i] = (p_pow_par_band1[i] / (p_pow_par_band2[i]));
555
948k
      clds[i] = (FLOAT32)(10 * log(clds[i] + 1e-10) / log(10.0));
556
948k
    } else if (p_pow_par_band1[i])
557
5.98k
      clds[i] = 50.0;
558
547k
    else
559
547k
      clds[i] = -50;  // 0.0;
560
1.50M
    iccs[i] =
561
1.50M
        p_xcor_par_band[i] / (FLOAT32)sqrt((p_pow_par_band1[i] * p_pow_par_band2[i] + 1e-10));
562
563
1.50M
    ptr_p_qclds[i] = ixheaace_mps_515_cld_quant(clds[i]);
564
1.50M
    ptr_qiccs[i] = ixheaace_mps_515_icc_quant(iccs[i]);
565
1.50M
  }
566
75.0k
}
567
568
IA_ERRORCODE ixheaace_mps_212_write_spatial_specific_config(
569
    ixheaace_mps_spatial_specific_config *const pstr_spatial_specific_config,
570
    UWORD8 *const ptr_output_buffer, const WORD32 output_buffer_size,
571
1.66k
    WORD32 *const ptr_output_bits, WORD32 aot) {
572
1.66k
  IA_ERRORCODE error = IA_NO_ERROR;
573
1.66k
  WORD32 bs_sampling_frequency_index = 0;
574
1.66k
  WORD32 bs_freq_res = 0;
575
1.66k
  ixheaace_bit_buf bit_buf;
576
1.66k
  ixheaace_bit_buf_handle pstr_bit_buf =
577
1.66k
      ia_enhaacplus_enc_create_bitbuffer(&bit_buf, ptr_output_buffer, output_buffer_size);
578
579
1.66k
  error = ixheaace_mps_212_get_bs_freq_res_index(pstr_spatial_specific_config->num_bands,
580
1.66k
                                                 &bs_freq_res, aot);
581
1.66k
  if (error) {
582
0
    return error;
583
0
  }
584
585
1.66k
  if (aot == AOT_AAC_ELD) {
586
335
    ixheaace_mps_212_get_sampling_frequency_index(
587
335
        pstr_spatial_specific_config->bs_sampling_frequency, &bs_sampling_frequency_index);
588
335
    ixheaace_write_bits(pstr_bit_buf, bs_sampling_frequency_index, 4);
589
590
335
    if (bs_sampling_frequency_index == 15) {
591
0
      ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_sampling_frequency, 24);
592
0
    }
593
594
335
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_frame_length, 5);
595
596
335
    ixheaace_write_bits(pstr_bit_buf, bs_freq_res, 3);
597
335
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_tree_config, 4);
598
335
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_quant_mode, 2);
599
600
335
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
601
602
335
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_fixed_gain_dmx, 3);
603
604
335
    ixheaace_write_bits(pstr_bit_buf, 0, 2);
605
335
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_decorr_config, 2);
606
607
335
    ixheaace_byte_align_buffer(pstr_bit_buf);
608
609
335
    if ((*ptr_output_bits = ia_enhaacplus_enc_get_bits_available(pstr_bit_buf)) >
610
335
        (output_buffer_size * 8)) {
611
0
      return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
612
0
    }
613
614
335
    ixheaace_byte_align_buffer(pstr_bit_buf);
615
1.32k
  } else {
616
1.32k
    ixheaace_mps_212_get_sampling_frequency_index(
617
1.32k
        pstr_spatial_specific_config->bs_sampling_frequency, &bs_sampling_frequency_index);
618
1.32k
    ixheaace_write_bits(pstr_bit_buf, bs_freq_res, 3);
619
620
1.32k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_fixed_gain_dmx, 3);
621
622
1.32k
    ixheaace_write_bits(pstr_bit_buf, 0, 2);
623
1.32k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_decorr_config, 2);
624
625
1.32k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
626
1.32k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
627
1.32k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
628
629
1.32k
    ixheaace_write_bits(pstr_bit_buf, 0, 5);
630
1.32k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
631
632
1.32k
    *ptr_output_bits = ia_enhaacplus_enc_get_bits_available(pstr_bit_buf);
633
1.32k
  }
634
1.66k
  return error;
635
1.66k
}
636
637
IA_ERRORCODE ixheaace_mps_212_write_spatial_frame(
638
    UWORD8 *const ptr_output_buffer, const WORD32 output_buffer_size,
639
94.6k
    WORD32 *const ptr_output_bits, ixheaace_mps_pstr_bsf_instance pstr_bsf_instance, WORD32 aot) {
640
94.6k
  IA_ERRORCODE error = IA_NO_ERROR;
641
94.6k
  WORD32 i, j, num_param_sets, num_ott_boxes;
642
94.6k
  ixheaace_mps_spatial_frame *pstr_spatial_frame = NULL;
643
94.6k
  ixheaace_mps_spatial_specific_config *pstr_specific_config = NULL;
644
94.6k
  ixheaace_bit_buf bit_buf;
645
94.6k
  ixheaace_bit_buf_handle pstr_bit_buf =
646
94.6k
      ia_enhaacplus_enc_create_bitbuffer(&bit_buf, ptr_output_buffer, output_buffer_size);
647
94.6k
  pstr_spatial_frame = &pstr_bsf_instance->frame;
648
94.6k
  pstr_specific_config = &pstr_bsf_instance->spatial_specific_config;
649
94.6k
  num_ott_boxes = pstr_bsf_instance->spatial_specific_config.tree_description.num_ott_boxes;
650
94.6k
  num_param_sets = pstr_spatial_frame->framing_info.num_param_sets;
651
652
94.6k
  if (pstr_spatial_frame->b_use_bb_cues) {
653
0
    for (i = 0; i < IXHEAACE_MPS_MAX_NUM_BOXES; i++) {
654
0
      if (num_param_sets == 1) {
655
0
        pstr_spatial_frame->cld_lossless_data.bs_freq_res_stride_xxx[i][0] = 3;
656
0
        pstr_spatial_frame->icc_lossless_data.bs_freq_res_stride_xxx[i][0] = 3;
657
0
      } else {
658
0
        for (j = 1; j < MAX_NUM_PARAMS; j++) {
659
0
          pstr_spatial_frame->cld_lossless_data.bs_freq_res_stride_xxx[i][j] = 3;
660
0
          pstr_spatial_frame->icc_lossless_data.bs_freq_res_stride_xxx[i][j] = 3;
661
0
        }
662
0
      }
663
0
    }
664
0
  }
665
666
94.6k
  if (aot == AOT_AAC_ELD) {
667
27.4k
    ixheaace_mps_212_write_framing_info(
668
27.4k
        pstr_bit_buf, &(pstr_spatial_frame->framing_info),
669
27.4k
        pstr_bsf_instance->spatial_specific_config.bs_frame_length);
670
27.4k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->bs_independency_flag, 1);
671
67.2k
  } else if (aot == AOT_USAC) {
672
67.2k
    if (!pstr_spatial_frame->bs_independency_flag) {
673
58.5k
      ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->bs_independency_flag, 1);
674
58.5k
    }
675
67.2k
  }
676
94.6k
  error = ixheaace_mps_212_write_ott_data(
677
94.6k
      pstr_bit_buf, &pstr_bsf_instance->prev_frame_data.prev_ott_data,
678
94.6k
      &pstr_spatial_frame->ott_data, pstr_specific_config->ott_config,
679
94.6k
      &pstr_spatial_frame->cld_lossless_data, &pstr_spatial_frame->icc_lossless_data,
680
94.6k
      num_ott_boxes, pstr_specific_config->num_bands, num_param_sets,
681
94.6k
      pstr_spatial_frame->bs_independency_flag);
682
94.6k
  if (error != IA_NO_ERROR) {
683
0
    return error;
684
0
  }
685
94.6k
  if (aot == AOT_AAC_ELD) {
686
27.4k
    ixheaace_mps_212_write_smg_data(pstr_bit_buf, &pstr_spatial_frame->smg_data, num_param_sets,
687
27.4k
                                    pstr_specific_config->num_bands);
688
27.4k
  }
689
690
94.6k
  *ptr_output_bits = ia_enhaacplus_enc_get_bits_available(pstr_bit_buf);
691
94.6k
  if ((*ptr_output_bits) > (output_buffer_size * 8)) {
692
0
    return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
693
0
  }
694
94.6k
  return error;
695
94.6k
}
696
697
IA_ERRORCODE
698
ixheaace_mps_515_write_spatial_specific_config(ixheaace_bit_buf_handle pstr_bit_buf,
699
486
                                               ixheaace_mps_sac_bsf_instance *pstr_bsf_instance) {
700
486
  WORD32 idx, box, bin;
701
486
  WORD32 bs_sampling_frequency_index;
702
486
  ixheaace_mps_sac_spatial_frame *pstr_spatial_frame = &(pstr_bsf_instance->current_frame);
703
486
  ixheaace_mps_sac_specific_config *pstr_specific_config =
704
486
      &(pstr_bsf_instance->spatial_specific_config);
705
486
  ixheaace_mps_sac_tree_description *pstr_tree_description =
706
486
      &(pstr_specific_config->tree_description);
707
708
486
  pstr_tree_description->num_ott_boxes =
709
486
      tree_config_table[pstr_specific_config->bs_tree_config].num_ott_boxes;
710
486
  pstr_tree_description->num_ttt_boxes =
711
486
      tree_config_table[pstr_specific_config->bs_tree_config].num_ttt_boxes;
712
486
  pstr_tree_description->num_in_chan =
713
486
      tree_config_table[pstr_specific_config->bs_tree_config].num_in_chan;
714
486
  pstr_tree_description->num_out_chan =
715
486
      tree_config_table[pstr_specific_config->bs_tree_config].num_out_chan;
716
717
486
  if (pstr_specific_config->bs_temp_shape_config == 2) {
718
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_GUIDED_ENV_SHAPE;
719
0
  }
720
721
486
  if (pstr_specific_config->bs_3d_audio_mode > 0) {
722
0
    return IA_EXHEAACE_EXE_FATAL_MPS_3D_STEREO_MODE_NOT_SUPPORTED;
723
0
  }
724
725
486
  if (pstr_specific_config->bs_residual_coding == 1) {
726
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_RESIDUAL_CODING;
727
0
  }
728
486
  if (pstr_specific_config->bs_arbitrary_downmix == 2) {
729
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_ARBITARY_DOWNMIX_CODING;
730
0
  }
731
486
  if (pstr_specific_config->tree_description.arbitrary_tree) {
732
0
    return IA_EXHEAACE_EXE_FATAL_MPS_ARBITARY_TREE_NOT_SUPPORTED;
733
0
  }
734
735
2.91k
  for (box = 0; box < MAX_NUM_BOXES; box++) {
736
2.43k
    pstr_tree_description->ott_mode_lfe[box] =
737
2.43k
        tree_config_table[pstr_specific_config->bs_tree_config].ott_mode_lfe[box];
738
2.43k
  }
739
486
  pstr_bsf_instance->num_bins = freq_res_bin_table[pstr_specific_config->bs_freq_res];
740
741
486
  bs_sampling_frequency_index = 15;
742
2.25k
  for (idx = 0; idx < 15; idx++) {
743
2.25k
    if (pstr_specific_config->bs_sampling_frequency == ia_sampl_freq_table[idx]) {
744
486
      bs_sampling_frequency_index = idx;
745
486
      break;
746
486
    }
747
2.25k
  }
748
749
486
  ixheaace_write_bits(pstr_bit_buf, bs_sampling_frequency_index, 4);
750
486
  if (bs_sampling_frequency_index == 15) {
751
0
    ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_sampling_frequency, 24);
752
0
  }
753
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_frame_length, 5);
754
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_freq_res, 3);
755
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_tree_config, 4);
756
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_quant_mode, 2);
757
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_one_icc, 1);
758
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_arbitrary_downmix, 1);
759
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_fixed_gain_sur, 3);
760
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_fixed_gain_lfe, 3);
761
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_fixed_gain_dmx, 3);
762
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_matrix_mode, 1);
763
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_temp_shape_config, 2);
764
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_decorr_config, 2);
765
486
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_3d_audio_mode, 1);
766
767
2.47k
  for (box = 0; box < pstr_tree_description->num_ott_boxes; box++) {
768
1.98k
    if (pstr_tree_description->ott_mode_lfe[box]) {
769
486
      ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->ott_config[box].bs_ott_bands, 5);
770
486
    }
771
1.98k
  }
772
707
  for (box = 0; box < pstr_tree_description->num_ttt_boxes; box++) {
773
221
    ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->ttt_config[box].bs_ttt_dual_mode, 1);
774
221
    ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->ttt_config[box].bs_ttt_mode_low, 3);
775
221
    if (pstr_specific_config->ttt_config[box].bs_ttt_dual_mode == 1) {
776
0
      ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->ttt_config[box].bs_ttt_mode_high,
777
0
                          3);
778
0
      ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->ttt_config[box].bs_ttt_bands_low,
779
0
                          5);
780
0
    }
781
221
  }
782
486
  ixheaace_byte_align_buffer(pstr_bit_buf);
783
784
2.91k
  for (box = 0; box < MAX_NUM_BOXES; box++) {
785
2.43k
    pstr_specific_config->ttt_config[box].bs_ttt_bands_low = pstr_bsf_instance->num_bins;
786
138k
    for (bin = 0; bin < MAX_NUM_BINS; bin++) {
787
136k
      pstr_spatial_frame->ott_data.cld_old[box][bin] = 0;
788
136k
      pstr_spatial_frame->ott_data.icc_old[box][bin] = 0;
789
136k
      pstr_spatial_frame->ttt_data.cpc_cld1_old[box][bin] = 0;
790
136k
      pstr_spatial_frame->ttt_data.cpc_cld2_old[box][bin] = 0;
791
136k
      pstr_spatial_frame->ttt_data.icc_old[box][bin] = 0;
792
136k
    }
793
2.43k
  }
794
795
2.47k
  for (box = 0; box < pstr_tree_description->num_ott_boxes; box++) {
796
1.98k
    if (!pstr_tree_description->ott_mode_lfe[box]) {
797
1.50k
      pstr_specific_config->ott_config[box].bs_ott_bands = pstr_bsf_instance->num_bins;
798
1.50k
    }
799
1.98k
    if (!pstr_specific_config->ttt_config[box].bs_ttt_dual_mode) {
800
1.98k
      pstr_specific_config->ttt_config[box].bs_ttt_bands_low = pstr_bsf_instance->num_bins;
801
1.98k
    }
802
1.98k
  }
803
804
486
  return IA_NO_ERROR;
805
486
}
806
807
IA_ERRORCODE
808
ixheaace_mps_515_write_spatial_frame(ixheaace_bit_buf_handle pstr_bit_buf,
809
18.7k
                                     ixheaace_mps_sac_bsf_instance *pstr_bsf_instance) {
810
18.7k
  IA_ERRORCODE error = IA_NO_ERROR;
811
18.7k
  UWORD8 bits_param_slot;
812
18.7k
  WORD32 param, box, ch, bin;
813
18.7k
  WORD32 prev_bs_param_slot, num_temp_shape_chan;
814
18.7k
  ixheaace_mps_sac_spatial_frame *pstr_spatial_frame = &(pstr_bsf_instance->current_frame);
815
18.7k
  ixheaace_mps_sac_specific_config *pstr_specific_config =
816
18.7k
      &(pstr_bsf_instance->spatial_specific_config);
817
18.7k
  WORD32 bs_independency_flag = pstr_spatial_frame->bs_independency_flag;
818
18.7k
  WORD32 num_param_sets = pstr_spatial_frame->framing_info.bs_num_param_sets;
819
18.7k
  WORD32 num_ott_boxes =
820
18.7k
      pstr_bsf_instance->spatial_specific_config.tree_description.num_ott_boxes;
821
18.7k
  WORD32 num_ttt_boxes =
822
18.7k
      pstr_bsf_instance->spatial_specific_config.tree_description.num_ttt_boxes;
823
18.7k
  WORD32 *ptr_ott_mode_lfe =
824
18.7k
      pstr_bsf_instance->spatial_specific_config.tree_description.ott_mode_lfe;
825
826
18.7k
  if (pstr_specific_config->bs_arbitrary_downmix) {
827
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_ARBITARY_DOWNMIX_CODING;
828
0
  }
829
18.7k
  if (pstr_specific_config->bs_residual_coding == 1) {
830
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_RESIDUAL_CODING;
831
0
  }
832
18.7k
  if (pstr_specific_config->bs_arbitrary_downmix == 2) {
833
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_ARBITARY_DOWNMIX_CODING;
834
0
  }
835
18.7k
  if (pstr_specific_config->tree_description.arbitrary_tree) {
836
0
    return IA_EXHEAACE_EXE_FATAL_MPS_ARBITARY_TREE_NOT_SUPPORTED;
837
0
  }
838
18.7k
  ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->framing_info.bs_framing_type, 1);
839
18.7k
  ixheaace_write_bits(pstr_bit_buf, num_param_sets - 1, 1);
840
841
18.7k
  if (pstr_spatial_frame->framing_info.bs_framing_type) {
842
18.7k
    prev_bs_param_slot = -1;
843
844
37.5k
    for (param = 0; param < num_param_sets; param++) {
845
18.7k
      bits_param_slot = 0;
846
93.8k
      while ((1 << bits_param_slot) < (pstr_specific_config->bs_frame_length + 1 -
847
93.8k
                                       num_param_sets + param - prev_bs_param_slot)) {
848
75.1k
        bits_param_slot++;
849
75.1k
      }
850
851
18.7k
      if (bits_param_slot > 0) {
852
18.7k
        ixheaace_write_bits(
853
18.7k
            pstr_bit_buf,
854
18.7k
            pstr_spatial_frame->framing_info.bs_param_slots[param] - prev_bs_param_slot - 1,
855
18.7k
            bits_param_slot);
856
18.7k
      }
857
18.7k
      prev_bs_param_slot = pstr_spatial_frame->framing_info.bs_param_slots[param];
858
18.7k
    }
859
18.7k
  }
860
861
18.7k
  ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->bs_independency_flag, 1);
862
863
93.8k
  for (box = 0; box < num_ott_boxes; box++) {
864
75.0k
    error = ixheaace_mps_515_ec_data(
865
75.0k
        pstr_bit_buf, pstr_spatial_frame->ott_data.cld[box],
866
75.0k
        pstr_spatial_frame->ott_data.cld_old[box], &(pstr_spatial_frame->cld_lossless_data),
867
75.0k
        IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets, bs_independency_flag, 0,
868
75.0k
        pstr_specific_config->ott_config[box].bs_ott_bands);
869
75.0k
    if (error) {
870
0
      return error;
871
0
    }
872
75.0k
  }
873
18.7k
  if (!pstr_bsf_instance->spatial_specific_config.bs_one_icc) {
874
93.8k
    for (box = 0; box < num_ott_boxes; box++) {
875
75.0k
      if (!ptr_ott_mode_lfe[box]) {
876
56.2k
        error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ott_data.icc[box],
877
56.2k
                                         pstr_spatial_frame->ott_data.icc_old[box],
878
56.2k
                                         &(pstr_spatial_frame->cld_lossless_data),
879
56.2k
                                         IXHEAACE_MPS_SAC_DATA_TYPE_ICC, box, num_param_sets,
880
56.2k
                                         bs_independency_flag, 0, pstr_bsf_instance->num_bins);
881
56.2k
        if (error) {
882
0
          return error;
883
0
        }
884
56.2k
      }
885
75.0k
    }
886
18.7k
  } else {
887
0
    error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ott_data.icc[0],
888
0
                                     pstr_spatial_frame->ott_data.icc_old[0],
889
0
                                     &(pstr_spatial_frame->cld_lossless_data),
890
0
                                     IXHEAACE_MPS_SAC_DATA_TYPE_ICC, 0, num_param_sets,
891
0
                                     bs_independency_flag, 0, pstr_bsf_instance->num_bins);
892
0
    if (error) {
893
0
      return error;
894
0
    }
895
0
  }
896
28.1k
  for (box = 0; box < num_ttt_boxes; box++) {
897
9.40k
    if (pstr_specific_config->ttt_config[box].bs_ttt_mode_low >= 2) {
898
9.40k
      error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld1[box],
899
9.40k
                                       pstr_spatial_frame->ttt_data.cpc_cld1_old[box],
900
9.40k
                                       &(pstr_spatial_frame->cld_lossless_data),
901
9.40k
                                       IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets,
902
9.40k
                                       bs_independency_flag, 0,
903
9.40k
                                       pstr_specific_config->ttt_config[box].bs_ttt_bands_low);
904
9.40k
      if (error) {
905
0
        return error;
906
0
      }
907
9.40k
      error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld2[box],
908
9.40k
                                       pstr_spatial_frame->ttt_data.cpc_cld2_old[box],
909
9.40k
                                       &(pstr_spatial_frame->cld_lossless_data),
910
9.40k
                                       IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets,
911
9.40k
                                       bs_independency_flag, 0,
912
9.40k
                                       pstr_specific_config->ttt_config[box].bs_ttt_bands_low);
913
9.40k
      if (error) {
914
0
        return error;
915
0
      }
916
9.40k
    } else {
917
0
      error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld1[box],
918
0
                                       pstr_spatial_frame->ttt_data.cpc_cld1_old[box],
919
0
                                       &(pstr_spatial_frame->cpc_lossless_data),
920
0
                                       IXHEAACE_MPS_SAC_DATA_TYPE_CPC, box, num_param_sets,
921
0
                                       bs_independency_flag, 0,
922
0
                                       pstr_specific_config->ttt_config[box].bs_ttt_bands_low);
923
0
      if (error) {
924
0
        return error;
925
0
      }
926
0
      error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld2[box],
927
0
                                       pstr_spatial_frame->ttt_data.cpc_cld2_old[box],
928
0
                                       &(pstr_spatial_frame->cpc_lossless_data),
929
0
                                       IXHEAACE_MPS_SAC_DATA_TYPE_CPC, box, num_param_sets,
930
0
                                       bs_independency_flag, 0,
931
0
                                       pstr_specific_config->ttt_config[box].bs_ttt_bands_low);
932
0
      if (error) {
933
0
        return error;
934
0
      }
935
0
      error = ixheaace_mps_515_ec_data(
936
0
          pstr_bit_buf, pstr_spatial_frame->ttt_data.icc[box],
937
0
          pstr_spatial_frame->ttt_data.icc_old[box], &(pstr_spatial_frame->icc_lossless_data),
938
0
          IXHEAACE_MPS_SAC_DATA_TYPE_ICC, box, num_param_sets, bs_independency_flag, 0,
939
0
          pstr_specific_config->ttt_config[box].bs_ttt_bands_low);
940
0
      if (error) {
941
0
        return error;
942
0
      }
943
0
    }
944
945
9.40k
    if (pstr_specific_config->ttt_config[box].bs_ttt_dual_mode) {
946
0
      if (pstr_specific_config->ttt_config[box].bs_ttt_mode_high >= 2) {
947
0
        error = ixheaace_mps_515_ec_data(
948
0
            pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld1[box],
949
0
            pstr_spatial_frame->ttt_data.cpc_cld1_old[box],
950
0
            &(pstr_spatial_frame->cld_lossless_data), IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box,
951
0
            num_param_sets, bs_independency_flag,
952
0
            pstr_specific_config->ttt_config[box].bs_ttt_bands_low, pstr_bsf_instance->num_bins);
953
0
        if (error) {
954
0
          return error;
955
0
        }
956
0
        error = ixheaace_mps_515_ec_data(
957
0
            pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld2[box],
958
0
            pstr_spatial_frame->ttt_data.cpc_cld2_old[box],
959
0
            &(pstr_spatial_frame->cld_lossless_data), IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box,
960
0
            num_param_sets, bs_independency_flag,
961
0
            pstr_specific_config->ttt_config[box].bs_ttt_bands_low, pstr_bsf_instance->num_bins);
962
0
        if (error) {
963
0
          return error;
964
0
        }
965
0
      } else {
966
0
        error = ixheaace_mps_515_ec_data(
967
0
            pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld1[box],
968
0
            pstr_spatial_frame->ttt_data.cpc_cld1_old[box],
969
0
            &(pstr_spatial_frame->cpc_lossless_data), IXHEAACE_MPS_SAC_DATA_TYPE_CPC, box,
970
0
            num_param_sets, bs_independency_flag,
971
0
            pstr_specific_config->ttt_config[box].bs_ttt_bands_low, pstr_bsf_instance->num_bins);
972
0
        if (error) {
973
0
          return error;
974
0
        }
975
0
        error = ixheaace_mps_515_ec_data(
976
0
            pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld2[box],
977
0
            pstr_spatial_frame->ttt_data.cpc_cld2_old[box],
978
0
            &(pstr_spatial_frame->cpc_lossless_data), IXHEAACE_MPS_SAC_DATA_TYPE_CPC, box,
979
0
            num_param_sets, bs_independency_flag,
980
0
            pstr_specific_config->ttt_config[box].bs_ttt_bands_low, pstr_bsf_instance->num_bins);
981
0
        if (error) {
982
0
          return error;
983
0
        }
984
0
        error = ixheaace_mps_515_ec_data(
985
0
            pstr_bit_buf, pstr_spatial_frame->ttt_data.icc[box],
986
0
            pstr_spatial_frame->ttt_data.icc_old[box], &(pstr_spatial_frame->icc_lossless_data),
987
0
            IXHEAACE_MPS_SAC_DATA_TYPE_ICC, box, num_param_sets, bs_independency_flag,
988
0
            pstr_specific_config->ttt_config[box].bs_ttt_bands_low, pstr_bsf_instance->num_bins);
989
0
        if (error) {
990
0
          return error;
991
0
        }
992
0
      }
993
0
    }
994
9.40k
  }
995
37.5k
  for (param = 0; param < num_param_sets; param++) {
996
18.7k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->smg_data.bs_smooth_mode[param], 2);
997
998
18.7k
    if (pstr_spatial_frame->smg_data.bs_smooth_mode[param] >= 2) {
999
0
      ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->smg_data.bs_smooth_time[param], 2);
1000
0
    }
1001
18.7k
    if (pstr_spatial_frame->smg_data.bs_smooth_mode[param] == 3) {
1002
0
      ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->smg_data.bs_freq_res_stride[param],
1003
0
                          2);
1004
0
      for (bin = 0; bin < pstr_bsf_instance->num_bins;
1005
0
           bin += pstr_spatial_frame->smg_data.bs_freq_res_stride[param]) {
1006
0
        ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->smg_data.bs_smg_data[param][bin],
1007
0
                            1);
1008
0
      }
1009
0
    }
1010
18.7k
  }
1011
18.7k
  if (pstr_specific_config->bs_temp_shape_config != 0) {
1012
0
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->temp_shape_data.bs_temp_shape_enable,
1013
0
                        1);
1014
0
    if (pstr_spatial_frame->temp_shape_data.bs_temp_shape_enable) {
1015
0
      num_temp_shape_chan = temp_shape_chan_table[pstr_specific_config->bs_temp_shape_config - 1]
1016
0
                                                 [pstr_specific_config->bs_tree_config];
1017
0
      for (ch = 0; ch < num_temp_shape_chan; ch++) {
1018
0
        ixheaace_write_bits(pstr_bit_buf,
1019
0
                            pstr_spatial_frame->temp_shape_data.bs_temp_shape_enable_channel[ch],
1020
0
                            1);
1021
0
      }
1022
0
      if (pstr_specific_config->bs_temp_shape_config == 2) {
1023
0
        return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_GUIDED_ENV_SHAPE;
1024
0
      }
1025
0
    }
1026
0
  }
1027
1028
18.7k
  ixheaace_byte_align_buffer(pstr_bit_buf);
1029
1030
18.7k
  return IA_NO_ERROR;
1031
18.7k
}