Coverage Report

Created: 2025-10-10 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_mps_bitstream.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 <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
46.7k
static UWORD8 ixheaace_mps_212_get_bs_freq_res_stride(const WORD32 index) {
52
46.7k
  WORD32 freq_res_stride_table_size = 0;
53
46.7k
  const UWORD8 *ptr_freq_res_stride_table = NULL;
54
55
46.7k
  ptr_freq_res_stride_table = freq_res_stride_table_212;
56
46.7k
  freq_res_stride_table_size =
57
46.7k
      sizeof(freq_res_stride_table_212) / sizeof(*freq_res_stride_table_212);
58
59
46.7k
  return (((index >= 0) && (index < freq_res_stride_table_size))
60
46.7k
              ? ptr_freq_res_stride_table[index]
61
46.7k
              : 1);
62
46.7k
}
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.49k
                                                           WORD32 aot) {
67
1.49k
  IA_ERRORCODE error = IA_NO_ERROR;
68
1.49k
  WORD32 idx;
69
1.49k
  const UWORD8 *p_freq_res_bin_table;
70
1.49k
  *ptr_bs_freq_res_index = -1;
71
72
1.49k
  if (aot == AOT_AAC_ELD) {
73
232
    p_freq_res_bin_table = freq_res_bin_table_ld;
74
1.26k
  } else {
75
1.26k
    p_freq_res_bin_table = freq_res_bin_table_usac;
76
1.26k
  }
77
3.21k
  for (idx = 0; idx < MAX_FREQ_RES_INDEX; idx++) {
78
3.21k
    if (num_bands == p_freq_res_bin_table[idx]) {
79
1.49k
      *ptr_bs_freq_res_index = idx;
80
1.49k
      break;
81
1.49k
    }
82
3.21k
  }
83
1.49k
  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.49k
  return error;
87
1.49k
}
88
89
static VOID ixheaace_mps_212_get_sampling_frequency_index(
90
1.49k
    const UWORD32 bs_sampling_frequency, WORD32 *const ptr_bs_sampling_frequency_index) {
91
1.49k
  WORD32 idx;
92
1.49k
  *ptr_bs_sampling_frequency_index = SAMPLING_FREQUENCY_INDEX_ESCAPE;
93
94
7.07k
  for (idx = 0; idx < MAX_SAMPLING_FREQUENCY_INDEX; idx++) {
95
7.07k
    if (bs_sampling_frequency == ia_sampl_freq_table[idx]) {
96
1.49k
      *ptr_bs_sampling_frequency_index = idx;
97
1.49k
      break;
98
1.49k
    }
99
7.07k
  }
100
1.49k
}
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
207k
    const WORD32 start_band, const WORD32 stop_band, const WORD32 default_value) {
108
207k
  IA_ERRORCODE error;
109
207k
  WORD32 ps, pb, str_offset, pb_stride, i;
110
207k
  WORD16 data_bands;
111
207k
  WORD32 a_strides[MAX_NUM_BINS + 1] = {0};
112
207k
  WORD16 cmp_idx_data[2][MAX_NUM_BINS] = {{0}};
113
207k
  WORD16 cmp_old_data[MAX_NUM_BINS] = {0};
114
115
207k
  if (num_param_sets > MAX_NUM_PARAMS) {
116
0
    return IA_EXHEAACE_EXE_FATAL_MPS_INVALID_NUM_PARAM_SETS;
117
0
  }
118
119
207k
  if (independency_flag || (pstr_lossless_data->bs_quant_coarse_xxx[param_idx][0] !=
120
192k
                            quant_coarse_xxx_prev[param_idx])) {
121
15.1k
    pstr_lossless_data->bs_xxx_data_mode[param_idx][0] = IXHEAACE_MPS_DATA_MODE_FINECOARSE;
122
192k
  } else {
123
192k
    pstr_lossless_data->bs_xxx_data_mode[param_idx][0] = IXHEAACE_MPS_DATA_MODE_KEEP;
124
4.37M
    for (i = start_band; i < stop_band; i++) {
125
4.21M
      if (data[0][i] != old_data[i]) {
126
31.5k
        pstr_lossless_data->bs_xxx_data_mode[param_idx][0] = IXHEAACE_MPS_DATA_MODE_FINECOARSE;
127
31.5k
        break;
128
31.5k
      }
129
4.21M
    }
130
192k
  }
131
132
207k
  ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_xxx_data_mode[param_idx][0], 2);
133
134
207k
  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
207k
  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
415k
  for (ps = 0; ps < num_param_sets; ps++) {
177
207k
    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
207k
    if (pstr_lossless_data->bs_xxx_data_mode[param_idx][ps] ==
185
207k
        IXHEAACE_MPS_DATA_MODE_FINECOARSE) {
186
46.7k
      ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_data_pair[param_idx][ps], 1);
187
46.7k
      ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps],
188
46.7k
                          1);
189
46.7k
      ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][ps],
190
46.7k
                          2);
191
192
46.7k
      if (pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps] !=
193
46.7k
          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
46.7k
      pb_stride = ixheaace_mps_212_get_bs_freq_res_stride(
216
46.7k
          pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][ps]);
217
46.7k
      data_bands = (WORD16)((stop_band - start_band - 1) / pb_stride + 1);
