Coverage Report

Created: 2025-11-10 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/drc_src/impd_drc_api.c
Line
Count
Source
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2023 The Android Open Source Project
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at:
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 *****************************************************************************
18
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19
 */
20
21
#include <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
1.20M
  {                                                         \
40
1.20M
    var = MIN(var, upper_bound);                            \
41
1.20M
    var = MAX(var, lower_bound);                            \
42
1.20M
  }
43
44
2.22k
IA_ERRORCODE impd_drc_validate_config_params(ia_drc_input_config *pstr_inp_config) {
45
2.22k
  LOOPIDX i, j, k;
46
2.22k
  WORD32 curr_start_subband_idx, next_start_subband_idx;
47
2.22k
  ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &pstr_inp_config->str_uni_drc_config;
48
2.22k
  ia_drc_loudness_info_set_struct *pstr_enc_loudness_info_set =
49
2.22k
      &pstr_inp_config->str_enc_loudness_info_set;
50
51
2.22k
  IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->drc_instructions_uni_drc_count, 0,
52
2.22k
                       MAX_DRC_INSTRUCTIONS_COUNT);
53
13.8k
  for (i = 0; i < pstr_uni_drc_config->drc_instructions_uni_drc_count; i++) {
54
11.6k
    IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_id, 0,
55
11.6k
                         MAX_DRC_SET_ID);
56
11.6k
    IMPD_DRC_BOUND_CHECK(
57
11.6k
        pstr_uni_drc_config->str_drc_instructions_uni_drc[i].additional_downmix_id_count, 0,
58
11.6k
        ADDITIONAL_DOWNMIX_ID_COUNT_MAX);
59
11.6k
    IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_location, 0,
60
11.6k
                         MAX_DRC_LOCATION);
61
11.6k
    IMPD_DRC_BOUND_CHECK(
62
11.6k
        pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_target_loudness_value_upper,
63
11.6k
        MIN_DRC_TARGET_LOUDNESS, 0);
64
11.6k
    IMPD_DRC_BOUND_CHECK(
65
11.6k
        pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_target_loudness_value_lower,
66
11.6k
        MIN_DRC_TARGET_LOUDNESS, 0);
67
104k
    for (j = 0; j < MAX_CHANNEL_COUNT; j++) {
68
92.9k
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].gain_set_index[j],
69
92.9k
                           0, GAIN_SET_COUNT_MAX - 1);
70
92.9k
    }
71
11.6k
    IMPD_DRC_BOUND_CHECK(
72
11.6k
        pstr_uni_drc_config->str_drc_instructions_uni_drc[i].num_drc_channel_groups, 0,
73
11.6k
        MAX_CHANNEL_GROUP_COUNT);
74
45.4k
    for (j = 0; j < pstr_uni_drc_config->str_drc_instructions_uni_drc[i].num_drc_channel_groups;
75
33.8k
         j++) {
76
33.8k
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i]
77
33.8k
                               .str_gain_modifiers[j]
78
33.8k
                               .attenuation_scaling[0],
79
33.8k
                           0, MAX_ATTENUATION_SCALING);
80
33.8k
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i]
81
33.8k
                               .str_gain_modifiers[j]
82
33.8k
                               .amplification_scaling[0],
83
33.8k
                           0, MAX_AMPLIFICATION_SCALING);
84
33.8k
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i]
85
33.8k
                               .str_gain_modifiers[j]
86
33.8k
                               .gain_offset[0],
87
33.8k
                           MIN_DRC_GAIN_OFFSET, MAX_DRC_GAIN_OFFSET);
88
33.8k
    }
89
11.6k
    IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_instructions_uni_drc[i].limiter_peak_target,
90
11.6k
                         MIN_LIMITER_PEAK_TARGET, 0.0f);
91
11.6k
#ifdef LOUDNESS_LEVELING_SUPPORT
92
11.6k
    if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_effect &
93
11.6k
        EFFECT_BIT_DUCK_SELF) {
94
5.14k
      if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present != 0 &&
95
3.72k
          pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present != 1) {
96
0
        pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present = 0;
97
0
      }
98
5.14k
      if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present != 0 &&
99
3.79k
          pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present != 1) {
100
0
        pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present = 0;
101
0
      }
102
5.14k
    }
103
11.6k
#endif
104
11.6k
  }
105
106
2.22k
  IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->drc_coefficients_uni_drc_count, 0,
107
2.22k
                       MAX_DRC_COEFF_COUNT);
108
4.26k
  for (i = 0; i < pstr_uni_drc_config->drc_coefficients_uni_drc_count; i++) {
109
2.36k
    IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].drc_location, 0,
110
2.36k
                         MAX_DRC_LOCATION);
111
2.36k
    IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].gain_set_count, 0,
112
2.36k
                         MAX_CHANNEL_GROUP_COUNT);
113
5.30k
    for (j = 0; j < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].gain_set_count; j++) {
114
3.26k
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
115
3.26k
                               .str_gain_set_params[j]
116
3.26k
                               .gain_coding_profile,
117
3.26k
                           0, MAX_GAIN_CODING_PROFILE);
118
3.26k
      IMPD_DRC_BOUND_CHECK(
119
3.26k
          pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].str_gain_set_params[j].band_count,
120
3.26k
          0, MAX_BAND_COUNT);
121
3.26k
      for (k = 0;
122
5.64k
           k <
123
5.64k
           pstr_uni_drc_config->str_drc_coefficients_uni_drc[i].str_gain_set_params[j].band_count;
124
3.26k
           k++) {
125
2.37k
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
126
2.37k
                                 .str_gain_set_params[j]
127
2.37k
                                 .gain_params[k]
128
2.37k
                                 .nb_points,
129
2.37k
                             0, MAX_GAIN_POINTS);
130
2.37k
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
131
2.37k
                                 .str_gain_set_params[j]
132
2.37k
                                 .gain_params[k]
133
2.37k
                                 .drc_characteristic,
