Coverage Report

Created: 2025-10-10 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/drc_src/impd_drc_mux.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 <math.h>
22
#include <string.h>
23
#include "ixheaac_type_def.h"
24
#include "ixheaac_error_standards.h"
25
#include "ixheaace_error_codes.h"
26
27
#include "iusace_bitbuffer.h"
28
#include "iusace_cnst.h"
29
#include "impd_drc_common_enc.h"
30
#include "impd_drc_uni_drc.h"
31
#include "impd_drc_tables.h"
32
#include "impd_drc_api.h"
33
#include "impd_drc_uni_drc_eq.h"
34
#include "impd_drc_uni_drc_filter_bank.h"
35
#include "impd_drc_gain_enc.h"
36
#include "impd_drc_struct_def.h"
37
#include "impd_drc_enc.h"
38
#include "impd_drc_mux.h"
39
40
static IA_ERRORCODE impd_drc_get_drc_complexity_level(
41
    ia_drc_uni_drc_config_struct *pstr_uni_drc_config, ia_drc_gain_enc_struct *pstr_drc_gain_enc,
42
910
    ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc, VOID *ptr_scratch) {
43
910
  IA_ERRORCODE err_code = IA_NO_ERROR;
44
910
  LOOPIDX c, g, k, i, group;
45
910
  WORD32 band_count;
46
910
  WORD32 gain_set_index;
47
910
  WORD32 skip_set;
48
910
  WORD32 gain_set_index_offset;
49
910
  WORD32 parametric_drc_type = 0;
50
910
  WORD32 channel_count_side_chain;
51
910
  WORD32 channel_count_drom_downmix_id;
52
910
  WORD32 channel_count_temp;
53
910
  WORD32 weighting_filter_order;
54
910
  WORD32 channel_count = pstr_uni_drc_config->str_channel_layout.base_ch_count;
55
910
  FLOAT32 w_mod, cplx, cplx_tmp, ratio;
56
910
  ia_drc_gain_modifiers_struct *pstr_gain_modifiers = NULL;
57
910
  ia_drc_shape_filter_block_params_struct *pstr_shape_filter_block_params = NULL;
58
910
  ia_drc_gain_set_params_struct *pstr_gain_set_params = NULL;
59
910
  ia_drc_parametric_drc_instructions_struct *pstr_parametric_drc_instructions = NULL;
60
910
  ia_drc_parametric_drc_gain_set_params_struct *pstr_parametric_drc_gain_set_params = NULL;
61
62
910
  if (pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0 &&
63
0
      ((pstr_drc_instructions_uni_drc->downmix_id == 0x7F) ||
64
0
       (pstr_drc_instructions_uni_drc->additional_downmix_id_count != 0))) {
65
0
    channel_count = 1;
66
910
  } else if ((pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0) &&
67
0
             (pstr_drc_instructions_uni_drc->downmix_id != 0) &&
68
0
             (pstr_drc_instructions_uni_drc->downmix_id != 0x7F) &&
69
0
             (pstr_drc_instructions_uni_drc->additional_downmix_id_count == 0)) {
70
0
    for (i = 0; i < pstr_uni_drc_config->downmix_instructions_count; i++) {
71
0
      if (pstr_drc_instructions_uni_drc->downmix_id ==
72
0
          pstr_uni_drc_config->str_downmix_instructions[i].downmix_id) {
73
0
        break;
74
0
      }
75
0
    }
76
0
    if (i == pstr_uni_drc_config->downmix_instructions_count) {
77
0
      return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
78
0
    }
79
0
    channel_count = pstr_uni_drc_config->str_downmix_instructions[i].target_ch_count;
80
0
  }
81
82
910
  pstr_drc_instructions_uni_drc->drc_channel_count = channel_count;
83
910
  group = 0;
84
2.60k
  for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) {
85
1.69k
    gain_set_index = pstr_drc_instructions_uni_drc->gain_set_index[c];
86
1.69k
    skip_set = FALSE;
87
1.69k
    if (gain_set_index < 0) {
88
0
      pstr_drc_instructions_uni_drc->channel_group_for_channel[c] = -1;
89
1.69k
    } else {
90
2.48k
      for (k = c - 1; k >= 0; k--) {
91
787
        if (pstr_drc_instructions_uni_drc->gain_set_index[k] == gain_set_index) {
92
711
          pstr_drc_instructions_uni_drc->channel_group_for_channel[c] =
93
711
              pstr_drc_instructions_uni_drc->channel_group_for_channel[k];
94
711
          skip_set = TRUE;
95
711
        }
96
787
      }
97
1.69k
      if (skip_set == FALSE) {
98
986
        pstr_drc_instructions_uni_drc->channel_group_for_channel[c] = group;
99
986
        group++;
100
986
      }
101
1.69k
    }
102
1.69k
  }
103
910
  if (group != pstr_drc_instructions_uni_drc->num_drc_channel_groups) {
104
215
    return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
105
215
  }
106
107
1.45k
  for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) {
108
763
    pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g] = 0;
109
2.23k
    for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) {
110
1.47k
      if (pstr_drc_instructions_uni_drc->channel_group_for_channel[c] == g) {
111
1.34k
        pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g]++;
112
1.34k
      }
113
1.47k
    }
114
763
  }
115
116
695
  cplx = 0.0f;
117
118
695
  if (pstr_drc_gain_enc->domain == TIME_DOMAIN) {
119
188
    w_mod = COMPLEXITY_W_MOD_TIME;
120
507
  } else {
121
507
    w_mod = COMPLEXITY_W_MOD_SUBBAND;
122
507
  }
123
2.03k
  for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) {
124
1.34k
    if (pstr_drc_instructions_uni_drc->gain_set_index[c] >= 0) {
125
1.34k
      cplx += w_mod;
126
1.34k
    }
127
1.34k
  }
128
129
695
  if (pstr_drc_gain_enc->domain != TIME_DOMAIN) {
130
507
    pstr_gain_set_params =
131
507
        pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0]
132
507
            .str_gain_set_params;
133
1.48k
    for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) {
134
982
      gain_set_index = pstr_drc_instructions_uni_drc->gain_set_index[c];
135
982
      if (gain_set_index >= 0) {
136
982
        if (pstr_gain_set_params[gain_set_index].drc_band_type == 1) {
137
0
          band_count = pstr_gain_set_params[gain_set_index].band_count;
138
0
          if (band_count > 1) {
139
0
            cplx += COMPLEXITY_W_LAP * band_count;
140
0
          }
141
0
        }
142
982
      }
143
982
    }
144
507
  } else {
145
188
    err_code = impd_drc_init_all_filter_banks(
146
188
        &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0],
147
188
        pstr_drc_instructions_uni_drc, &pstr_drc_gain_enc->str_filter_banks, ptr_scratch);
148
149
188
    if (err_code) return err_code;
150
151
175
    cplx += COMPLEXITY_W_IIR * pstr_drc_gain_enc->str_filter_banks.complexity;
152
153
367
    for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) {
154
192
      pstr_gain_modifiers = &pstr_drc_instructions_uni_drc->str_gain_modifiers[g];
155
192
      if (pstr_gain_modifiers->shape_filter_present == 1) {
156
0
        cplx_tmp = 0.0f;
157
0
        pstr_shape_filter_block_params =
158
0
            &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0]
159
0
                 .str_shape_filter_block_params[pstr_gain_modifiers->shape_filter_index];
160
0
        if (pstr_shape_filter_block_params->lf_cut_filter_present == 1) {
161
0
          cplx_tmp += COMPLEXITY_W_SHAPE;
162
0
        }
163
0
        if (pstr_shape_filter_block_params->lf_boost_filter_present == 1) {
164
0
          cplx_tmp += COMPLEXITY_W_SHAPE;
165
0
        }
166
0
        if (pstr_shape_filter_block_params->hf_cut_filter_present == 1) {
167
0
          cplx_tmp += COMPLEXITY_W_SHAPE * 2.0f;
168
0
        }
169
0
        if (pstr_shape_filter_block_params->hf_boost_filter_present == 1) {
170
0
          cplx_tmp += COMPLEXITY_W_SHAPE * 2.0f;
171
0
        }
172
0
        cplx += cplx_tmp * pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g];
173
0
      }
174
192
    }
175
175
  }
176
177
1.42k
  for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) {
178
746
    gain_set_index_offset = 0;
179
746
    gain_set_index = -1;
180
810
    for (c = 0; c < pstr_drc_instructions_uni_drc->drc_channel_count; c++) {
181
810
      if (pstr_drc_instructions_uni_drc->channel_group_for_channel[c] == g) {
182
746
        gain_set_index = pstr_drc_instructions_uni_drc->gain_set_index[c];
183
746
        break;
184
746
      }
185
810
    }
186
746
    if (pstr_uni_drc_config->str_uni_drc_config_ext.drc_coefficients_uni_drc_v1_count > 0) {
187
655
      gain_set_index_offset =
188
655
          pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0]
189
655
              .gain_set_count;
190
655
      pstr_gain_set_params =
191
655
          pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0]
192
655
              .str_gain_set_params;
193
655
    }
194
746
    if (gain_set_index >= gain_set_index_offset) {
195
209
      pstr_parametric_drc_instructions = NULL;
196
209
      pstr_parametric_drc_gain_set_params =
197
209
          &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coeff_parametric_drc
198
209
               .parametric_drc_gain_set_params[gain_set_index - gain_set_index_offset];
199
209
      for (i = 0;
200
209
           i < pstr_uni_drc_config->str_uni_drc_config_ext.parametric_drc_instructions_count;
201
209
           i++) {
202
0
        if (pstr_parametric_drc_gain_set_params->parametric_drc_id ==
203
0
            pstr_uni_drc_config->str_uni_drc_config_ext.str_parametric_drc_instructions[i]
204
0
                .parametric_drc_id) {
205
0
          pstr_parametric_drc_instructions =
206
0
              &pstr_uni_drc_config->str_uni_drc_config_ext.str_parametric_drc_instructions[i];
207
0
          break;
208
0
        }
209
0
      }
210
209
      if (pstr_parametric_drc_instructions != NULL) {
211
0
        if (pstr_parametric_drc_instructions->parametric_drc_preset_id_present) {
212
0
          switch (pstr_parametric_drc_instructions->parametric_drc_preset_id) {
213
0
            case 0:
214
0
            case 1:
215
0
            case 2:
216
0
            case 3:
217
0
            case 4:
218
0
              parametric_drc_type = PARAM_DRC_TYPE_FF;
219
0
              break;
220
0
            case 5:
221
0
              parametric_drc_type = PARAM_DRC_TYPE_LIM;
222
0
              break;
223
0
            default:
224
0
              return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
225
0
              break;
226
0
          }
227
0
        } else {
228
0
          parametric_drc_type = pstr_parametric_drc_instructions->parametric_drc_type;
229
0
        }
230
0
      }
231
209
      channel_count_side_chain = pstr_drc_instructions_uni_drc->num_channels_per_channel_group[g];
232
209
      if (pstr_parametric_drc_gain_set_params->side_chain_config_type == 1) {
233
0
        channel_count_temp = 0;
234
0
        if (pstr_parametric_drc_gain_set_params->downmix_id == 0x0) {
235
0
          channel_count_drom_downmix_id = pstr_uni_drc_config->str_channel_layout.base_ch_count;
236
0
        } else if (pstr_parametric_drc_gain_set_params->downmix_id == 0x7F) {
237
0
          channel_count_drom_downmix_id = 1;
238
0
        } else {
239
0
          for (i = 0; i < pstr_uni_drc_config->downmix_instructions_count; i++) {
240
0
            if (pstr_parametric_drc_gain_set_params->downmix_id ==
241
0
                pstr_uni_drc_config->str_downmix_instructions[i].downmix_id) {
242
0
              break;
243
0
            }
244
0
          }
245
0
          if (i == pstr_uni_drc_config->downmix_instructions_count) {
246
0
            return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
247
0
          }
248
0
          channel_count_drom_downmix_id =
249
0
              pstr_uni_drc_config->str_downmix_instructions[i].target_ch_count;
250
0
        }
251
252
0
        for (i = 0; i < channel_count_drom_downmix_id; i++) {
253
0
          if (pstr_parametric_drc_gain_set_params->level_estim_channel_weight[i] != 0) {
254
0
            channel_count_temp++;
255
0
          }
256
0
        }
257
0
        channel_count_side_chain = channel_count_temp;
258
0
      }
259
209
      if (pstr_parametric_drc_instructions != NULL) {
260
0
        if (pstr_drc_gain_enc->domain == TIME_DOMAIN) {
261
0
          if (parametric_drc_type == PARAM_DRC_TYPE_FF) {
262
0
            weighting_filter_order = 2;
263
0
            if (pstr_parametric_drc_instructions->parametric_drc_preset_id_present == 0) {
264
0
              if (pstr_parametric_drc_instructions->str_parametric_drc_type_feed_forward
265
0
                      .level_estim_k_weighting_type == 0) {
266
0
                weighting_filter_order = 0;
267
0
              } else if (pstr_parametric_drc_instructions->str_parametric_drc_type_feed_forward
268
0
                             .level_estim_k_weighting_type == 1) {
269
0
                weighting_filter_order = 1;
270
0
              }
271
0
            }
272
0
            cplx += channel_count_side_chain *
273
0
                        (COMPLEXITY_W_PARAM_DRC_FILT * weighting_filter_order + 1) +
274
0
                    3;
275
0
          } else if (parametric_drc_type == PARAM_DRC_TYPE_LIM) {
276
0
            ratio = 1.0f;
277
0
            if (pstr_parametric_drc_instructions->parametric_drc_look_ahead_present == 1) {
278
0
              ratio = (FLOAT32)pstr_parametric_drc_instructions->parametric_drc_look_ahead /
279
0
                      (FLOAT32)PARAM_DRC_TYPE_LIM_ATTACK_DEFAULT;
280
0
            }
281
0
            cplx += (FLOAT32)(channel_count_side_chain * COMPLEXITY_W_PARAM_LIM_FILT +
282
0
                              COMPLEXITY_W_PARAM_DRC_ATTACK * sqrt(ratio));
283
0
          }
284
0
        } else {
285
0
          if (parametric_drc_type == PARAM_DRC_TYPE_FF) {
286
0
            cplx += channel_count_side_chain * COMPLEXITY_W_PARAM_DRC_SUBBAND;
287
0
          }
288
0
        }
289
0
      }
290
537
    } else {
291
537
      if (pstr_drc_gain_enc->domain == TIME_DOMAIN && pstr_gain_set_params != NULL) {
292
162
        if (pstr_gain_set_params[gain_set_index].gain_interpolation_type ==
293
162
            GAIN_INTERPOLATION_TYPE_SPLINE) {
294
106
          cplx += COMPLEXITY_W_SPLINE;
295
106
        }
296
162
        if (pstr_gain_set_params[gain_set_index].gain_interpolation_type ==
297
162
            GAIN_INTERPOLATION_TYPE_LINEAR) {
298
56
          cplx += COMPLEXITY_W_LINEAR;
299
56
        }
300
162
      }
301
537
    }
302
746
  }
303
304
682
  if (pstr_drc_instructions_uni_drc->downmix_id == 0x7F) {
305
8
    channel_count = pstr_uni_drc_config->str_channel_layout.base_ch_count;
306
8
  }
307
308
682
  cplx = (FLOAT32)(log10(cplx / channel_count) / log10(2.0f));
309
682
  pstr_drc_instructions_uni_drc->drc_set_complexity_level = (WORD32)MAX(0, ceil(cplx));
310
311
682
  if (pstr_drc_instructions_uni_drc->drc_set_complexity_level > DRC_COMPLEXITY_LEVEL_MAX) {
312
0
    return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
313
0
  }
314
315
682
  return IA_NO_ERROR;
316
682
}
317
318
static IA_ERRORCODE impd_drc_get_eq_complexity_level(
319
    ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext,
320
    ia_drc_gain_enc_struct *pstr_drc_params, ia_drc_eq_instructions_struct *pstr_eq_instructions,
321
0
    VOID *ptr_scratch, WORD32 *scratch_used) {
322
0
  IA_ERRORCODE err_code = IA_NO_ERROR;
323
0
  WORD32 subband_domain_mode;
324
0
  ia_drc_eq_set_struct *pstr_eq_set = &pstr_drc_params->str_eq_set;
325
326
0
  if ((pstr_drc_params->domain == TIME_DOMAIN) &&
327
0
      (pstr_eq_instructions->td_filter_cascade_present == 0) &&
328
0
      (pstr_eq_instructions->subband_gains_present == 0)) {
329
0
    pstr_eq_instructions->eq_set_complexity_level = 0;
330
0
    return err_code;
331
0
  }
332
333
0
  subband_domain_mode = SUBBAND_DOMAIN_MODE_OFF;
334
0
  if (pstr_eq_instructions->subband_gains_present == 1) {
335
0
    subband_domain_mode = SUBBAND_DOMAIN_MODE_QMF64;
336
0
  }
337
0
  memset(pstr_eq_set, 0, sizeof(ia_drc_eq_set_struct));
338
339
0
  err_code = impd_drc_derive_eq_set(&pstr_uni_drc_config_ext->str_eq_coefficients,
340
0
                                    pstr_eq_instructions, (FLOAT32)pstr_drc_params->sample_rate,
341
0
                                    pstr_drc_params->drc_frame_size, subband_domain_mode,
342
0
                                    pstr_eq_set, ptr_scratch, scratch_used);
343
0
  if (err_code & IA_FATAL_ERROR) {
344
0
    return err_code;
345
0
  }
346
347
0
  err_code =
348
0
      impd_drc_get_eq_complexity(pstr_eq_set, &pstr_eq_instructions->eq_set_complexity_level);
349
0
  if (err_code & IA_FATAL_ERROR) {
350
0
    return err_code;
351
0
  }
352
353
0
  return err_code;
354
0
}
355
356
8.68k
static WORD32 impd_drc_encode_downmix_coefficient(FLOAT32 downmix_coeff, FLOAT32 downmix_offset) {
357
8.68k
  WORD32 idx, code;
358
8.68k
  FLOAT32 coeff_db;
359
8.68k
  const FLOAT32 *coeff_table;
360
361
8.68k
  coeff_table = impd_drc_downmix_coeff_v1;
362
8.68k
  coeff_db = 20.0f * (FLOAT32)log10(downmix_coeff) - downmix_offset;
363
364
8.68k
  if (coeff_db >= coeff_table[30]) {
365
0
    idx = 0;
366
0
    while (coeff_db < coeff_table[idx]) {
367
0
      idx++;
368
0
    }
369
0
    if ((idx > 0) && (coeff_db > 0.5f * (coeff_table[idx - 1] + coeff_table[idx]))) {
370
0
      idx--;
371
0
    }
372
0
    code = idx;
373
8.68k
  } else {
374
8.68k
    code = 31;
375
8.68k
  }
376
377
8.68k
  return code;
378
8.68k
}
379
380
static VOID impd_drc_dec_write_downmix_coeff_v1(ia_bit_buf_struct *it_bit_buf,
381
                                                const FLOAT32 downmix_coeff[],
382
                                                const WORD32 base_ch_count,
383
                                                const WORD32 target_ch_count,
384
514
                                                WORD32 *ptr_bit_cnt) {
385
514
  LOOPIDX i, j;
386
514
  WORD32 bs_downmix_offset = 0, code;
387
514
  WORD32 bit_cnt_local = 0;
388
514
  FLOAT32 downmix_offset[3];
389
514
  FLOAT32 tmp;
390
514
  FLOAT32 quant_err, quant_err_min;
391
514
  const FLOAT32 *coeff_table;
392
393
514
  coeff_table = impd_drc_downmix_coeff_v1;
394
514
  tmp = (FLOAT32)log10((FLOAT32)target_ch_count / (FLOAT32)base_ch_count);
395
514
  downmix_offset[0] = 0.0f;
396
514
  downmix_offset[1] = (FLOAT32)(0.5f * floor(0.5f + 20.0f * tmp));
397
514
  downmix_offset[2] = (FLOAT32)(0.5f * floor(0.5f + 40.0f * tmp));
398
399
514
  quant_err_min = 1000.0f;
400
2.05k
  for (i = 0; i < 3; i++) {
401
1.54k
    quant_err = 0.0f;
402
8.05k
    for (j = 0; j < (target_ch_count * base_ch_count); j++) {
403
6.51k
      code = impd_drc_encode_downmix_coefficient(downmix_coeff[j], downmix_offset[i]);
404
6.51k
      quant_err += (FLOAT32)fabs(20.0f * log10(downmix_coeff[j]) -
405
6.51k
                                 (coeff_table[code] + downmix_offset[i]));
406
6.51k
    }
407
1.54k
    if (quant_err_min > quant_err) {
408
308
      quant_err_min = quant_err;
409
308
      bs_downmix_offset = i;
410
308
    }
411
1.54k
  }
412
413
514
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_downmix_offset, 4);
414
415
2.68k
  for (j = 0; j < target_ch_count * base_ch_count; j++) {
416
2.17k
    code =
417
2.17k
        impd_drc_encode_downmix_coefficient(downmix_coeff[j], downmix_offset[bs_downmix_offset]);
418
2.17k
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5);
419
2.17k
  }
420
421
514
  *ptr_bit_cnt += bit_cnt_local;
