xref: /aosp_15_r20/external/libxaac/encoder/drc_src/impd_drc_api.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 <string.h>
22 #include "ixheaac_type_def.h"
23 #include "ixheaac_error_standards.h"
24 #include "ixheaace_error_codes.h"
25 
26 #include "iusace_bitbuffer.h"
27 #include "iusace_cnst.h"
28 #include "impd_drc_common_enc.h"
29 #include "impd_drc_uni_drc.h"
30 #include "impd_drc_tables.h"
31 #include "impd_drc_api.h"
32 #include "impd_drc_uni_drc_eq.h"
33 #include "impd_drc_uni_drc_filter_bank.h"
34 #include "impd_drc_gain_enc.h"
35 #include "impd_drc_struct_def.h"
36 #include "impd_drc_enc.h"
37 
38 #define IMPD_DRC_BOUND_CHECK(var, lower_bound, upper_bound) \
39   {                                                         \
40     var = MIN(var, upper_bound);                            \
41     var = MAX(var, lower_bound);                            \
42   }
43 
impd_drc_validate_config_params(ia_drc_input_config * pstr_inp_config)44 IA_ERRORCODE impd_drc_validate_config_params(ia_drc_input_config *pstr_inp_config) {
45   LOOPIDX i, j, k;
46   WORD32 curr_start_subband_idx, next_start_subband_idx;
47   ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &pstr_inp_config->str_uni_drc_config;
48   ia_drc_loudness_info_set_struct *pstr_enc_loudness_info_set =
49       &pstr_inp_config->str_enc_loudness_info_set;
50 
51   IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->drc_instructions_uni_drc_count, 0,
52                        MAX_DRC_INSTRUCTIONS_COUNT);
53   for (i = 0; i < pstr_uni_drc_config->drc_instructions_uni_drc_count; i++) {
54     IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_id, 0,
55                          MAX_DRC_SET_ID);
56     IMPD_DRC_BOUND_CHECK(
57         pstr_uni_drc_config->str_drc_instructions_uni_drc[i].additional_downmix_id_count, 0,
58         ADDITIONAL_DOWNMIX_ID_COUNT_MAX);
59     IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_location, 0,
60                          MAX_DRC_LOCATION);
61     IMPD_DRC_BOUND_CHECK(
62         pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_target_loudness_value_upper,
63         MIN_DRC_TARGET_LOUDNESS, 0);
64     IMPD_DRC_BOUND_CHECK(
65         pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_target_loudness_value_lower,
66         MIN_DRC_TARGET_LOUDNESS, 0);
67     for (j = 0; j < MAX_CHANNEL_COUNT; j++) {
68       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].gain_set_index[j],
69                            0, GAIN_SET_COUNT_MAX - 1);
70     }
71     IMPD_DRC_BOUND_CHECK(
72         pstr_uni_drc_config->str_drc_instructions_uni_drc[i].num_drc_channel_groups, 0,
73         MAX_CHANNEL_GROUP_COUNT);
74     for (j = 0; j < pstr_uni_drc_config->str_drc_instructions_uni_drc[i].num_drc_channel_groups;
75          j++) {
76       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i]
77                                .str_gain_modifiers[j]
78                                .attenuation_scaling[0],
79                            0, MAX_ATTENUATION_SCALING);
80       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i]
81                                .str_gain_modifiers[j]
82                                .amplification_scaling[0],
83                            0, MAX_AMPLIFICATION_SCALING);
84       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i]
85                                .str_gain_modifiers[j]
86                                .gain_offset[0],
87                            MIN_DRC_GAIN_OFFSET, MAX_DRC_GAIN_OFFSET);
88     }
89     IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].limiter_peak_target,
90                          MIN_LIMITER_PEAK_TARGET, 0.0f);
91   }
92 
93   IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->drc_coefficients_uni_drc_count, 0,
94                        MAX_DRC_COEFF_COUNT);
95   for (i = 0; i < pstr_uni_drc_config->drc_coefficients_uni_drc_count; i++) {
96     IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].drc_location, 0,
97                          MAX_DRC_LOCATION);
98     IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].gain_set_count, 0,
99                          MAX_CHANNEL_GROUP_COUNT);
100     for (j = 0; j < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].gain_set_count; j++) {
101       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
102                                .str_gain_set_params[j]
103                                .gain_coding_profile,
104                            0, MAX_GAIN_CODING_PROFILE);
105       IMPD_DRC_BOUND_CHECK(
106           pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].str_gain_set_params[j].band_count,
107           0, MAX_BAND_COUNT);
108       for (k = 0;
109            k <
110            pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].str_gain_set_params[j].band_count;
111            k++) {
112         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
113                                  .str_gain_set_params[j]
114                                  .gain_params[k]
115                                  .nb_points,
116                              0, MAX_GAIN_POINTS);
117         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
118                                  .str_gain_set_params[j]
119                                  .gain_params[k]
120                                  .drc_characteristic,
121                              0, MAX_DRC_CHARACTERISTIC_VALUE);
122         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
123                                  .str_gain_set_params[j]
124                                  .gain_params[k]
125                                  .crossover_freq_index,
126                              0, MAX_CROSSOVER_FREQ_INDEX);
127         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
128                                  .str_gain_set_params[j]
129                                  .gain_params[k]
130                                  .start_sub_band_index,
131                              0, STFT256_HOP_SIZE - 1);
132         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
133                                  .str_gain_set_params[j]
134                                  .gain_params[k]
135                                  .width,
136                              -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
137         for (WORD32 m = 0; m < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
138                                    .str_gain_set_params[j]
139                                    .gain_params[k]
140                                    .nb_points;
141              m++) {
142           IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
143                                    .str_gain_set_params[j]
144                                    .gain_params[k]
145                                    .gain_points[m]
146                                    .x,
147                                -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
148           IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
149                                    .str_gain_set_params[j]
150                                    .gain_params[k]
151                                    .gain_points[m]
152                                    .y,
153                                -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
154         }
155       }
156       for (k = 0; k < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
157                               .str_gain_set_params[j]
158                               .band_count -
159                           1;
160            k++) {
161         curr_start_subband_idx = pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
162                                      .str_gain_set_params[j]
163                                      .gain_params[k]
164                                      .start_sub_band_index;
165         next_start_subband_idx = pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
166                                      .str_gain_set_params[j]
167                                      .gain_params[k + 1]
168                                      .start_sub_band_index;
169         /* It is assumed that the start index of a subband is greater than
170            the start index of its previous subbands for a multiband */
171         if (next_start_subband_idx <= curr_start_subband_idx) {
172           return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_SUBBAND_INDEX;
173         }
174       }
175     }
176   }
177   IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->downmix_instructions_count, 0,
178                        MAX_DOWNMIX_INSTRUCTION_COUNT);
179 
180   IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->loudness_info_count, 0,
181                        MAX_LOUDNESS_INFO_COUNT);
182   for (i = 0; i < pstr_enc_loudness_info_set->loudness_info_count; i++) {
183     IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i].sample_peak_level,
184                          MIN_SAMPLE_PEAK_LEVEL, MAX_SAMPLE_PEAK_LEVEL);
185     IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i].true_peak_level,
186                          MIN_TRUE_PEAK_LEVEL, MAX_TRUE_PEAK_LEVEL);
187     IMPD_DRC_BOUND_CHECK(
188         pstr_enc_loudness_info_set->str_loudness_info[i].true_peak_level_measurement_system, 0,
189         MAX_MEASUREMENT_SYSTEM_TYPE);
190     IMPD_DRC_BOUND_CHECK(
191         pstr_enc_loudness_info_set->str_loudness_info[i].true_peak_level_reliability, 0,
192         MAX_RELIABILITY_TYPE);
193     IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i].measurement_count, 0,
194                          MAX_MEASUREMENT_COUNT);
195     for (j = 0; j < pstr_enc_loudness_info_set->str_loudness_info[i].measurement_count; j++) {
196       IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i]
197                                .str_loudness_measure[j]
198                                .method_definition,
199                            0, MAX_METHOD_DEFINITION_TYPE);
200       IMPD_DRC_BOUND_CHECK(
201           pstr_enc_loudness_info_set->str_loudness_info[i].str_loudness_measure[j].method_value,
202           MIN_METHOD_VALUE, MAX_METHOD_VALUE);
203       IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i]
204                                .str_loudness_measure[j]
205                                .measurement_system,
206                            0, MAX_MEASUREMENT_SYSTEM_TYPE);
207       IMPD_DRC_BOUND_CHECK(
208           pstr_enc_loudness_info_set->str_loudness_info[i].str_loudness_measure[j].reliability, 0,
209           MAX_RELIABILITY_TYPE);
210     }
211   }
212   IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->loudness_info_album_count, 0,
213                        MAX_LOUDNESS_INFO_COUNT);
214   for (i = 0; i < pstr_enc_loudness_info_set->loudness_info_album_count; i++) {
215     IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i].sample_peak_level,
216                          MIN_SAMPLE_PEAK_LEVEL, MAX_SAMPLE_PEAK_LEVEL);
217     IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i].true_peak_level,
218                          MIN_TRUE_PEAK_LEVEL, MAX_TRUE_PEAK_LEVEL);
219     IMPD_DRC_BOUND_CHECK(
220         pstr_enc_loudness_info_set->str_loudness_info_album[i].true_peak_level_measurement_system,
221         0, MAX_MEASUREMENT_SYSTEM_TYPE);
222     IMPD_DRC_BOUND_CHECK(
223         pstr_enc_loudness_info_set->str_loudness_info_album[i].true_peak_level_reliability, 0,
224         MAX_RELIABILITY_TYPE);
225     IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i].measurement_count,
226                          0, MAX_MEASUREMENT_COUNT);
227     for (j = 0; j < pstr_enc_loudness_info_set->str_loudness_info_album[i].measurement_count;
228          j++) {
229       IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
230                                .str_loudness_measure[j]
231                                .method_definition,
232                            0, MAX_METHOD_DEFINITION_TYPE);
233       IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
234                                .str_loudness_measure[j]
235                                .method_value,
236                            MIN_METHOD_VALUE, MAX_METHOD_VALUE);
237       IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
238                                .str_loudness_measure[j]
239                                .measurement_system,
240                            0, MAX_MEASUREMENT_SYSTEM_TYPE);
241       IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
242                                .str_loudness_measure[j]
243                                .reliability,
244                            0, MAX_RELIABILITY_TYPE);
245     }
246   }
247 
248   if (pstr_uni_drc_config->uni_drc_config_ext_present) {
249     ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext =
250         &pstr_uni_drc_config->str_uni_drc_config_ext;
251     if (pstr_uni_drc_config_ext->downmix_instructions_v1_present) {
252       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->downmix_instructions_v1_count, 0,
253                            DOWNMIX_INSTRUCTIONS_COUNT_MAX);
254       for (i = 0; i < pstr_uni_drc_config_ext->downmix_instructions_v1_count; i++) {
255         IMPD_DRC_BOUND_CHECK(
256             pstr_uni_drc_config_ext->str_downmix_instructions_v1[i].target_layout, 0,
257             MAX_TARGET_LAYOUT_COUNT);
258         IMPD_DRC_BOUND_CHECK(
259             pstr_uni_drc_config_ext->str_downmix_instructions_v1[i].target_ch_count, 0,
260             MAX_CHANNEL_COUNT);
261       }
262     }
263 
264     if (pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present) {
265       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count, 0,
266                            DRC_COEFFICIENTS_UNIDRC_V1_COUNT_MAX);
267       for (i = 0; i < pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count; i++) {
268         IMPD_DRC_BOUND_CHECK(
269             pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i].gain_set_count, 0,
270             GAIN_SET_COUNT_MAX);
271         for (j = 0;
272              j < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i].gain_set_count;
273              j++) {
274           IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
275                                    .str_gain_set_params[j]
276                                    .gain_coding_profile,
277                                0, MAX_GAIN_CODING_PROFILE);
278           IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
279                                    .str_gain_set_params[j]
280                                    .band_count,
281                                0, MAX_BAND_COUNT);
282           for (k = 0; k < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
283                               .str_gain_set_params[j]
284                               .band_count;
285                k++) {
286             IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
287                                      .str_gain_set_params[j]
288                                      .gain_params[k]
289                                      .nb_points,
290                                  0, MAX_GAIN_POINTS);
291             IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
292                                      .str_gain_set_params[j]
293                                      .gain_params[k]
294                                      .drc_characteristic,
295                                  0, MAX_DRC_CHARACTERISTIC_VALUE);
296             IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
297                                      .str_gain_set_params[j]
298                                      .gain_params[k]
299                                      .crossover_freq_index,
300                                  0, MAX_CROSSOVER_FREQ_INDEX);
301             IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
302                                      .str_gain_set_params[j]
303                                      .gain_params[k]
304                                      .start_sub_band_index,
305                                  0, STFT256_HOP_SIZE - 1);
306             IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
307                                      .str_gain_set_params[j]
308                                      .gain_params[k]
309                                      .width,
310                                  -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
311             for (WORD32 m = 0; m < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
312                                        .str_gain_set_params[j]
313                                        .gain_params[k]
314                                        .nb_points;
315                  m++) {
316               IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
317                                        .str_gain_set_params[j]
318                                        .gain_params[k]
319                                        .gain_points[m]
320                                        .x,
321                                    -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
322               IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
323                                        .str_gain_set_params[j]
324                                        .gain_params[k]
325                                        .gain_points[m]
326                                        .y,
327                                    -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
328             }
329           }
330           for (k = 0; k < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
331                                   .str_gain_set_params[j]
332                                   .band_count -
333                               1;
334                k++) {
335             curr_start_subband_idx = pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
336                                          .str_gain_set_params[j]
337                                          .gain_params[k]
338                                          .start_sub_band_index;
339             next_start_subband_idx = pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
340                                          .str_gain_set_params[j]
341                                          .gain_params[k + 1]
342                                          .start_sub_band_index;
343             /* It is assumed that the start index of a subband is greater than
344                the start index of its previous subbands for a multiband */
345             if (next_start_subband_idx <= curr_start_subband_idx) {
346               return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_SUBBAND_INDEX;
347             }
348           }
349         }
350       }
351 
352       IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 0,
353                            DRC_INSTRUCTIONS_UNIDRC_V1_COUNT_MAX);
354       for (i = 0; i < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; i++) {
355         IMPD_DRC_BOUND_CHECK(
356             pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_set_id, 0,
357             MAX_DRC_SET_ID);
358         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
359                                  .additional_downmix_id_count,
360                              0, MAX_ADDITIONAL_DOWNMIX_ID);
361         IMPD_DRC_BOUND_CHECK(
362             pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_location, 0,
363             MAX_DRC_LOCATION);
364         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
365                                  .drc_set_target_loudness_value_upper,
366                              MIN_DRC_TARGET_LOUDNESS, 0);
367         IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
368                                  .drc_set_target_loudness_value_lower,
369                              MIN_DRC_TARGET_LOUDNESS, 0);
370         for (j = 0; j < MAX_CHANNEL_COUNT; j++) {
371           IMPD_DRC_BOUND_CHECK(
372               pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].gain_set_index[j], 0,
373               GAIN_SET_COUNT_MAX - 1);
374         }
375         IMPD_DRC_BOUND_CHECK(
376             pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].num_drc_channel_groups, 0,
377             MAX_CHANNEL_GROUP_COUNT);
378         for (j = 0;
379              j <
380              pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].num_drc_channel_groups;
381              j++) {
382           IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
383                                    .str_gain_modifiers[j]
384                                    .attenuation_scaling[0],
385                                0, MAX_ATTENUATION_SCALING);
386           IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
387                                    .str_gain_modifiers[j]
388                                    .amplification_scaling[0],
389                                0, MAX_AMPLIFICATION_SCALING);
390           IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
391                                    .str_gain_modifiers[j]
392                                    .gain_offset[0],
393                                MIN_DRC_GAIN_OFFSET, MAX_DRC_GAIN_OFFSET);
394         }
395         IMPD_DRC_BOUND_CHECK(
396             pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].limiter_peak_target,
397             MIN_LIMITER_PEAK_TARGET, 0.0f);
398       }
399     }
400   }
401   return IA_NO_ERROR;
402 }
403 
impd_drc_validate_drc_instructions(ia_drc_uni_drc_config_struct * pstr_uni_drc_config)404 static IA_ERRORCODE impd_drc_validate_drc_instructions(
405     ia_drc_uni_drc_config_struct *pstr_uni_drc_config) {
406   LOOPIDX i, j;
407   WORD32 profile_found = FALSE;
408 
409   for (i = 0; i < pstr_uni_drc_config->drc_instructions_uni_drc_count; i++) {
410     profile_found = FALSE;
411     for (j = 0; j < pstr_uni_drc_config->drc_coefficients_uni_drc_count; j++) {
412       if (pstr_uni_drc_config->str_drc_coefficients_uni_drc[j].drc_location == 1) {
413         profile_found = TRUE;
414         break;
415       }
416     }
417     if (pstr_uni_drc_config->uni_drc_config_ext_present &&
418         pstr_uni_drc_config->str_uni_drc_config_ext.parametric_drc_present &&
419         pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coeff_parametric_drc.drc_location ==
420             1) {
421       profile_found = TRUE;
422     }
423     if (profile_found == FALSE) {
424       return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
425     }
426   }
427 
428   return IA_NO_ERROR;
429 }
430 
impd_drc_enc_init(VOID * pstr_drc_state,VOID * ptr_drc_scratch,ia_drc_input_config * pstr_inp_config)431 IA_ERRORCODE impd_drc_enc_init(VOID *pstr_drc_state, VOID *ptr_drc_scratch,
432                                ia_drc_input_config *pstr_inp_config) {
433   IA_ERRORCODE err_code = IA_NO_ERROR;
434   WORD32 bit_count = 0;
435   ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state;
436 
437   pstr_drc_state_local->drc_scratch_mem = ptr_drc_scratch;
438   pstr_drc_state_local->drc_scratch_used = 0;
439 
440   iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg,
441                            pstr_drc_state_local->bit_buf_base_cfg,
442                            sizeof(pstr_drc_state_local->bit_buf_base_cfg), 1);
443 
444   iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_ext,
445                            pstr_drc_state_local->bit_buf_base_cfg_ext,
446                            sizeof(pstr_drc_state_local->bit_buf_base_cfg_ext), 1);
447 
448   iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_tmp,
449                            pstr_drc_state_local->bit_buf_base_cfg_tmp,
450                            sizeof(pstr_drc_state_local->bit_buf_base_cfg_tmp), 1);
451 
452   iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_out,
453                            pstr_drc_state_local->bit_buf_base_out,
454                            sizeof(pstr_drc_state_local->bit_buf_base_out), 1);
455 
456   err_code = impd_drc_gain_enc_init(
457       &pstr_drc_state_local->str_gain_enc, &pstr_inp_config->str_uni_drc_config,
458       &pstr_inp_config->str_enc_loudness_info_set, pstr_inp_config->str_enc_params.frame_size,
459       pstr_inp_config->str_enc_params.sample_rate, pstr_inp_config->str_enc_params.delay_mode,
460       pstr_inp_config->str_enc_params.domain);
461   if (err_code) {
462     return err_code;
463   }
464   pstr_drc_state_local->str_enc_params = pstr_inp_config->str_enc_params;
465   pstr_drc_state_local->str_uni_drc_config = pstr_inp_config->str_uni_drc_config;
466   pstr_drc_state_local->str_enc_gain_extension = pstr_inp_config->str_enc_gain_extension;
467 
468   err_code = impd_drc_validate_drc_instructions(&pstr_inp_config->str_uni_drc_config);
469   if (err_code & IA_FATAL_ERROR) {
470     return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
471   }
472 
473   err_code = impd_drc_write_uni_drc_config(pstr_drc_state_local, &bit_count, 1);
474   if (err_code & IA_FATAL_ERROR) {
475     return err_code;
476   }
477   pstr_drc_state_local->drc_config_data_size_bit = bit_count;
478 
479   // Loudness info set
480   if (pstr_drc_state_local->str_gain_enc.str_uni_drc_config.loudness_info_set_present == 1) {
481     bit_count = 0;
482     iusace_reset_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_ext);
483     err_code = impd_drc_write_loudness_info_set(
484         pstr_drc_state, &pstr_drc_state_local->str_bit_buf_cfg_ext, &bit_count, 1);
485     if (err_code & IA_FATAL_ERROR) {
486       return (err_code);
487     }
488     pstr_drc_state_local->drc_config_ext_data_size_bit = bit_count;
489   }
490 
491   return err_code;
492 }
493 
impd_loudness_info_init(VOID * pstr_drc_state,ia_drc_input_config * pstr_inp_config)494 IA_ERRORCODE impd_loudness_info_init(VOID *pstr_drc_state, ia_drc_input_config *pstr_inp_config) {
495   IA_ERRORCODE err_code = IA_NO_ERROR;
496   ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state;
497 
498   iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_ext,
499                            pstr_drc_state_local->bit_buf_base_cfg_ext,
500                            sizeof(pstr_drc_state_local->bit_buf_base_cfg_ext), 1);
501 
502   memcpy(&pstr_drc_state_local->str_gain_enc.str_loudness_info_set,
503          &pstr_inp_config->str_enc_loudness_info_set, sizeof(ia_drc_loudness_info_set_struct));
504 
505   err_code = impd_drc_write_measured_loudness_info(pstr_drc_state_local);
506   return err_code;
507 }
508 
impd_drc_enc(VOID * pstr_drc_state,FLOAT32 ** pptr_input,UWORD32 inp_offset,WORD32 * ptr_bits_written,VOID * pstr_scratch)509 IA_ERRORCODE impd_drc_enc(VOID *pstr_drc_state, FLOAT32 **pptr_input, UWORD32 inp_offset,
510                           WORD32 *ptr_bits_written, VOID *pstr_scratch) {
511   LOOPIDX i, j, k;
512   WORD32 band_count = 0;
513   WORD32 stop_sub_band_index;
514   WORD32 num_bits_payload = 0;
515   UWORD8 is_fft_ready[MAX_NUM_CHANNELS] = {0};
516   ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state;
517   ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state_local->str_gain_enc;
518   ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &pstr_drc_state_local->str_uni_drc_config;
519   ia_drc_compand_struct *pstr_drc_compand;
520   ia_drc_stft_gain_calc_struct *pstr_drc_stft_gain_calc;
521   IA_ERRORCODE err_code = IA_NO_ERROR;
522   if (pstr_drc_state_local->str_enc_params.gain_sequence_present) {
523     for (i = 0; i < MAX_DRC_COEFF_COUNT; i++) {
524       for (j = 0; j < GAIN_SET_COUNT_MAX; j++) {
525         pstr_drc_stft_gain_calc = &pstr_gain_enc->str_drc_stft_gain_handle[i][j][0];
526         pstr_drc_compand = &pstr_gain_enc->str_drc_compand[i][j];
527         if ((pstr_drc_compand->is_valid == 0) && (pstr_drc_stft_gain_calc->is_valid == 0)) {
528           break;
529         }
530 
531         if (pstr_drc_compand->is_valid == 0) {
532           if (is_fft_ready[pstr_drc_stft_gain_calc->ch_idx] == 0) {
533             impd_drc_stft_drc_convert_to_fd(
534                 pstr_gain_enc, &pptr_input[pstr_drc_stft_gain_calc->ch_idx][inp_offset],
535                 pstr_drc_stft_gain_calc->ch_idx, pstr_drc_state_local->str_enc_params.frame_size,
536                 pstr_gain_enc->complex_fft_ptr[pstr_drc_stft_gain_calc->ch_idx], pstr_scratch);
537             is_fft_ready[pstr_drc_stft_gain_calc->ch_idx] = 1;
538           }
539 
540           for (k = 0; k < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
541                               .str_gain_set_params[j]
542                               .band_count;
543                k++) {
544             if (k == pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
545                              .str_gain_set_params[j]
546                              .band_count -
547                          1) {
548               stop_sub_band_index = STFT256_HOP_SIZE - 1;
549             } else {
550               stop_sub_band_index = pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
551                                         .str_gain_set_params[j]
552                                         .gain_params[k + 1]
553                                         .start_sub_band_index -
554                                     1;
555             }
556 
557             impd_drc_stft_drc_gain_calc_process(
558                 pstr_gain_enc, i, j, k,
559                 pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
560                     .str_gain_set_params[j]
561                     .gain_params[k]
562                     .start_sub_band_index,
563                 stop_sub_band_index, pstr_drc_state_local->str_enc_params.frame_size,
564                 pstr_gain_enc->complex_fft_ptr[pstr_drc_stft_gain_calc->ch_idx],
565                 pstr_drc_state_local->gain_buffer[band_count + k]);
566           }
567         } else {
568           impd_drc_td_drc_gain_calc_process(pstr_gain_enc, i, j,
569                                             pstr_drc_state_local->str_enc_params.frame_size,
570                                             &pptr_input[pstr_drc_compand->ch_idx][inp_offset],
571                                             pstr_drc_state_local->gain_buffer[band_count]);
572         }
573 
574         band_count += pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
575                           .str_gain_set_params[j]
576                           .band_count;
577       }
578     }
579   }
580   err_code = impd_drc_encode_uni_drc_gain(pstr_gain_enc, pstr_drc_state_local->gain_buffer[0],
581                                           pstr_scratch);
582   if (err_code) {
583     return err_code;
584   }
585 
586   if (pstr_drc_state_local->is_first_drc_process_complete == 1) {
587     impd_drc_write_uni_drc_gain(pstr_drc_state_local, &num_bits_payload);
588   }
589 
590   *ptr_bits_written = num_bits_payload;
591   return err_code;
592 }
593