134
2.37k
                             0, MAX_DRC_CHARACTERISTIC_VALUE);
135
2.37k
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
136
2.37k
                                 .str_gain_set_params[j]
137
2.37k
                                 .gain_params[k]
138
2.37k
                                 .crossover_freq_index,
139
2.37k
                             0, MAX_CROSSOVER_FREQ_INDEX);
140
2.37k
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
141
2.37k
                                 .str_gain_set_params[j]
142
2.37k
                                 .gain_params[k]
143
2.37k
                                 .start_sub_band_index,
144
2.37k
                             0, STFT256_HOP_SIZE - 1);
145
2.37k
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
146
2.37k
                                 .str_gain_set_params[j]
147
2.37k
                                 .gain_params[k]
148
2.37k
                                 .width,
149
2.37k
                             -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
150
100k
        for (WORD32 m = 0; m < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
151
100k
                                   .str_gain_set_params[j]
152
100k
                                   .gain_params[k]
153
100k
                                   .nb_points;
154
98.2k
             m++) {
155
98.2k
          IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
156
98.2k
                                   .str_gain_set_params[j]
157
98.2k
                                   .gain_params[k]
158
98.2k
                                   .gain_points[m]
159
98.2k
                                   .x,
160
98.2k
                               -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
161
98.2k
          IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
162
98.2k
                                   .str_gain_set_params[j]
163
98.2k
                                   .gain_params[k]
164
98.2k
                                   .gain_points[m]
165
98.2k
                                   .y,
166
98.2k
                               -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
167
98.2k
        }
168
2.37k
      }
169
3.39k
      for (k = 0; k < pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
170
3.39k
                              .str_gain_set_params[j]
171
3.39k
                              .band_count -
172
3.39k
                          1;
173
3.26k
           k++) {
174
451
        curr_start_subband_idx = pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
175
451
                                     .str_gain_set_params[j]
176
451
                                     .gain_params[k]
177
451
                                     .start_sub_band_index;
178
451
        next_start_subband_idx = pstr_uni_drc_config->str_drc_coefficients_uni_drc[i]
179
451
                                     .str_gain_set_params[j]
180
451
                                     .gain_params[k + 1]
181
451
                                     .start_sub_band_index;
182
        /* It is assumed that the start index of a subband is greater than
183
           the start index of its previous subbands for a multiband */
184
451
        if (next_start_subband_idx <= curr_start_subband_idx) {
185
327
          return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_SUBBAND_INDEX;
186
327
        }
187
451
      }
188
3.26k
    }
189
2.36k
  }
190
1.89k
  IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config->downmix_instructions_count, 0,
191
1.89k
                       MAX_DOWNMIX_INSTRUCTION_COUNT);
192
193
1.89k
  IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->loudness_info_count, 0,
194
1.89k
                       MAX_LOUDNESS_INFO_COUNT);
195
4.82k
  for (i = 0; i < pstr_enc_loudness_info_set->loudness_info_count; i++) {
196
2.92k
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i].sample_peak_level,
197
2.92k
                         MIN_SAMPLE_PEAK_LEVEL, MAX_SAMPLE_PEAK_LEVEL);
198
2.92k
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i].true_peak_level,
199
2.92k
                         MIN_TRUE_PEAK_LEVEL, MAX_TRUE_PEAK_LEVEL);
200
2.92k
    IMPD_DRC_BOUND_CHECK(
201
2.92k
        pstr_enc_loudness_info_set->str_loudness_info[i].true_peak_level_measurement_system, 0,
202
2.92k
        MAX_MEASUREMENT_SYSTEM_TYPE);
203
2.92k
    IMPD_DRC_BOUND_CHECK(
204
2.92k
        pstr_enc_loudness_info_set->str_loudness_info[i].true_peak_level_reliability, 0,
205
2.92k
        MAX_RELIABILITY_TYPE);
206
2.92k
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i].measurement_count, 0,
207
2.92k
                         MAX_MEASUREMENT_COUNT);
208
14.8k
    for (j = 0; j < pstr_enc_loudness_info_set->str_loudness_info[i].measurement_count; j++) {
209
11.9k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i]
210
11.9k
                               .str_loudness_measure[j]
211
11.9k
                               .method_definition,
212
11.9k
                           0, MAX_METHOD_DEFINITION_TYPE);
213
11.9k
      IMPD_DRC_BOUND_CHECK(
214
11.9k
          pstr_enc_loudness_info_set->str_loudness_info[i].str_loudness_measure[j].method_value,
215
11.9k
          MIN_METHOD_VALUE, MAX_METHOD_VALUE);
216
11.9k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info[i]
217
11.9k
                               .str_loudness_measure[j]
218
11.9k
                               .measurement_system,
219
11.9k
                           0, MAX_MEASUREMENT_SYSTEM_TYPE);
220
11.9k
      IMPD_DRC_BOUND_CHECK(
221
11.9k
          pstr_enc_loudness_info_set->str_loudness_info[i].str_loudness_measure[j].reliability, 0,
222
11.9k
          MAX_RELIABILITY_TYPE);
223
11.9k
    }
224
2.92k
  }
225
1.89k
  IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->loudness_info_album_count, 0,
226
1.89k
                       MAX_LOUDNESS_INFO_COUNT);
227
6.83k
  for (i = 0; i < pstr_enc_loudness_info_set->loudness_info_album_count; i++) {
228
4.93k
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i].sample_peak_level,
229
4.93k
                         MIN_SAMPLE_PEAK_LEVEL, MAX_SAMPLE_PEAK_LEVEL);
230
4.93k
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i].true_peak_level,
231
4.93k
                         MIN_TRUE_PEAK_LEVEL, MAX_TRUE_PEAK_LEVEL);
232
4.93k
    IMPD_DRC_BOUND_CHECK(
233
4.93k
        pstr_enc_loudness_info_set->str_loudness_info_album[i].true_peak_level_measurement_system,
234
4.93k
        0, MAX_MEASUREMENT_SYSTEM_TYPE);