422
514
}
423
424
static VOID impd_drc_enc_downmix_coeff(const FLOAT32 downmix_coeff_var,
425
                                       const WORD32 is_lfe_channel, WORD32 *code_size,
426
0
                                       WORD32 *code) {
427
0
  LOOPIDX idx;
428
0
  const FLOAT32 *coeff_table;
429
0
  FLOAT32 coeff_db;
430
431
0
  coeff_db = 20.0f * (FLOAT32)log10(downmix_coeff_var);
432
433
0
  if (is_lfe_channel == TRUE) {
434
0
    coeff_table = impd_drc_downmix_coeff_lfe;
435
0
  } else {
436
0
    coeff_table = impd_drc_downmix_coeff;
437
0
  }
438
0
  if (coeff_db >= coeff_table[14]) {
439
0
    idx = 0;
440
0
    while (coeff_db < coeff_table[idx]) {
441
0
      idx++;
442
0
    }
443
0
    if ((idx > 0) && (coeff_db > 0.5f * (coeff_table[idx - 1] + coeff_table[idx]))) {
444
0
      idx--;
445
0
    }
446
0
    *code = idx;
447
0
  } else {
448
0
    *code = 15;
449
0
  }
450
451
0
  *code_size = 4;
452
0
}
453
454
22.3k
static VOID impd_drc_enc_peak(const FLOAT32 peak_level, WORD32 *code, WORD32 *code_size) {
455
22.3k
  WORD32 bits;
456
457
22.3k
  bits = ((WORD32)(0.5f + 32.0f * (20.0f - peak_level) + 10000.0f)) - 10000;
458
22.3k
  bits = MIN(0x0FFF, bits);
459
22.3k
  bits = MAX(0x1, bits);
460
461
22.3k
  *code = bits;
462
22.3k
  *code_size = 12;
463
22.3k
}
464
465
static IA_ERRORCODE impd_drc_enc_method_value(const WORD32 method_definition,
466
                                              const FLOAT32 method_value, WORD32 *code_size,
467
89.4k
                                              WORD32 *code) {
468
89.4k
  WORD32 bits;
469
89.4k
  switch (method_definition) {
470
52.3k
    case METHOD_DEFINITION_UNKNOWN_OTHER:
471
57.1k
    case METHOD_DEFINITION_PROGRAM_LOUDNESS:
472
57.5k
    case METHOD_DEFINITION_ANCHOR_LOUDNESS:
473
59.6k
    case METHOD_DEFINITION_MAX_OF_LOUDNESS_RANGE:
474
59.9k
    case METHOD_DEFINITION_MOMENTARY_LOUDNESS_MAX:
475
60.4k
    case METHOD_DEFINITION_SHORT_TERM_LOUDNESS_MAX:
476
60.4k
      bits = ((WORD32)(0.5f + 4.0f * (method_value + 57.75f) + 10000.0f)) - 10000;
477
60.4k
      bits = MIN(0x0FF, bits);
478
60.4k
      bits = MAX(0x0, bits);
479
60.4k
      *code_size = 8;
480
60.4k
      break;
481
373
    case METHOD_DEFINITION_LOUDNESS_RANGE:
482
373
      if (method_value >= 121.0f) {
483
47
        bits = 255;
484
326
      } else if (method_value > 70.0f) {
485
0
        bits = ((WORD32)((method_value - 70.0f) + 0.5f)) + 204;
486
326
      } else if (method_value > 32.0f) {
487
0
        bits = ((WORD32)(2.0f * (method_value - 32.0f) + 0.5f)) + 128;
488
326
      } else if (method_value >= 0.0f) {
489
3
        bits = (WORD32)(4.0f * method_value + 0.5f);
490
323
      } else {
491
323
        bits = 0;
492
323
      }
493
373
      *code_size = 8;
494
373
      break;
495
510
    case METHOD_DEFINITION_MIXING_LEVEL:
496
510
      bits = (WORD32)(0.5f + method_value - 80.0f);
497
510
      bits = MIN(0x1F, bits);
498
510
      bits = MAX(0x0, bits);
499
510
      *code_size = 5;
500
510
      break;
501
217
    case METHOD_DEFINITION_ROOM_TYPE:
502
217
      bits = (WORD32)(0.5f + method_value);
503
217
      if (bits > 0x2) {
504
16
        return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE;
505
16
      }
506
201
      bits = MIN(0x2, bits);
507
201
      bits = MAX(0x0, bits);
508
201
      *code_size = 2;
509
201
      break;
510
27.9k
    case METHOD_DEFINITION_SHORT_TERM_LOUDNESS:
511
27.9k
      bits = ((WORD32)(0.5f + 2.0f * (method_value + 116.f) + 10000.0f)) - 10000;
512
27.9k
      bits = MIN(0x0FF, bits);
513
27.9k
      bits = MAX(0x0, bits);
514
27.9k
      *code_size = 8;
515
27.9k
      break;
516
0
    default: {
517
0
      return IA_EXHEAACE_CONFIG_FATAL_DRC_PARAM_OUT_OF_RANGE;
518
217
    }
519
89.4k
  }
520
89.4k
  *code = bits;
521
522
89.4k
  return IA_NO_ERROR;
523
89.4k
}
524
525
static VOID impd_drc_quantize_ducking_scaling(
526
892
    ia_drc_ducking_modifiers_struct *pstr_ducking_modifiers) {
527
892
  WORD32 mu;
528
892
  FLOAT32 delta;
529
530
892
  if (pstr_ducking_modifiers->ducking_scaling_present) {
531
0
    delta = pstr_ducking_modifiers->ducking_scaling - 1.0f;
532
533
0
    if (delta <= 0.0f) {
534
0
      mu = -1 + (WORD32)(0.5f - 8.0f * delta);
535
0
      if (mu != -1) {
536
0
        mu = MIN(7, mu);
537
0
        mu = MAX(0, mu);
538
0
        pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f - 0.125f * (1.0f + mu);
539
0
      } else {
540
0
        pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f;
541
0
        pstr_ducking_modifiers->ducking_scaling_present = FALSE;
542
0
      }
543
0
    } else {
544
0
      mu = -1 + (WORD32)(0.5f + 8.0f * delta);
545
0
      if (mu != -1) {
546
0
        mu = MIN(7, mu);
547
0
        mu = MAX(0, mu);
548
0
        pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f + 0.125f * (1.0f + mu);
549
0
      } else {
550
0
        pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f;
551
0
        pstr_ducking_modifiers->ducking_scaling_present = FALSE;
552
0
      }
553
0
    }
554
892
  } else {
555
892
    pstr_ducking_modifiers->ducking_scaling_quantized = 1.0f;
556
892
  }
557
892
}
558
559
static VOID impd_drc_enc_ducking_scaling(const FLOAT32 scaling, WORD32 *bits,
560
                                         FLOAT32 *scaling_quantized,
561
0
                                         WORD32 *remove_scaling_value) {
562
0
  WORD32 mu, sigma;
563
0
  FLOAT32 delta;
564
565
0
  delta = scaling - 1.0f;
566
0
  *remove_scaling_value = FALSE;
567
0
  if (delta <= 0.0f) {
568
0
    mu = -1 + (WORD32)(0.5f - 8.0f * delta);
569
0
    sigma = -1;
570
0
    *bits = 1 << 3;
571
0
  } else {
572
0
    mu = -1 + (WORD32)(0.5f + 8.0f * delta);
573
0
    sigma = 0;
574
0
    *bits = 0;
575
0
  }
576
0
  if (mu != -1) {
577
0
    mu = MIN(7, mu);
578
0
    mu = MAX(0, mu);
579
0
    *bits += mu;
580
0
    if (sigma == 0) {
581
0
      *scaling_quantized = 1.0f + 0.125f * (1.0f + mu);
582
0
    } else {
583
0
      *scaling_quantized = 1.0f - 0.125f * (1.0f + mu);
584
0
    }
585
0
  } else {
586
0
    *scaling_quantized = 1.0f;
587
0
    *remove_scaling_value = TRUE;
588
0
  }
589
0
}
590
591
static VOID impd_drc_enc_ducking_modifiers(
592
    ia_bit_buf_struct *it_bit_buf, ia_drc_ducking_modifiers_struct *pstr_ducking_modifiers,
593
1.92k
    WORD32 *ptr_bit_cnt) {
594
1.92k
  WORD32 bits;
595
1.92k
  WORD32 remove_scaling_value;
596
1.92k
  WORD32 bit_cnt_local = 0;
597
598
1.92k
  if (pstr_ducking_modifiers->ducking_scaling_present == FALSE) {
599
1.92k
    bit_cnt_local +=
600
1.92k
        iusace_write_bits_buf(it_bit_buf, pstr_ducking_modifiers->ducking_scaling_present, 1);
601
1.92k
  } else {
602
0
    impd_drc_enc_ducking_scaling(pstr_ducking_modifiers->ducking_scaling, &bits,
603
0
                                 &(pstr_ducking_modifiers->ducking_scaling_quantized),
604
0
                                 &remove_scaling_value);
605
606
0
    if (remove_scaling_value) {
607
0
      pstr_ducking_modifiers->ducking_scaling_present = FALSE;
608
0
    }
609
610
0
    bit_cnt_local +=
611
0
        iusace_write_bits_buf(it_bit_buf, pstr_ducking_modifiers->ducking_scaling_present, 1);
612
613
0
    if (pstr_ducking_modifiers->ducking_scaling_present) {
614
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bits, 4);
615
0
    }
616
0
  }
617
618
1.92k
  *ptr_bit_cnt += bit_cnt_local;
619
1.92k
}
620
621
static VOID impd_drc_enc_gain_modifiers(ia_bit_buf_struct *it_bit_buf, const WORD32 version,
622
                                        const WORD32 band_count,
623
                                        ia_drc_gain_modifiers_struct *pstr_gain_modifiers,
624
749
                                        WORD32 *ptr_bit_cnt) {
625
749
  LOOPIDX idx;
626
749
  WORD32 tmp, sign;
627
749
  WORD32 bit_cnt_local = 0;
628
629
749
  if (version == 1) {
630
635
    for (idx = 0; idx < band_count; idx++) {
631
312
      bit_cnt_local += iusace_write_bits_buf(
632
312
          it_bit_buf, pstr_gain_modifiers->target_characteristic_left_present[idx], 1);
633
312
      if (pstr_gain_modifiers->target_characteristic_left_present[idx]) {
634
0
        bit_cnt_local += iusace_write_bits_buf(
635
0
            it_bit_buf, pstr_gain_modifiers->target_characteristic_left_index[idx], 4);
636
0
      }
637
638
312
      bit_cnt_local += iusace_write_bits_buf(
639
312
          it_bit_buf, pstr_gain_modifiers->target_characteristic_right_present[idx], 1);
640
312
      if (pstr_gain_modifiers->target_characteristic_right_present[idx]) {
641
0
        bit_cnt_local += iusace_write_bits_buf(
642
0
            it_bit_buf, pstr_gain_modifiers->target_characteristic_right_index[idx], 4);
643
0
      }
644
645
312
      bit_cnt_local +=
646
312
          iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_scaling_present[idx], 1);
647
312
      if (pstr_gain_modifiers->gain_scaling_present[idx]) {
648
155
        tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->attenuation_scaling[idx]);
649
155
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4);
650
651
155
        tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->amplification_scaling[idx]);
652
155
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4);
653
155
      }
654
655
312
      bit_cnt_local +=
656
312
          iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_offset_present[idx], 1);
657
312
      if (pstr_gain_modifiers->gain_offset_present[idx]) {
658
148
        if (pstr_gain_modifiers->gain_offset[idx] >= 0.0f) {
659
95
          tmp = (WORD32)(0.5f + MAX(0.0f, 4.0f * pstr_gain_modifiers->gain_offset[idx] - 1.0f));
660
95
          sign = 0;
661
95
        } else {
662
53
          tmp = (WORD32)(0.5f + MAX(0.0f, -4.0f * pstr_gain_modifiers->gain_offset[idx] - 1.0f));
663
53
          sign = 1;
664
53
        }
665
148
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1);
666
148
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 5);
667
148
      }
668
312
    }
669
323
    if (band_count == 1) {
670
102
      bit_cnt_local +=
671
102
          iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->shape_filter_present, 1);
672
102
      if (pstr_gain_modifiers->shape_filter_present) {
673
0
        bit_cnt_local +=
674
0
            iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->shape_filter_index, 4);
675
0
      }
676
102
    }
677
426
  } else if (version == 0) {
678
426
    bit_cnt_local +=
679
426
        iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_scaling_present[0], 1);
680
681
426
    if (pstr_gain_modifiers->gain_scaling_present[0]) {
682
274
      tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->attenuation_scaling[0]);
683
274
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4);
684
685
274
      tmp = (WORD32)(0.5f + 8.0f * pstr_gain_modifiers->amplification_scaling[0]);
686
274
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 4);
687
274
    }
688
689
426
    bit_cnt_local +=
690
426
        iusace_write_bits_buf(it_bit_buf, pstr_gain_modifiers->gain_offset_present[0], 1);
691
426
    if (pstr_gain_modifiers->gain_offset_present[0]) {
692
252
      if (pstr_gain_modifiers->gain_offset[0] >= 0.0f) {
693
236
        tmp = (WORD32)(0.5f + MAX(0.0f, 4.0f * pstr_gain_modifiers->gain_offset[0] - 1.0f));
694
236
        sign = 0;
695
236
      } else {
696
16
        tmp = (WORD32)(0.5f + MAX(0.0f, -4.0f * pstr_gain_modifiers->gain_offset[0] - 1.0f));
697
16
        sign = 1;
698
16
      }
699
252
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1);
700
252
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 5);
701
252
    }
702
426
  }
703
704
749
  *ptr_bit_cnt += bit_cnt_local;
705
749
}
706
707
static IA_ERRORCODE impd_drc_write_loudness_measure(
708
    ia_bit_buf_struct *it_bit_buf, ia_drc_loudness_measure_struct *pstr_loudness_measure,
709
89.4k
    WORD32 *ptr_bit_cnt) {
710
89.4k
  IA_ERRORCODE err_code = IA_NO_ERROR;
711
89.4k
  WORD32 code, code_size;
712
89.4k
  WORD32 bit_cnt_local = 0;
713
714
89.4k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_measure->method_definition, 4);
715
716
89.4k
  err_code = impd_drc_enc_method_value(pstr_loudness_measure->method_definition,
717
89.4k
                                       pstr_loudness_measure->method_value, &code_size, &code);
718
89.4k
  if (err_code) return (err_code);
719
720
89.4k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size);
721
89.4k
  bit_cnt_local +=
722
89.4k
      iusace_write_bits_buf(it_bit_buf, pstr_loudness_measure->measurement_system, 4);
723
89.4k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_measure->reliability, 2);
724
725
89.4k
  *ptr_bit_cnt += bit_cnt_local;
726
727
89.4k
  return IA_NO_ERROR;
728
89.4k
}
729
730
static IA_ERRORCODE impd_drc_write_loudness_info(ia_bit_buf_struct *it_bit_buf,
731
                                                 const WORD32 version,
732
                                                 ia_drc_loudness_info_struct *pstr_loudness_info,
733
30.4k
                                                 WORD32 *ptr_bit_cnt) {
734
30.4k
  IA_ERRORCODE err_code = IA_NO_ERROR;
735
30.4k
  LOOPIDX idx;
736
30.4k
  WORD32 code, code_size;
737
30.4k
  WORD32 bit_cnt_local = 0;
738
739
30.4k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->drc_set_id, 6);
740
30.4k
  if (version >= 1) {
741
20.2k
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->eq_set_id, 6);
742
20.2k
  }
743
30.4k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->downmix_id, 7);
744
745
30.4k
  bit_cnt_local +=
746
30.4k
      iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->sample_peak_level_present, 1);
747
30.4k
  if (pstr_loudness_info->sample_peak_level_present) {
748
10.6k
    impd_drc_enc_peak(pstr_loudness_info->sample_peak_level, &code, &code_size);
749
750
10.6k
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size);
751
10.6k
  }
752
753
30.4k
  bit_cnt_local +=
754
30.4k
      iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->true_peak_level_present, 1);
755
30.4k
  if (pstr_loudness_info->true_peak_level_present) {
756
11.7k
    impd_drc_enc_peak(pstr_loudness_info->true_peak_level, &code, &code_size);
757
758
11.7k
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size);
759
760
11.7k
    bit_cnt_local += iusace_write_bits_buf(
761
11.7k
        it_bit_buf, pstr_loudness_info->true_peak_level_measurement_system, 4);
762
763
11.7k
    bit_cnt_local +=
764
11.7k
        iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->true_peak_level_reliability, 2);
765
11.7k
  }
766
767
30.4k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loudness_info->measurement_count, 4);
768
769
119k
  for (idx = 0; idx < pstr_loudness_info->measurement_count; idx++) {
770
89.4k
    err_code = impd_drc_write_loudness_measure(
771
89.4k
        it_bit_buf, &(pstr_loudness_info->str_loudness_measure[idx]), &bit_cnt_local);
772
773
89.4k
    if (err_code) return (err_code);
774
89.4k
  }
775
776
30.4k
  *ptr_bit_cnt += bit_cnt_local;
777
778
30.4k
  return IA_NO_ERROR;
779
30.4k
}
780
781
static IA_ERRORCODE impd_drc_write_drc_instruct_uni_drc(
782
    ia_bit_buf_struct *it_bit_buf, const WORD32 version,
783
    ia_drc_uni_drc_config_struct *pstr_uni_drc_config, ia_drc_gain_enc_struct *pstr_gain_enc,
784
    ia_drc_instructions_uni_drc *pstr_drc_instructions_uni_drc, VOID *ptr_scratch,
785
2.20k
    WORD32 *ptr_bit_cnt) {
786
2.20k
  IA_ERRORCODE err_code = IA_NO_ERROR;
787
2.20k
  LOOPIDX i, j, n;
788
2.20k
  WORD32 g, k, tmp, tmp_2, match, channel_count;
789
2.20k
  WORD32 bs_sequence_index, sequence_index_prev, repeat_sequence_count;
790
2.20k
  WORD32 ducking_sequence, index;
791
2.20k
  WORD32 repeat_parameters_count;
792
2.20k
  WORD32 bit_cnt_local = 0;
793
2.20k
  WORD32 band_count = 0;
794
2.20k
  WORD32 *unique_index;
795
2.20k
  FLOAT32 *unique_scaling;
796
2.20k
  FLOAT32 ducking_scaling_quantized_prev, factor;
797
2.20k
  ia_drc_ducking_modifiers_struct *pstr_ducking_modifiers;
798
799
2.20k
  bit_cnt_local +=
800
2.20k
      iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_id, 6);
801
2.20k
  if (version == 1) {
802
910
    err_code = impd_drc_get_drc_complexity_level(pstr_uni_drc_config, pstr_gain_enc,
803
910
                                                 pstr_drc_instructions_uni_drc, ptr_scratch);
804
910
    if (err_code & IA_FATAL_ERROR) {
805
228
      return (err_code);
806
228
    }
807
808
682
    bit_cnt_local += iusace_write_bits_buf(
809
682
        it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_complexity_level, 4);
810
682
  }
811
812
1.97k
  unique_index = (WORD32 *)ptr_scratch;
813
1.97k
  unique_scaling =
814
1.97k
      (FLOAT32 *)((UWORD8 *)ptr_scratch + (MAX_CHANNEL_COUNT) * sizeof(unique_index[0]));
815
1.97k
  bit_cnt_local +=
816
1.97k
      iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->drc_location, 4);
817
818
1.97k
  if (version != 1) {
819
1.29k
    pstr_drc_instructions_uni_drc->downmix_id_present = 1;
820
1.29k
  } else {
821
682
    bit_cnt_local +=
822
682
        iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->downmix_id_present, 1);
823
682
  }
824
825
1.97k
  if (pstr_drc_instructions_uni_drc->downmix_id_present != 1) {
826
682
    pstr_drc_instructions_uni_drc->downmix_id = 0;
827
1.29k
  } else {
828
1.29k
    bit_cnt_local +=
829
1.29k
        iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->downmix_id, 7);
830
1.29k
    if (version == 1) {
831
0
      bit_cnt_local += iusace_write_bits_buf(
832
0
          it_bit_buf, pstr_drc_instructions_uni_drc->drc_apply_to_downmix, 1);
833
0
    }
834
1.29k
    bit_cnt_local += iusace_write_bits_buf(
835
1.29k
        it_bit_buf, pstr_drc_instructions_uni_drc->additional_downmix_id_present, 1);
836
837
1.29k
    if (pstr_drc_instructions_uni_drc->additional_downmix_id_present) {
838
731
      bit_cnt_local += iusace_write_bits_buf(
839
731
          it_bit_buf, pstr_drc_instructions_uni_drc->additional_downmix_id_count, 3);
840
4.02k
      for (i = 0; i < pstr_drc_instructions_uni_drc->additional_downmix_id_count; i++) {
841
3.29k
        bit_cnt_local += iusace_write_bits_buf(
842
3.29k
            it_bit_buf, pstr_drc_instructions_uni_drc->additional_downmix_id[i], 7);
843
3.29k
      }
844
731
    } else {
845
564
      pstr_drc_instructions_uni_drc->additional_downmix_id_count = 0;
846
564
    }
847
1.29k
  }
848
849
1.97k
  bit_cnt_local +=
850
1.97k
      iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_effect, 16);
851
852
1.97k
  if ((pstr_drc_instructions_uni_drc->drc_set_effect &
853
1.97k
       (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) == 0) {
854
948
    bit_cnt_local += iusace_write_bits_buf(
855
948
        it_bit_buf, pstr_drc_instructions_uni_drc->limiter_peak_target_present, 1);
856
948
    if (pstr_drc_instructions_uni_drc->limiter_peak_target_present) {
857
404
      tmp = (WORD32)(0.5f - 8.0f * pstr_drc_instructions_uni_drc->limiter_peak_target);
858
404
      tmp = MAX(0, tmp);
859
404
      tmp = MIN(0xFF, tmp);
860
404
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, tmp, 8);
861
404
    }
862
948
  }
863
864
1.97k
  bit_cnt_local += iusace_write_bits_buf(
865
1.97k
      it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_present, 1);
866
867
1.97k
  if (pstr_drc_instructions_uni_drc->drc_set_target_loudness_present == 1) {
868
1.03k
    bit_cnt_local += iusace_write_bits_buf(
869
1.03k
        it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_upper + 63, 6);
870
871
1.03k
    bit_cnt_local += iusace_write_bits_buf(
872
1.03k
        it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower_present,
873
1.03k
        1);
874
1.03k
    if (pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower_present == 1) {
875
835
      bit_cnt_local += iusace_write_bits_buf(
876
835
          it_bit_buf, pstr_drc_instructions_uni_drc->drc_set_target_loudness_value_lower + 63, 6);
877
835
    }
878
1.03k
  }
879
880
1.97k
  bit_cnt_local += iusace_write_bits_buf(
881
1.97k
      it_bit_buf, pstr_drc_instructions_uni_drc->depends_on_drc_set_present, 1);
882
883
1.97k
  if (pstr_drc_instructions_uni_drc->depends_on_drc_set_present) {
884
1.08k
    bit_cnt_local +=
885
1.08k
        iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->depends_on_drc_set, 6);