218
219
46.7k
      a_strides[0] = start_band;
220
1.24M
      for (pb = 1; pb <= data_bands; pb++) {
221
1.19M
        a_strides[pb] = a_strides[pb - 1] + pb_stride;
222
1.19M
      }
223
224
46.7k
      str_offset = 0;
225
46.7k
      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
1.24M
      for (pb = 0; pb < data_bands; pb++) {
235
1.19M
        cmp_old_data[start_band + pb] = old_data[a_strides[pb]];
236
1.19M
        cmp_idx_data[0][start_band + pb] = data[ps][a_strides[pb]];
237
238
1.19M
        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
1.19M
      }
242
243
46.7k
      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
46.7k
      } else {
252
46.7k
        error = ixheaace_mps_212_ec_data_single_enc(
253
46.7k
            pstr_bit_buf, cmp_idx_data, cmp_old_data, data_type, 0, start_band, data_bands,
254
46.7k
            pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps],
255
46.7k
            independency_flag && (ps == 0));
256
46.7k
        if (error != IA_NO_ERROR) {
257
0
          return error;
258
0
        }
259
46.7k
      }
260
1.24M
      for (i = start_band; i < stop_band; i++) {
261
1.19M
        if (pstr_lossless_data->bs_data_pair[param_idx][ps]) {
262
0
          old_data[i] = data[ps + 1][i];
263
1.19M
        } else {
264
1.19M
          old_data[i] = data[ps][i];
265
1.19M
        }
266
1.19M
      }
267
268
46.7k
      quant_coarse_xxx_prev[param_idx] = pstr_lossless_data->bs_quant_coarse_xxx[param_idx][ps];
269
270
46.7k
      if (pstr_lossless_data->bs_data_pair[param_idx][ps]) {
271
0
        ps++;
272
0
      }
273
46.7k
    }
274
207k
  }
275
207k
  return IA_NO_ERROR;
276
207k
}
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
18.9k
                                            const WORD32 data_bands) {
282
18.9k
  WORD32 param, band;
283
284
37.9k
  for (param = 0; param < num_param_sets; param++) {
285
18.9k
    ixheaace_write_bits(pstr_bit_buf, pstr_smg_data->bs_smooth_mode[param], 2);
286
18.9k
    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
18.9k
    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
18.9k
  }
298
18.9k
}
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
103k
    const WORD32 num_bands, const WORD32 num_param_sets, const WORD32 bs_independency_flag) {
307
103k
  IA_ERRORCODE error = IA_NO_ERROR;
308
103k
  WORD32 box;
309
207k
  for (box = 0; box < num_ott_boxes; box++) {
310
103k
    error = ixheaace_mps_212_ec_data(
311
103k
        pstr_bit_buf, pstr_ott_data->cld[box], pstr_prev_ott_data->cld_old[box],
312
103k
        pstr_prev_ott_data->quant_coarse_cld_prev[box], pstr_cld_lossless_data,
313
103k
        IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets, bs_independency_flag, 0,
314
103k
        ott_config[box].bs_ott_bands, 15);
315
103k
    if (error != IA_NO_ERROR) {
316
0
      return error;
317
0
    }
318
103k
  }
319
207k
  for (box = 0; box < num_ott_boxes; box++) {
320
103k
    error = ixheaace_mps_212_ec_data(pstr_bit_buf, pstr_ott_data->icc[box],
321
103k
                                     pstr_prev_ott_data->icc_old[box],
322
103k
                                     pstr_prev_ott_data->quant_coarse_icc_prev[box],
323
103k
                                     pstr_icc_lossless_data, IXHEAACE_MPS_SAC_DATA_TYPE_ICC, box,
324
103k
                                     num_param_sets, bs_independency_flag, 0, num_bands, 0);
325
103k
    if (error != IA_NO_ERROR) {
326
0
      return error;
327
0
    }
328
103k
  }
329
330
103k
  return IA_NO_ERROR;
331
103k
}
332
333
static VOID ixheaace_mps_212_write_framing_info(
334
    ixheaace_bit_buf_handle pstr_bit_buf,
335
18.9k
    const ixheaace_mps_framing_info *const pstr_framing_info, const WORD32 frame_length) {
336
18.9k
  ixheaace_write_bits(pstr_bit_buf, pstr_framing_info->bs_framing_type, 1);
337
18.9k
  ixheaace_write_bits(pstr_bit_buf, pstr_framing_info->num_param_sets - 1, 1);
338
339
18.9k
  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
18.9k
}
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
169k
                                             WORD32 start_band, WORD32 stop_band) {
361
169k
  WORD32 param_set, set_idx, pb_stride, data_bands, bin, data_sets;
362
169k
  WORD32 param_set_index[MAX_NUM_PARAMS] = {0};
363
364
339k
  for (param_set = 0; param_set < num_param_sets; param_set++) {
365
169k
    pstr_lossless_data->bs_xxx_data_mode[param_idx][param_set] =
366
169k
        IXHEAACE_MPS_DATA_MODE_FINECOARSE;
367
169k
    ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_xxx_data_mode[param_idx][param_set],
368
169k
                        2);
369
169k
  }