235
4.93k
    IMPD_DRC_BOUND_CHECK(
236
4.93k
        pstr_enc_loudness_info_set->str_loudness_info_album[i].true_peak_level_reliability, 0,
237
4.93k
        MAX_RELIABILITY_TYPE);
238
4.93k
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i].measurement_count,
239
4.93k
                         0, MAX_MEASUREMENT_COUNT);
240
26.3k
    for (j = 0; j < pstr_enc_loudness_info_set->str_loudness_info_album[i].measurement_count;
241
21.3k
         j++) {
242
21.3k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
243
21.3k
                               .str_loudness_measure[j]
244
21.3k
                               .method_definition,
245
21.3k
                           0, MAX_METHOD_DEFINITION_TYPE);
246
21.3k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
247
21.3k
                               .str_loudness_measure[j]
248
21.3k
                               .method_value,
249
21.3k
                           MIN_METHOD_VALUE, MAX_METHOD_VALUE);
250
21.3k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
251
21.3k
                               .str_loudness_measure[j]
252
21.3k
                               .measurement_system,
253
21.3k
                           0, MAX_MEASUREMENT_SYSTEM_TYPE);
254
21.3k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set->str_loudness_info_album[i]
255
21.3k
                               .str_loudness_measure[j]
256
21.3k
                               .reliability,
257
21.3k
                           0, MAX_RELIABILITY_TYPE);
258
21.3k
    }
259
4.93k
  }
260
261
1.89k
  if (pstr_uni_drc_config->uni_drc_config_ext_present != 0 &&
262
919
      pstr_uni_drc_config->uni_drc_config_ext_present != 1) {
263
0
    pstr_uni_drc_config->uni_drc_config_ext_present = 0;
264
0
  }
265
266
1.89k
  if (pstr_uni_drc_config->uni_drc_config_ext_present &&
267
919
      (pstr_uni_drc_config->drc_instructions_uni_drc_count > 0 ||
268
868
       pstr_uni_drc_config->drc_coefficients_uni_drc_count > 0)) {
269
105
    memset(pstr_uni_drc_config->str_drc_instructions_uni_drc, 0,
270
105
           sizeof(pstr_uni_drc_config->str_drc_instructions_uni_drc[0]) *
271
105
               pstr_uni_drc_config->drc_instructions_uni_drc_count);
272
105
    memset(pstr_uni_drc_config->str_drc_coefficients_uni_drc, 0,
273
105
           sizeof(pstr_uni_drc_config->str_drc_coefficients_uni_drc[0]) *
274
105
               pstr_uni_drc_config->drc_coefficients_uni_drc_count);
275
105
    pstr_uni_drc_config->drc_instructions_uni_drc_count = 0;
276
105
    pstr_uni_drc_config->drc_coefficients_uni_drc_count = 0;
277
105
  }
278
1.89k
  if (pstr_uni_drc_config->uni_drc_config_ext_present) {
279
919
    ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext =
280
919
        &pstr_uni_drc_config->str_uni_drc_config_ext;
281
919
    if (pstr_uni_drc_config_ext->downmix_instructions_v1_present != 0 &&
282
458
        pstr_uni_drc_config_ext->downmix_instructions_v1_present != 1) {
283
0
      pstr_uni_drc_config_ext->downmix_instructions_v1_present = 0;
284
0
    }
285
919
    if (pstr_uni_drc_config_ext->downmix_instructions_v1_present) {
286
458
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->downmix_instructions_v1_count, 0,
287
458
                           DOWNMIX_INSTRUCTIONS_COUNT_MAX);
288
2.41k
      for (i = 0; i < pstr_uni_drc_config_ext->downmix_instructions_v1_count; i++) {
289
1.95k
        IMPD_DRC_BOUND_CHECK(
290
1.95k
            pstr_uni_drc_config_ext->str_downmix_instructions_v1[i].target_layout, 0,
291
1.95k
            MAX_TARGET_LAYOUT_COUNT);
292
1.95k
        IMPD_DRC_BOUND_CHECK(
293
1.95k
            pstr_uni_drc_config_ext->str_downmix_instructions_v1[i].target_ch_count, 0,
294
1.95k
            MAX_CHANNEL_COUNT);
295
1.95k
      }
296
458
    }
297
298
919
    if (pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present != 0 &&
299
842
        pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present != 1) {
300
0
      pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present = 0;
301
0
    }
302
919
    if (pstr_uni_drc_config_ext->drc_coeffs_and_instructions_uni_drc_v1_present) {
303
842
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count, 0,
304
842
                           DRC_COEFFICIENTS_UNIDRC_V1_COUNT_MAX);
305
1.48k
      for (i = 0; i < pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count; i++) {
306
1.08k
        IMPD_DRC_BOUND_CHECK(
307
1.08k
            pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i].gain_set_count, 0,
308
1.08k
            GAIN_SET_COUNT_MAX);
309
1.08k
        for (j = 0;
310
2.76k
             j < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i].gain_set_count;
311
2.12k
             j++) {
312
2.12k
          IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
313
2.12k
                                   .str_gain_set_params[j]
314
2.12k
                                   .gain_coding_profile,
315
2.12k
                               0, MAX_GAIN_CODING_PROFILE);
316
2.12k
          IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
317
2.12k
                                   .str_gain_set_params[j]
318
2.12k
                                   .band_count,
319
2.12k
                               0, MAX_BAND_COUNT);
320
6.03k
          for (k = 0; k < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
321
6.03k
                              .str_gain_set_params[j]
322
6.03k
                              .band_count;
323
3.91k
               k++) {
324
3.91k
            IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
325
3.91k
                                     .str_gain_set_params[j]
326
3.91k
                                     .gain_params[k]
327
3.91k
                                     .nb_points,
328
3.91k
                                 0, MAX_GAIN_POINTS);
329
3.91k
            IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