886
1.08k
  } else {
887
897
    bit_cnt_local +=
888
897
        iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->no_independent_use, 1);
889
897
  }
890
891
1.97k
  if (version == 1) {
892
682
    bit_cnt_local +=
893
682
        iusace_write_bits_buf(it_bit_buf, pstr_drc_instructions_uni_drc->requires_eq, 1);
894
682
  }
895
896
1.97k
  channel_count = pstr_uni_drc_config->str_channel_layout.base_ch_count;
897
1.97k
  if (pstr_drc_instructions_uni_drc->drc_set_effect &
898
1.97k
      (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) {
899
1.02k
    i = 0;
900
2.95k
    while (i < channel_count) {
901
1.92k
      pstr_ducking_modifiers = pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel;
902
1.92k
      bs_sequence_index = pstr_drc_instructions_uni_drc->gain_set_index[i] + 1;
903
904
1.92k
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_sequence_index, 6);
905
906
1.92k
      impd_drc_enc_ducking_modifiers(it_bit_buf, &(pstr_ducking_modifiers[i]), &bit_cnt_local);
907
908
1.92k
      sequence_index_prev = pstr_drc_instructions_uni_drc->gain_set_index[i];
909
1.92k
      ducking_scaling_quantized_prev = pstr_ducking_modifiers[i].ducking_scaling_quantized;
910
1.92k
      i++;
911
912
1.92k
      if (i < channel_count) {
913
892
        impd_drc_quantize_ducking_scaling(&(pstr_ducking_modifiers[i]));
914
892
      }
915
916
1.92k
      repeat_parameters_count = 0;
917
1.92k
      while ((i < channel_count) && (repeat_parameters_count <= 32) &&
918
892
             (sequence_index_prev == pstr_drc_instructions_uni_drc->gain_set_index[i]) &&
919
813
             (ducking_scaling_quantized_prev ==
920
813
              pstr_ducking_modifiers[i].ducking_scaling_quantized)) {
921
0
        repeat_parameters_count++;
922
0
        i++;
923
0
        if (i < channel_count) {
924
0
          impd_drc_quantize_ducking_scaling(&(pstr_ducking_modifiers[i]));
925
0
        }
926
0
      }
927
1.92k
      if (repeat_parameters_count <= 0) {
928
1.92k
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1);
929
1.92k
      } else {
930
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 1, 1);
931
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, repeat_parameters_count - 1, 5);
932
0
      }
933
1.92k
    }
934
9.26k
    for (j = 0; j < MAX_CHANNEL_COUNT; j++) {
935
8.23k
      unique_index[j] = -10;
936
8.23k
      unique_scaling[j] = -10.0f;
937
8.23k
    }
938
939
1.02k
    ducking_sequence = -1;
940
1.02k
    g = 0;
941
942
1.02k
    if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
943
2.12k
      for (j = 0; j < channel_count; j++) {
944
1.39k
        match = FALSE;
945
1.39k
        index = pstr_drc_instructions_uni_drc->gain_set_index[j];
946
1.39k
        factor =
947
1.39k
            pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel[j].ducking_scaling;
948
1.45k
        for (n = 0; n < g; n++) {
949
653
          if ((index >= 0) && (unique_index[n] == index) && (unique_scaling[n] == factor)) {
950
587
            match = TRUE;
951
587
            break;
952
587
          }
953
653
        }
954
1.39k
        if (match == FALSE) {
955
803
          if (index >= 0) {
956
803
            unique_index[g] = index;
957
803
            unique_scaling[g] = factor;
958
803
            g++;
959
803
          }
960
803
        }
961
1.39k
      }
962
737
      pstr_drc_instructions_uni_drc->num_drc_channel_groups = g;
963
737
    } else if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_OTHER) {
964
814
      for (j = 0; j < channel_count; j++) {
965
531
        match = FALSE;
966
531
        index = pstr_drc_instructions_uni_drc->gain_set_index[j];
967
531
        factor =
968
531
            pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel[j].ducking_scaling;
969
531
        for (n = 0; n < g; n++) {
970
0
          if (((index >= 0) && (unique_index[n] == index)) ||
971
0
              ((index < 0) && (unique_scaling[n] == factor))) {
972
0
            match = TRUE;
973
0
            break;
974
0
          }
975
0
        }
976
531
        if (match == FALSE) {
977
531
          if (index < 0) {
978
0
            unique_index[g] = index;
979
0
            unique_scaling[g] = factor;
980
0
            g++;
981
531
          } else {
982
531
            if ((ducking_sequence > 0) && (ducking_sequence != index)) {
983
9
              return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
984
9
            }
985
522
            ducking_sequence = index;
986
522
          }
987
531
        }
988
531
      }
989
283
      pstr_drc_instructions_uni_drc->num_drc_channel_groups = g;
990
283
      if (ducking_sequence < 0) {
991
0
        return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
992
0
      }
993
283
    }
994
995
1.82k
    for (g = 0; g < pstr_drc_instructions_uni_drc->num_drc_channel_groups; g++) {
996
803
      if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
997
803
        pstr_drc_instructions_uni_drc->gain_set_index_for_channel_group[g] = unique_index[g];
998
803
      } else if (pstr_drc_instructions_uni_drc->drc_set_effect & EFFECT_BIT_DUCK_OTHER) {
999
0
        pstr_drc_instructions_uni_drc->gain_set_index_for_channel_group[g] = -1;
1000
0
      }
1001
1002
803
      pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel_group[g].ducking_scaling =
1003
803
          unique_scaling[g];
1004
803
      if (unique_scaling[g] == 1.0f) {
1005
0
        pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel_group[g]
1006
0
            .ducking_scaling_present = FALSE;
1007
803
      } else {
1008
803
        pstr_drc_instructions_uni_drc->str_ducking_modifiers_for_channel_group[g]
1009
803
            .ducking_scaling_present = TRUE;
1010
803
      }
1011
803
    }
1012
1.02k
  } else {
1013
948
    if ((version == 0 || pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0) &&
1014
657
        ((pstr_drc_instructions_uni_drc->downmix_id == 0x7F) ||
1015
594
         (pstr_drc_instructions_uni_drc->additional_downmix_id_count != 0))) {
1016
370
      channel_count = 1;
1017
578
    } else if ((version == 0 || pstr_drc_instructions_uni_drc->drc_apply_to_downmix != 0) &&
1018
287
               (pstr_drc_instructions_uni_drc->downmix_id != 0) &&
1019
234
               (pstr_drc_instructions_uni_drc->downmix_id != 0x7F) &&
1020
234
               (pstr_drc_instructions_uni_drc->additional_downmix_id_count == 0)) {
1021
511
      for (i = 0; i < pstr_uni_drc_config->downmix_instructions_count; i++) {
1022
277
        if (pstr_drc_instructions_uni_drc->downmix_id ==
1023
277
            pstr_uni_drc_config->str_downmix_instructions[i].downmix_id) {
1024
0
          break;
1025
0
        }
1026
277
      }
1027
234
      if (i == pstr_uni_drc_config->downmix_instructions_count) {
1028
234
        return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
1029
234
      }
1030
0
      channel_count = pstr_uni_drc_config->str_downmix_instructions[i].target_ch_count;
1031
0
    }
1032
1033
714
    i = 0;
1034
1.46k
    while (i < channel_count) {
1035
749
      bs_sequence_index = pstr_drc_instructions_uni_drc->gain_set_index[i] + 1;
1036
749
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_sequence_index, 6);
1037
749
      sequence_index_prev = pstr_drc_instructions_uni_drc->gain_set_index[i];
1038
749
      i++;
1039
1040
749
      repeat_sequence_count = 0;
1041
1.00k
      while ((i < channel_count) &&
1042
288
             (sequence_index_prev == pstr_drc_instructions_uni_drc->gain_set_index[i]) &&
1043
253
             (repeat_sequence_count <= 32)) {
1044
253
        repeat_sequence_count++;
1045
253
        i++;
1046
253
      }
1047
749
      if (repeat_sequence_count <= 0) {
1048
496
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1);
1049
496
      } else {
1050
253
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 1, 1);
1051
253
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, repeat_sequence_count - 1, 5);
1052
253
      }
1053
749
    }
1054
6.42k
    for (i = 0; i < MAX_CHANNEL_COUNT; i++) {
1055
5.71k
      unique_index[i] = -1;
1056
5.71k
    }
1057
1058
714
    k = 0;
1059
1.71k
    for (i = 0; i < channel_count; i++) {
1060
1.00k
      tmp_2 = pstr_drc_instructions_uni_drc->gain_set_index[i];
1061
1.00k
      if (tmp_2 >= 0) {
1062
1.00k
        match = FALSE;
1063
1.29k
        for (n = 0; n < k; n++) {
1064
288
          if (unique_index[n] == tmp_2) {
1065
253
            match = TRUE;
1066
253
          }
1067
288
        }
1068
1.00k
        if (match == FALSE) {
1069
749
          unique_index[k] = tmp_2;
1070
749
          k++;
1071
749
        }
1072
1.00k
      }
1073
1.00k
    }
1074
714
    pstr_drc_instructions_uni_drc->num_drc_channel_groups = k;
1075
1.46k
    for (i = 0; i < pstr_drc_instructions_uni_drc->num_drc_channel_groups; i++) {
1076
749
      band_count = 0;
1077
749
      pstr_drc_instructions_uni_drc->gain_set_index_for_channel_group[i] = unique_index[i];
1078
1079
749
      if (pstr_uni_drc_config->str_uni_drc_config_ext.drc_coefficients_uni_drc_v1_count > 0) {
1080
272
        band_count =
1081
272
            pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0]
1082
272
                .str_gain_set_params[pstr_drc_instructions_uni_drc
1083
272
                                         ->gain_set_index_for_channel_group[i]]
1084
272
                .band_count;
1085
477
      } else if (pstr_uni_drc_config->drc_coefficients_uni_drc_count > 0) {
1086
147
        band_count = pstr_uni_drc_config->str_drc_coefficients_uni_drc[0]
1087
147
                         .str_gain_set_params[pstr_drc_instructions_uni_drc
1088
147
                                                  ->gain_set_index_for_channel_group[i]]
1089
147
                         .band_count;
1090
147
      }
1091
1092
749
      impd_drc_enc_gain_modifiers(it_bit_buf, version, band_count,
1093
749
                                  &(pstr_drc_instructions_uni_drc->str_gain_modifiers[i]),
1094
749
                                  &bit_cnt_local);
1095
749
    }
1096
714
  }
1097
1098
1.73k
  *ptr_bit_cnt += bit_cnt_local;
1099
1.73k
  return err_code;
1100
1.97k
}
1101
1102
#ifdef LOUDNESS_LEVELING_SUPPORT
1103
static UWORD32 get_num_ducking_only_drc_sets(
1104
    ia_drc_instructions_uni_drc const *pstr_drc_instructions_uni_drc,
1105
3.30k
    UWORD32 drc_intructions_uni_drc_count) {
1106
3.30k
  UWORD32 num_ducking_only_drc_sets = 0;
1107
9.82k
  for (UWORD16 i = 0; i < drc_intructions_uni_drc_count; i++) {
1108
6.52k
    if (pstr_drc_instructions_uni_drc[i].ducking_only_set_present) {
1109
809
      num_ducking_only_drc_sets++;
1110
809
    }
1111
6.52k
  }
1112
1113
3.30k
  return num_ducking_only_drc_sets;
1114
3.30k
}
1115
1116
static WORD32 write_loudness_leveling_extension(ia_bit_buf_struct *it_bit_buf,
1117
                                                ia_drc_uni_drc_config_struct *pstr_uni_drc_config,
1118
                                                ia_drc_gain_enc_struct *pstr_gain_enc,
1119
182
                                                VOID *ptr_scratch, WORD32 *bit_cnt) {
1120
182
  IA_ERRORCODE err_code = IA_NO_ERROR;
1121
182
  WORD32 bit_cnt_local = 0;
1122
182
  WORD32 drc_instructions_uni_drc_count_v1 =
1123
182
      pstr_uni_drc_config->str_uni_drc_config_ext.drc_instructions_uni_drc_v1_count;
1124
182
  WORD32 drc_instructions_uni_drc_count = pstr_uni_drc_config->drc_instructions_uni_drc_count;
1125
182
  WORD32 version = 0;
1126
  // V0 instructions
1127
182
  for (WORD16 i = 0; i < drc_instructions_uni_drc_count; i++) {
1128
0
    ia_drc_instructions_uni_drc *pstr_drc_instruction =
1129
0
        &pstr_uni_drc_config->str_drc_instructions_uni_drc[i];
1130
0
    if (pstr_drc_instruction->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
1131
0
      if (i > 0 && pstr_uni_drc_config->str_drc_instructions_uni_drc[i - 1].leveling_present &&
1132
0
          pstr_uni_drc_config->str_drc_instructions_uni_drc[i - 1].ducking_only_set_present) {
1133
0
        err_code = impd_drc_write_drc_instruct_uni_drc(it_bit_buf, version, pstr_uni_drc_config,
1134
0
                                                       pstr_gain_enc, pstr_drc_instruction,
1135
0
                                                       ptr_scratch, &bit_cnt_local);
1136
0
        if (err_code & IA_FATAL_ERROR) {
1137
0
          return (err_code);
1138
0
        }
1139
0
      } else {
1140
0
        bit_cnt_local +=
1141
0
            iusace_write_bits_buf(it_bit_buf, pstr_drc_instruction->leveling_present, 1);
1142
0
        if (pstr_drc_instruction->leveling_present) {
1143
0
          bit_cnt_local += iusace_write_bits_buf(
1144
0
              it_bit_buf, pstr_drc_instruction->ducking_only_set_present, 1);
1145
0
        }
1146
0
      }
1147
0
    }
1148
0
  }
1149
1150
  // V1 instructions
1151
182
  version = 1;
1152
620
  for (WORD16 i = 0; i < drc_instructions_uni_drc_count_v1; i++) {
1153
453
    ia_drc_instructions_uni_drc *pstr_drc_instruction =
1154
453
        &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_instructions_uni_drc_v1[i];
1155
453
    if (pstr_drc_instruction->drc_set_effect & EFFECT_BIT_DUCK_SELF) {
1156
315
      if (i > 0 &&
1157
218
          pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_instructions_uni_drc_v1[i - 1]
1158
218
              .leveling_present &&
1159
93
          pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_instructions_uni_drc_v1[i - 1]
1160
93
              .ducking_only_set_present) {
1161
76
        err_code = impd_drc_write_drc_instruct_uni_drc(it_bit_buf, version, pstr_uni_drc_config,
1162
76
                                                       pstr_gain_enc, pstr_drc_instruction,
1163
76
                                                       ptr_scratch, &bit_cnt_local);
1164
76
        if (err_code & IA_FATAL_ERROR) {
1165
15
          return (err_code);
1166
15
        }
1167
239
      } else {
1168
239
        bit_cnt_local +=
1169
239
            iusace_write_bits_buf(it_bit_buf, pstr_drc_instruction->leveling_present, 1);
1170
239
        if (pstr_drc_instruction->leveling_present) {
1171
125
          bit_cnt_local += iusace_write_bits_buf(
1172
125
              it_bit_buf, pstr_drc_instruction->ducking_only_set_present, 1);
1173
125
        }
1174
239
      }
1175
315
    }
1176
453
  }
1177
167
  *bit_cnt += bit_cnt_local;
1178
167
  return IA_NO_ERROR;
1179
182
}
1180
#endif
1181
1182
static VOID impd_drc_write_gain_params(ia_bit_buf_struct *it_bit_buf, const WORD32 version,
1183
                                       const WORD32 band_count, const WORD32 drc_band_type,
1184
                                       ia_drc_gain_params_struct *pstr_gain_params,
1185
5.94k
                                       WORD32 *ptr_bit_cnt) {
1186
5.94k
  LOOPIDX idx;
1187
5.94k
  WORD32 bit_cnt_local = 0;
1188
1189
5.94k
  if (version != 1) {
1190
4.29k
    for (idx = 0; idx < band_count; idx++) {
1191
938
      bit_cnt_local +=
1192
938
          iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].drc_characteristic, 7);
1193
938
    }
1194
3.35k
  } else {
1195
2.58k
    WORD32 index_present;
1196
2.58k
    WORD32 gain_sequence_index_last = -1;
1197
5.26k
    for (idx = 0; idx < band_count; idx++) {
1198
2.68k
      if (pstr_gain_params[idx].gain_sequence_index == gain_sequence_index_last + 1) {
1199
2.68k
        index_present = 0;
1200
2.68k
      } else {
1201
0
        index_present = 1;
1202
0
      }
1203
2.68k
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, index_present, 1);
1204
1205
2.68k
      if (index_present == 1) {
1206
0
        bit_cnt_local +=
1207
0
            iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].gain_sequence_index, 6);
1208
0
        gain_sequence_index_last = pstr_gain_params[idx].gain_sequence_index;
1209
0
      }
1210
1211
2.68k
      bit_cnt_local +=
1212
2.68k
          iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].drc_characteristic_present, 1);
1213
2.68k
      if (pstr_gain_params[idx].drc_characteristic_present) {
1214
0
        bit_cnt_local += iusace_write_bits_buf(
1215
0
            it_bit_buf, pstr_gain_params[idx].drc_characteristic_format_is_cicp, 1);
1216
0
        if (pstr_gain_params[idx].drc_characteristic_format_is_cicp == 1) {
1217
0
          bit_cnt_local +=
1218
0
              iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].drc_characteristic, 7);
1219
0
        } else {
1220
0
          bit_cnt_local += iusace_write_bits_buf(
1221
0
              it_bit_buf, pstr_gain_params[idx].drc_characteristic_left_index, 4);
1222
1223
0
          bit_cnt_local += iusace_write_bits_buf(
1224
0
              it_bit_buf, pstr_gain_params[idx].drc_characteristic_right_index, 4);
1225
0
        }
1226
0
      }
1227
2.68k
    }
1228
2.58k
  }
1229
1230
6.93k
  for (idx = 1; idx < band_count; idx++) {
1231
991
    if (drc_band_type) {
1232
29
      bit_cnt_local +=
1233
29
          iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].crossover_freq_index, 4);
1234
962
    } else {
1235
962
      bit_cnt_local +=
1236
962
          iusace_write_bits_buf(it_bit_buf, pstr_gain_params[idx].start_sub_band_index, 10);
1237
962
    }
1238
991
  }
1239
1240
5.94k
  *ptr_bit_cnt += bit_cnt_local;
1241
5.94k
}
1242
1243
static VOID impd_drc_write_gain_set_params(ia_bit_buf_struct *it_bit_buf, const WORD32 version,
1244
                                           ia_drc_gain_set_params_struct *pstr_gain_set_params,
1245
7.89k
                                           WORD32 *ptr_bit_cnt) {
1246
7.89k
  WORD32 bit_cnt_local = 0;
1247
1248
7.89k
  bit_cnt_local +=
1249
7.89k
      iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->gain_coding_profile, 2);
1250
1251
7.89k
  bit_cnt_local +=
1252
7.89k
      iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->gain_interpolation_type, 1);
1253
1254
7.89k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->full_frame, 1);
1255
1256
7.89k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->time_alignment, 1);
1257
1258
7.89k
  bit_cnt_local +=
1259
7.89k
      iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->time_delta_min_present, 1);
1260
1261
7.89k
  if (pstr_gain_set_params->time_delta_min_present) {
1262
3.00k
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->delta_tmin - 1, 11);
1263
3.00k
  }
1264
7.89k
  if (pstr_gain_set_params->gain_coding_profile != GAIN_CODING_PROFILE_CONSTANT) {
1265
5.94k
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->band_count, 4);
1266
5.94k
    if (pstr_gain_set_params->band_count > 1) {
1267
987
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_gain_set_params->drc_band_type, 1);
1268
987
    }
1269
1270
5.94k
    impd_drc_write_gain_params(it_bit_buf, version, pstr_gain_set_params->band_count,
1271
5.94k
                               pstr_gain_set_params->drc_band_type,
1272
5.94k
                               pstr_gain_set_params->gain_params, &bit_cnt_local);
1273
5.94k
  }
1274
1275
7.89k
  *ptr_bit_cnt += bit_cnt_local;
1276
7.89k
}
1277
1278
static VOID impd_drc_write_split_drc_characteristic(
1279
    ia_bit_buf_struct *it_bit_buf, const WORD32 side,
1280
0
    ia_drc_split_drc_characteristic_struct *pstr_split_characteristic, WORD32 *ptr_bit_cnt) {
1281
0
  LOOPIDX idx;
1282
0
  WORD32 bs_node_gain, bs_node_level_delta;
1283
0
  WORD32 bit_cnt_local = 0;
1284
0
  FLOAT32 bs_node_level_previous;
1285
1286
0
  bit_cnt_local +=
1287
0
      iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->characteristic_format, 1);
1288
1289
0
  if (pstr_split_characteristic->characteristic_format != 0) {
1290
0
    bs_node_level_previous = DRC_INPUT_LOUDNESS_TARGET;
1291
1292
0
    bit_cnt_local += iusace_write_bits_buf(
1293
0
        it_bit_buf, pstr_split_characteristic->characteristic_node_count - 1, 2);
1294
1295
0
    for (idx = 1; idx <= pstr_split_characteristic->characteristic_node_count; idx++) {
1296
0
      bs_node_level_delta = (WORD32)(floor(fabs(pstr_split_characteristic->node_level[idx] -
1297
0
                                                bs_node_level_previous) +
1298
0
                0.5f) -
1299
0
          1);
1300
1301
0
      if (bs_node_level_delta < 0) {
1302
0
        bs_node_level_delta = 0;
1303
0
      }
1304
0
      if (bs_node_level_delta > 31) {
1305
0
        bs_node_level_delta = 31;
1306
0
      }
1307
0
      if (side == RIGHT_SIDE) {
1308
0
        bs_node_level_previous = bs_node_level_previous + (bs_node_level_delta + 1);
1309
0
      } else {
1310
0
        bs_node_level_previous = bs_node_level_previous - (bs_node_level_delta + 1);
1311
0
      }
1312
1313
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_node_level_delta, 5);
1314
1315
0
      bs_node_gain =
1316
0
          (WORD32)floor((pstr_split_characteristic->node_gain[idx] + 64.0f) * 2.0f + 0.5f);
1317
1318
0
      if (bs_node_gain < 0) {
1319
0
        bs_node_gain = 0;
1320
0
      }
1321
0
      if (bs_node_gain > 255) {
1322
0
        bs_node_gain = 255;
1323
0
      }
1324
1325
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_node_gain, 8);
1326
0
    }