370
371
339k
  for (param_set = 0, set_idx = 0; param_set < num_param_sets; param_set++) {
372
169k
    param_set_index[set_idx] = param_set;
373
169k
    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
169k
    } else {
379
169k
      pstr_lossless_data->bs_data_pair[param_idx][set_idx] = 0;
380
169k
      set_idx++;
381
169k
    }
382
169k
  }
383
169k
  data_sets = set_idx;
384
385
339k
  for (set_idx = 0; set_idx < data_sets;) {
386
169k
    ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_data_pair[param_idx][set_idx], 1);
387
169k
    ixheaace_write_bits(pstr_bit_buf, pstr_lossless_data->bs_quant_coarse_xxx[param_idx][set_idx],
388
169k
                        1);
389
169k
    ixheaace_write_bits(pstr_bit_buf,
390
169k
                        pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][set_idx], 2);
391
392
169k
    pb_stride =
393
169k
        freq_res_stride_table[pstr_lossless_data->bs_freq_res_stride_xxx[param_idx][set_idx]];
394
169k
    data_bands = (stop_band - start_band - 1) / pb_stride + 1;
395
396
169k
    ixheaace_mps_515_ec_data_pair_enc(
397
169k
        pstr_bit_buf, data, old_data, data_type, param_set_index[set_idx], start_band, data_bands,
398
169k
        pstr_lossless_data->bs_data_pair[param_idx][set_idx],
399
169k
        pstr_lossless_data->bs_quant_coarse_xxx[param_idx][set_idx], independency_flag);
400
401
169k
    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
9.68M
    for (bin = 0; bin < MAX_NUM_BINS; bin++) {
413
9.51M
      old_data[bin] = data[param_set_index[set_idx] +
414
9.51M
                           pstr_lossless_data->bs_data_pair[param_idx][set_idx]][bin];
415
9.51M
    }
416
417
169k
    set_idx += pstr_lossless_data->bs_data_pair[param_idx][set_idx] + 1;
418
169k
  }
419
169k
  return IA_NO_ERROR;
420
169k
}
421
422
1.68M
WORD32 ixheaace_mps_515_icc_quant(FLOAT32 val) {
423
1.68M
  FLOAT32 p_qsteps[7] = {0.9685f, 0.88909f, 0.72105f, 0.48428f, 0.18382f, -0.2945f, -0.7895f};
424
1.68M
  WORD32 i;
425
426
1.68M
  if (val >= p_qsteps[0]) {
427
773k
    return 0;
428
773k
  }
429
4.34M
  for (i = 1; i < 6; i++) {
430
4.27M
    if ((val >= p_qsteps[i]) && (val <= p_qsteps[i - 1])) {
431
841k
      return i;
432
841k
    }
433
4.27M
  }
434
70.6k
  return 7;
435
912k
}
436
437
2.14M
WORD32 ixheaace_mps_515_cld_quant(FLOAT32 val) {
438
2.14M
  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
2.14M
                          -9.0,  -7.0,  -5.0,  -3.0,  -1.0,  1.0,   3.0,   5.0,   7.0,   9.0,
440
2.14M
                          11.5,  14.5,  17.5,  20.5,  23.5,  27.5,  32.5,  37.5,  42.5,  47.5};
441
442
2.14M
  WORD32 i;
443
444
2.14M
  if (val < p_qsteps[0]) {
445
834k
    return 0 - 15;
446
834k
  }
447
22.7M
  for (i = 1; i < 30; i++) {
448
22.7M
    if ((val <= p_qsteps[i]) && (val >= p_qsteps[i - 1])) {
449
1.29M
      return i - 15;
450
1.29M
    }
451
22.7M
  }
452
13.7k
  return 30 - 15;