330
3.91k
                                     .str_gain_set_params[j]
331
3.91k
                                     .gain_params[k]
332
3.91k
                                     .drc_characteristic,
333
3.91k
                                 0, MAX_DRC_CHARACTERISTIC_VALUE);
334
3.91k
            IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
335
3.91k
                                     .str_gain_set_params[j]
336
3.91k
                                     .gain_params[k]
337
3.91k
                                     .crossover_freq_index,
338
3.91k
                                 0, MAX_CROSSOVER_FREQ_INDEX);
339
3.91k
            IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
340
3.91k
                                     .str_gain_set_params[j]
341
3.91k
                                     .gain_params[k]
342
3.91k
                                     .start_sub_band_index,
343
3.91k
                                 0, STFT256_HOP_SIZE - 1);
344
3.91k
            IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
345
3.91k
                                     .str_gain_set_params[j]
346
3.91k
                                     .gain_params[k]
347
3.91k
                                     .width,
348
3.91k
                                 -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
349
179k
            for (WORD32 m = 0; m < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
350
179k
                                       .str_gain_set_params[j]
351
179k
                                       .gain_params[k]
352
179k
                                       .nb_points;
353
175k
                 m++) {
354
175k
              IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
355
175k
                                       .str_gain_set_params[j]
356
175k
                                       .gain_params[k]
357
175k
                                       .gain_points[m]
358
175k
                                       .x,
359
175k
                                   -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
360
175k
              IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
361
175k
                                       .str_gain_set_params[j]
362
175k
                                       .gain_params[k]
363
175k
                                       .gain_points[m]
364
175k
                                       .y,
365
175k
                                   -MAX_FLT_VAL_DB, MAX_FLT_VAL_DB);
366
175k
            }
367
3.91k
          }
368
2.54k
          for (k = 0; k < pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
369
2.54k
                                  .str_gain_set_params[j]
370
2.54k
                                  .band_count -
371
2.54k
                              1;
372
2.12k
               k++) {
373
868
            curr_start_subband_idx = pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
374
868
                                         .str_gain_set_params[j]
375
868
                                         .gain_params[k]
376
868
                                         .start_sub_band_index;
377
868
            next_start_subband_idx = pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[i]
378
868
                                         .str_gain_set_params[j]
379
868
                                         .gain_params[k + 1]
380
868
                                         .start_sub_band_index;
381
            /* It is assumed that the start index of a subband is greater than
382
               the start index of its previous subbands for a multiband */
383
868
            if (next_start_subband_idx <= curr_start_subband_idx) {
384
445
              return IA_EXHEAACE_EXE_NONFATAL_USAC_INVALID_SUBBAND_INDEX;
385
445
            }
386
868
          }
387
2.12k
        }
388
1.08k
      }
389
390
397
      IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count, 0,
391
397
                           DRC_INSTRUCTIONS_UNIDRC_V1_COUNT_MAX);
392
1.31k
      for (i = 0; i < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; i++) {
393
921
        IMPD_DRC_BOUND_CHECK(
394
921
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_set_id, 0,
395
921
            MAX_DRC_SET_ID);
396
921
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
397
921
                                 .additional_downmix_id_count,
398
921
                             0, MAX_ADDITIONAL_DOWNMIX_ID);
399
921
        IMPD_DRC_BOUND_CHECK(
400
921
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_location, 0,
401
921
            MAX_DRC_LOCATION);
402
921
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
403
921
                                 .drc_set_target_loudness_value_upper,
404
921
                             MIN_DRC_TARGET_LOUDNESS, 0);
405
921
        IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
406
921
                                 .drc_set_target_loudness_value_lower,
407
921
                             MIN_DRC_TARGET_LOUDNESS, 0);
408
8.28k
        for (j = 0; j < MAX_CHANNEL_COUNT; j++) {
409
7.36k
          IMPD_DRC_BOUND_CHECK(
410
7.36k
              pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].gain_set_index[j], 0,
411
7.36k
              GAIN_SET_COUNT_MAX - 1);
412
7.36k
        }
413
921
        IMPD_DRC_BOUND_CHECK(
414
921
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].num_drc_channel_groups, 0,
415
921
            MAX_CHANNEL_GROUP_COUNT);
416
921
        for (j = 0;
417
2.44k
             j <
418
2.44k
             pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].num_drc_channel_groups;
419
1.52k
             j++) {
420
1.52k
          IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
421
1.52k
                                   .str_gain_modifiers[j]
422
1.52k
                                   .attenuation_scaling[0],
423
1.52k
                               0, MAX_ATTENUATION_SCALING);
424
1.52k
          IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
425
1.52k
                                   .str_gain_modifiers[j]
426
1.52k
                                   .amplification_scaling[0],
427
1.52k
                               0, MAX_AMPLIFICATION_SCALING);
428
1.52k
          IMPD_DRC_BOUND_CHECK(pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
429
1.52k
                                   .str_gain_modifiers[j]
430
1.52k
                                   .gain_offset[0],
431
1.52k
                               MIN_DRC_GAIN_OFFSET, MAX_DRC_GAIN_OFFSET);
432
1.52k
        }
433
921
        IMPD_DRC_BOUND_CHECK(
434
921
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].limiter_peak_target,
435
921
            MIN_LIMITER_PEAK_TARGET, 0.0f);
436
921
#ifdef LOUDNESS_LEVELING_SUPPORT
437
921
        if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_set_effect &
438
921
            EFFECT_BIT_DUCK_SELF) {
439
370
          if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].leveling_present != 0 &&
440
167
              pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].leveling_present != 1) {
441
0
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].leveling_present = 0;
442
0
          }
443
370
          if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
444
370
                      .ducking_only_set_present != 0 &&
445
153
              pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
446
153
                      .ducking_only_set_present != 1) {
447
0
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].ducking_only_set_present =
448
0
                0;
449
0
          }
450
370
        }
451
921
#endif
452
921
      }