1327
0
  } else {
1328
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->bs_gain, 6);
1329
1330
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->bs_io_ratio, 4);
1331
1332
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->bs_exp, 4);
1333
1334
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_split_characteristic->flip_sign, 1);
1335
0
  }
1336
1337
0
  *ptr_bit_cnt += bit_cnt_local;
1338
0
}
1339
1340
static VOID impd_drc_write_shape_filter_block_params(
1341
    ia_bit_buf_struct *it_bit_buf,
1342
    ia_drc_shape_filter_block_params_struct *pstr_shape_filter_block_params,
1343
0
    WORD32 *ptr_bit_cnt) {
1344
0
  WORD32 bit_cnt_local = 0;
1345
1346
0
  bit_cnt_local +=
1347
0
      iusace_write_bits_buf(it_bit_buf, pstr_shape_filter_block_params->lf_cut_filter_present, 1);
1348
0
  if (pstr_shape_filter_block_params->lf_cut_filter_present == 1) {
1349
0
    bit_cnt_local += iusace_write_bits_buf(
1350
0
        it_bit_buf, pstr_shape_filter_block_params->str_lf_cut_params.corner_freq_index, 3);
1351
1352
0
    bit_cnt_local += iusace_write_bits_buf(
1353
0
        it_bit_buf, pstr_shape_filter_block_params->str_lf_cut_params.filter_strength_index, 2);
1354
0
  }
1355
1356
0
  bit_cnt_local += iusace_write_bits_buf(
1357
0
      it_bit_buf, pstr_shape_filter_block_params->lf_boost_filter_present, 1);
1358
0
  if (pstr_shape_filter_block_params->lf_boost_filter_present == 1) {
1359
0
    bit_cnt_local += iusace_write_bits_buf(
1360
0
        it_bit_buf, pstr_shape_filter_block_params->str_lf_boost_params.corner_freq_index, 3);
1361
1362
0
    bit_cnt_local += iusace_write_bits_buf(
1363
0
        it_bit_buf, pstr_shape_filter_block_params->str_lf_boost_params.filter_strength_index, 2);
1364
0
  }
1365
1366
0
  bit_cnt_local +=
1367
0
      iusace_write_bits_buf(it_bit_buf, pstr_shape_filter_block_params->hf_cut_filter_present, 1);
1368
0
  if (pstr_shape_filter_block_params->hf_cut_filter_present == 1) {
1369
0
    bit_cnt_local += iusace_write_bits_buf(
1370
0
        it_bit_buf, pstr_shape_filter_block_params->str_hf_cut_params.corner_freq_index, 3);
1371
1372
0
    bit_cnt_local += iusace_write_bits_buf(
1373
0
        it_bit_buf, pstr_shape_filter_block_params->str_hf_cut_params.filter_strength_index, 2);
1374
0
  }
1375
1376
0
  bit_cnt_local += iusace_write_bits_buf(
1377
0
      it_bit_buf, pstr_shape_filter_block_params->hf_boost_filter_present, 1);
1378
0
  if (pstr_shape_filter_block_params->hf_boost_filter_present == 1) {
1379
0
    bit_cnt_local += iusace_write_bits_buf(
1380
0
        it_bit_buf, pstr_shape_filter_block_params->str_hf_boost_params.corner_freq_index, 3);
1381
1382
0
    bit_cnt_local += iusace_write_bits_buf(
1383
0
        it_bit_buf, pstr_shape_filter_block_params->str_hf_boost_params.filter_strength_index, 2);
1384
0
  }
1385
1386
0
  *ptr_bit_cnt += bit_cnt_local;
1387
0
}
1388
1389
static VOID impd_drc_write_drc_coeff_uni_drc(
1390
    ia_bit_buf_struct *it_bit_buf, const WORD32 version,
1391
4.38k
    ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc, WORD32 *ptr_bit_cnt) {
1392
4.38k
  LOOPIDX idx;
1393
4.38k
  WORD32 bit_cnt_local = 0;
1394
1395
4.38k
  bit_cnt_local +=
1396
4.38k
      iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->drc_location, 4);
1397
1398
4.38k
  bit_cnt_local +=
1399
4.38k
      iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->drc_frame_size_present, 1);
1400
1401
4.38k
  if (pstr_drc_coefficients_uni_drc->drc_frame_size_present) {
1402
144
    bit_cnt_local += iusace_write_bits_buf(
1403
144
        it_bit_buf, (pstr_drc_coefficients_uni_drc->drc_frame_size - 1), 15);
1404
144
  }
1405
1406
4.38k
  if (version != 1) {
1407
2.28k
    bit_cnt_local +=
1408
2.28k
        iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->gain_set_count, 6);
1409
1410
5.99k
    for (idx = 0; idx < pstr_drc_coefficients_uni_drc->gain_set_count; idx++) {
1411
3.70k
      impd_drc_write_gain_set_params(it_bit_buf, version,
1412
3.70k
                                     &(pstr_drc_coefficients_uni_drc->str_gain_set_params[idx]),
1413
3.70k
                                     &bit_cnt_local);
1414
3.70k
    }
1415
2.28k
  } else {
1416
2.10k
    bit_cnt_local += iusace_write_bits_buf(
1417
2.10k
        it_bit_buf, pstr_drc_coefficients_uni_drc->drc_characteristic_left_present, 1);
1418
2.10k
    if (pstr_drc_coefficients_uni_drc->drc_characteristic_left_present) {
1419
0
      bit_cnt_local += iusace_write_bits_buf(
1420
0
          it_bit_buf, pstr_drc_coefficients_uni_drc->characteristic_left_count, 4);
1421
1422
0
      for (idx = 1; idx <= pstr_drc_coefficients_uni_drc->characteristic_left_count; idx++) {
1423
0
        impd_drc_write_split_drc_characteristic(
1424
0
            it_bit_buf, LEFT_SIDE,
1425
0
            &pstr_drc_coefficients_uni_drc->str_split_characteristic_left[idx], &bit_cnt_local);
1426
0
      }
1427
0
    }
1428
1429
2.10k
    bit_cnt_local += iusace_write_bits_buf(
1430
2.10k
        it_bit_buf, pstr_drc_coefficients_uni_drc->drc_characteristic_right_present, 1);
1431
2.10k
    if (pstr_drc_coefficients_uni_drc->drc_characteristic_right_present) {
1432
0
      bit_cnt_local += iusace_write_bits_buf(
1433
0
          it_bit_buf, pstr_drc_coefficients_uni_drc->characteristic_right_count, 4);
1434
0
      for (idx = 1; idx <= pstr_drc_coefficients_uni_drc->characteristic_right_count; idx++) {
1435
0
        impd_drc_write_split_drc_characteristic(
1436
0
            it_bit_buf, RIGHT_SIDE,
1437
0
            &pstr_drc_coefficients_uni_drc->str_split_characteristic_right[idx], &bit_cnt_local);
1438
0
      }
1439
0
    }
1440
1441
2.10k
    bit_cnt_local += iusace_write_bits_buf(
1442
2.10k
        it_bit_buf, pstr_drc_coefficients_uni_drc->shape_filters_present, 1);
1443
2.10k
    if (pstr_drc_coefficients_uni_drc->shape_filters_present) {
1444
0
      bit_cnt_local +=
1445
0
          iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->shape_filter_count, 4);
1446
0
      for (idx = 1; idx <= pstr_drc_coefficients_uni_drc->shape_filter_count; idx++) {
1447
0
        impd_drc_write_shape_filter_block_params(
1448
0
            it_bit_buf, &pstr_drc_coefficients_uni_drc->str_shape_filter_block_params[idx],
1449
0
            &bit_cnt_local);
1450
0
      }
1451
0
    }
1452
1453
2.10k
    bit_cnt_local +=
1454
2.10k
        iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->gain_sequence_count, 6);
1455
1456
2.10k
    bit_cnt_local +=
1457
2.10k
        iusace_write_bits_buf(it_bit_buf, pstr_drc_coefficients_uni_drc->gain_set_count, 6);
1458
1459
6.29k
    for (idx = 0; idx < pstr_drc_coefficients_uni_drc->gain_set_count; idx++) {
1460
4.19k
      impd_drc_write_gain_set_params(it_bit_buf, version,
1461
4.19k
                                     &(pstr_drc_coefficients_uni_drc->str_gain_set_params[idx]),
1462
4.19k
                                     &bit_cnt_local);
1463
4.19k
    }
1464
2.10k
  }
1465
1466
4.38k
  *ptr_bit_cnt += bit_cnt_local;
1467
4.38k
}
1468
1469
static VOID impd_drc_write_downmix_instructions(
1470
    ia_bit_buf_struct *it_bit_buf, const WORD32 version, ia_drc_gain_enc_struct *pstr_gain_enc,
1471
904
    ia_drc_downmix_instructions_struct *pstr_downmix_instructions, WORD32 *ptr_bit_cnt) {
1472
904
  LOOPIDX idx;
1473
904
  WORD32 code, code_size;
1474
904
  WORD32 bit_cnt_local = 0;
1475
1476
904
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_downmix_instructions->downmix_id, 7);
1477
1478
904
  bit_cnt_local +=
1479
904
      iusace_write_bits_buf(it_bit_buf, pstr_downmix_instructions->target_ch_count, 7);
1480
1481
904
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_downmix_instructions->target_layout, 8);
1482
1483
904
  bit_cnt_local += iusace_write_bits_buf(
1484
904
      it_bit_buf, pstr_downmix_instructions->downmix_coefficients_present, 1);
1485
1486
904
  if (pstr_downmix_instructions->downmix_coefficients_present) {
1487
514
    if (version != 1) {
1488
0
      WORD32 is_lfe_channel = FALSE;
1489
0
      for (idx = 0;
1490
0
           idx < (pstr_downmix_instructions->target_ch_count * pstr_gain_enc->base_ch_count);
1491
0
           idx++) {
1492
0
        impd_drc_enc_downmix_coeff(pstr_downmix_instructions->downmix_coeff[idx], is_lfe_channel,
1493
0
                                   &code_size, &code);
1494
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size);
1495
0
      }
1496
514
    } else {
1497
514
      impd_drc_dec_write_downmix_coeff_v1(
1498
514
          it_bit_buf, pstr_downmix_instructions->downmix_coeff, pstr_gain_enc->base_ch_count,
1499
514
          pstr_downmix_instructions->target_ch_count, &bit_cnt_local);
1500
514
    }
1501
514
  }
1502
1503
904
  *ptr_bit_cnt += bit_cnt_local;
1504
904
}
1505
1506
static VOID impd_drc_enc_channel_weight(const FLOAT32 channel_weight_lin, WORD32 *code_size,
1507
0
                                        WORD32 *code) {
1508
0
  LOOPIDX idx;
1509
0
  FLOAT32 channel_weight_db;
1510
0
  const FLOAT32 *channel_weight_table;
1511
1512
0
  channel_weight_table = impd_drc_channel_weight;
1513
0
  channel_weight_db = 20.0f * (FLOAT32)log10(channel_weight_lin);
1514
1515
0
  if (channel_weight_db >= channel_weight_table[14]) {
1516
0
    idx = 0;
1517
0
    while (channel_weight_db < channel_weight_table[idx]) {
1518
0
      idx++;
1519
0
    }
1520
0
    if ((idx > 0) && (channel_weight_db >
1521
0
                      0.5f * (channel_weight_table[idx - 1] + channel_weight_table[idx]))) {
1522
0
      idx--;
1523
0
    }
1524
0
    *code = idx;
1525
0
  } else {
1526
0
    *code = 15;
1527
0
  }
1528
1529
0
  *code_size = 4;
1530
0
}
1531
1532
static IA_ERRORCODE impd_drc_write_parametric_drc_gain_set_params(
1533
    ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_config_struct *pstr_uni_drc_config,
1534
    ia_drc_parametric_drc_gain_set_params_struct *pstr_parametric_drc_gain_set_params,
1535
0
    WORD32 *ptr_bit_cnt) {
1536
0
  LOOPIDX idx;
1537
0
  WORD32 code_size = 0, code = 0;
1538
0
  WORD32 bit_cnt_local = 0;
1539
1540
0
  bit_cnt_local += iusace_write_bits_buf(
1541
0
      it_bit_buf, pstr_parametric_drc_gain_set_params->parametric_drc_id, 4);
1542
1543
0
  bit_cnt_local += iusace_write_bits_buf(
1544
0
      it_bit_buf, pstr_parametric_drc_gain_set_params->side_chain_config_type, 3);
1545
1546
0
  if (pstr_parametric_drc_gain_set_params->side_chain_config_type == 1) {
1547
0
    bit_cnt_local +=
1548
0
        iusace_write_bits_buf(it_bit_buf, pstr_parametric_drc_gain_set_params->downmix_id, 7);
1549
1550
0
    bit_cnt_local += iusace_write_bits_buf(
1551
0
        it_bit_buf, pstr_parametric_drc_gain_set_params->level_estim_channel_weight_format, 1);
1552
1553
0
    if (pstr_parametric_drc_gain_set_params->downmix_id == 0x7F) {
1554
0
      pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id = 1;
1555
0
    } else if (pstr_parametric_drc_gain_set_params->downmix_id == 0x0) {
1556
0
      pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id =
1557
0
          pstr_uni_drc_config->str_channel_layout.base_ch_count;
1558
0
    } else {
1559
0
      for (idx = 0; idx < pstr_uni_drc_config->downmix_instructions_count; idx++) {
1560
0
        if (pstr_parametric_drc_gain_set_params->downmix_id ==
1561
0
            pstr_uni_drc_config->str_downmix_instructions[idx].downmix_id) {
1562
0
          break;
1563
0
        }
1564
0
      }
1565
0
      if (idx == pstr_uni_drc_config->downmix_instructions_count) {
1566
0
        return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
1567
0
      }
1568
0
      pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id =
1569
0
          pstr_uni_drc_config->str_downmix_instructions[idx].target_ch_count;
1570
0
    }
1571
1572
0
    for (idx = 0; idx < pstr_parametric_drc_gain_set_params->channel_count_drom_downmix_id;
1573
0
         idx++) {
1574
0
      if (pstr_parametric_drc_gain_set_params->level_estim_channel_weight_format != 0) {
1575
0
        impd_drc_enc_channel_weight(
1576
0
            pstr_parametric_drc_gain_set_params->level_estim_channel_weight[idx], &code_size,
1577
0
            &code);
1578
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)code_size);
1579
0
      } else {
1580
0
        if (pstr_parametric_drc_gain_set_params->level_estim_channel_weight[idx] == 0) {
1581
0
          code = 0;
1582
0
        } else {
1583
0
          code = 1;
1584
0
        }
1585
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 1);
1586
0
      }
1587
0
    }
1588
0
  }
1589
1590
0
  bit_cnt_local += iusace_write_bits_buf(
1591
0
      it_bit_buf, pstr_parametric_drc_gain_set_params->drc_input_loudness_present, 1);
1592
0
  if (pstr_parametric_drc_gain_set_params->drc_input_loudness_present) {
1593
0
    code = ((WORD32)(0.5f +
1594
0
                     4.0f * (pstr_parametric_drc_gain_set_params->drc_input_loudness + 57.75f) +
1595
0
                     10000.0f)) -
1596
0
           10000;
1597
0
    code = MIN(0x0FF, code);
1598
0
    code = MAX(0x0, code);
1599
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8);
1600
0
  }
1601
1602
0
  *ptr_bit_cnt += bit_cnt_local;
1603
1604
0
  return IA_NO_ERROR;
1605
0
}
1606
1607
static VOID impd_drc_write_parametric_drc_type_feed_forward(
1608
    ia_bit_buf_struct *it_bit_buf, WORD32 drc_frame_size_parametric_drc,
1609
    ia_drc_parametric_drc_type_feed_forward_struct *pstr_parametric_drc_type_feed_forward,
1610
0
    WORD32 *ptr_bit_cnt) {
1611
0
  LOOPIDX idx;
1612
0
  WORD32 code = 0;
1613
0
  WORD32 bit_cnt_local = 0;
1614
1615
0
  bit_cnt_local += iusace_write_bits_buf(
1616
0
      it_bit_buf, pstr_parametric_drc_type_feed_forward->level_estim_k_weighting_type, 2);
1617
1618
0
  bit_cnt_local += iusace_write_bits_buf(
1619
0
      it_bit_buf, pstr_parametric_drc_type_feed_forward->level_estim_integration_time_present, 1);
1620
1621
0
  if (pstr_parametric_drc_type_feed_forward->level_estim_integration_time_present) {
1622
0
    code =
1623
0
        (WORD32)(((FLOAT32)pstr_parametric_drc_type_feed_forward->level_estim_integration_time /
1624
0
                      drc_frame_size_parametric_drc +
1625
0
                  0.5f) -
1626
0
                 1);
1627
1628
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 6);
1629
0
  }
1630
1631
0
  bit_cnt_local += iusace_write_bits_buf(
1632
0
      it_bit_buf, pstr_parametric_drc_type_feed_forward->drc_curve_definition_type, 1);
1633
0
  if (pstr_parametric_drc_type_feed_forward->drc_curve_definition_type != 0) {
1634
0
    bit_cnt_local += iusace_write_bits_buf(
1635
0
        it_bit_buf, pstr_parametric_drc_type_feed_forward->node_count - 2, 3);
1636
1637
0
    for (idx = 0; idx < pstr_parametric_drc_type_feed_forward->node_count; idx++) {
1638
0
      if (idx == 0) {
1639
0
        code = -11 - pstr_parametric_drc_type_feed_forward->node_level[0];
1640
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 6);
1641
0
      } else {
1642
0
        code = pstr_parametric_drc_type_feed_forward->node_level[idx] -
1643
0
               pstr_parametric_drc_type_feed_forward->node_level[idx - 1] - 1;
1644
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5);
1645
0
      }
1646
0
      code = pstr_parametric_drc_type_feed_forward->node_gain[idx] + 39;
1647
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 6);
1648
0
    }
1649
0
  } else {
1650
0
    bit_cnt_local += iusace_write_bits_buf(
1651
0
        it_bit_buf, pstr_parametric_drc_type_feed_forward->drc_characteristic, 7);
1652
0
  }
1653
1654
0
  bit_cnt_local += iusace_write_bits_buf(
1655
0
      it_bit_buf, pstr_parametric_drc_type_feed_forward->drc_gain_smooth_parameters_present, 1);
1656
0
  if (pstr_parametric_drc_type_feed_forward->drc_gain_smooth_parameters_present) {
1657
0
    code = (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_attack_time_slow * 0.2);
1658
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8);
1659
1660
0
    code = (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_release_time_slow * 0.025);
1661
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8);
1662
1663
0
    bit_cnt_local += iusace_write_bits_buf(
1664
0
        it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_time_fast_present, 1);
1665
0
    if (pstr_parametric_drc_type_feed_forward->gain_smooth_time_fast_present) {
1666
0
      code = (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_attack_time_fast * 0.2);
1667
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8);
1668
1669
0
      code =
1670
0
          (WORD32)(pstr_parametric_drc_type_feed_forward->gain_smooth_release_time_fast * 0.05);
1671
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 8);
1672
1673
0
      bit_cnt_local += iusace_write_bits_buf(
1674
0
          it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_threshold_present, 1);
1675
0
      if (pstr_parametric_drc_type_feed_forward->gain_smooth_threshold_present) {
1676
0
        if (pstr_parametric_drc_type_feed_forward->gain_smooth_attack_threshold <= 30) {
1677
0
          code = pstr_parametric_drc_type_feed_forward->gain_smooth_attack_threshold;
1678
0
        } else {
1679
0
          code = 31;
1680
0
        }
1681
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5);
1682
1683
0
        if (pstr_parametric_drc_type_feed_forward->gain_smooth_release_threshold <= 30) {
1684
0
          code = pstr_parametric_drc_type_feed_forward->gain_smooth_release_threshold;
1685
0
        } else {
1686
0
          code = 31;
1687
0
        }
1688
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5);
1689
0
      }
1690
0
    }
1691
1692
0
    bit_cnt_local += iusace_write_bits_buf(
1693
0
        it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_hold_off_count_present, 1);
1694
0
    if (pstr_parametric_drc_type_feed_forward->gain_smooth_hold_off_count_present) {
1695
0
      bit_cnt_local += iusace_write_bits_buf(
1696
0
          it_bit_buf, pstr_parametric_drc_type_feed_forward->gain_smooth_hold_off, 7);
1697
0
    }
1698
0
  }
1699
1700
0
  *ptr_bit_cnt += bit_cnt_local;
1701
0
}
1702
1703
static VOID impd_drc_write_parametric_drc_type_lim(
1704
    ia_bit_buf_struct *it_bit_buf,
1705
0
    ia_drc_parametric_drc_type_lim_struct *pstr_parametric_drc_type_lim, WORD32 *ptr_bit_cnt) {
1706
0
  WORD32 temp = 0;
1707
0
  WORD32 bit_cnt_local = 0;
1708
1709
0
  bit_cnt_local += iusace_write_bits_buf(
1710
0
      it_bit_buf, pstr_parametric_drc_type_lim->parametric_lim_threshold_present, 1);
1711
0
  if (pstr_parametric_drc_type_lim->parametric_lim_threshold_present) {
1712
0
    temp = (WORD32)(0.5f - 8.0f * pstr_parametric_drc_type_lim->parametric_lim_threshold);
1713
0
    temp = MAX(0, temp);
1714
0
    temp = MIN(0xFF, temp);
1715
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, temp, 8);
1716
0
  }
1717
1718
0
  bit_cnt_local += iusace_write_bits_buf(
1719
0
      it_bit_buf, pstr_parametric_drc_type_lim->parametric_lim_release_present, 1);
1720
0
  if (pstr_parametric_drc_type_lim->parametric_lim_release_present) {
1721
0
    temp = (WORD32)(pstr_parametric_drc_type_lim->parametric_lim_release * 0.1);
1722
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, temp, 8);
1723
0
  }