453
1.30M
}
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
11.4k
                              FLOAT32 *ptr_imag3, WORD32 *ptr_qclds1, WORD32 *ptr_qclds2) {
458
11.4k
  WORD32 i, j;
459
460
11.4k
  FLOAT32 cld_s1[PARAMETER_BANDS] = {0};
461
11.4k
  FLOAT32 cld_s2[PARAMETER_BANDS] = {0};
462
11.4k
  FLOAT32 p_pow1[MAX_HYBRID_BANDS] = {0};
463
11.4k
  FLOAT32 p_pow2[MAX_HYBRID_BANDS] = {0};
464
11.4k
  FLOAT32 p_pow3[MAX_HYBRID_BANDS] = {0};
465
466
11.4k
  FLOAT32 p_pow_par_band1[PARAMETER_BANDS] = {0};
467
11.4k
  FLOAT32 p_pow_par_band2[PARAMETER_BANDS] = {0};
468
11.4k
  FLOAT32 p_pow_par_band3[PARAMETER_BANDS] = {0};
469
470
189k
  for (i = 0; i < slots; i++) {
471
12.7M
    for (j = 0; j < MAX_HYBRID_BANDS; j++) {
472
12.6M
      p_pow1[j] += ptr_real1[i * MAX_HYBRID_BANDS + j] * ptr_real1[i * MAX_HYBRID_BANDS + j] +
473
12.6M
                   ptr_imag1[i * MAX_HYBRID_BANDS + j] * ptr_imag1[i * MAX_HYBRID_BANDS + j];
474
12.6M
      p_pow2[j] += ptr_real2[i * MAX_HYBRID_BANDS + j] * ptr_real2[i * MAX_HYBRID_BANDS + j] +
475
12.6M
                   ptr_imag2[i * MAX_HYBRID_BANDS + j] * ptr_imag2[i * MAX_HYBRID_BANDS + j];
476
12.6M
      p_pow3[j] += ptr_real3[i * MAX_HYBRID_BANDS + j] * ptr_real3[i * MAX_HYBRID_BANDS + j] +
477
12.6M
                   ptr_imag3[i * MAX_HYBRID_BANDS + j] * ptr_imag3[i * MAX_HYBRID_BANDS + j];
478
479
12.6M
      ptr_real1[i * MAX_HYBRID_BANDS + j] =
480
12.6M
          (ptr_real1[i * MAX_HYBRID_BANDS + j] + ptr_real3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
481
12.6M
      ptr_imag1[i * MAX_HYBRID_BANDS + j] =
482
12.6M
          (ptr_imag1[i * MAX_HYBRID_BANDS + j] + ptr_imag3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
483
484
12.6M
      ptr_real2[i * MAX_HYBRID_BANDS + j] =
485
12.6M
          (ptr_real2[i * MAX_HYBRID_BANDS + j] + ptr_real3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
486
12.6M
      ptr_imag2[i * MAX_HYBRID_BANDS + j] =
487
12.6M
          (ptr_imag2[i * MAX_HYBRID_BANDS + j] + ptr_imag3[i * MAX_HYBRID_BANDS + j] * 0.7071f);
488
12.6M
    }
489
177k
  }
490
821k
  for (i = 0; i < MAX_HYBRID_BANDS; i++) {
491
810k
    p_pow_par_band1[kernels_20[i]] += p_pow1[i];
492
810k
    p_pow_par_band2[kernels_20[i]] += p_pow2[i];
493
810k
    p_pow_par_band3[kernels_20[i]] += p_pow3[i];
494
810k
  }
495
239k
  for (i = 0; i < PARAMETER_BANDS; i++) {
496
228k
    if (p_pow_par_band3[i]) {
497
143k
      cld_s1[i] = ((p_pow_par_band1[i] + p_pow_par_band2[i]) / (p_pow_par_band3[i]));
498
143k
      cld_s1[i] = (FLOAT32)(10.0 * log(cld_s1[i] + 1e-10) / log(10.0));
499
143k
    } else if ((p_pow_par_band1[i] + p_pow_par_band2[i]))
500
1.96k
      cld_s1[i] = 50.0;
501
83.0k
    else
502
83.0k
      cld_s1[i] = -50;
503
228k
    ptr_qclds1[i] = ixheaace_mps_515_cld_quant(cld_s1[i]);
504
505
228k
    if (p_pow_par_band2[i]) {
506
143k
      cld_s2[i] = (p_pow_par_band1[i] / (p_pow_par_band2[i]));
507
143k
      cld_s2[i] = (FLOAT32)(10 * log(cld_s2[i] + 1e-10f) / log(10.0));
508
143k
    } else if (p_pow_par_band1[i])
509
1.26k
      cld_s2[i] = 50.0;
510
83.7k
    else
511
83.7k
      cld_s2[i] = -50;
512
228k
    ptr_qclds2[i] = ixheaace_mps_515_cld_quant(cld_s2[i]);
513
228k
  }
514
11.4k
}
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
84.2k
                              WORD32 *ptr_qiccs) {
519
84.2k
  WORD32 i, j;
520
521
84.2k
  FLOAT32 clds[PARAMETER_BANDS] = {0};
522
84.2k
  FLOAT32 iccs[PARAMETER_BANDS] = {0};
523
84.2k
  FLOAT32 p_pow1[MAX_HYBRID_BANDS] = {0};
524
84.2k
  FLOAT32 p_pow2[MAX_HYBRID_BANDS] = {0};
525
84.2k
  FLOAT32 p_xcor_real[MAX_HYBRID_BANDS] = {0};
526
527
84.2k
  FLOAT32 p_pow_par_band1[PARAMETER_BANDS] = {0};
528
84.2k
  FLOAT32 p_pow_par_band2[PARAMETER_BANDS] = {0};
529
84.2k
  FLOAT32 p_xcor_par_band[PARAMETER_BANDS] = {0};
530
531
1.38M
  for (i = 0; i < slots; i++) {
532
93.9M
    for (j = 0; j < MAX_HYBRID_BANDS; j++) {
533
92.6M
      p_pow1[j] += ptr_real1[i * MAX_HYBRID_BANDS + j] * ptr_real1[i * MAX_HYBRID_BANDS + j] +
534
92.6M
                   ptr_imag1[i * MAX_HYBRID_BANDS + j] * ptr_imag1[i * MAX_HYBRID_BANDS + j];
535
92.6M
      p_pow2[j] += ptr_real2[i * MAX_HYBRID_BANDS + j] * ptr_real2[i * MAX_HYBRID_BANDS + j] +
536
92.6M
                   ptr_imag2[i * MAX_HYBRID_BANDS + j] * ptr_imag2[i * MAX_HYBRID_BANDS + j];
537
92.6M
      p_xcor_real[j] +=
538
92.6M
          ptr_real1[i * MAX_HYBRID_BANDS + j] * ptr_real2[i * MAX_HYBRID_BANDS + j] +
539
92.6M
          ptr_imag1[i * MAX_HYBRID_BANDS + j] * ptr_imag2[i * MAX_HYBRID_BANDS + j];
540
541
92.6M
      ptr_real1[i * MAX_HYBRID_BANDS + j] =
542
92.6M
          (ptr_real1[i * MAX_HYBRID_BANDS + j] + ptr_real2[i * MAX_HYBRID_BANDS + j]);
543
92.6M
      ptr_imag1[i * MAX_HYBRID_BANDS + j] =
544
92.6M
          (ptr_imag1[i * MAX_HYBRID_BANDS + j] + ptr_imag2[i * MAX_HYBRID_BANDS + j]);
545
92.6M
    }
546
1.30M
  }
547
6.06M
  for (i = 0; i < MAX_HYBRID_BANDS; i++) {
548
5.98M
    p_pow_par_band1[kernels_20[i]] += p_pow1[i];
549
5.98M
    p_pow_par_band2[kernels_20[i]] += p_pow2[i];
550
5.98M
    p_xcor_par_band[kernels_20[i]] += p_xcor_real[i];
551
5.98M
  }
552
1.76M
  for (i = 0; i < PARAMETER_BANDS; i++) {
553
1.68M
    if (p_pow_par_band2[i]) {
554
1.02M
      clds[i] = (p_pow_par_band1[i] / (p_pow_par_band2[i]));
555
1.02M
      clds[i] = (FLOAT32)(10 * log(clds[i] + 1e-10) / log(10.0));
556
1.02M
    } else if (p_pow_par_band1[i])
557
5.04k
      clds[i] = 50.0;
558
657k
    else
559
657k
      clds[i] = -50;  // 0.0;
560
1.68M
    iccs[i] =
561
1.68M
        p_xcor_par_band[i] / (FLOAT32)sqrt((p_pow_par_band1[i] * p_pow_par_band2[i] + 1e-10));
562
563
1.68M
    ptr_p_qclds[i] = ixheaace_mps_515_cld_quant(clds[i]);
564
1.68M
    ptr_qiccs[i] = ixheaace_mps_515_icc_quant(iccs[i]);
565
1.68M
  }
566
84.2k
}
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.49k
    WORD32 *const ptr_output_bits, WORD32 aot) {
572
1.49k
  IA_ERRORCODE error = IA_NO_ERROR;
573
1.49k
  WORD32 bs_sampling_frequency_index = 0;
574
1.49k
  WORD32 bs_freq_res = 0;
575
1.49k
  ixheaace_bit_buf bit_buf;
576
1.49k
  ixheaace_bit_buf_handle pstr_bit_buf =
577
1.49k
      ia_enhaacplus_enc_create_bitbuffer(&bit_buf, ptr_output_buffer, output_buffer_size);
578
579
1.49k
  error = ixheaace_mps_212_get_bs_freq_res_index(pstr_spatial_specific_config->num_bands,
580
1.49k
                                                 &bs_freq_res, aot);
581
1.49k
  if (error) {
582
0
    return error;
583
0
  }
584
585
1.49k
  if (aot == AOT_AAC_ELD) {
586
232
    ixheaace_mps_212_get_sampling_frequency_index(
587
232
        pstr_spatial_specific_config->bs_sampling_frequency, &bs_sampling_frequency_index);
588
232
    ixheaace_write_bits(pstr_bit_buf, bs_sampling_frequency_index, 4);
589
590
232
    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
232
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_frame_length, 5);
595
596
232
    ixheaace_write_bits(pstr_bit_buf, bs_freq_res, 3);
597
232
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_tree_config, 4);
598
232
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_quant_mode, 2);
599
600
232
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
601
602
232
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_fixed_gain_dmx, 3);
603
604
232
    ixheaace_write_bits(pstr_bit_buf, 0, 2);