453
397
    }
454
919
  }
455
456
1.45k
  if (pstr_enc_loudness_info_set->loudness_info_set_ext_present != 0 &&
457
458
      pstr_enc_loudness_info_set->loudness_info_set_ext_present != 1) {
458
0
    pstr_enc_loudness_info_set->loudness_info_set_ext_present = 0;
459
0
  }
460
1.45k
  if (pstr_enc_loudness_info_set->loudness_info_set_ext_present) {
461
458
    ia_drc_loudness_info_set_ext_eq_struct *pstr_enc_loudness_info_set_ext =
462
458
        &pstr_enc_loudness_info_set->str_loudness_info_set_extension.str_loudness_info_set_ext_eq;
463
458
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->loudness_info_v1_count, 0,
464
458
                         MAX_LOUDNESS_INFO_COUNT);
465
3.29k
    for (i = 0; i < pstr_enc_loudness_info_set_ext->loudness_info_v1_count; i++) {
466
2.84k
      IMPD_DRC_BOUND_CHECK(
467
2.84k
          pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i].sample_peak_level,
468
2.84k
          MIN_SAMPLE_PEAK_LEVEL, MAX_SAMPLE_PEAK_LEVEL);
469
2.84k
      IMPD_DRC_BOUND_CHECK(
470
2.84k
          pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i].true_peak_level,
471
2.84k
          MIN_TRUE_PEAK_LEVEL, MAX_TRUE_PEAK_LEVEL);
472
2.84k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i]
473
2.84k
                               .true_peak_level_measurement_system,
474
2.84k
                           0, MAX_MEASUREMENT_SYSTEM_TYPE);
475
2.84k
      IMPD_DRC_BOUND_CHECK(
476
2.84k
          pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i].true_peak_level_reliability, 0,
477
2.84k
          MAX_RELIABILITY_TYPE);
478
2.84k
      IMPD_DRC_BOUND_CHECK(
479
2.84k
          pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i].measurement_count, 0,
480
2.84k
          MAX_MEASUREMENT_COUNT);
481
12.0k
      for (j = 0; j < pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i].measurement_count;
482
9.19k
           j++) {
483
9.19k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i]
484
9.19k
                                 .str_loudness_measure[j]
485
9.19k
                                 .method_definition,
486
9.19k
                             0, MAX_METHOD_DEFINITION_TYPE);
487
9.19k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i]
488
9.19k
                                 .str_loudness_measure[j]
489
9.19k
                                 .method_value,
490
9.19k
                             MIN_METHOD_VALUE, MAX_METHOD_VALUE);
491
9.19k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i]
492
9.19k
                                 .str_loudness_measure[j]
493
9.19k
                                 .measurement_system,
494
9.19k
                             0, MAX_MEASUREMENT_SYSTEM_TYPE);
495
9.19k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1[i]
496
9.19k
                                 .str_loudness_measure[j]
497
9.19k
                                 .reliability,
498
9.19k
                             0, MAX_RELIABILITY_TYPE);
499
9.19k
      }
500
2.84k
    }
501
502
458
    IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->loudness_info_v1_album_count, 0,
503
458
                         MAX_LOUDNESS_INFO_COUNT);
504
4.62k
    for (i = 0; i < pstr_enc_loudness_info_set_ext->loudness_info_v1_album_count; i++) {
505
4.17k
      IMPD_DRC_BOUND_CHECK(
506
4.17k
          pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i].sample_peak_level,
507
4.17k
          MIN_SAMPLE_PEAK_LEVEL, MAX_SAMPLE_PEAK_LEVEL);
508
4.17k
      IMPD_DRC_BOUND_CHECK(
509
4.17k
          pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i].true_peak_level,
510
4.17k
          MIN_TRUE_PEAK_LEVEL, MAX_TRUE_PEAK_LEVEL);
511
4.17k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i]
512
4.17k
                               .true_peak_level_measurement_system,
513
4.17k
                           0, MAX_MEASUREMENT_SYSTEM_TYPE);
514
4.17k
      IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i]
515
4.17k
                               .true_peak_level_reliability,
516
4.17k
                           0, MAX_RELIABILITY_TYPE);
517
4.17k
      IMPD_DRC_BOUND_CHECK(
518
4.17k
          pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i].measurement_count, 0,
519
4.17k
          MAX_MEASUREMENT_COUNT);
520
4.17k
      for (j = 0;
521
17.1k
           j < pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i].measurement_count;
522
12.9k
           j++) {
523
12.9k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i]
524
12.9k
                                 .str_loudness_measure[j]
525
12.9k
                                 .method_definition,
526
12.9k
                             0, MAX_METHOD_DEFINITION_TYPE);
527
12.9k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i]
528
12.9k
                                 .str_loudness_measure[j]
529
12.9k
                                 .method_value,
530
12.9k
                             MIN_METHOD_VALUE, MAX_METHOD_VALUE);
531
12.9k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i]
532
12.9k
                                 .str_loudness_measure[j]
533
12.9k
                                 .measurement_system,
534
12.9k
                             0, MAX_MEASUREMENT_SYSTEM_TYPE);
535
12.9k
        IMPD_DRC_BOUND_CHECK(pstr_enc_loudness_info_set_ext->str_loudness_info_v1_album[i]
536
12.9k
                                 .str_loudness_measure[j]
537
12.9k
                                 .reliability,
538
12.9k
                             0, MAX_RELIABILITY_TYPE);
539
12.9k
      }
540
4.17k
    }
541
458
  }
542
543
1.45k
  return IA_NO_ERROR;