1724
1725
0
  *ptr_bit_cnt += bit_cnt_local;
1726
0
}
1727
1728
static IA_ERRORCODE impd_drc_write_parametric_drc_instructions(
1729
    ia_bit_buf_struct *it_bit_buf, WORD32 drc_frame_size_parametric_drc,
1730
    ia_drc_parametric_drc_instructions_struct *pstr_parametric_drc_instructions,
1731
0
    WORD32 *ptr_bit_cnt) {
1732
0
  WORD32 bit_size = 0, len_size_bits = 0, bit_size_len = 0;
1733
0
  WORD32 bit_cnt_local = 0;
1734
1735
0
  bit_cnt_local +=
1736
0
      iusace_write_bits_buf(it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_id, 4);
1737
1738
0
  bit_cnt_local += iusace_write_bits_buf(
1739
0
      it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_look_ahead_present, 1);
1740
1741
0
  if (pstr_parametric_drc_instructions->parametric_drc_look_ahead_present) {
1742
0
    bit_cnt_local += iusace_write_bits_buf(
1743
0
        it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_look_ahead, 7);
1744
0
  }
1745
1746
0
  bit_cnt_local += iusace_write_bits_buf(
1747
0
      it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_preset_id_present, 1);
1748
0
  if (!(pstr_parametric_drc_instructions->parametric_drc_preset_id_present)) {
1749
0
    bit_cnt_local += iusace_write_bits_buf(
1750
0
        it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_type, 3);
1751
1752
0
    if (pstr_parametric_drc_instructions->parametric_drc_type == PARAM_DRC_TYPE_LIM) {
1753
0
      impd_drc_write_parametric_drc_type_lim(
1754
0
          it_bit_buf, &(pstr_parametric_drc_instructions->str_parametric_drc_type_lim),
1755
0
          &bit_cnt_local);
1756
0
    } else if (pstr_parametric_drc_instructions->parametric_drc_type == PARAM_DRC_TYPE_FF) {
1757
0
      impd_drc_write_parametric_drc_type_feed_forward(
1758
0
          it_bit_buf, drc_frame_size_parametric_drc,
1759
0
          &(pstr_parametric_drc_instructions->str_parametric_drc_type_feed_forward),
1760
0
          &bit_cnt_local);
1761
0
    } else {
1762
0
      bit_size = pstr_parametric_drc_instructions->len_bit_size - 1;
1763
0
      len_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1;
1764
0
      bit_size_len = len_size_bits - 4;
1765
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 4);
1766
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)bit_size);
1767
0
      switch (pstr_parametric_drc_instructions->parametric_drc_type) {
1768
0
        default:
1769
0
          return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
1770
0
      }
1771
0
    }
1772
0
  } else {
1773
0
    bit_cnt_local += iusace_write_bits_buf(
1774
0
        it_bit_buf, pstr_parametric_drc_instructions->parametric_drc_preset_id, 7);
1775
0
  }
1776
1777
0
  *ptr_bit_cnt += bit_cnt_local;
1778
1779
0
  return IA_NO_ERROR;
1780
0
}
1781
1782
static IA_ERRORCODE impd_drc_write_drc_coeff_parametric_drc(
1783
    ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_config_struct *pstr_uni_drc_config,
1784
0
    ia_drc_coeff_parametric_drc_struct *pstr_drc_coeff_parametric_drc, WORD32 *ptr_bit_cnt) {
1785
0
  IA_ERRORCODE err_code = IA_NO_ERROR;
1786
0
  LOOPIDX idx;
1787
0
  WORD32 bits = 0, mu = 0, nu = 0;
1788
0
  WORD32 bit_cnt_local = 0;
1789
0
  FLOAT32 exp = 0.f;
1790
1791
0
  bit_cnt_local +=
1792
0
      iusace_write_bits_buf(it_bit_buf, pstr_drc_coeff_parametric_drc->drc_location, 4);
1793
1794
0
  exp = (FLOAT32)(log(pstr_drc_coeff_parametric_drc->parametric_drc_frame_size) / log(2));
1795
0
  if (exp == (FLOAT32)((WORD32)exp)) {
1796
0
    pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format = 0;
1797
0
  } else {
1798
0
    pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format = 1;
1799
0
  }
1800
1801
0
  bit_cnt_local += iusace_write_bits_buf(
1802
0
      it_bit_buf, pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format, 1);
1803
0
  if (!(pstr_drc_coeff_parametric_drc->parametric_drc_frame_size_format)) {
1804
0
    bits = (WORD32)exp;
1805
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bits, 4);
1806
0
  } else {
1807
0
    bit_cnt_local += iusace_write_bits_buf(
1808
0
        it_bit_buf, (pstr_drc_coeff_parametric_drc->parametric_drc_frame_size - 1), 15);
1809
0
  }
1810
1811
0
  bit_cnt_local += iusace_write_bits_buf(
1812
0
      it_bit_buf, pstr_drc_coeff_parametric_drc->parametric_drc_delay_max_present, 1);
1813
0
  if (pstr_drc_coeff_parametric_drc->parametric_drc_delay_max_present == 1) {
1814
0
    for (nu = 0; nu < 8; nu++) {
1815
0
      mu = pstr_drc_coeff_parametric_drc->parametric_drc_delay_max / (16 << nu);
1816
0
      if (mu * (16 << nu) < pstr_drc_coeff_parametric_drc->parametric_drc_delay_max) {
1817
0
        mu++;
1818
0
      }
1819
0
      if (mu < 32) {
1820
0
        break;
1821
0
      }
1822
0
    }
1823
0
    if (nu == 8) {
1824
0
      mu = 31;
1825
0
      nu = 7;
1826
0
    }
1827
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, mu, 5);
1828
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, nu, 3);
1829
0
  }
1830
1831
0
  bit_cnt_local +=
1832
0
      iusace_write_bits_buf(it_bit_buf, pstr_drc_coeff_parametric_drc->reset_parametric_drc, 1);
1833
1834
0
  bit_cnt_local += iusace_write_bits_buf(
1835
0
      it_bit_buf, pstr_drc_coeff_parametric_drc->parametric_drc_gain_set_count, 6);
1836
0
  for (idx = 0; idx < pstr_drc_coeff_parametric_drc->parametric_drc_gain_set_count; idx++) {
1837
0
    err_code = impd_drc_write_parametric_drc_gain_set_params(
1838
0
        it_bit_buf, pstr_uni_drc_config,
1839
0
        &(pstr_drc_coeff_parametric_drc->parametric_drc_gain_set_params[idx]), &bit_cnt_local);
1840
1841
0
    if (err_code & IA_FATAL_ERROR) {
1842
0
      return err_code;
1843
0
    }
1844
0
  }
1845
1846
0
  *ptr_bit_cnt += bit_cnt_local;
1847
1848
0
  return err_code;
1849
0
}
1850
1851
static VOID impd_drc_write_loud_eq_instructions(
1852
    ia_bit_buf_struct *it_bit_buf, ia_drc_loud_eq_instructions_struct *pstr_loud_eq_instructions,
1853
0
    WORD32 *ptr_bit_cnt) {
1854
0
  LOOPIDX idx;
1855
0
  WORD32 bit_cnt_local = 0;
1856
0
  WORD32 bs_loud_eq_offset;
1857
0
  WORD32 bs_loud_eq_scaling;
1858
1859
0
  bit_cnt_local +=
1860
0
      iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->loud_eq_set_id, 4);
1861
1862
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->drc_location, 4);
1863
1864
0
  bit_cnt_local +=
1865
0
      iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->downmix_id_present, 1);
1866
0
  if (pstr_loud_eq_instructions->downmix_id_present) {
1867
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->downmix_id, 7);
1868
1869
0
    bit_cnt_local += iusace_write_bits_buf(
1870
0
        it_bit_buf, pstr_loud_eq_instructions->additional_downmix_id_present, 1);
1871
0
    if (!(pstr_loud_eq_instructions->additional_downmix_id_present)) {
1872
0
      pstr_loud_eq_instructions->additional_downmix_id_count = 0;
1873
0
    } else {
1874
0
      bit_cnt_local += iusace_write_bits_buf(
1875
0
          it_bit_buf, pstr_loud_eq_instructions->additional_downmix_id_count, 7);
1876
0
      for (idx = 0; idx < pstr_loud_eq_instructions->additional_downmix_id_count; idx++) {
1877
0
        bit_cnt_local += iusace_write_bits_buf(
1878
0
            it_bit_buf, pstr_loud_eq_instructions->additional_downmix_id[idx], 7);
1879
0
      }
1880
0
    }
1881
0
  }
1882
1883
0
  bit_cnt_local +=
1884
0
      iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->drc_set_id_present, 1);
1885
0
  if (pstr_loud_eq_instructions->drc_set_id_present) {
1886
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->drc_set_id, 6);
1887
1888
0
    bit_cnt_local += iusace_write_bits_buf(
1889
0
        it_bit_buf, pstr_loud_eq_instructions->additional_drc_set_id_present, 1);
1890
0
    if (!(pstr_loud_eq_instructions->additional_drc_set_id_present)) {
1891
0
      pstr_loud_eq_instructions->additional_drc_set_id_count = 0;
1892
0
    } else {
1893
0
      bit_cnt_local += iusace_write_bits_buf(
1894
0
          it_bit_buf, pstr_loud_eq_instructions->additional_drc_set_id_count, 6);
1895
0
      for (idx = 0; idx < pstr_loud_eq_instructions->additional_drc_set_id_count; idx++) {
1896
0
        bit_cnt_local += iusace_write_bits_buf(
1897
0
            it_bit_buf, pstr_loud_eq_instructions->additional_drc_set_id[idx], 6);
1898
0
      }
1899
0
    }
1900
0
  }
1901
1902
0
  bit_cnt_local +=
1903
0
      iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->eq_set_id_present, 1);
1904
0
  if (pstr_loud_eq_instructions->eq_set_id_present) {
1905
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->eq_set_id, 6);
1906
1907
0
    bit_cnt_local += iusace_write_bits_buf(
1908
0
        it_bit_buf, pstr_loud_eq_instructions->additional_eq_set_id_present, 1);
1909
0
    if (!(pstr_loud_eq_instructions->additional_eq_set_id_present)) {
1910
0
      pstr_loud_eq_instructions->additional_eq_set_id_count = 0;
1911
0
    } else {
1912
0
      bit_cnt_local += iusace_write_bits_buf(
1913
0
          it_bit_buf, pstr_loud_eq_instructions->additional_eq_set_id_count, 6);
1914
0
      for (idx = 0; idx < pstr_loud_eq_instructions->additional_eq_set_id_count; idx++) {
1915
0
        bit_cnt_local += iusace_write_bits_buf(
1916
0
            it_bit_buf, pstr_loud_eq_instructions->additional_eq_set_id[idx], 6);
1917
0
      }
1918
0
    }
1919
0
  }
1920
1921
0
  bit_cnt_local +=
1922
0
      iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->loudness_after_drc, 1);
1923
1924
0
  bit_cnt_local +=
1925
0
      iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->loudness_after_eq, 1);
1926
1927
0
  bit_cnt_local += iusace_write_bits_buf(
1928
0
      it_bit_buf, pstr_loud_eq_instructions->loud_eq_gain_sequence_count, 6);
1929
0
  for (idx = 0; idx < pstr_loud_eq_instructions->loud_eq_gain_sequence_count; idx++) {
1930
0
    bit_cnt_local +=
1931
0
        iusace_write_bits_buf(it_bit_buf, pstr_loud_eq_instructions->gain_sequence_index[idx], 6);
1932
1933
0
    bit_cnt_local += iusace_write_bits_buf(
1934
0
        it_bit_buf, pstr_loud_eq_instructions->drc_characteristic_format_is_cicp[idx], 1);
1935
0
    if (pstr_loud_eq_instructions->drc_characteristic_format_is_cicp[idx] == 1) {
1936
0
      bit_cnt_local += iusace_write_bits_buf(
1937
0
          it_bit_buf, pstr_loud_eq_instructions->drc_characteristic[idx], 7);
1938
0
    } else {
1939
0
      bit_cnt_local += iusace_write_bits_buf(
1940
0
          it_bit_buf, pstr_loud_eq_instructions->drc_characteristic_left_index[idx], 4);
1941
1942
0
      bit_cnt_local += iusace_write_bits_buf(
1943
0
          it_bit_buf, pstr_loud_eq_instructions->drc_characteristic_right_index[idx], 4);
1944
0
    }
1945
1946
0
    bit_cnt_local += iusace_write_bits_buf(
1947
0
        it_bit_buf, pstr_loud_eq_instructions->frequency_range_index[idx], 6);
1948
0
    bs_loud_eq_scaling = (WORD32)floor(
1949
0
        0.5f - 2.0f * INV_LOG10_2 * log10(pstr_loud_eq_instructions->loud_eq_scaling[idx]));
1950
0
    if (bs_loud_eq_scaling < 0) {
1951
0
      bs_loud_eq_scaling = 0;
1952
0
    } else if (bs_loud_eq_scaling > 7) {
1953
0
      bs_loud_eq_scaling = 7;
1954
0
    }
1955
1956
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_loud_eq_scaling, 3);
1957
0
    bs_loud_eq_offset =
1958
0
        (WORD32)floor(0.5f + pstr_loud_eq_instructions->loud_eq_offset[idx] / 1.5f + 16.0f);
1959
0
    if (bs_loud_eq_offset < 0) {
1960
0
      bs_loud_eq_offset = 0;
1961
0
    } else if (bs_loud_eq_offset > 31) {
1962
0
      bs_loud_eq_offset = 31;
1963
0
    }
1964
1965
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_loud_eq_offset, 5);
1966
0
  }
1967
1968
0
  *ptr_bit_cnt += bit_cnt_local;
1969
0
}
1970
1971
static VOID impd_drc_write_filter_element(ia_bit_buf_struct *it_bit_buf,
1972
                                          ia_drc_filter_element_struct *pstr_filter_element,
1973
0
                                          WORD32 *ptr_bit_cnt) {
1974
0
  WORD32 bs_filter_element_gain;
1975
0
  WORD32 bit_cnt_local = 0;
1976
1977
0
  bit_cnt_local +=
1978
0
      iusace_write_bits_buf(it_bit_buf, pstr_filter_element->filter_element_index, 6);
1979
1980
0
  bit_cnt_local +=
1981
0
      iusace_write_bits_buf(it_bit_buf, pstr_filter_element->filter_element_gain_present, 1);
1982
0
  if (pstr_filter_element->filter_element_gain_present) {
1983
0
    bs_filter_element_gain =
1984
0
        (WORD32)floor(0.5f + 8.0f * (pstr_filter_element->filter_element_gain + 96.0f));
1985
0
    bs_filter_element_gain = MAX(0, bs_filter_element_gain);
1986
0
    bs_filter_element_gain = MIN(1023, bs_filter_element_gain);
1987
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_filter_element_gain, 10);
1988
0
  }
1989
1990
0
  *ptr_bit_cnt += bit_cnt_local;
1991
0
}
1992
1993
static VOID impd_drc_write_filter_block(ia_bit_buf_struct *it_bit_buf,
1994
                                        ia_drc_filter_block_struct *pstr_filter_block,
1995
0
                                        WORD32 *ptr_bit_cnt) {
1996
0
  LOOPIDX idx;
1997
0
  WORD32 bit_cnt_local = 0;
1998
1999
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_filter_block->filter_element_count, 6);
2000
0
  for (idx = 0; idx < pstr_filter_block->filter_element_count; idx++) {
2001
0
    impd_drc_write_filter_element(it_bit_buf, &(pstr_filter_block->filter_element[idx]),
2002
0
                                  &bit_cnt_local);
2003
0
  }
2004
2005
0
  *ptr_bit_cnt += bit_cnt_local;
2006
0
}
2007
2008
0
static IA_ERRORCODE impd_drc_encode_radius(FLOAT32 radius, WORD32 *code) {
2009
0
  LOOPIDX idx;
2010
0
  FLOAT32 rho;
2011
2012
0
  if (radius < 0.0f) {
2013
0
    return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
2014
0
  }
2015
0
  rho = 1.0f - radius;
2016
0
  if ((rho < 0.0f) || (rho > 1.0f)) {
2017
0
    if (rho < 0.0f) {
2018
0
      rho = 0.0f;
2019
0
    }
2020
0
    if (rho > 1.0f) {
2021
0
      rho = 1.0f;
2022
0
    }
2023
0
  }
2024
0
  if (rho > impd_drc_zero_pole_radius_table[127]) {
2025
0
    rho = impd_drc_zero_pole_radius_table[127];
2026
0
  }
2027
0
  idx = 0;
2028
0
  while (rho > impd_drc_zero_pole_radius_table[idx]) {
2029
0
    idx++;
2030
0
  }
2031
0
  if (idx == 0) {
2032
0
    return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
2033
0
  }
2034
0
  if (rho <
2035
0
      0.5f * (impd_drc_zero_pole_radius_table[idx - 1] + impd_drc_zero_pole_radius_table[idx])) {
2036
0
    idx--;
2037
0
  }
2038
0
  *code = idx;
2039
2040
0
  return IA_NO_ERROR;
2041
0
}
2042
2043
0
static LOOPIDX impd_drc_encode_angle(FLOAT32 angle) {
2044
0
  LOOPIDX idx;
2045
2046
0
  if ((angle < 0.0f) || (angle > 1.0f)) {
2047
0
    if (angle < 0.0f) {
2048
0
      angle = 0.0f;
2049
0
    }
2050
0
    if (angle > 1.0f) {
2051
0
      angle = 1.0f;
2052
0
    }
2053
0
  }
2054
0
  idx = 0;
2055
0
  while (angle > impd_drc_zero_pole_angle_table[idx]) {
2056
0
    idx++;
2057
0
  }
2058
0
  if (idx == 0) {
2059
0
    return idx;
2060
0
  }
2061
0
  if (angle <
2062
0
      0.5f * (impd_drc_zero_pole_angle_table[idx - 1] + impd_drc_zero_pole_angle_table[idx])) {
2063
0
    idx--;
2064
0
  }
2065
2066
0
  return (idx);
2067
0
}
2068
2069
static IA_ERRORCODE impd_drc_write_unique_td_filter_element(
2070
    ia_bit_buf_struct *it_bit_buf,
2071
0
    ia_drc_unique_td_filter_element_struct *pstr_unique_td_filter_element, WORD32 *ptr_bit_cnt) {
2072
0
  IA_ERRORCODE err_code = IA_NO_ERROR;
2073
0
  LOOPIDX idx;
2074
0
  WORD32 sign, code;
2075
0
  WORD32 bs_real_zero_radius_one_count;
2076
0
  WORD32 bs_fir_coefficient;
2077
0
  WORD32 bit_cnt_local = 0;
2078
2079
0
  bit_cnt_local +=
2080
0
      iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->eq_filter_format, 1);
2081
0
  if (pstr_unique_td_filter_element->eq_filter_format != 0) {
2082
0
    bit_cnt_local +=
2083
0
        iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->fir_filter_order, 7);
2084
2085
0
    bit_cnt_local +=
2086
0
        iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->fir_symmetry, 1);
2087
2088
0
    for (idx = 0; idx < pstr_unique_td_filter_element->fir_filter_order / 2 + 1; idx++) {
2089
0
      if (pstr_unique_td_filter_element->fir_coefficient[idx] >= 0.0f) {
2090
0
        sign = 0;
2091
0
      } else {
2092
0
        sign = 1;
2093
0
      }
2094
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1);
2095
2096
0
      bs_fir_coefficient =
2097
0
          (WORD32)floor(0.5f - log10(fabs(pstr_unique_td_filter_element->fir_coefficient[idx])) /
2098
0
                                   (0.05f * 0.0625f));
2099
2100
0
      if (bs_fir_coefficient > 1023) {
2101
0
        bs_fir_coefficient = 1023;
2102
0
      }
2103
0
      if (bs_fir_coefficient < 0) {
2104
0
        bs_fir_coefficient = 0;
2105
0
      }
2106
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_fir_coefficient, 10);
2107
0
    }
2108
0
  } else {
2109
0
    bs_real_zero_radius_one_count = pstr_unique_td_filter_element->real_zero_radius_one_count / 2;
2110
0
    if ((pstr_unique_td_filter_element->real_zero_radius_one_count ==
2111
0
         2 * bs_real_zero_radius_one_count) &&
2112
0
        (bs_real_zero_radius_one_count < 8)) {
2113
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_real_zero_radius_one_count, 3);
2114
0
    } else {
2115
0
      return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
2116
0
    }
2117
2118
0
    bit_cnt_local +=
2119
0
        iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->real_zero_count, 6);
2120
2121
0
    bit_cnt_local +=
2122
0
        iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->generic_zero_count, 6);
2123
2124
0
    bit_cnt_local +=
2125
0
        iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->real_pole_count, 4);
2126
2127
0
    bit_cnt_local +=
2128
0
        iusace_write_bits_buf(it_bit_buf, pstr_unique_td_filter_element->complex_pole_count, 4);
2129
2130
0
    for (idx = 0; idx < pstr_unique_td_filter_element->real_zero_radius_one_count; idx++) {
2131
0
      bit_cnt_local += iusace_write_bits_buf(
2132
0
          it_bit_buf, (UWORD32)pstr_unique_td_filter_element->zero_sign[idx], 1);
2133
0
    }
2134
2135
0
    for (idx = 0; idx < pstr_unique_td_filter_element->real_zero_count; idx++) {
2136
0
      err_code = impd_drc_encode_radius(
2137
0
          (FLOAT32)fabs(pstr_unique_td_filter_element->real_zero_radius[idx]), &code);
2138
2139
0
      if (err_code & IA_FATAL_ERROR) {
2140
0
        return err_code;
2141
0
      }
2142
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7);
2143
2144
0
      if (pstr_unique_td_filter_element->real_zero_radius[idx] >= 0.0f) {
2145
0
        sign = 0;
2146
0
      } else {
2147
0
        sign = 1;
2148
0
      }
2149
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1);
2150
0
    }