605
232
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_decorr_config, 2);
606
607
232
    ixheaace_byte_align_buffer(pstr_bit_buf);
608
609
232
    if ((*ptr_output_bits = ia_enhaacplus_enc_get_bits_available(pstr_bit_buf)) >
610
232
        (output_buffer_size * 8)) {
611
0
      return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
612
0
    }
613
614
232
    ixheaace_byte_align_buffer(pstr_bit_buf);
615
1.26k
  } else {
616
1.26k
    ixheaace_mps_212_get_sampling_frequency_index(
617
1.26k
        pstr_spatial_specific_config->bs_sampling_frequency, &bs_sampling_frequency_index);
618
1.26k
    ixheaace_write_bits(pstr_bit_buf, bs_freq_res, 3);
619
620
1.26k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_fixed_gain_dmx, 3);
621
622
1.26k
    ixheaace_write_bits(pstr_bit_buf, 0, 2);
623
1.26k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_specific_config->bs_decorr_config, 2);
624
625
1.26k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
626
1.26k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
627
1.26k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
628
629
1.26k
    ixheaace_write_bits(pstr_bit_buf, 0, 5);
630
1.26k
    ixheaace_write_bits(pstr_bit_buf, 0, 1);
631
632
1.26k
    *ptr_output_bits = ia_enhaacplus_enc_get_bits_available(pstr_bit_buf);
633
1.26k
  }
634
1.49k
  return error;