544
1.89k
}
545
546
static IA_ERRORCODE impd_drc_validate_drc_instructions(
547
1.37k
    ia_drc_uni_drc_config_struct *pstr_uni_drc_config) {
548
1.37k
  LOOPIDX i, j;
549
1.37k
  WORD32 profile_found = FALSE;
550
551
1.83k
  for (j = 0; j < pstr_uni_drc_config->drc_coefficients_uni_drc_count; j++) {
552
955
    if (pstr_uni_drc_config->str_drc_coefficients_uni_drc[j].drc_location == 1) {
553
497
      profile_found = TRUE;
554
497
      break;
555
497
    }
556
955
  }
557
1.37k
  if (pstr_uni_drc_config->uni_drc_config_ext_present &&
558
441
      pstr_uni_drc_config->str_uni_drc_config_ext.parametric_drc_present &&
559
0
      pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coeff_parametric_drc.drc_location ==
560
0
          1) {
561
0
    profile_found = TRUE;
562
0
  }
563
1.37k
  if ((pstr_uni_drc_config->uni_drc_config_ext_present == 0) && profile_found == FALSE) {
564
436
    return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
565
436
  }
566
938
#ifdef LOUDNESS_LEVELING_SUPPORT
567
1.26k
  for (i = 0; i < pstr_uni_drc_config->drc_instructions_uni_drc_count; i++) {
568
330
    if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].drc_set_effect &
569
330
        EFFECT_BIT_DUCK_SELF) {
570
175
      if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present &&
571
73
          pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present) {
572
63
        if (i < pstr_uni_drc_config->drc_instructions_uni_drc_count - 1) {
573
59
          if (pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].drc_set_effect !=
574
59
                  EFFECT_BIT_DUCK_SELF &&
575
59
              pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].drc_set_effect !=
576
59
                  EFFECT_BIT_DUCK_OTHER) {
577
59
            pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].drc_set_effect =
578
59
                EFFECT_BIT_DUCK_SELF;
579
59
          }
580
59
          pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].leveling_present = 0;
581
59
          pstr_uni_drc_config->str_drc_instructions_uni_drc[i + 1].ducking_only_set_present = 0;
582
59
        } else {
583
4
          pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present = 0;
584
4
        }
585
112
      } else if (!pstr_uni_drc_config->str_drc_instructions_uni_drc[i].leveling_present &&
586
102
                 pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present) {
587
12
        pstr_uni_drc_config->str_drc_instructions_uni_drc[i].ducking_only_set_present = 0;
588
12
      }
589
175
    }
590
330
  }
591
938
#endif
592
593
938
  if (pstr_uni_drc_config->uni_drc_config_ext_present) {
594
441
    ia_drc_uni_drc_config_ext_struct *pstr_uni_drc_config_ext =
595
441
        &pstr_uni_drc_config->str_uni_drc_config_ext;
596
441
    profile_found = FALSE;
597
768
    for (j = 0; j < pstr_uni_drc_config_ext->drc_coefficients_uni_drc_v1_count; j++) {
598
523
      if (pstr_uni_drc_config_ext->str_drc_coefficients_uni_drc_v1[j].drc_location == 1) {
599
196
        profile_found = TRUE;
600
196
        break;
601
196
      }
602
523
    }
603
441
    if (pstr_uni_drc_config->str_uni_drc_config_ext.parametric_drc_present &&
604
0
        pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coeff_parametric_drc.drc_location ==
605
0
            1) {
606
0
      profile_found = TRUE;
607
0
    }
608
441
    if (profile_found == FALSE) {
609
245
      return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
610
245
    }
611
196
#ifdef LOUDNESS_LEVELING_SUPPORT
612
418
    for (i = 0; i < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count; i++) {
613
222
      if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].drc_set_effect &
614
222
          EFFECT_BIT_DUCK_SELF) {
615
143
        if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].leveling_present &&
616
51
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
617
51
                .ducking_only_set_present) {
618
40
          if (i < pstr_uni_drc_config_ext->drc_instructions_uni_drc_v1_count - 1) {
619
35
            if (pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].drc_set_effect !=
620
35
                    EFFECT_BIT_DUCK_SELF &&
621
35
                pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].drc_set_effect !=
622
35
                    EFFECT_BIT_DUCK_OTHER) {
623
35
              pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].drc_set_effect =
624
35
                  EFFECT_BIT_DUCK_SELF;
625
35
            }
626
35
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1].leveling_present = 0;
627
35
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i + 1]
628
35
                .ducking_only_set_present = 0;
629
35
          } else {
630
5
            pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].ducking_only_set_present =
631
5
                0;
632
5
          }
633
103
        } else if (!pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
634
103
                        .leveling_present &&
635
92
                   pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i]
636
92
                       .ducking_only_set_present) {
637
8
          pstr_uni_drc_config_ext->str_drc_instructions_uni_drc_v1[i].ducking_only_set_present =
638
8
              0;
639
8
        }
640
143
      }
641
222
    }
642
196
#endif
643
196
  }
644
645
693
  return IA_NO_ERROR;
646
938
}
647
648
IA_ERRORCODE impd_drc_enc_init(VOID *pstr_drc_state, VOID *ptr_drc_scratch,
649
1.41k
                               ia_drc_input_config *pstr_inp_config) {
650
1.41k
  IA_ERRORCODE err_code = IA_NO_ERROR;
651
1.41k
  WORD32 bit_count = 0;
652
1.41k
  ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state;
653
654
1.41k
  pstr_drc_state_local->drc_scratch_mem = ptr_drc_scratch;
655
1.41k
  pstr_drc_state_local->drc_scratch_used = 0;
656
657
1.41k
  iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg,
658
1.41k
                           pstr_drc_state_local->bit_buf_base_cfg,
659
1.41k
                           sizeof(pstr_drc_state_local->bit_buf_base_cfg), 1);
660
661
1.41k
  iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_ext,
662
1.41k
                           pstr_drc_state_local->bit_buf_base_cfg_ext,
663
1.41k
                           sizeof(pstr_drc_state_local->bit_buf_base_cfg_ext), 1);
664
665
1.41k
  iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_tmp,
666
1.41k
                           pstr_drc_state_local->bit_buf_base_cfg_tmp,