2151
2152
0
    for (idx = 0; idx < pstr_unique_td_filter_element->generic_zero_count; idx++) {
2153
0
      err_code =
2154
0
          impd_drc_encode_radius(pstr_unique_td_filter_element->generic_zero_radius[idx], &code);
2155
0
      if (err_code & IA_FATAL_ERROR) {
2156
0
        return err_code;
2157
0
      }
2158
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7);
2159
2160
0
      bit_cnt_local += iusace_write_bits_buf(
2161
0
          it_bit_buf,
2162
0
          impd_drc_encode_angle(pstr_unique_td_filter_element->generic_zero_angle[idx]), 7);
2163
0
    }
2164
2165
0
    for (idx = 0; idx < pstr_unique_td_filter_element->real_pole_count; idx++) {
2166
0
      err_code = impd_drc_encode_radius(
2167
0
          (FLOAT32)fabs(pstr_unique_td_filter_element->real_pole_radius[idx]), &code);
2168
0
      if (err_code & IA_FATAL_ERROR) {
2169
0
        return err_code;
2170
0
      }
2171
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7);
2172
2173
0
      if (pstr_unique_td_filter_element->real_pole_radius[idx] >= 0.0f) {
2174
0
        sign = 0;
2175
0
      } else {
2176
0
        sign = 1;
2177
0
      }
2178
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1);
2179
0
    }
2180
2181
0
    for (idx = 0; idx < pstr_unique_td_filter_element->complex_pole_count; idx++) {
2182
0
      err_code =
2183
0
          impd_drc_encode_radius(pstr_unique_td_filter_element->complex_pole_radius[idx], &code);
2184
0
      if (err_code & IA_FATAL_ERROR) {
2185
0
        return err_code;
2186
0
      }
2187
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 7);
2188
2189
0
      bit_cnt_local += iusace_write_bits_buf(
2190
0
          it_bit_buf,
2191
0
          impd_drc_encode_angle(pstr_unique_td_filter_element->complex_pole_angle[idx]), 7);
2192
0
    }
2193
0
  }
2194
2195
0
  *ptr_bit_cnt += bit_cnt_local;
2196
2197
0
  return err_code;
2198
0
}
2199
2200
0
static VOID impd_drc_encode_eq_slope(FLOAT32 eq_slope, WORD32 *size, WORD32 *code) {
2201
0
  LOOPIDX idx;
2202
2203
0
  if (fabs(eq_slope) >= 0.5f) {
2204
0
    *size = 5;
2205
0
    if (eq_slope > 32.0f) {
2206
0
      *code = 15;
2207
0
    } else if (eq_slope <= -32.0f) {
2208
0
      *code = 0;
2209
0
    } else {
2210
0
      idx = 1;
2211
0
      while (eq_slope > impd_drc_eq_slope_table[idx]) {
2212
0
        idx++;
2213
0
      }
2214
0
      if (eq_slope < 0.5f * (impd_drc_eq_slope_table[idx - 1] + impd_drc_eq_slope_table[idx])) {
2215
0
        idx--;
2216
0
      }
2217
0
      *code = idx;
2218
0
    }
2219
0
  } else {
2220
0
    *size = 1;
2221
0
    *code = 1;
2222
0
  }
2223
0
}
2224
2225
static VOID impd_drc_encode_eq_gain_initial(FLOAT32 eq_gain_initial, WORD32 *prefix_code,
2226
0
                                            WORD32 *size, WORD32 *code) {
2227
0
  if ((eq_gain_initial > -8.5f) && (eq_gain_initial < 7.75f)) {
2228
0
    *size = 5;
2229
0
    *prefix_code = 0;
2230
0
    *code = (WORD32)floor(0.5f + 2.0f * (MAX(-8.0f, eq_gain_initial) + 8.0f));
2231
0
  } else if (eq_gain_initial < 0.0f) {
2232
0
    if (eq_gain_initial > -17.0f) {
2233
0
      *size = 4;
2234
0
      *prefix_code = 1;
2235
0
      *code = (WORD32)floor(0.5f + MAX(-16.0f, eq_gain_initial) + 16.0f);
2236
0
    } else if (eq_gain_initial > -34.0f) {
2237
0
      *size = 4;
2238
0
      *prefix_code = 2;
2239
0
      *code = (WORD32)floor(0.5f + 0.5f * (MAX(-32.0f, eq_gain_initial) + 32.0f));
2240
0
    } else {
2241
0
      *size = 3;
2242
0
      *prefix_code = 3;
2243
0
      *code = (WORD32)floor(0.5f + 0.25f * (MAX(-64.0f, eq_gain_initial) + 64.0f));
2244
0
    }
2245
0
  } else {
2246
0
    if (eq_gain_initial >= 15.5f) {
2247
0
      *size = 4;
2248
0
      *prefix_code = 2;
2249
0
      *code = (WORD32)floor(0.5f + 0.5f * MIN(30.0f, eq_gain_initial));
2250
0
    } else {
2251
0
      *size = 4;
2252
0
      *prefix_code = 1;
2253
0
      *code = (WORD32)floor(0.5f + eq_gain_initial);
2254
0
    }
2255
0
  }
2256
0
}
2257
2258
0
static VOID impd_drc_encode_eq_gain_delta(FLOAT32 eq_gain_delta, WORD32 *code) {
2259
0
  LOOPIDX idx;
2260
2261
0
  if (eq_gain_delta >= 32.0f) {
2262
0
    *code = 31;
2263
0
  } else if (eq_gain_delta <= -22.0f) {
2264
0
    *code = 0;
2265
0
  } else {
2266
0
    idx = 1;
2267
0
    while (eq_gain_delta > impd_drc_eq_gain_delta_table[idx]) {
2268
0
      idx++;
2269
0
    }
2270
0
    if (eq_gain_delta <
2271
0
        0.5f * (impd_drc_eq_gain_delta_table[idx - 1] + impd_drc_eq_gain_delta_table[idx])) {
2272
0
      idx--;
2273
0
    }
2274
0
    *code = idx;
2275
0
  }
2276
0
}
2277
2278
static VOID impd_drc_write_eq_subband_gain_spline(
2279
    ia_bit_buf_struct *it_bit_buf,
2280
0
    ia_drc_eq_subband_gain_spline_struct *pstr_eq_subband_gain_spline, WORD32 *ptr_bit_cnt) {
2281
0
  LOOPIDX idx;
2282
0
  WORD32 size, code, prefix_code;
2283
0
  WORD32 bit_cnt_local = 0;
2284
0
  WORD32 bs_eq_node_count = pstr_eq_subband_gain_spline->n_eq_nodes - 2;
2285
2286
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_node_count, 5);
2287
2288
0
  for (idx = 0; idx < pstr_eq_subband_gain_spline->n_eq_nodes; idx++) {
2289
0
    impd_drc_encode_eq_slope(pstr_eq_subband_gain_spline->eq_slope[idx], &size, &code);
2290
2291
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)size);
2292
0
  }
2293
2294
0
  for (idx = 1; idx < pstr_eq_subband_gain_spline->n_eq_nodes; idx++) {
2295
0
    code = MIN(15, pstr_eq_subband_gain_spline->eq_freq_delta[idx] - 1);
2296
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 4);
2297
0
  }
2298
2299
0
  impd_drc_encode_eq_gain_initial(pstr_eq_subband_gain_spline->eq_gain_initial, &prefix_code,
2300
0
                                  &size, &code);
2301
2302
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, prefix_code, 2);
2303
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, (UWORD8)size);
2304
2305
0
  for (idx = 1; idx < pstr_eq_subband_gain_spline->n_eq_nodes; idx++) {
2306
0
    impd_drc_encode_eq_gain_delta(pstr_eq_subband_gain_spline->eq_gain_delta[idx], &code);
2307
2308
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, code, 5);
2309
0
  }
2310
2311
0
  *ptr_bit_cnt += bit_cnt_local;
2312
0
}
2313
2314
static VOID impd_drc_write_eq_subband_gain_vector(
2315
    ia_bit_buf_struct *it_bit_buf, WORD32 eq_subband_gain_count,
2316
0
    ia_drc_eq_subband_gain_vector_struct *pstr_eq_subband_gain_vector, WORD32 *ptr_bit_cnt) {
2317
0
  LOOPIDX idx = 0;
2318
0
  WORD32 sign;
2319
0
  WORD32 bs_eq_subband_gain;
2320
0
  WORD32 bit_cnt_local = 0;
2321
2322
0
  for (idx = 0; idx < eq_subband_gain_count; idx++) {
2323
0
    bs_eq_subband_gain =
2324
0
        (WORD32)floor(0.5f + fabs(pstr_eq_subband_gain_vector->eq_subband_gain[idx] * 8.0f));
2325
2326
0
    if (pstr_eq_subband_gain_vector->eq_subband_gain[idx] >= 0.0f) {
2327
0
      sign = 0;
2328
0
    } else {
2329
0
      sign = 1;
2330
0
    }
2331
2332
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, sign, 1);
2333
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_subband_gain, 8);
2334
0
  }
2335
2336
0
  *ptr_bit_cnt += bit_cnt_local;
2337
0
}
2338
2339
static IA_ERRORCODE impd_drc_write_eq_coefficients(
2340
    ia_bit_buf_struct *it_bit_buf, ia_drc_eq_coefficients_struct *pstr_eq_coefficients,
2341
0
    WORD32 *ptr_bit_cnt) {
2342
0
  IA_ERRORCODE err_code = IA_NO_ERROR;
2343
0
  LOOPIDX idx;
2344
0
  WORD32 bs_eq_gain_count;
2345
0
  WORD32 mu = 0, nu = 0;
2346
0
  WORD32 bit_cnt_local = 0;
2347
2348
0
  bit_cnt_local +=
2349
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->eq_delay_max_present, 1);
2350
0
  if (pstr_eq_coefficients->eq_delay_max_present == 1) {
2351
0
    for (nu = 0; nu < 8; nu++) {
2352
0
      mu = pstr_eq_coefficients->eq_delay_max / (16 << nu);
2353
0
      if (mu * (16 << nu) < pstr_eq_coefficients->eq_delay_max) {
2354
0
        mu++;
2355
0
      }
2356
0
      if (mu < 32) {
2357
0
        break;
2358
0
      }
2359
0
    }
2360
0
    if (nu == 8) {
2361
0
      mu = 31;
2362
0
      nu = 7;
2363
0
    }
2364
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, mu, 5);
2365
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, nu, 3);
2366
0
  }
2367
2368
0
  bit_cnt_local +=
2369
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->unique_filter_block_count, 6);
2370
0
  for (idx = 0; idx < pstr_eq_coefficients->unique_filter_block_count; idx++) {
2371
0
    impd_drc_write_filter_block(it_bit_buf, &(pstr_eq_coefficients->str_filter_block[idx]),
2372
0
                                &bit_cnt_local);
2373
0
  }
2374
2375
0
  bit_cnt_local +=
2376
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->unique_td_filter_element_count, 6);
2377
0
  for (idx = 0; idx < pstr_eq_coefficients->unique_td_filter_element_count; idx++) {
2378
0
    err_code = impd_drc_write_unique_td_filter_element(
2379
0
        it_bit_buf, &(pstr_eq_coefficients->str_unique_td_filter_element[idx]), &bit_cnt_local);
2380
0
    if (err_code & IA_FATAL_ERROR) {
2381
0
      return err_code;
2382
0
    }
2383
0
  }
2384
2385
0
  bit_cnt_local +=
2386
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->unique_eq_subband_gains_count, 6);
2387
0
  if (pstr_eq_coefficients->unique_eq_subband_gains_count > 0) {
2388
0
    bit_cnt_local += iusace_write_bits_buf(
2389
0
        it_bit_buf, pstr_eq_coefficients->eq_subband_gain_representation, 1);
2390
2391
0
    bit_cnt_local +=
2392
0
        iusace_write_bits_buf(it_bit_buf, pstr_eq_coefficients->eq_subband_gain_format, 4);
2393
2394
0
    switch (pstr_eq_coefficients->eq_subband_gain_format) {
2395
0
      case GAINFORMAT_QMFHYBRID135:
2396
0
        pstr_eq_coefficients->eq_subband_gain_count = 135;
2397
0
        break;
2398
0
      case GAINFORMAT_QMF128:
2399
0
        pstr_eq_coefficients->eq_subband_gain_count = 128;
2400
0
        break;
2401
0
      case GAINFORMAT_QMFHYBRID71:
2402
0
        pstr_eq_coefficients->eq_subband_gain_count = 71;
2403
0
        break;
2404
0
      case GAINFORMAT_QMF64:
2405
0
        pstr_eq_coefficients->eq_subband_gain_count = 64;
2406
0
        break;
2407
0
      case GAINFORMAT_QMFHYBRID39:
2408
0
        pstr_eq_coefficients->eq_subband_gain_count = 39;
2409
0
        break;
2410
0
      case GAINFORMAT_QMF32:
2411
0
        pstr_eq_coefficients->eq_subband_gain_count = 32;
2412
0
        break;
2413
0
      case GAINFORMAT_UNIFORM:
2414
0
      default:
2415
0
        bs_eq_gain_count = pstr_eq_coefficients->eq_subband_gain_count - 1;
2416
0
        bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_gain_count, 8);
2417
0
        break;
2418
0
    }
2419
2420
0
    for (idx = 0; idx < pstr_eq_coefficients->unique_eq_subband_gains_count; idx++) {
2421
0
      if (pstr_eq_coefficients->eq_subband_gain_representation != 1) {
2422
0
        impd_drc_write_eq_subband_gain_vector(
2423
0
            it_bit_buf, pstr_eq_coefficients->eq_subband_gain_count,
2424
0
            &(pstr_eq_coefficients->str_eq_subband_gain_vector[idx]), &bit_cnt_local);
2425
0
      } else {
2426
0
        impd_drc_write_eq_subband_gain_spline(
2427
0
            it_bit_buf, &(pstr_eq_coefficients->str_eq_subband_gain_spline[idx]), &bit_cnt_local);
2428
0
      }
2429
0
    }
2430
0
  }
2431
2432
0
  *ptr_bit_cnt += bit_cnt_local;
2433
2434
0
  return err_code;
2435
0
}
2436
2437
static VOID impd_drc_write_filter_block_refs(
2438
    ia_bit_buf_struct *it_bit_buf, ia_drc_filter_block_refs_struct *pstr_filter_block_refs,
2439
0
    WORD32 *ptr_bit_cnt) {
2440
0
  LOOPIDX idx;
2441
0
  WORD32 bit_cnt_local = 0;
2442
2443
0
  bit_cnt_local +=
2444
0
      iusace_write_bits_buf(it_bit_buf, pstr_filter_block_refs->filter_block_count, 4);
2445
0
  for (idx = 0; idx < pstr_filter_block_refs->filter_block_count; idx++) {
2446
0
    bit_cnt_local +=
2447
0
        iusace_write_bits_buf(it_bit_buf, pstr_filter_block_refs->filter_block_index[idx], 7);
2448
0
  }
2449
2450
0
  *ptr_bit_cnt += bit_cnt_local;
2451
0
}
2452
2453
static VOID impd_drc_write_td_filter_cascade(
2454
    ia_bit_buf_struct *it_bit_buf, const WORD32 eq_channel_group_count,
2455
0
    ia_drc_td_filter_cascade_struct *pstr_td_filter_cascade, WORD32 *ptr_bit_cnt) {
2456
0
  LOOPIDX i, j;
2457
0
  WORD32 bs_eq_cascade_gain;
2458
0
  WORD32 bit_cnt_local = 0;
2459
2460
0
  for (i = 0; i < eq_channel_group_count; i++) {
2461
0
    bit_cnt_local +=
2462
0
        iusace_write_bits_buf(it_bit_buf, pstr_td_filter_cascade->eq_cascade_gain_present[i], 1);
2463
0
    if (pstr_td_filter_cascade->eq_cascade_gain_present[i] == 1) {
2464
0
      bs_eq_cascade_gain =
2465
0
          (WORD32)floor(0.5f + 8.0f * (pstr_td_filter_cascade->eq_cascade_gain[i] + 96.0f));
2466
0
      bs_eq_cascade_gain = MAX(0, bs_eq_cascade_gain);
2467
0
      bs_eq_cascade_gain = MIN(1023, bs_eq_cascade_gain);
2468
0
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_cascade_gain, 10);
2469
0
    }
2470
0
    impd_drc_write_filter_block_refs(
2471
0
        it_bit_buf, &(pstr_td_filter_cascade->str_filter_block_refs[i]), &bit_cnt_local);
2472
0
  }
2473
2474
0
  bit_cnt_local +=
2475
0
      iusace_write_bits_buf(it_bit_buf, pstr_td_filter_cascade->eq_phase_alignment_present, 1);
2476
0
  if (pstr_td_filter_cascade->eq_phase_alignment_present == 1) {
2477
0
    for (i = 0; i < eq_channel_group_count; i++) {
2478
0
      for (j = i + 1; j < eq_channel_group_count; j++) {
2479
0
        bit_cnt_local += iusace_write_bits_buf(
2480
0
            it_bit_buf, pstr_td_filter_cascade->eq_phase_alignment[i][j], 1);
2481
0
      }
2482
0
    }
2483
0
  }
2484
2485
0
  *ptr_bit_cnt += bit_cnt_local;
2486
0
}
2487
2488
static IA_ERRORCODE impd_drc_write_eq_instructions(
2489
    ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext,
2490
    ia_drc_gain_enc_struct *pstr_gain_enc, ia_drc_eq_instructions_struct *pstr_eq_instructions,
2491
0
    WORD32 *ptr_bit_cnt, VOID *ptr_scratch, WORD32 *scratch_used) {
2492
0
  IA_ERRORCODE err_code = IA_NO_ERROR;
2493
0
  LOOPIDX idx;
2494
0
  WORD32 bs_eq_transition_duration;
2495
0
  WORD32 bit_cnt_local = 0;
2496
0
  FLOAT32 temp;
2497
2498
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_set_id, 6);
2499
2500
0
  err_code = impd_drc_get_eq_complexity_level(pstr_uni_drc_config_ext, pstr_gain_enc,
2501
0
                                              pstr_eq_instructions, ptr_scratch, scratch_used);
2502
0
  if (err_code & IA_FATAL_ERROR) {
2503
0
    return err_code;
2504
0
  }
2505
2506
0
  bit_cnt_local +=
2507
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_set_complexity_level, 4);
2508
2509
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->downmix_id_present, 1);
2510
0
  if (pstr_eq_instructions->downmix_id_present == 1) {
2511
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->downmix_id, 7);
2512
2513
0
    bit_cnt_local +=
2514
0
        iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_apply_to_downmix, 1);
2515
2516
0
    bit_cnt_local +=
2517
0
        iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_downmix_id_present, 1);
2518
0
    if (pstr_eq_instructions->additional_downmix_id_present == 1) {
2519
0
      bit_cnt_local +=
2520
0
          iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_downmix_id_count, 7);
2521
0
      for (idx = 0; idx < pstr_eq_instructions->additional_downmix_id_count; idx++) {
2522
0
        bit_cnt_local += iusace_write_bits_buf(
2523
0
            it_bit_buf, pstr_eq_instructions->additional_downmix_id[idx], 7);
2524
0
      }
2525
0
    }
2526
0
  }
2527
2528
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->drc_set_id, 6);
2529
2530
0
  bit_cnt_local +=
2531
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_drc_set_id_present, 1);
2532
0
  if (pstr_eq_instructions->additional_drc_set_id_present == 1) {
2533
0
    bit_cnt_local +=
2534
0
        iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_drc_set_id_count, 6);
2535
0
    for (idx = 0; idx < pstr_eq_instructions->additional_drc_set_id_count; idx++) {
2536
0
      bit_cnt_local +=
2537
0
          iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->additional_drc_set_id[idx], 6);
2538
0
    }
2539
0
  }
2540
2541
0
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_set_purpose, 16);
2542
2543
0
  bit_cnt_local +=
2544
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->depends_on_eq_set_present, 1);
2545
0
  if (pstr_eq_instructions->depends_on_eq_set_present != 1) {
2546
0
    bit_cnt_local +=
2547
0
        iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->no_independent_eq_use, 1);
2548
0
  } else {
2549
0
    bit_cnt_local +=
2550
0
        iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->depends_on_eq_set, 6);
2551
0
  }
2552
2553
0
  for (idx = 0; idx < pstr_eq_instructions->eq_channel_count; idx++) {
2554
0
    bit_cnt_local += iusace_write_bits_buf(
2555
0
        it_bit_buf, pstr_eq_instructions->eq_channel_group_for_channel[idx], 7);
2556
0
  }
2557
2558
0
  bit_cnt_local +=
2559
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->td_filter_cascade_present, 1);
2560
0
  if (pstr_eq_instructions->td_filter_cascade_present == 1) {
2561
0
    impd_drc_write_td_filter_cascade(it_bit_buf, pstr_eq_instructions->eq_channel_group_count,
2562
0
                                     &(pstr_eq_instructions->str_td_filter_cascade),
2563
0
                                     &bit_cnt_local);
2564
0
  }
2565
2566
0
  bit_cnt_local +=
2567
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->subband_gains_present, 1);
2568
0
  if (pstr_eq_instructions->subband_gains_present == 1) {
2569
0
    for (idx = 0; idx < pstr_eq_instructions->eq_channel_group_count; idx++) {
2570
0
      bit_cnt_local +=
2571
0
          iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->subband_gains_index[idx], 6);
2572
0
    }
2573
0
  }
2574
2575
0
  bit_cnt_local +=
2576
0
      iusace_write_bits_buf(it_bit_buf, pstr_eq_instructions->eq_transition_duration_present, 1);
2577
0
  if (pstr_eq_instructions->eq_transition_duration_present == 1) {
2578
0
    temp = MAX(0.004f, pstr_eq_instructions->eq_transition_duration);
2579
0
    temp = MIN(0.861f, temp);
2580
0
    bs_eq_transition_duration =
2581
0
        (WORD32)floor(0.5f + 4.0f * (log10(1000.0f * temp) / log10(2.0f) - 2.0f));
2582
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bs_eq_transition_duration, 5);
2583
0
  }
2584
2585
0
  *ptr_bit_cnt += bit_cnt_local;
2586
2587
0
  return err_code;
