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