667
1.41k
                           sizeof(pstr_drc_state_local->bit_buf_base_cfg_tmp), 1);
668
669
1.41k
  iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_out,
670
1.41k
                           pstr_drc_state_local->bit_buf_base_out,
671
1.41k
                           sizeof(pstr_drc_state_local->bit_buf_base_out), 1);
672
673
1.41k
  err_code = impd_drc_gain_enc_init(
674
1.41k
      &pstr_drc_state_local->str_gain_enc, &pstr_inp_config->str_uni_drc_config,
675
1.41k
      &pstr_inp_config->str_enc_loudness_info_set, pstr_inp_config->str_enc_params.frame_size,
676
1.41k
      pstr_inp_config->str_enc_params.sample_rate, pstr_inp_config->str_enc_params.delay_mode,
677
1.41k
      pstr_inp_config->str_enc_params.domain);
678
1.41k
  if (err_code) {
679
43
    return err_code;
680
43
  }
681
682
1.37k
  err_code = impd_drc_validate_drc_instructions(&pstr_inp_config->str_uni_drc_config);
683
684
1.37k
  if (err_code & IA_FATAL_ERROR) {
685
681
    return IA_EXHEAACE_CONFIG_FATAL_DRC_INVALID_CONFIG;
686
681
  }
687
688
693
  pstr_drc_state_local->str_enc_params = pstr_inp_config->str_enc_params;
689
693
  pstr_drc_state_local->str_uni_drc_config = pstr_inp_config->str_uni_drc_config;
690
693
  pstr_drc_state_local->str_enc_gain_extension = pstr_inp_config->str_enc_gain_extension;
691
693
  pstr_drc_state_local->str_gain_enc.str_uni_drc_config = pstr_inp_config->str_uni_drc_config;
692
693
693
  pstr_drc_state_local->str_enc_params.gain_sequence_present = FALSE;
694
788
  for (WORD16 k = 0; k < pstr_drc_state_local->str_uni_drc_config.drc_coefficients_uni_drc_count;
695
693
       k++) {
696
568
    if ((pstr_drc_state_local->str_uni_drc_config.str_drc_coefficients_uni_drc[k].drc_location ==
697
568
         1) &&
698
499
        (pstr_drc_state_local->str_uni_drc_config.str_drc_coefficients_uni_drc[k].gain_set_count >
699
499
         0)) {
700
473
      pstr_drc_state_local->str_enc_params.gain_sequence_present = TRUE;
701
473
      break;
702
473
    }
703
568
  }
704
705
693
  if (pstr_drc_state_local->str_enc_params.gain_sequence_present == FALSE) {
706
422
    for (WORD16 k = 0; k < pstr_drc_state_local->str_uni_drc_config.str_uni_drc_config_ext
707
422
                               .drc_coefficients_uni_drc_v1_count;
708
392
         k++) {
709
392
      if ((pstr_drc_state_local->str_uni_drc_config.str_uni_drc_config_ext
710
392
               .str_drc_coefficients_uni_drc_v1[k]
711
392
               .drc_location == 1) &&
712
196
          (pstr_drc_state_local->str_uni_drc_config.str_uni_drc_config_ext
713
196
               .str_drc_coefficients_uni_drc_v1[k]
714
196
               .gain_set_count > 0)) {
715
190
        pstr_drc_state_local->str_enc_params.gain_sequence_present = TRUE;
716
190
        break;
717
190
      }
718
392
    }
719
220
  }
720
721
693
  err_code = impd_drc_write_uni_drc_config(pstr_drc_state_local, &bit_count, 1);
722
693
  if (err_code & IA_FATAL_ERROR) {
723
71
    return err_code;
724
71
  }
725
622
  pstr_drc_state_local->drc_config_data_size_bit = bit_count;
726
727
  // Loudness info set
728
622
  if (pstr_drc_state_local->str_gain_enc.str_uni_drc_config.loudness_info_set_present == 1) {
729
569
    bit_count = 0;
730
569
    iusace_reset_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_ext);
731
569
    memset(pstr_drc_state_local->bit_buf_base_cfg_ext, 0,
732
569
           sizeof(MAX_DRC_PAYLOAD_BYTES * sizeof(pstr_drc_state_local->bit_buf_base_cfg_ext[0])));
733
569
    err_code = impd_drc_write_loudness_info_set(
734
569
        pstr_drc_state, &pstr_drc_state_local->str_bit_buf_cfg_ext, &bit_count, 1);
735
569
    if (err_code & IA_FATAL_ERROR) {
736
5
      return (err_code);
737
5
    }
738
564
    pstr_drc_state_local->drc_config_ext_data_size_bit = bit_count;
739
564
  }
740
741
617
  return err_code;