2588
0
}
2589
2590
static IA_ERRORCODE impd_drc_write_uni_drc_config_extn(
2591
    ia_drc_enc_state *pstr_drc_state, ia_drc_gain_enc_struct *pstr_gain_enc,
2592
    ia_drc_uni_drc_config_struct *pstr_uni_drc_config,
2593
    ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext, WORD32 *ptr_bit_cnt,
2594
788
    FLAG write_bs) {
2595
788
  IA_ERRORCODE err_code = IA_NO_ERROR;
2596
788
  LOOPIDX idx;
2597
788
  WORD32 version;
2598
788
  WORD32 counter = 0;
2599
788
  WORD32 ext_size_bits = 0, bit_size_len = 0, bit_size = 0;
2600
788
  WORD32 bit_cnt_local = 0, bit_cnt_local_ext = 0;
2601
788
  WORD32 *scratch_used = &pstr_drc_state->drc_scratch_used;
2602
788
  VOID *ptr_scratch = &pstr_drc_state->drc_scratch_mem;
2603
788
  ia_bit_buf_struct *it_bit_buf = NULL;
2604
788
  ia_bit_buf_struct *ptr_bit_buf_ext = NULL;
2605
2606
788
  if (write_bs) {
2607
240
    it_bit_buf = &pstr_drc_state->str_bit_buf_cfg;
2608
240
    ptr_bit_buf_ext = &pstr_drc_state->str_bit_buf_cfg_ext;
2609
2610
240
    iusace_reset_bit_buffer(ptr_bit_buf_ext);
2611
240
  }
2612
2613
788
  bit_cnt_local += iusace_write_bits_buf(
2614
788
      it_bit_buf, pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter], 4);
2615
1.44k
  while (counter < 2 &&
2616
1.36k
         pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter] != UNIDRC_CONF_EXT_TERM) {
2617
886
    switch (pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter]) {
2618
0
      case UNIDRC_CONF_EXT_PARAM_DRC: {
2619
0
#ifdef LOUDNESS_LEVELING_SUPPORT
2620
0
        bit_cnt_local_ext = 0;
2621
0
#endif  // LOUDNESS_LEVELING_SUPPORT
2622
0
        err_code = impd_drc_write_drc_coeff_parametric_drc(
2623
0
            ptr_bit_buf_ext, pstr_uni_drc_config,
2624
0
            &(pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc), &bit_cnt_local_ext);
2625
2626
0
        if (err_code & IA_FATAL_ERROR) {
2627
0
          return err_code;
2628
0
        }
2629
2630
0
        bit_cnt_local_ext += iusace_write_bits_buf(
2631
0
            ptr_bit_buf_ext, pstr_uni_drc_config_ext->parametric_drc_instructions_count, 4);
2632
0
        for (idx = 0; idx < pstr_uni_drc_config_ext->parametric_drc_instructions_count; idx++) {
2633
0
          err_code = impd_drc_write_parametric_drc_instructions(
2634
0
              ptr_bit_buf_ext,
2635
0
              pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc.parametric_drc_frame_size,
2636
0
              &(pstr_uni_drc_config_ext->str_parametric_drc_instructions[idx]),
2637
0
              &bit_cnt_local_ext);
2638
0
          if (err_code & IA_FATAL_ERROR) {
2639
0
            return err_code;
2640
0
          }
2641
0
        }
2642
0
      } break;
2643
788
      case UNIDRC_CONF_EXT_V1: {
2644
788
        version = 1;
2645
788
#ifdef LOUDNESS_LEVELING_SUPPORT
2646
788
        bit_cnt_local_ext = 0;
2647
788
#endif  // LOUDNESS_LEVELING_SUPPORT
2648
788
        bit_cnt_local_ext += iusace_write_bits_buf(
2649
788
            ptr_bit_buf_ext, pstr_uni_drc_config_ext->downmix_instructions_v1_present, 1);
2650
788
        if (pstr_uni_drc_config_ext->downmix_instructions_v1_present == 1) {
2651
170
          bit_cnt_local_ext += iusace_write_bits_buf(
2652
170
              ptr_bit_buf_ext, pstr_uni_drc_config_ext->downmix_instructions_v1_count, 7);
2653
718
          for (idx = 0; idx < pstr_uni_drc_config_ext->downmix_instructions_v1_count; idx++) {
2654
548
            impd_drc_write_downmix_instructions(
2655
548
                ptr_bit_buf_ext, version, pstr_gain_enc,
2656
548
                &(pstr_uni_drc_config_ext->str_downmix_instructions_v1[idx]), &bit_cnt_local_ext);
2657
548
          }
2658
170
        }
2659
2660
788
        bit_cnt_local_ext += iusace_write_bits_buf(
2661
788
            ptr_bit_buf_ext,
2662
788
            pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present, 1);
2663
788
        if (pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present == 1) {
2664
701
          bit_cnt_local_ext += iusace_write_bits_buf(
2665
701
              ptr_bit_buf_ext, pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count, 3);
2666
1.85k
          for (idx = 0; idx < pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count; idx++) {
2667
1.15k
            impd_drc_write_drc_coeff_uni_drc(
2668
1.15k
                ptr_bit_buf_ext, version,
2669
1.15k
                &(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[idx]),
2670
1.15k
                &bit_cnt_local_ext);
2671
1.15k
          }
2672
701
#ifdef LOUDNESS_LEVELING_SUPPORT
2673
701
          UWORD32 num_ducking_only_drc_sets = get_num_ducking_only_drc_sets(
2674
701
              pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1,
2675
701
              pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count);
2676
2677
701
          bit_cnt_local_ext +=
2678
701
              iusace_write_bits_buf(ptr_bit_buf_ext,
2679
701
                                    pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count -
2680
701
                                        num_ducking_only_drc_sets,
2681
701
                                    6);
2682
#else
2683
          bit_cnt_local_ext += iusace_write_bits_buf(
2684
              ptr_bit_buf_ext, pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 6);
2685
#endif
2686
1.17k
          for (idx = 0; idx < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; idx++) {
2687
664
#ifdef LOUDNESS_LEVELING_SUPPORT
2688
664
            if (idx > 0 && pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx - 1]
2689
347
                               .ducking_only_set_present) {
2690
95
              continue;
2691
95
            }
2692
569
#endif
2693
569
            err_code = impd_drc_write_drc_instruct_uni_drc(
2694
569
                ptr_bit_buf_ext, version, pstr_uni_drc_config, pstr_gain_enc,
2695
569
                &(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx]), ptr_scratch,
2696
569
                &bit_cnt_local_ext);
2697
569
            if (err_code & IA_FATAL_ERROR) {
2698
194
              return (err_code);
2699
194
            }
2700
569
          }
2701
701
        }
2702
2703
594
        bit_cnt_local_ext += iusace_write_bits_buf(
2704
594
            ptr_bit_buf_ext, pstr_uni_drc_config_ext->loud_eq_instructions_present, 1);
2705
594
        if (pstr_uni_drc_config_ext->loud_eq_instructions_present == 1) {
2706
0
          bit_cnt_local_ext += iusace_write_bits_buf(
2707
0
              ptr_bit_buf_ext, pstr_uni_drc_config_ext->loud_eq_instructions_count, 4);
2708
0
          for (idx = 0; idx < pstr_uni_drc_config_ext->loud_eq_instructions_count; idx++) {
2709
0
            impd_drc_write_loud_eq_instructions(
2710
0
                ptr_bit_buf_ext, &(pstr_uni_drc_config_ext->str_loud_eq_instructions[idx]),
2711
0
                &bit_cnt_local_ext);
2712
0
          }
2713
0
        }
2714
2715
594
        bit_cnt_local_ext +=
2716
594
            iusace_write_bits_buf(ptr_bit_buf_ext, pstr_uni_drc_config_ext->eq_present, 1);
2717
594
        if (pstr_uni_drc_config_ext->eq_present == 1) {
2718
0
          err_code = impd_drc_write_eq_coefficients(
2719
0
              ptr_bit_buf_ext, &(pstr_uni_drc_config_ext->str_eq_coefficients),
2720
0
              &bit_cnt_local_ext);
2721
0
          if (err_code & IA_FATAL_ERROR) {
2722
0
            return err_code;
2723
0
          }
2724
2725
0
          bit_cnt_local_ext += iusace_write_bits_buf(
2726
0
              ptr_bit_buf_ext, pstr_uni_drc_config_ext->eq_instructions_count, 4);
2727
0
          for (idx = 0; idx < pstr_uni_drc_config_ext->eq_instructions_count; idx++) {
2728
0
            err_code = impd_drc_write_eq_instructions(
2729
0
                ptr_bit_buf_ext, pstr_uni_drc_config_ext, pstr_gain_enc,
2730
0
                &(pstr_uni_drc_config_ext->str_eq_instructions[idx]), &bit_cnt_local_ext,
2731
0
                ptr_scratch, scratch_used);
2732
0
            if (err_code & IA_FATAL_ERROR) {
2733
0
              return (err_code);
2734
0
            }
2735
0
          }
2736
0
        }
2737
594
      } break;
2738
2739
594
#ifdef LOUDNESS_LEVELING_SUPPORT
2740
594
      case UNIDRCCONFEXT_LEVELING: {
2741
98
        bit_cnt_local_ext = 0;
2742
98
        err_code = write_loudness_leveling_extension(
2743
98
            ptr_bit_buf_ext, pstr_uni_drc_config, pstr_gain_enc, ptr_scratch, &bit_cnt_local_ext);
2744
98
        if (err_code & IA_FATAL_ERROR) {
2745
14
          return (err_code);
2746
14
        }
2747
98
      } break;
2748
84
#endif
2749
84
      default:
2750
0
        break;
2751
886
    }
2752
2753
678
    pstr_uni_drc_config_ext->ext_bit_size[counter] = bit_cnt_local_ext;
2754
678
    bit_size = pstr_uni_drc_config_ext->ext_bit_size[counter] - 1;
2755
678
    ext_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1;
2756
678
#ifdef LOUDNESS_LEVELING_SUPPORT
2757
678
    ext_size_bits = (ext_size_bits < 4) ? 4 : ext_size_bits;
2758
678
#endif  // LOUDNESS_LEVELING_SUPPORT
2759
678
    bit_size_len = ext_size_bits - 4;
2760
2761
678
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 4);
2762
2763
678
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)ext_size_bits);
2764
2765
678
    switch (pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter]) {
2766
0
      case UNIDRC_CONF_EXT_PARAM_DRC: {
2767
0
        err_code = impd_drc_write_drc_coeff_parametric_drc(
2768
0
            it_bit_buf, pstr_uni_drc_config,
2769
0
            &(pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc), &bit_cnt_local);
2770
2771
0
        if (err_code & IA_FATAL_ERROR) {
2772
0
          return (err_code);
2773
0
        }
2774
2775
0
        bit_cnt_local += iusace_write_bits_buf(
2776
0
            it_bit_buf, pstr_uni_drc_config_ext->parametric_drc_instructions_count, 4);
2777
0
        for (idx = 0; idx < pstr_uni_drc_config_ext->parametric_drc_instructions_count; idx++) {
2778
0
          err_code = impd_drc_write_parametric_drc_instructions(
2779
0
              it_bit_buf,
2780
0
              pstr_uni_drc_config_ext->str_drc_coeff_parametric_drc.parametric_drc_frame_size,
2781
0
              &(pstr_uni_drc_config_ext->str_parametric_drc_instructions[idx]), &bit_cnt_local);
2782
0
          if (err_code & IA_FATAL_ERROR) {
2783
0
            return (err_code);
2784
0
          }
2785
0
        }
2786
0
      } break;
2787
594
      case UNIDRC_CONF_EXT_V1: {
2788
594
        version = 1;
2789
594
        bit_cnt_local += iusace_write_bits_buf(
2790
594
            it_bit_buf, pstr_uni_drc_config_ext->downmix_instructions_v1_present, 1);
2791
594
        if (pstr_uni_drc_config_ext->downmix_instructions_v1_present == 1) {
2792
98
          bit_cnt_local += iusace_write_bits_buf(
2793
98
              it_bit_buf, pstr_uni_drc_config_ext->downmix_instructions_v1_count, 7);
2794
454
          for (idx = 0; idx < pstr_uni_drc_config_ext->downmix_instructions_v1_count; idx++) {
2795
356
            impd_drc_write_downmix_instructions(
2796
356
                it_bit_buf, version, pstr_gain_enc,
2797
356
                &(pstr_uni_drc_config_ext->str_downmix_instructions_v1[idx]), &bit_cnt_local);
2798
356
          }
2799
98
        }
2800
2801
594
        bit_cnt_local += iusace_write_bits_buf(
2802
594
            it_bit_buf, pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present,
2803
594
            1);
2804
594
        if (pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present == 1) {
2805
507
          version = 1;
2806
507
          bit_cnt_local += iusace_write_bits_buf(
2807
507
              it_bit_buf, pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count, 3);
2808
1.45k
          for (idx = 0; idx < pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count; idx++) {
2809
944
            impd_drc_write_drc_coeff_uni_drc(
2810
944
                it_bit_buf, version,
2811
944
                &(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[idx]), &bit_cnt_local);
2812
944
          }
2813
507
#ifdef LOUDNESS_LEVELING_SUPPORT
2814
507
          UWORD32 num_ducking_only_drc_sets = get_num_ducking_only_drc_sets(
2815
507
              pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1,
2816
507
              pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count);
2817
507
          bit_cnt_local +=
2818
507
              iusace_write_bits_buf(it_bit_buf,
2819
507
                                    pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count -
2820
507
                                        num_ducking_only_drc_sets,
2821
507
                                    6);
2822
#else
2823
          bit_cnt_local += iusace_write_bits_buf(
2824
              it_bit_buf, pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 6);
2825
#endif
2826
837
          for (idx = 0; idx < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; idx++) {
2827
349
#ifdef LOUDNESS_LEVELING_SUPPORT
2828
349
            if (idx > 0 && pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx - 1]
2829
226
                               .ducking_only_set_present) {
2830
84
              continue;
2831
84
            }
2832
265
#endif
2833
265
            err_code = impd_drc_write_drc_instruct_uni_drc(
2834
265
                it_bit_buf, version, pstr_uni_drc_config, pstr_gain_enc,
2835
265
                &(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[idx]), ptr_scratch,
2836
265
                &bit_cnt_local);
2837
265
            if (err_code & IA_FATAL_ERROR) {
2838
19
              return (err_code);
2839
19
            }
2840
265
          }
2841
507
        }
2842
2843
575
        bit_cnt_local += iusace_write_bits_buf(
2844
575
            it_bit_buf, pstr_uni_drc_config_ext->loud_eq_instructions_present, 1);
2845
575
        if (pstr_uni_drc_config_ext->loud_eq_instructions_present == 1) {
2846
0
          bit_cnt_local += iusace_write_bits_buf(
2847
0
              it_bit_buf, pstr_uni_drc_config_ext->loud_eq_instructions_count, 4);
2848
0
          for (idx = 0; idx < pstr_uni_drc_config_ext->loud_eq_instructions_count; idx++) {
2849
0
            impd_drc_write_loud_eq_instructions(
2850
0
                it_bit_buf, &(pstr_uni_drc_config_ext->str_loud_eq_instructions[idx]),
2851
0
                &bit_cnt_local);
2852
0
          }
2853
0
        }
2854
2855
575
        bit_cnt_local +=
2856
575
            iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config_ext->eq_present, 1);
2857
575
        if (pstr_uni_drc_config_ext->eq_present == 1) {
2858
0
          err_code = impd_drc_write_eq_coefficients(
2859
0
              it_bit_buf, &(pstr_uni_drc_config_ext->str_eq_coefficients), &bit_cnt_local);
2860
0
          if (err_code & IA_FATAL_ERROR) {
2861
0
            return err_code;
2862
0
          }
2863
2864
0
          bit_cnt_local += iusace_write_bits_buf(
2865
0
              it_bit_buf, pstr_uni_drc_config_ext->eq_instructions_count, 4);
2866
0
          for (idx = 0; idx < pstr_uni_drc_config_ext->eq_instructions_count; idx++) {
2867
0
            err_code = impd_drc_write_eq_instructions(
2868
0
                it_bit_buf, pstr_uni_drc_config_ext, pstr_gain_enc,
2869
0
                &(pstr_uni_drc_config_ext->str_eq_instructions[idx]), &bit_cnt_local, ptr_scratch,
2870
0
                scratch_used);
2871
0
            if (err_code & IA_FATAL_ERROR) {
2872
0
              return err_code;
2873
0
            }
2874
0
          }
2875
0
        }
2876
575
      } break;
2877
575
#ifdef LOUDNESS_LEVELING_SUPPORT
2878
575
      case UNIDRCCONFEXT_LEVELING: {
2879
84
        err_code = write_loudness_leveling_extension(it_bit_buf, pstr_uni_drc_config,
2880
84
                                                     pstr_gain_enc, ptr_scratch, &bit_cnt_local);
2881
84
        if (err_code & IA_FATAL_ERROR) {
2882
1
          return (err_code);
2883
1
        }
2884
84
      } break;
2885
83
#endif
2886
83
      default:
2887
0
        for (idx = 0; idx < pstr_uni_drc_config_ext->ext_bit_size[counter]; idx++) {
2888
0
          bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1);
2889
0
        }
2890
0
        break;
2891
678
    }
2892
2893
658
    counter++;
2894
2895
658
    bit_cnt_local += iusace_write_bits_buf(
2896
658
        it_bit_buf, pstr_uni_drc_config_ext->uni_drc_config_ext_type[counter], 4);
2897
658
  }
2898
2899
560
  *ptr_bit_cnt += bit_cnt_local;
2900
2901
560
  return err_code;
2902
788
}
2903
2904
IA_ERRORCODE impd_drc_write_loudness_info_set_extension(
2905
    ia_drc_enc_state *pstr_drc_state, ia_bit_buf_struct *it_bit_buf,
2906
    ia_drc_loudness_info_set_extension_struct *pstr_loudness_info_set_extension,
2907
655
    WORD32 *ptr_bit_cnt, FLAG write_bs) {
2908
655
  IA_ERRORCODE err_code = IA_NO_ERROR;
2909
655
  LOOPIDX idx;
2910
655
  WORD32 counter = 0, version = 1;
2911
655
  WORD32 ext_size_bits = 0, bit_size_len = 0, bit_size = 0;
2912
655
  WORD32 bit_cnt_local = 0;
2913
655
  WORD32 bit_cnt_local_tmp = 0;
2914
655
  ia_drc_loudness_info_set_ext_eq_struct *pstr_loudness_info_set_ext_eq =
2915
655
      &pstr_loudness_info_set_extension->str_loudness_info_set_ext_eq;
2916
655
  ia_bit_buf_struct *ptr_bit_buf_tmp = NULL;
2917
2918
655
  if (write_bs) {
2919
149
    ptr_bit_buf_tmp = &pstr_drc_state->str_bit_buf_cfg_tmp;
2920
2921
149
    iusace_reset_bit_buffer(ptr_bit_buf_tmp);
2922
149
  }
2923
2924
655
  bit_cnt_local += iusace_write_bits_buf(
2925
655
      it_bit_buf, pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter], 4);
2926
1.30k
  while ((counter < 2) &&
2927
1.30k
         (pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter] !=
2928
1.30k
          UNIDRC_LOUD_EXT_TERM)) {
2929
655
    switch (pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter]) {
2930
655
      case UNIDRC_LOUD_EXT_EQ: {
2931
655
        bit_cnt_local_tmp += iusace_write_bits_buf(
2932
655
            ptr_bit_buf_tmp, pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count, 6);
2933
2934
655
        bit_cnt_local_tmp += iusace_write_bits_buf(
2935
655
            ptr_bit_buf_tmp, pstr_loudness_info_set_ext_eq->loudness_info_v1_count, 6);
2936
6.69k
        for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count; idx++) {
2937
6.04k
          err_code = impd_drc_write_loudness_info(
2938
6.04k
              ptr_bit_buf_tmp, version,
2939
6.04k
              &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1_album[idx]),
2940
6.04k
              &bit_cnt_local_tmp);
2941
6.04k
          if (err_code) {
2942
4
            return err_code;
2943
4
          }
2944
6.04k
        }
2945
4.79k
        for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_count; idx++) {
2946
4.15k
          err_code = impd_drc_write_loudness_info(
2947
4.15k
              ptr_bit_buf_tmp, version,
2948
4.15k
              &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1[idx]), &bit_cnt_local_tmp);
2949
4.15k
          if (err_code) {
2950
3
            return (err_code);
2951
3
          }
2952
4.15k
        }
2953
651
      } break;
2954
648
      default:
2955
0
        break;
2956
655
    }
2957
648
    pstr_loudness_info_set_extension->ext_bit_size[counter] = bit_cnt_local_tmp;
2958
648
    bit_size = pstr_loudness_info_set_extension->ext_bit_size[counter] - 1;
2959
648
    ext_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1;
2960
648
    bit_size_len = ext_size_bits - 4;
2961
648
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 4);
2962
648
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)ext_size_bits);
2963
2964
648
    switch (pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter]) {
2965
648
      case UNIDRC_LOUD_EXT_EQ: {
2966
648
        bit_cnt_local += iusace_write_bits_buf(
2967
648
            it_bit_buf, pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count, 6);
2968
2969
648
        bit_cnt_local += iusace_write_bits_buf(
2970
648
            it_bit_buf, pstr_loudness_info_set_ext_eq->loudness_info_v1_count, 6);
2971
6.55k
        for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_album_count; idx++) {
2972
5.90k
          err_code = impd_drc_write_loudness_info(
2973
5.90k
              it_bit_buf, version,
2974
5.90k
              &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1_album[idx]), &bit_cnt_local);
2975
5.90k
          if (err_code) {
2976
0
            return err_code;
2977
0
          }
2978
5.90k
        }
2979
4.77k
        for (idx = 0; idx < pstr_loudness_info_set_ext_eq->loudness_info_v1_count; idx++) {
2980
4.13k
          err_code = impd_drc_write_loudness_info(
2981
4.13k
              it_bit_buf, version, &(pstr_loudness_info_set_ext_eq->str_loudness_info_v1[idx]),
2982
4.13k
              &bit_cnt_local);
2983
4.13k
          if (err_code) {
2984
0
            return (err_code);
2985
0
          }
2986
4.13k
        }
2987
648
      } break;
2988
648
      default:
2989
0
        for (idx = 0; idx < pstr_loudness_info_set_extension->ext_bit_size[counter]; idx++) {
2990
0
          bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1);
