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