635
1.49k
}
636
637
IA_ERRORCODE ixheaace_mps_212_write_spatial_frame(
638
    UWORD8 *const ptr_output_buffer, const WORD32 output_buffer_size,
639
103k
    WORD32 *const ptr_output_bits, ixheaace_mps_pstr_bsf_instance pstr_bsf_instance, WORD32 aot) {
640
103k
  IA_ERRORCODE error = IA_NO_ERROR;
641
103k
  WORD32 i, j, num_param_sets, num_ott_boxes;
642
103k
  ixheaace_mps_spatial_frame *pstr_spatial_frame = NULL;
643
103k
  ixheaace_mps_spatial_specific_config *pstr_specific_config = NULL;
644
103k
  ixheaace_bit_buf bit_buf;
645
103k
  ixheaace_bit_buf_handle pstr_bit_buf =
646
103k
      ia_enhaacplus_enc_create_bitbuffer(&bit_buf, ptr_output_buffer, output_buffer_size);
647
103k
  pstr_spatial_frame = &pstr_bsf_instance->frame;
648
103k
  pstr_specific_config = &pstr_bsf_instance->spatial_specific_config;
649
103k
  num_ott_boxes = pstr_bsf_instance->spatial_specific_config.tree_description.num_ott_boxes;
650
103k
  num_param_sets = pstr_spatial_frame->framing_info.num_param_sets;
651
652
103k
  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
103k
  if (aot == AOT_AAC_ELD) {
667
18.9k
    ixheaace_mps_212_write_framing_info(
668
18.9k
        pstr_bit_buf, &(pstr_spatial_frame->framing_info),
669
18.9k
        pstr_bsf_instance->spatial_specific_config.bs_frame_length);
670
18.9k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->bs_independency_flag, 1);
671
84.8k
  } else if (aot == AOT_USAC) {
672
84.8k
    if (!pstr_spatial_frame->bs_independency_flag) {
673
78.3k
      ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->bs_independency_flag, 1);
674
78.3k
    }
675
84.8k
  }
676
103k
  error = ixheaace_mps_212_write_ott_data(
677
103k
      pstr_bit_buf, &pstr_bsf_instance->prev_frame_data.prev_ott_data,
678
103k
      &pstr_spatial_frame->ott_data, pstr_specific_config->ott_config,
679
103k
      &pstr_spatial_frame->cld_lossless_data, &pstr_spatial_frame->icc_lossless_data,
680
103k
      num_ott_boxes, pstr_specific_config->num_bands, num_param_sets,
681
103k
      pstr_spatial_frame->bs_independency_flag);
682
103k
  if (error != IA_NO_ERROR) {
683
0
    return error;
684
0
  }
685
103k
  if (aot == AOT_AAC_ELD) {
686
18.9k
    ixheaace_mps_212_write_smg_data(pstr_bit_buf, &pstr_spatial_frame->smg_data, num_param_sets,
687
18.9k
                                    pstr_specific_config->num_bands);
688
18.9k
  }
689
690
103k
  *ptr_output_bits = ia_enhaacplus_enc_get_bits_available(pstr_bit_buf);
691
103k
  if ((*ptr_output_bits) > (output_buffer_size * 8)) {
692
0
    return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG;
693
0
  }
694
103k
  return error;
695
103k
}
696
697
IA_ERRORCODE
698
ixheaace_mps_515_write_spatial_specific_config(ixheaace_bit_buf_handle pstr_bit_buf,
699
432
                                               ixheaace_mps_sac_bsf_instance *pstr_bsf_instance) {
700
432
  WORD32 idx, box, bin;
701
432
  WORD32 bs_sampling_frequency_index;
702
432
  ixheaace_mps_sac_spatial_frame *pstr_spatial_frame = &(pstr_bsf_instance->current_frame);
703
432
  ixheaace_mps_sac_specific_config *pstr_specific_config =
704
432
      &(pstr_bsf_instance->spatial_specific_config);
705
432
  ixheaace_mps_sac_tree_description *pstr_tree_description =
706
432
      &(pstr_specific_config->tree_description);
707
708
432
  pstr_tree_description->num_ott_boxes =
709
432
      tree_config_table[pstr_specific_config->bs_tree_config].num_ott_boxes;
710
432
  pstr_tree_description->num_ttt_boxes =
711
432
      tree_config_table[pstr_specific_config->bs_tree_config].num_ttt_boxes;
712
432
  pstr_tree_description->num_in_chan =
713
432
      tree_config_table[pstr_specific_config->bs_tree_config].num_in_chan;
714
432
  pstr_tree_description->num_out_chan =
715
432
      tree_config_table[pstr_specific_config->bs_tree_config].num_out_chan;
716
717
432
  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
432
  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
432
  if (pstr_specific_config->bs_residual_coding == 1) {
726
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_RESIDUAL_CODING;
727
0
  }
728
432
  if (pstr_specific_config->bs_arbitrary_downmix == 2) {
729
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_ARBITARY_DOWNMIX_CODING;
730
0
  }
731
432
  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.59k
  for (box = 0; box < MAX_NUM_BOXES; box++) {
736
2.16k
    pstr_tree_description->ott_mode_lfe[box] =
737
2.16k
        tree_config_table[pstr_specific_config->bs_tree_config].ott_mode_lfe[box];
738
2.16k
  }
739
432
  pstr_bsf_instance->num_bins = freq_res_bin_table[pstr_specific_config->bs_freq_res];
740
741
432
  bs_sampling_frequency_index = 15;
742
1.93k
  for (idx = 0; idx < 15; idx++) {
743
1.93k
    if (pstr_specific_config->bs_sampling_frequency == ia_sampl_freq_table[idx]) {
744
432
      bs_sampling_frequency_index = idx;
745
432
      break;
746
432
    }
747
1.93k
  }
748
749
432
  ixheaace_write_bits(pstr_bit_buf, bs_sampling_frequency_index, 4);
750
432
  if (bs_sampling_frequency_index == 15) {
751
0
    ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_sampling_frequency, 24);
752
0
  }