2991
0
        }
2992
0
        break;
2993
648
    }
2994
648
    counter++;
2995
2996
648
    bit_cnt_local += iusace_write_bits_buf(
2997
648
        it_bit_buf, pstr_loudness_info_set_extension->loudness_info_set_ext_type[counter], 4);
2998
648
  }
2999
3000
648
  *ptr_bit_cnt += bit_cnt_local;
3001
3002
648
  return IA_NO_ERROR;
3003
655
}
3004
3005
IA_ERRORCODE impd_drc_write_loudness_info_set(ia_drc_enc_state *pstr_drc_state,
3006
                                              ia_bit_buf_struct *it_bit_buf, WORD32 *ptr_bit_cnt,
3007
5.09k
                                              FLAG write_bs) {
3008
5.09k
  IA_ERRORCODE err_code = IA_NO_ERROR;
3009
5.09k
  LOOPIDX idx;
3010
5.09k
  WORD32 version = 0;
3011
5.09k
  WORD32 bit_cnt_local = 0;
3012
5.09k
  ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state->str_gain_enc;
3013
5.09k
  ia_drc_loudness_info_set_struct *pstr_loudness_info_set =
3014
5.09k
      &(pstr_gain_enc->str_loudness_info_set);
3015
3016
5.09k
  bit_cnt_local +=
3017
5.09k
      iusace_write_bits_buf(it_bit_buf, pstr_loudness_info_set->loudness_info_album_count, 6);
3018
3019
5.09k
  bit_cnt_local +=
3020
5.09k
      iusace_write_bits_buf(it_bit_buf, pstr_loudness_info_set->loudness_info_count, 6);
3021
3022
7.99k
  for (idx = 0; idx < pstr_loudness_info_set->loudness_info_album_count; idx++) {
3023
2.90k
    err_code = impd_drc_write_loudness_info(it_bit_buf, version,
3024
2.90k
                                            &pstr_loudness_info_set->str_loudness_info_album[idx],
3025
2.90k
                                            &bit_cnt_local);
3026
2.90k
    if (err_code) {
3027
4
      return err_code;
3028
4
    }
3029
2.90k
  }
3030
3031
12.4k
  for (idx = 0; idx < pstr_loudness_info_set->loudness_info_count; idx++) {
3032
7.33k
    err_code = impd_drc_write_loudness_info(
3033
7.33k
        it_bit_buf, version, &pstr_loudness_info_set->str_loudness_info[idx], &bit_cnt_local);
3034
7.33k
    if (err_code) {
3035
5
      return err_code;
3036
5
    }
3037
7.33k
  }
3038
3039
5.08k
  bit_cnt_local +=
3040
5.08k
      iusace_write_bits_buf(it_bit_buf, pstr_loudness_info_set->loudness_info_set_ext_present, 1);
3041
5.08k
  if (pstr_loudness_info_set->loudness_info_set_ext_present) {
3042
655
    err_code = impd_drc_write_loudness_info_set_extension(
3043
655
        pstr_drc_state, it_bit_buf, &pstr_loudness_info_set->str_loudness_info_set_extension,
3044
655
        &bit_cnt_local, write_bs);
3045
655
    if (err_code) {
3046
7
      return err_code;
3047
7
    }
3048
655
  }
3049
3050
5.08k
  *ptr_bit_cnt += bit_cnt_local;
3051
3052
5.08k
  return err_code;
3053
5.08k
}
3054
3055
IA_ERRORCODE impd_drc_write_uni_drc_config(ia_drc_enc_state *pstr_drc_state, WORD32 *ptr_bit_cnt,
3056
2.09k
                                           FLAG write_bs) {
3057
2.09k
  IA_ERRORCODE err_code = IA_NO_ERROR;
3058
2.09k
  LOOPIDX idx;
3059
2.09k
  WORD32 version = 0;
3060
2.09k
  WORD32 bit_cnt_local = 0;
3061
2.09k
  VOID *ptr_scratch = pstr_drc_state->drc_scratch_mem;
3062
2.09k
  ia_bit_buf_struct *it_bit_buf = NULL;
3063
2.09k
  ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state->str_gain_enc;
3064
2.09k
  ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &(pstr_gain_enc->str_uni_drc_config);
3065
3066
2.09k
  if (write_bs) {
3067
635
    it_bit_buf = &pstr_drc_state->str_bit_buf_cfg;
3068
635
  }
3069
3070
2.09k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->sample_rate_present, 1);
3071
3072
2.09k
  if (1 == pstr_uni_drc_config->sample_rate_present) {
3073
1.76k
    bit_cnt_local +=
3074
1.76k
        iusace_write_bits_buf(it_bit_buf, (pstr_uni_drc_config->sample_rate - 1000), 18);
3075
1.76k
  }
3076
3077
2.09k
  bit_cnt_local +=
3078
2.09k
      iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->downmix_instructions_count, 7);
3079
3080
2.09k
  bit_cnt_local +=
3081
2.09k
      iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_description_basic_present, 1);
3082
3083
2.09k
  if (1 == pstr_uni_drc_config->drc_description_basic_present) {
3084
716
    bit_cnt_local +=
3085
716
        iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_coefficients_basic_count, 3);
3086
716
    bit_cnt_local +=
3087
716
        iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_instructions_basic_count, 4);
3088
716
  }
3089
3090
2.09k
  bit_cnt_local +=
3091
2.09k
      iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_coefficients_uni_drc_count, 3);
3092
3093
2.09k
#ifdef LOUDNESS_LEVELING_SUPPORT
3094
2.09k
  UWORD32 num_ducking_only_drc_sets =
3095
2.09k
      get_num_ducking_only_drc_sets(pstr_uni_drc_config->str_drc_instructions_uni_drc,
3096
2.09k
                                    pstr_uni_drc_config->drc_instructions_uni_drc_count);
3097
2.09k
  bit_cnt_local += iusace_write_bits_buf(
3098
2.09k
      it_bit_buf, pstr_uni_drc_config->drc_instructions_uni_drc_count - num_ducking_only_drc_sets,
3099
2.09k
      6);
3100
#else
3101
  bit_cnt_local +=
3102
      iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->drc_instructions_uni_drc_count, 6);
3103
#endif
3104
2.09k
  bit_cnt_local +=
3105
2.09k
      iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->str_channel_layout.base_ch_count, 7);
3106
2.09k
  bit_cnt_local += iusace_write_bits_buf(
3107
2.09k
      it_bit_buf, pstr_uni_drc_config->str_channel_layout.layout_signaling_present, 1);
3108
2.09k
  if (1 == pstr_uni_drc_config->str_channel_layout.layout_signaling_present) {
3109
114
    bit_cnt_local += iusace_write_bits_buf(
3110
114
        it_bit_buf, pstr_uni_drc_config->str_channel_layout.defined_layout, 8);
3111
114
    if (0 == pstr_uni_drc_config->str_channel_layout.defined_layout) {
3112
9
      for (idx = 0; idx < pstr_uni_drc_config->str_channel_layout.base_ch_count; idx++) {
3113
6
        bit_cnt_local += iusace_write_bits_buf(
3114
6
            it_bit_buf, pstr_uni_drc_config->str_channel_layout.speaker_position[idx], 7);
3115
6
      }
3116
3
    }
3117
114
  }
3118
3119
6.82k
  for (idx = 0; idx < pstr_uni_drc_config->downmix_instructions_count; idx++) {
3120
    // downmixInstructions();
3121
4.72k
  }
3122
3123
2.09k
  for (idx = 0; idx < pstr_uni_drc_config->drc_coefficients_basic_count; idx++) {
3124
    // drcCoefficientsBasic();
3125
0
  }
3126
3127
2.09k
  for (idx = 0; idx < pstr_uni_drc_config->drc_instructions_basic_count; idx++) {
3128
    // drcInstructionsBasics();
3129
0
  }
3130
3131
4.38k
  for (idx = 0; idx < pstr_uni_drc_config->drc_coefficients_uni_drc_count; idx++) {
3132
2.28k
    impd_drc_write_drc_coeff_uni_drc(it_bit_buf, version,
3133
2.28k
                                     &(pstr_uni_drc_config->str_drc_coefficients_uni_drc[idx]),
3134
2.28k
                                     &bit_cnt_local);
3135
2.28k
  }
3136
3137
3.38k
  for (idx = 0; idx < pstr_uni_drc_config->drc_instructions_uni_drc_count; idx++) {
3138
1.52k
#ifdef LOUDNESS_LEVELING_SUPPORT
3139
1.52k
    if (idx > 0 &&
3140
1.24k
        pstr_uni_drc_config->str_drc_instructions_uni_drc[idx - 1].ducking_only_set_present) {
3141
234
      continue;
3142
234
    }
3143
1.29k
#endif
3144
1.29k
    err_code = impd_drc_write_drc_instruct_uni_drc(
3145
1.29k
        it_bit_buf, version, pstr_uni_drc_config, pstr_gain_enc,
3146
1.29k
        &(pstr_uni_drc_config->str_drc_instructions_uni_drc[idx]), ptr_scratch, &bit_cnt_local);
3147
1.29k
    if (err_code & IA_FATAL_ERROR) {
3148
243
      return err_code;
3149
243
    }
3150
1.29k
  }
3151
3152
1.85k
  bit_cnt_local +=
3153
1.85k
      iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_config->uni_drc_config_ext_present, 1);
3154
1.85k
  if (pstr_uni_drc_config->uni_drc_config_ext_present) {
3155
788
    err_code = impd_drc_write_uni_drc_config_extn(
3156
788
        pstr_drc_state, pstr_gain_enc, pstr_uni_drc_config,
3157
788
        &(pstr_uni_drc_config->str_uni_drc_config_ext), &bit_cnt_local, write_bs);
3158
788
    if (err_code & IA_FATAL_ERROR) {
3159
228
      return (err_code);
3160
228
    }
3161
788
  }
3162
3163
1.62k
  *ptr_bit_cnt += bit_cnt_local;
3164
3165
1.62k
  return err_code;
3166
1.85k
}
3167
3168
3.11k
IA_ERRORCODE impd_drc_write_measured_loudness_info(ia_drc_enc_state *pstr_drc_state) {
3169
3170
3.11k
  IA_ERRORCODE err_code = IA_NO_ERROR;
3171
3.11k
  ia_bit_buf_struct *it_bit_buf_lis = &pstr_drc_state->str_bit_buf_cfg_ext;
3172
3.11k
  WORD32 bit_cnt_lis = 0;
3173
3.11k
  err_code = impd_drc_write_loudness_info_set(pstr_drc_state, it_bit_buf_lis, &bit_cnt_lis, 1);
3174
3.11k
  if (err_code & IA_FATAL_ERROR) {
3175
0
    return (err_code);
3176
0
  }
3177
3.11k
  pstr_drc_state->drc_config_ext_data_size_bit = bit_cnt_lis;
3178
3179
3.11k
  return err_code;
3180
3.11k
}
3181
3182
IA_ERRORCODE impd_drc_enc_initial_gain(const WORD32 gain_coding_profile, FLOAT32 gain_initial,
3183
                                       FLOAT32 *gain_initial_quant, WORD32 *code_size,
3184
181k
                                       WORD32 *code) {
3185
181k
  WORD32 sign, magnitude, bits, size;
3186
3187
181k
  switch (gain_coding_profile) {
3188
56.4k
    case GAIN_CODING_PROFILE_CONSTANT: {
3189
56.4k
      bits = 0;
3190
56.4k
      size = 0;
3191
56.4k
    } break;
3192
2.62k
    case GAIN_CODING_PROFILE_CLIPPING: {
3193
2.62k
      if (gain_initial > -0.0625f) {
3194
2.14k
        sign = 0;
3195
2.14k
        *gain_initial_quant = 0.0f;
3196
2.14k
        bits = sign;
3197
2.14k
        size = 1;
3198
2.14k
      } else {
3199
477
        sign = 1;
3200
477
        gain_initial = MAX(-1000.0f, gain_initial);
3201
477
        magnitude = (WORD32)(-1.0f + 0.5f - 8.0f * gain_initial);
3202
477
        magnitude = MIN(0xFF, magnitude);
3203
477
        *gain_initial_quant = -(magnitude + 1) * 0.125f;
3204
477
        bits = (sign << 8) + magnitude;
3205
477
        size = 9;
3206
477
      }
3207
2.62k
    } break;
3208
5.64k
    case GAIN_CODING_PROFILE_FADING: {
3209
5.64k
      if (gain_initial > -0.0625f) {
3210
2.09k
        sign = 0;
3211
2.09k
        *gain_initial_quant = 0.0f;
3212
2.09k
        bits = sign;
3213
2.09k
        size = 1;
3214
3.55k
      } else {
3215
3.55k
        sign = 1;
3216
3.55k
        gain_initial = MAX(-1000.0f, gain_initial);
3217
3.55k
        magnitude = (WORD32)(-1.0f + 0.5f - 8.0f * gain_initial);
3218
3.55k
        magnitude = MIN(0x3FF, magnitude);
3219
3.55k
        *gain_initial_quant = -(magnitude + 1) * 0.125f;
3220
3.55k
        bits = (sign << 10) + magnitude;
3221
3.55k
        size = 11;
3222
3.55k
      }
3223
5.64k
    } break;
3224
116k
    case GAIN_CODING_PROFILE_REGULAR: {
3225
116k
      if (gain_initial < 0.0f) {
3226
2.90k
        sign = 1;
3227
2.90k
        gain_initial = MAX(-1000.0f, gain_initial);
3228
2.90k
        magnitude = (WORD32)(0.5f - 8.0f * gain_initial);
3229
2.90k
        magnitude = MIN(0xFF, magnitude);
3230
2.90k
        *gain_initial_quant = -magnitude * 0.125f;
3231
113k
      } else {
3232
113k
        sign = 0;
3233
113k
        gain_initial = MIN(1000.0f, gain_initial);
3234
113k
        magnitude = (WORD32)(0.5f + 8.0f * gain_initial);
3235
113k
        magnitude = MIN(0xFF, magnitude);
3236
113k
        *gain_initial_quant = magnitude * 0.125f;
3237
113k
      }
3238
116k
      bits = (sign << 8) + magnitude;
3239
116k
      size = 9;
3240
116k
    } break;
3241
0
    default:
3242
0
      return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
3243
181k
  }
3244
3245
181k
  *code = bits;
3246
181k
  *code_size = size;
3247
3248
181k
  return IA_NO_ERROR;
3249
181k
}
3250
3251
static VOID impd_drc_write_spline_nodes(ia_bit_buf_struct *it_bit_buf,
3252
                                        ia_drc_gain_enc_struct *pstr_gain_enc,
3253
                                        ia_drc_gain_set_params_struct *pstr_gain_set_params,
3254
                                        ia_drc_group_for_output_struct *pstr_drc_group_for_output,
3255
61.6k
                                        WORD32 *ptr_bit_cnt) {
3256
61.6k
  LOOPIDX idx;
3257
61.6k
  WORD32 frame_end_flag;
3258
61.6k
  WORD32 bit_cnt_local = 0;
3259
3260
61.6k
  bit_cnt_local += iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->coding_mode, 1);
3261
61.6k
  if (pstr_drc_group_for_output->coding_mode != 0) {
3262
200k
    for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values - 1; idx++) {
3263
174k
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1);
3264
174k
    }
3265
26.1k
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 1, 1);
3266
3267
26.1k
    if (pstr_gain_set_params->gain_interpolation_type == GAIN_INTERPOLATION_TYPE_SPLINE) {
3268
213k
      for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values; idx++) {
3269
193k
        bit_cnt_local +=
3270
193k
            iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->slope_code[idx],
3271
193k
                                  (UWORD8)pstr_drc_group_for_output->slope_code_size[idx]);
3272
193k
      }
3273
19.3k
    }
3274
3275
26.1k
    if (pstr_gain_set_params->full_frame == 0 && pstr_drc_group_for_output->n_gain_values > 0) {
3276
9.21k
      if (pstr_drc_group_for_output->ts_gain_quant[pstr_drc_group_for_output->n_gain_values -
3277
9.21k
                                                   1] == (pstr_gain_enc->drc_frame_size - 1)) {
3278
8.10k
        frame_end_flag = 1;
3279
8.10k
      } else {
3280
1.10k
        frame_end_flag = 0;
3281
1.10k
      }
3282
9.21k
      bit_cnt_local += iusace_write_bits_buf(it_bit_buf, frame_end_flag, 1);
3283
16.8k
    } else {
3284
16.8k
      frame_end_flag = 1;
3285
16.8k
    }
3286
3287
226k
    for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values; idx++) {
3288
200k
      if (idx < (pstr_drc_group_for_output->n_gain_values - 1) || !frame_end_flag) {
3289
175k
        bit_cnt_local +=
3290
175k
            iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->time_delta_code[idx],
3291
175k
                                  (UWORD8)pstr_drc_group_for_output->time_delta_code_size[idx]);
3292
175k
      }
3293
200k
    }
3294
226k
    for (idx = 0; idx < pstr_drc_group_for_output->n_gain_values; idx++) {
3295
200k
      bit_cnt_local +=
3296
200k
          iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->gain_code[idx],
3297
200k
                                (UWORD8)pstr_drc_group_for_output->gain_code_length[idx]);
3298
200k
    }
3299
35.4k
  } else {
3300
35.4k
    bit_cnt_local +=
3301
35.4k
        iusace_write_bits_buf(it_bit_buf, pstr_drc_group_for_output->gain_code[0],
3302
35.4k
                              (UWORD8)pstr_drc_group_for_output->gain_code_length[0]);
3303
35.4k
  }
3304
3305
61.6k
  *ptr_bit_cnt += bit_cnt_local;
3306
61.6k
}
3307
3308
static VOID impd_drc_write_uni_drc_gain_extension(
3309
    ia_bit_buf_struct *it_bit_buf, ia_drc_uni_drc_gain_ext_struct *pstr_uni_drc_gain_ext,
3310
1.10k
    WORD32 *ptr_bit_cnt) {
3311
1.10k
  LOOPIDX idx;
3312
1.10k
  WORD32 counter = 0;
3313
1.10k
  WORD32 ext_size_bits, bit_size_len, bit_size;
3314
1.10k
  WORD32 bit_cnt_local = 0;
3315
3316
1.10k
  bit_cnt_local +=
3317
1.10k
      iusace_write_bits_buf(it_bit_buf, pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter], 4);
3318
1.10k
  while (pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter] != UNIDRC_GAIN_EXT_TERM) {
3319
0
    bit_size = pstr_uni_drc_gain_ext->ext_bit_size[counter] - 1;
3320
0
    ext_size_bits = (WORD32)(log((FLOAT32)bit_size) / log(2.f)) + 1;
3321
0
    bit_size_len = ext_size_bits - 4;
3322
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size_len, 3);
3323
0
    bit_cnt_local += iusace_write_bits_buf(it_bit_buf, bit_size, (UWORD8)ext_size_bits);
3324
0
    switch (pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter]) {
3325
0
      default:
3326
0
        for (idx = 0; idx < pstr_uni_drc_gain_ext->ext_bit_size[counter]; idx++) {
3327
0
          bit_cnt_local += iusace_write_bits_buf(it_bit_buf, 0, 1);
3328
0
        }
3329
0
    }
3330
0
    counter++;
3331
3332
0
    bit_cnt_local += iusace_write_bits_buf(
3333
0
        it_bit_buf, pstr_uni_drc_gain_ext->uni_drc_gain_ext_type[counter], 4);
3334
0
  }
3335
3336
1.10k
  *ptr_bit_cnt += bit_cnt_local;
3337
1.10k
}
3338
3339
55.4k
VOID impd_drc_write_uni_drc_gain(ia_drc_enc_state *pstr_drc_state, WORD32 *ptr_bit_cnt) {
3340
55.4k
  LOOPIDX idx;
3341
55.4k
  WORD32 bit_cnt_local = 0;
3342
55.4k
  ia_bit_buf_struct *it_bit_buf = &pstr_drc_state->str_bit_buf_out;
3343
55.4k
  ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state->str_gain_enc;
3344
55.4k
  ia_drc_group_for_output_struct *pstr_drc_group_for_output;
3345
55.4k
  ia_drc_gain_set_params_struct *pstr_gain_set_params;
3346
55.4k
  ia_drc_uni_drc_gain_ext_struct str_uni_drc_gain_extension =
3347
55.4k
      pstr_drc_state->str_enc_gain_extension;
3348
3349
144k
  for (idx = 0; idx < pstr_gain_enc->n_sequences; idx++) {
3350
89.5k
    pstr_drc_group_for_output =
3351
89.5k
        &(pstr_gain_enc->str_drc_gain_seq_buf[idx].str_drc_group_for_output);
3352
89.5k
    pstr_gain_set_params = &(pstr_gain_enc->str_drc_gain_seq_buf[idx].str_gain_set_params);
3353
3354
89.5k
    if (pstr_gain_set_params->gain_coding_profile < GAIN_CODING_PROFILE_CONSTANT) {
3355
61.6k
      impd_drc_write_spline_nodes(it_bit_buf, pstr_gain_enc, pstr_gain_set_params,
3356
61.6k
                                  pstr_drc_group_for_output, &bit_cnt_local);
3357
61.6k
    }
3358
89.5k
  }
3359
3360
55.4k
  bit_cnt_local +=
3361
55.4k
      iusace_write_bits_buf(it_bit_buf, str_uni_drc_gain_extension.uni_drc_gain_ext_present, 1);
3362
55.4k
  if (str_uni_drc_gain_extension.uni_drc_gain_ext_present) {
3363
1.10k
    impd_drc_write_uni_drc_gain_extension(it_bit_buf, &str_uni_drc_gain_extension,
3364
1.10k
                                          &bit_cnt_local);
3365
1.10k
  }
3366
3367
55.4k
  if (bit_cnt_local & 0x07) {
3368
51.7k
    pstr_drc_state->bit_buf_base_out[bit_cnt_local >> 3] |= 0xFF >> (bit_cnt_local & 0x07);
3369
3370
51.7k
    bit_cnt_local += 8 - (bit_cnt_local & 0x07);
3371
51.7k
  }
3372
3373
55.4k
  *ptr_bit_cnt += bit_cnt_local;
3374
55.4k
}