742
622
}
743
744
3.24k
IA_ERRORCODE impd_loudness_info_init(VOID *pstr_drc_state, ia_drc_input_config *pstr_inp_config) {
745
3.24k
  IA_ERRORCODE err_code = IA_NO_ERROR;
746
3.24k
  ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state;
747
748
3.24k
  iusace_create_bit_buffer(&pstr_drc_state_local->str_bit_buf_cfg_ext,
749
3.24k
                           pstr_drc_state_local->bit_buf_base_cfg_ext,
750
3.24k
                           sizeof(pstr_drc_state_local->bit_buf_base_cfg_ext), 1);
751
752
3.24k
  memcpy(&pstr_drc_state_local->str_gain_enc.str_loudness_info_set,
753
3.24k
         &pstr_inp_config->str_enc_loudness_info_set, sizeof(ia_drc_loudness_info_set_struct));
754
755
3.24k
  err_code = impd_drc_write_measured_loudness_info(pstr_drc_state_local);
756
3.24k
  return err_code;
757
3.24k
}
758
759
IA_ERRORCODE impd_drc_enc(VOID *pstr_drc_state, FLOAT32 **pptr_input, UWORD32 inp_offset,
760
74.6k
                          WORD32 *ptr_bits_written, VOID *pstr_scratch) {
761
74.6k
  LOOPIDX i, j, k;
762
74.6k
  WORD32 band_count = 0;
763
74.6k
  WORD32 stop_sub_band_index;
764
74.6k
  WORD32 num_bits_payload = 0;
765
74.6k
  UWORD8 is_fft_ready[MAX_NUM_CHANNELS] = {0};
766
74.6k
  ia_drc_enc_state *pstr_drc_state_local = pstr_drc_state;
767
74.6k
  ia_drc_gain_enc_struct *pstr_gain_enc = &pstr_drc_state_local->str_gain_enc;
768
74.6k
  ia_drc_uni_drc_config_struct *pstr_uni_drc_config = &pstr_drc_state_local->str_uni_drc_config;
769
74.6k
  ia_drc_compand_struct *pstr_drc_compand;
770
74.6k
  ia_drc_stft_gain_calc_struct *pstr_drc_stft_gain_calc;
771
74.6k
  IA_ERRORCODE err_code = IA_NO_ERROR;
772
74.6k
  ia_drc_coefficients_uni_drc_struct *pstr_drc_coefficients_uni_drc;
773
774
74.6k
  if (pstr_uni_drc_config->str_uni_drc_config_ext.drc_coefficients_uni_drc_v1_count > 0) {
775
11.8k
    pstr_drc_coefficients_uni_drc =
776
11.8k
        &pstr_uni_drc_config->str_uni_drc_config_ext.str_drc_coefficients_uni_drc_v1[0];
777
62.7k
  } else {
778
62.7k
    pstr_drc_coefficients_uni_drc = &pstr_uni_drc_config->str_drc_coefficients_uni_drc[0];
779
62.7k
  }
780
781
74.6k
  if (pstr_drc_state_local->str_enc_params.gain_sequence_present) {
782
595k
    for (i = 0; i < MAX_DRC_COEFF_COUNT; i++) {
783
621k
      for (j = 0; j < GAIN_SET_COUNT_MAX; j++) {
784
621k
        pstr_drc_stft_gain_calc = &pstr_gain_enc->str_drc_stft_gain_handle[i][j][0];
785
621k
        pstr_drc_compand = &pstr_gain_enc->str_drc_compand[i][j];
786
621k
        if ((pstr_drc_compand->is_valid == 0) && (pstr_drc_stft_gain_calc->is_valid == 0)) {
787
520k
          break;
788
520k
        }
789
790
100k
        if (pstr_drc_compand->is_valid == 0) {
791
12.8k
          if (is_fft_ready[pstr_drc_stft_gain_calc->ch_idx] == 0) {
792
12.2k
            impd_drc_stft_drc_convert_to_fd(
793
12.2k
                pstr_gain_enc, &pptr_input[pstr_drc_stft_gain_calc->ch_idx][inp_offset],
794
12.2k
                pstr_drc_stft_gain_calc->ch_idx, pstr_drc_state_local->str_enc_params.frame_size,
795
12.2k
                pstr_gain_enc->complex_fft_ptr[pstr_drc_stft_gain_calc->ch_idx], pstr_scratch);
796
12.2k
            is_fft_ready[pstr_drc_stft_gain_calc->ch_idx] = 1;
797
12.2k
          }
798
799
38.8k
          for (k = 0; k < pstr_drc_coefficients_uni_drc[i].str_gain_set_params[j].band_count;
800
25.9k
               k++) {
801
25.9k
            if (k == pstr_drc_coefficients_uni_drc[i].str_gain_set_params[j].band_count - 1) {
802
12.8k
              stop_sub_band_index = STFT256_HOP_SIZE - 1;
803
13.0k
            } else {
804
13.0k
              stop_sub_band_index = pstr_drc_coefficients_uni_drc[i]
805
13.0k
                                        .str_gain_set_params[j]
806
13.0k
                                        .gain_params[k + 1]
807
13.0k
                                        .start_sub_band_index -
808
13.0k
                                    1;
809
13.0k
            }
810
811
25.9k
            impd_drc_stft_drc_gain_calc_process(
812
25.9k
                pstr_gain_enc, i, j, k,
813
25.9k
                pstr_drc_coefficients_uni_drc[i]
814
25.9k
                    .str_gain_set_params[j]
815
25.9k
                    .gain_params[k]
816
25.9k
                    .start_sub_band_index,
817
25.9k
                stop_sub_band_index, pstr_drc_state_local->str_enc_params.frame_size,
818
25.9k
                pstr_gain_enc->complex_fft_ptr[pstr_drc_stft_gain_calc->ch_idx],
819
25.9k
                pstr_drc_state_local->gain_buffer[band_count + k]);
820
25.9k
          }
821
87.4k
        } else {
822
87.4k
          impd_drc_td_drc_gain_calc_process(pstr_gain_enc, i, j,
823
87.4k
                                            pstr_drc_state_local->str_enc_params.frame_size,
824
87.4k
                                            &pptr_input[pstr_drc_compand->ch_idx][inp_offset],
825
87.4k
                                            pstr_drc_state_local->gain_buffer[band_count]);
826
87.4k
        }
827
828
100k
        band_count += pstr_drc_coefficients_uni_drc[i].str_gain_set_params[j].band_count;
829
100k
      }
830
520k
    }
831
74.3k
  }
832
74.6k
  err_code = impd_drc_encode_uni_drc_gain(pstr_gain_enc, pstr_drc_state_local->gain_buffer[0],
833
74.6k
                                          pstr_scratch);
834
74.6k
  if (err_code) {
835
0
    return err_code;
836
0
  }
837
838
74.6k
  if (pstr_drc_state_local->is_first_drc_process_complete == 1) {
839
74.0k
    impd_drc_write_uni_drc_gain(pstr_drc_state_local, &num_bits_payload);
840
74.0k
  }
841
842
74.6k
  *ptr_bits_written = num_bits_payload;
843
74.6k
  return err_code;
844
74.6k
}