753
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_frame_length, 5);
754
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_freq_res, 3);
755
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_tree_config, 4);
756
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_quant_mode, 2);
757
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_one_icc, 1);
758
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_arbitrary_downmix, 1);
759
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_fixed_gain_sur, 3);
760
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_fixed_gain_lfe, 3);
761
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_fixed_gain_dmx, 3);
762
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_matrix_mode, 1);
763
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_temp_shape_config, 2);
764
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_decorr_config, 2);
765
432
  ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->bs_3d_audio_mode, 1);
766
767
2.15k
  for (box = 0; box < pstr_tree_description->num_ott_boxes; box++) {
768
1.71k
    if (pstr_tree_description->ott_mode_lfe[box]) {
769
432
      ixheaace_write_bits(pstr_bit_buf, pstr_specific_config->ott_config[box].bs_ott_bands, 5);
770
432
    }
771
1.71k
  }
772
653
  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
432
  ixheaace_byte_align_buffer(pstr_bit_buf);
783
784
2.59k
  for (box = 0; box < MAX_NUM_BOXES; box++) {
785
2.16k
    pstr_specific_config->ttt_config[box].bs_ttt_bands_low = pstr_bsf_instance->num_bins;
786
123k
    for (bin = 0; bin < MAX_NUM_BINS; bin++) {
787
120k
      pstr_spatial_frame->ott_data.cld_old[box][bin] = 0;
788
120k
      pstr_spatial_frame->ott_data.icc_old[box][bin] = 0;
789
120k
      pstr_spatial_frame->ttt_data.cpc_cld1_old[box][bin] = 0;
790
120k
      pstr_spatial_frame->ttt_data.cpc_cld2_old[box][bin] = 0;
791
120k
      pstr_spatial_frame->ttt_data.icc_old[box][bin] = 0;
792
120k
    }
793
2.16k
  }
794
795
2.15k
  for (box = 0; box < pstr_tree_description->num_ott_boxes; box++) {
796
1.71k
    if (!pstr_tree_description->ott_mode_lfe[box]) {
797
1.28k
      pstr_specific_config->ott_config[box].bs_ott_bands = pstr_bsf_instance->num_bins;
798
1.28k
    }
799
1.71k
    if (!pstr_specific_config->ttt_config[box].bs_ttt_dual_mode) {
800
1.71k
      pstr_specific_config->ttt_config[box].bs_ttt_bands_low = pstr_bsf_instance->num_bins;
801
1.71k
    }
802
1.71k
  }
803
804
432
  return IA_NO_ERROR;
805
432
}
806
807
IA_ERRORCODE
808
ixheaace_mps_515_write_spatial_frame(ixheaace_bit_buf_handle pstr_bit_buf,
809
21.4k
                                     ixheaace_mps_sac_bsf_instance *pstr_bsf_instance) {
810
21.4k
  IA_ERRORCODE error = IA_NO_ERROR;
811
21.4k
  UWORD8 bits_param_slot;
812
21.4k
  WORD32 param, box, ch, bin;
813
21.4k
  WORD32 prev_bs_param_slot, num_temp_shape_chan;
814
21.4k
  ixheaace_mps_sac_spatial_frame *pstr_spatial_frame = &(pstr_bsf_instance->current_frame);
815
21.4k
  ixheaace_mps_sac_specific_config *pstr_specific_config =
816
21.4k
      &(pstr_bsf_instance->spatial_specific_config);
817
21.4k
  WORD32 bs_independency_flag = pstr_spatial_frame->bs_independency_flag;
818
21.4k
  WORD32 num_param_sets = pstr_spatial_frame->framing_info.bs_num_param_sets;
819
21.4k
  WORD32 num_ott_boxes =
820
21.4k
      pstr_bsf_instance->spatial_specific_config.tree_description.num_ott_boxes;
821
21.4k
  WORD32 num_ttt_boxes =
822
21.4k
      pstr_bsf_instance->spatial_specific_config.tree_description.num_ttt_boxes;
823
21.4k
  WORD32 *ptr_ott_mode_lfe =
824
21.4k
      pstr_bsf_instance->spatial_specific_config.tree_description.ott_mode_lfe;
825
826
21.4k
  if (pstr_specific_config->bs_arbitrary_downmix) {
827
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_ARBITARY_DOWNMIX_CODING;
828
0
  }
829
21.4k
  if (pstr_specific_config->bs_residual_coding == 1) {
830
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_RESIDUAL_CODING;
831
0
  }
832
21.4k
  if (pstr_specific_config->bs_arbitrary_downmix == 2) {
833
0
    return IA_EXHEAACE_EXE_FATAL_MPS_UNSUPPORTED_ARBITARY_DOWNMIX_CODING;
834
0
  }
835
21.4k
  if (pstr_specific_config->tree_description.arbitrary_tree) {
836
0
    return IA_EXHEAACE_EXE_FATAL_MPS_ARBITARY_TREE_NOT_SUPPORTED;
837
0
  }
838
21.4k
  ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->framing_info.bs_framing_type, 1);
839
21.4k
  ixheaace_write_bits(pstr_bit_buf, num_param_sets - 1, 1);
840
841
21.4k
  if (pstr_spatial_frame->framing_info.bs_framing_type) {
842
21.4k
    prev_bs_param_slot = -1;
843
844
42.8k
    for (param = 0; param < num_param_sets; param++) {
845
21.4k
      bits_param_slot = 0;
846
107k
      while ((1 << bits_param_slot) < (pstr_specific_config->bs_frame_length + 1 -
847
107k
                                       num_param_sets + param - prev_bs_param_slot)) {
848
85.6k
        bits_param_slot++;
849
85.6k
      }
850
851
21.4k
      if (bits_param_slot > 0) {
852
21.4k
        ixheaace_write_bits(
853
21.4k
            pstr_bit_buf,
854
21.4k
            pstr_spatial_frame->framing_info.bs_param_slots[param] - prev_bs_param_slot - 1,
855
21.4k
            bits_param_slot);
856
21.4k
      }
857
21.4k
      prev_bs_param_slot = pstr_spatial_frame->framing_info.bs_param_slots[param];
858
21.4k
    }
859
21.4k
  }
860
861
21.4k
  ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->bs_independency_flag, 1);
862
863
105k
  for (box = 0; box < num_ott_boxes; box++) {
864
84.2k
    error = ixheaace_mps_515_ec_data(
865
84.2k
        pstr_bit_buf, pstr_spatial_frame->ott_data.cld[box],
866
84.2k
        pstr_spatial_frame->ott_data.cld_old[box], &(pstr_spatial_frame->cld_lossless_data),
867
84.2k
        IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets, bs_independency_flag, 0,
868
84.2k
        pstr_specific_config->ott_config[box].bs_ott_bands);
869
84.2k
    if (error) {
870
0
      return error;
871
0
    }
872
84.2k
  }
873
21.4k
  if (!pstr_bsf_instance->spatial_specific_config.bs_one_icc) {
874
105k
    for (box = 0; box < num_ott_boxes; box++) {
875
84.2k
      if (!ptr_ott_mode_lfe[box]) {
876
62.8k
        error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ott_data.icc[box],
877
62.8k
                                         pstr_spatial_frame->ott_data.icc_old[box],
878
62.8k
                                         &(pstr_spatial_frame->cld_lossless_data),
879
62.8k
                                         IXHEAACE_MPS_SAC_DATA_TYPE_ICC, box, num_param_sets,
880
62.8k
                                         bs_independency_flag, 0, pstr_bsf_instance->num_bins);
881
62.8k
        if (error) {
882
0
          return error;
883
0
        }
884
62.8k
      }
885
84.2k
    }
886
21.4k
  } 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
32.8k
  for (box = 0; box < num_ttt_boxes; box++) {
897
11.4k
    if (pstr_specific_config->ttt_config[box].bs_ttt_mode_low >= 2) {
898
11.4k
      error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld1[box],
899
11.4k
                                       pstr_spatial_frame->ttt_data.cpc_cld1_old[box],
900
11.4k
                                       &(pstr_spatial_frame->cld_lossless_data),
901
11.4k
                                       IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets,
902
11.4k
                                       bs_independency_flag, 0,
903
11.4k
                                       pstr_specific_config->ttt_config[box].bs_ttt_bands_low);
904
11.4k
      if (error) {
905
0
        return error;
906
0
      }
907
11.4k
      error = ixheaace_mps_515_ec_data(pstr_bit_buf, pstr_spatial_frame->ttt_data.cpc_cld2[box],
908
11.4k
                                       pstr_spatial_frame->ttt_data.cpc_cld2_old[box],
909
11.4k
                                       &(pstr_spatial_frame->cld_lossless_data),
910
11.4k
                                       IXHEAACE_MPS_SAC_DATA_TYPE_CLD, box, num_param_sets,
911
11.4k
                                       bs_independency_flag, 0,
912
11.4k
                                       pstr_specific_config->ttt_config[box].bs_ttt_bands_low);
913
11.4k
      if (error) {
914
0
        return error;
915
0
      }
916
11.4k
    } 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
11.4k
    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
11.4k
  }
995
42.8k
  for (param = 0; param < num_param_sets; param++) {
996
21.4k
    ixheaace_write_bits(pstr_bit_buf, pstr_spatial_frame->smg_data.bs_smooth_mode[param], 2);
997
998
21.4k
    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
21.4k
    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
21.4k
  }
1011
21.4k
  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
21.4k
  ixheaace_byte_align_buffer(pstr_bit_buf);
1029
1030
21.4k
  return IA_NO_ERROR;
1031
21.4k
}