1 /******************************************************************************
2 *
3 * Copyright (C) 2018 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 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <string.h>
24 #include "impd_type_def.h"
25 #include "impd_drc_extr_delta_coded_info.h"
26 #include "impd_drc_common.h"
27 #include "impd_drc_struct.h"
28 #include "impd_parametric_drc_dec.h"
29 #include "impd_drc_filter_bank.h"
30 #include "impd_drc_rom.h"
31
32 #define PI 3.14159265f
33
34 #ifndef max
35 #define max(a, b) (((a) > (b)) ? (a) : (b))
36 #endif
37 #ifndef min
38 #define min(a, b) (((a) < (b)) ? (a) : (b))
39 #endif
40
impd_init_parametric_drc(WORD32 drc_frame_size,WORD32 sampling_rate,WORD32 sub_band_domain_mode,ia_parametric_drc_params_struct * p_parametricdrc_params)41 WORD32 impd_init_parametric_drc(
42 WORD32 drc_frame_size, WORD32 sampling_rate, WORD32 sub_band_domain_mode,
43 ia_parametric_drc_params_struct* p_parametricdrc_params) {
44 WORD32 sub_band_count_tbl[4] = {0, 64, 71, 256};
45 p_parametricdrc_params->drc_frame_size = drc_frame_size;
46 p_parametricdrc_params->sampling_rate = sampling_rate;
47 p_parametricdrc_params->sub_band_domain_mode = sub_band_domain_mode;
48
49 p_parametricdrc_params->sub_band_count =
50 sub_band_count_tbl[sub_band_domain_mode];
51
52 return 0;
53 }
54
impd_init_parametric_drc_feed_fwd(ia_drc_config * pstr_drc_config,WORD32 instance_idx,WORD32 ch_count_from_dwnmix_id,ia_parametric_drc_params_struct * p_parametricdrc_params)55 WORD32 impd_init_parametric_drc_feed_fwd(
56 ia_drc_config* pstr_drc_config, WORD32 instance_idx,
57 WORD32 ch_count_from_dwnmix_id,
58 ia_parametric_drc_params_struct* p_parametricdrc_params) {
59 WORD32 err = 0, i = 0;
60
61 WORD32 parametric_drc_idx =
62 p_parametricdrc_params->parametric_drc_idx[instance_idx];
63 WORD32 gain_set_index = p_parametricdrc_params->gain_set_index[instance_idx];
64 WORD32* channel_map = p_parametricdrc_params->channel_map[instance_idx];
65
66 ia_drc_coeff_parametric_drc_struct* hDrcCoefficientsParametricDrcBs =
67 &(pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc);
68 ia_parametric_drc_type_feed_forward_struct* hParametricDrcTypeFeedForwardBs =
69 &(pstr_drc_config->str_drc_config_ext
70 .str_parametric_drc_instructions[parametric_drc_idx]
71 .str_parametric_drc_type_feed_forward);
72 ia_parametric_drc_type_ff_params_struct*
73 pstr_parametric_ffwd_type_drc_params =
74 &(p_parametricdrc_params
75 ->str_parametric_drc_instance_params[instance_idx]
76 .str_parametric_drc_type_ff_params);
77
78 /* level estimation */
79 pstr_parametric_ffwd_type_drc_params->frame_size =
80 p_parametricdrc_params->parametric_drc_frame_size;
81 pstr_parametric_ffwd_type_drc_params->sub_band_domain_mode =
82 p_parametricdrc_params->sub_band_domain_mode;
83 pstr_parametric_ffwd_type_drc_params->sub_band_count =
84 p_parametricdrc_params->sub_band_count;
85 pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type = 0;
86
87 if (pstr_parametric_ffwd_type_drc_params->sub_band_domain_mode ==
88 SUBBAND_DOMAIN_MODE_QMF64) {
89 if (p_parametricdrc_params->sampling_rate == 48000) {
90 pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type = 1;
91 } else {
92 /* support of other sampling rates than 48000 might be missing */
93 return UNEXPECTED_ERROR;
94 }
95 }
96
97 pstr_parametric_ffwd_type_drc_params->audio_num_chan =
98 p_parametricdrc_params->audio_num_chan;
99 pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type =
100 hParametricDrcTypeFeedForwardBs->level_estim_k_weighting_type;
101 pstr_parametric_ffwd_type_drc_params->level_estim_integration_time =
102 hParametricDrcTypeFeedForwardBs->level_estim_integration_time;
103 pstr_parametric_ffwd_type_drc_params->level_estim_frame_index = 0;
104 pstr_parametric_ffwd_type_drc_params->level_estim_frame_count =
105 hParametricDrcTypeFeedForwardBs->level_estim_integration_time /
106 pstr_parametric_ffwd_type_drc_params->frame_size;
107
108 memset(pstr_parametric_ffwd_type_drc_params->level, 0,
109 PARAM_DRC_TYPE_FF_LEVEL_ESTIM_FRAME_COUNT_MAX * sizeof(FLOAT32));
110
111 if (ch_count_from_dwnmix_id != 0) {
112 memcpy(pstr_parametric_ffwd_type_drc_params->level_estim_ch_weight,
113 hDrcCoefficientsParametricDrcBs
114 ->str_parametric_drc_gain_set_params[gain_set_index]
115 .level_estim_ch_weight,
116 ch_count_from_dwnmix_id * sizeof(FLOAT32));
117 } else {
118 for (i = 0; i < pstr_parametric_ffwd_type_drc_params->audio_num_chan; i++) {
119 pstr_parametric_ffwd_type_drc_params->level_estim_ch_weight[i] =
120 (FLOAT32)channel_map[i];
121 }
122 }
123
124 if (pstr_parametric_ffwd_type_drc_params->sub_band_domain_mode ==
125 SUBBAND_DOMAIN_MODE_OFF) {
126 err = impd_init_lvl_est_filt_time(
127 pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type,
128 p_parametricdrc_params->sampling_rate,
129 &pstr_parametric_ffwd_type_drc_params->pre_filt_coeff,
130 &pstr_parametric_ffwd_type_drc_params->rlb_filt_coeff);
131
132 if (err) return (err);
133 } else {
134 err = impd_init_lvl_est_filt_subband(
135 pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type,
136 p_parametricdrc_params->sampling_rate,
137 p_parametricdrc_params->sub_band_domain_mode,
138 p_parametricdrc_params->sub_band_count,
139 pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type,
140 pstr_parametric_ffwd_type_drc_params->weighting_filt,
141 &pstr_parametric_ffwd_type_drc_params->filt_coeff_subband);
142
143 if (err) return (err);
144 }
145
146 pstr_parametric_ffwd_type_drc_params->node_count =
147 hParametricDrcTypeFeedForwardBs->node_count;
148
149 memcpy(pstr_parametric_ffwd_type_drc_params->node_level,
150 hParametricDrcTypeFeedForwardBs->node_level,
151 pstr_parametric_ffwd_type_drc_params->node_count * sizeof(WORD32));
152 memcpy(pstr_parametric_ffwd_type_drc_params->node_gain,
153 hParametricDrcTypeFeedForwardBs->node_gain,
154 pstr_parametric_ffwd_type_drc_params->node_count * sizeof(WORD32));
155
156 pstr_parametric_ffwd_type_drc_params->ref_level_parametric_drc =
157 hDrcCoefficientsParametricDrcBs
158 ->str_parametric_drc_gain_set_params[gain_set_index]
159 .drc_input_loudness;
160
161 {
162 WORD32 gain_smooth_attack_time_fast =
163 hParametricDrcTypeFeedForwardBs->gain_smooth_attack_time_fast;
164 WORD32 gain_smooth_release_time_fast =
165 hParametricDrcTypeFeedForwardBs->gain_smooth_release_time_fast;
166 WORD32 gain_smooth_attack_time_slow =
167 hParametricDrcTypeFeedForwardBs->gain_smooth_attack_time_slow;
168 WORD32 gain_smooth_release_time_slow =
169 hParametricDrcTypeFeedForwardBs->gain_smooth_release_time_slow;
170 WORD32 gain_smooth_hold_off =
171 hParametricDrcTypeFeedForwardBs->gain_smooth_hold_off;
172 WORD32 sampling_rate = p_parametricdrc_params->sampling_rate;
173 WORD32 parametric_drc_frame_size =
174 p_parametricdrc_params->parametric_drc_frame_size;
175
176 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_fast =
177 1 -
178 (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
179 (gain_smooth_attack_time_fast * sampling_rate * 0.001));
180 pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_fast =
181 1 -
182 (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
183 (gain_smooth_release_time_fast * sampling_rate * 0.001));
184 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_slow =
185 1 -
186 (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
187 (gain_smooth_attack_time_slow * sampling_rate * 0.001));
188 pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_slow =
189 1 -
190 (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
191 (gain_smooth_release_time_slow * sampling_rate * 0.001));
192 pstr_parametric_ffwd_type_drc_params->gain_smooth_hold_off_count =
193 gain_smooth_hold_off * 256 * sampling_rate /
194 (parametric_drc_frame_size * 48000);
195 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_threshold =
196 hParametricDrcTypeFeedForwardBs->gain_smooth_attack_threshold;
197 pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_threshold =
198 hParametricDrcTypeFeedForwardBs->gain_smooth_rel_threshold;
199 }
200
201 err =
202 impd_parametric_ffwd_type_drc_reset(pstr_parametric_ffwd_type_drc_params);
203
204 if (err) return (err);
205
206 return 0;
207 }
208
impd_init_parametric_drc_lim(ia_drc_config * pstr_drc_config,WORD32 instance_idx,WORD32 ch_count_from_dwnmix_id,ia_parametric_drc_params_struct * p_parametricdrc_params,pVOID * mem_ptr)209 WORD32 impd_init_parametric_drc_lim(
210 ia_drc_config* pstr_drc_config, WORD32 instance_idx,
211 WORD32 ch_count_from_dwnmix_id,
212 ia_parametric_drc_params_struct* p_parametricdrc_params, pVOID* mem_ptr) {
213 WORD32 err = 0, i = 0;
214 UWORD32 j;
215 UWORD32 attack, sec_len;
216
217 WORD32 parametric_drc_idx =
218 p_parametricdrc_params->parametric_drc_idx[instance_idx];
219 WORD32 gain_set_index = p_parametricdrc_params->gain_set_index[instance_idx];
220 WORD32* channel_map = p_parametricdrc_params->channel_map[instance_idx];
221
222 ia_drc_coeff_parametric_drc_struct* hDrcCoefficientsParametricDrcBs =
223 &(pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc);
224 ia_parametric_drc_lim_struct* hParametricDrcTypeLimBs =
225 &(pstr_drc_config->str_drc_config_ext
226 .str_parametric_drc_instructions[parametric_drc_idx]
227 .parametric_drc_lim);
228 ia_parametric_drc_type_lim_params_struct*
229 pstr_parametric_lim_type_drc_params =
230 &(p_parametricdrc_params
231 ->str_parametric_drc_instance_params[instance_idx]
232 .str_parametric_drc_type_lim_params);
233
234 pstr_parametric_lim_type_drc_params->frame_size =
235 p_parametricdrc_params->drc_frame_size;
236 pstr_parametric_lim_type_drc_params->audio_num_chan =
237 p_parametricdrc_params->audio_num_chan;
238
239 if (ch_count_from_dwnmix_id != 0) {
240 memcpy(pstr_parametric_lim_type_drc_params->level_estim_ch_weight,
241 hDrcCoefficientsParametricDrcBs
242 ->str_parametric_drc_gain_set_params[gain_set_index]
243 .level_estim_ch_weight,
244 ch_count_from_dwnmix_id * sizeof(FLOAT32));
245 } else {
246 for (i = 0; i < pstr_parametric_lim_type_drc_params->audio_num_chan; i++) {
247 pstr_parametric_lim_type_drc_params->level_estim_ch_weight[i] =
248 (FLOAT32)channel_map[i];
249 }
250 }
251
252 attack = (UWORD32)(hParametricDrcTypeLimBs->parametric_lim_attack *
253 p_parametricdrc_params->sampling_rate / 1000);
254
255 sec_len = (UWORD32)sqrt(attack + 1);
256
257 pstr_parametric_lim_type_drc_params->sec_len = sec_len;
258 pstr_parametric_lim_type_drc_params->num_max_buf_sec = (attack + 1) / sec_len;
259 if (pstr_parametric_lim_type_drc_params->num_max_buf_sec * sec_len <
260 (attack + 1))
261 pstr_parametric_lim_type_drc_params->num_max_buf_sec++;
262
263 pstr_parametric_lim_type_drc_params->max_buf = (FLOAT32*)(*mem_ptr);
264 *mem_ptr = (pVOID)((SIZE_T)(*mem_ptr) +
265 pstr_parametric_lim_type_drc_params->num_max_buf_sec *
266 sec_len * sizeof(FLOAT32));
267
268 pstr_parametric_lim_type_drc_params->attack_ms =
269 (FLOAT32)hParametricDrcTypeLimBs->parametric_lim_attack;
270 pstr_parametric_lim_type_drc_params->release_ms =
271 (FLOAT32)hParametricDrcTypeLimBs->parametric_lim_release;
272 pstr_parametric_lim_type_drc_params->attack = attack;
273 pstr_parametric_lim_type_drc_params->attack_constant =
274 (FLOAT32)pow(0.1, 1.0 / (attack + 1));
275 pstr_parametric_lim_type_drc_params->release_constant = (FLOAT32)pow(
276 0.1, 1.0 / (hParametricDrcTypeLimBs->parametric_lim_release *
277 p_parametricdrc_params->sampling_rate / 1000 +
278 1));
279 pstr_parametric_lim_type_drc_params->threshold = (FLOAT32)pow(
280 10.0f, 0.05f * hParametricDrcTypeLimBs->parametric_lim_threshold);
281 pstr_parametric_lim_type_drc_params->channels =
282 pstr_parametric_lim_type_drc_params->audio_num_chan;
283 pstr_parametric_lim_type_drc_params->sampling_rate =
284 p_parametricdrc_params->sampling_rate;
285 pstr_parametric_lim_type_drc_params->cor = 1.0f;
286 pstr_parametric_lim_type_drc_params->smooth_state_0 = 1.0;
287
288 for (j = 0; j < pstr_parametric_lim_type_drc_params->num_max_buf_sec *
289 pstr_parametric_lim_type_drc_params->sec_len;
290 j++) {
291 pstr_parametric_lim_type_drc_params->max_buf[j] = 0.f;
292 }
293
294 if (err) return (err);
295
296 return 0;
297 }
298
impd_init_parametric_drcInstance(ia_drc_config * pstr_drc_config,WORD32 instance_idx,WORD32 ch_count_from_dwnmix_id,ia_parametric_drc_params_struct * p_parametricdrc_params,pVOID * mem_ptr)299 WORD32 impd_init_parametric_drcInstance(
300 ia_drc_config* pstr_drc_config, WORD32 instance_idx,
301 WORD32 ch_count_from_dwnmix_id,
302 ia_parametric_drc_params_struct* p_parametricdrc_params, pVOID* mem_ptr) {
303 WORD32 err = 0;
304
305 WORD32 parametric_drc_idx =
306 p_parametricdrc_params->parametric_drc_idx[instance_idx];
307 ia_parametric_drc_instructions_struct* hParametricDrcInstructions =
308 &(pstr_drc_config->str_drc_config_ext
309 .str_parametric_drc_instructions[parametric_drc_idx]);
310
311 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx]
312 .disable_paramteric_drc =
313 hParametricDrcInstructions->disable_paramteric_drc;
314 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx]
315 .parametric_drc_type = hParametricDrcInstructions->parametric_drc_type;
316 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx]
317 .str_spline_nodes.num_nodes = p_parametricdrc_params->num_nodes;
318
319 if (p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx]
320 .disable_paramteric_drc == 0) {
321 if (p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx]
322 .parametric_drc_type == PARAM_DRC_TYPE_FF) {
323 err = impd_init_parametric_drc_feed_fwd(pstr_drc_config, instance_idx,
324 ch_count_from_dwnmix_id,
325 p_parametricdrc_params);
326
327 if (err) return (err);
328
329 } else if (p_parametricdrc_params
330 ->str_parametric_drc_instance_params[instance_idx]
331 .parametric_drc_type == PARAM_DRC_TYPE_LIM) {
332 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx]
333 .str_spline_nodes.num_nodes = p_parametricdrc_params->drc_frame_size;
334
335 err = impd_init_parametric_drc_lim(pstr_drc_config, instance_idx,
336 ch_count_from_dwnmix_id,
337 p_parametricdrc_params, mem_ptr);
338
339 if (err) return (err);
340
341 } else {
342 return (UNEXPECTED_ERROR);
343 }
344 }
345
346 return 0;
347 }
348
impd_init_parametric_drc_after_config(ia_drc_config * pstr_drc_config,ia_drc_loudness_info_set_struct * pstr_loudness_info,ia_parametric_drc_params_struct * p_parametricdrc_params,pVOID * mem_ptr)349 WORD32 impd_init_parametric_drc_after_config(
350 ia_drc_config* pstr_drc_config,
351 ia_drc_loudness_info_set_struct* pstr_loudness_info,
352 ia_parametric_drc_params_struct* p_parametricdrc_params, pVOID* mem_ptr) {
353 WORD32 err = 0, instance_idx = 0, gain_set_index = 0,
354 side_chain_config_type = 0, downmix_id = 0,
355 ch_count_from_dwnmix_id = 0, L = 0;
356
357 p_parametricdrc_params->parametric_drc_frame_size =
358 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
359 .parametric_drc_frame_size;
360 p_parametricdrc_params->reset_parametric_drc =
361 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
362 .reset_parametric_drc;
363 p_parametricdrc_params->num_nodes =
364 p_parametricdrc_params->drc_frame_size /
365 p_parametricdrc_params->parametric_drc_frame_size;
366
367 switch (p_parametricdrc_params->sub_band_domain_mode) {
368 case SUBBAND_DOMAIN_MODE_QMF64:
369 L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF64;
370 break;
371 case SUBBAND_DOMAIN_MODE_QMF71:
372 L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF71;
373 break;
374 case SUBBAND_DOMAIN_MODE_STFT256:
375 L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_STFT256;
376 break;
377 case SUBBAND_DOMAIN_MODE_OFF:
378 default:
379 L = 0;
380 break;
381 }
382
383 if (p_parametricdrc_params->sub_band_domain_mode != SUBBAND_DOMAIN_MODE_OFF &&
384 p_parametricdrc_params->parametric_drc_frame_size != L) {
385 return (EXTERNAL_ERROR);
386 }
387
388 for (instance_idx = 0;
389 instance_idx < p_parametricdrc_params->parametric_drc_instance_count;
390 instance_idx++) {
391 gain_set_index = p_parametricdrc_params->gain_set_index[instance_idx];
392 side_chain_config_type =
393 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
394 .str_parametric_drc_gain_set_params[gain_set_index]
395 .side_chain_config_type;
396 downmix_id = pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
397 .str_parametric_drc_gain_set_params[gain_set_index]
398 .downmix_id;
399
400 if (side_chain_config_type == 1 &&
401 downmix_id ==
402 p_parametricdrc_params
403 ->dwnmix_id_from_drc_instructions[instance_idx]) {
404 ch_count_from_dwnmix_id =
405 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
406 .str_parametric_drc_gain_set_params[gain_set_index]
407 .ch_count_from_dwnmix_id;
408 } else {
409 ch_count_from_dwnmix_id = 0;
410 }
411
412 if (pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
413 .str_parametric_drc_gain_set_params[gain_set_index]
414 .drc_input_loudness_present == 0) {
415 WORD32 n = 0, m = 0, drcInputLoudnessFound = 0;
416 FLOAT32 drc_input_loudness = 0.f;
417
418 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
419 ia_loudness_info_struct* loudness_info =
420 &pstr_loudness_info->loudness_info[n];
421 if (p_parametricdrc_params
422 ->dwnmix_id_from_drc_instructions[instance_idx] ==
423 loudness_info->downmix_id) {
424 if (0 == loudness_info->drc_set_id) {
425 for (m = 0; m < loudness_info->measurement_count; m++) {
426 if (loudness_info->loudness_measure[m].method_def ==
427 METHOD_DEFINITION_PROGRAM_LOUDNESS) {
428 drc_input_loudness =
429 loudness_info->loudness_measure[m].method_val;
430 drcInputLoudnessFound = 1;
431 break;
432 }
433 }
434 if (drcInputLoudnessFound == 0) {
435 for (m = 0; m < loudness_info->measurement_count; m++) {
436 if (loudness_info->loudness_measure[m].method_def ==
437 METHOD_DEFINITION_ANCHOR_LOUDNESS) {
438 drc_input_loudness =
439 loudness_info->loudness_measure[m].method_val;
440 drcInputLoudnessFound = 1;
441 break;
442 }
443 }
444 }
445 }
446 }
447 }
448 if (drcInputLoudnessFound == 0) {
449 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) {
450 ia_loudness_info_struct* loudness_info =
451 &pstr_loudness_info->loudness_info[n];
452 if (0 == loudness_info->downmix_id) {
453 if (0 == loudness_info->drc_set_id) {
454 for (m = 0; m < loudness_info->measurement_count; m++) {
455 if (loudness_info->loudness_measure[m].method_def ==
456 METHOD_DEFINITION_PROGRAM_LOUDNESS) {
457 drc_input_loudness =
458 loudness_info->loudness_measure[m].method_val;
459 drcInputLoudnessFound = 1;
460 break;
461 }
462 }
463 if (drcInputLoudnessFound == 0) {
464 for (m = 0; m < loudness_info->measurement_count; m++) {
465 if (loudness_info->loudness_measure[m].method_def ==
466 METHOD_DEFINITION_ANCHOR_LOUDNESS) {
467 drc_input_loudness =
468 loudness_info->loudness_measure[m].method_val;
469 drcInputLoudnessFound = 1;
470 break;
471 }
472 }
473 }
474 }
475 }
476 }
477 }
478 if (drcInputLoudnessFound == 0) {
479 return (UNEXPECTED_ERROR);
480 } else {
481 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
482 .str_parametric_drc_gain_set_params[gain_set_index]
483 .drc_input_loudness = drc_input_loudness;
484 }
485 }
486
487 impd_init_parametric_drcInstance(pstr_drc_config, instance_idx,
488 ch_count_from_dwnmix_id,
489 p_parametricdrc_params, mem_ptr);
490 if (err) return (err);
491 }
492
493 return 0;
494 }
495
impd_init_lvl_est_filt_time(WORD32 level_estim_k_weighting_type,WORD32 sampling_rate,ia_2nd_order_filt_coeff_struct * pre_filt_coeff,ia_2nd_order_filt_coeff_struct * rlb_filt_coeff)496 WORD32 impd_init_lvl_est_filt_time(
497 WORD32 level_estim_k_weighting_type, WORD32 sampling_rate,
498 ia_2nd_order_filt_coeff_struct* pre_filt_coeff,
499 ia_2nd_order_filt_coeff_struct* rlb_filt_coeff) {
500 WORD32 i;
501 const FLOAT32* ptr_samp_tbl;
502
503 switch (sampling_rate) {
504 case 96000:
505 i = 0;
506 break;
507 case 88200:
508 i = 1;
509 break;
510 case 64000:
511 i = 2;
512 break;
513 case 48000:
514 i = 3;
515 break;
516 case 44100:
517 i = 4;
518 break;
519 case 32000:
520 i = 5;
521 break;
522 case 24000:
523 i = 6;
524 break;
525 case 22050:
526 i = 7;
527 break;
528 case 16000:
529 i = 8;
530 break;
531 case 12000:
532 i = 9;
533 break;
534 case 11025:
535 i = 10;
536 break;
537 case 8000:
538 i = 11;
539 break;
540 case 7350:
541 i = 12;
542 break;
543 default:
544 i = 3;
545 break;
546 }
547
548 ptr_samp_tbl = samp_rate_tbl[i];
549
550 if (level_estim_k_weighting_type == 2) {
551 pre_filt_coeff->b0 = ptr_samp_tbl[0];
552 pre_filt_coeff->b1 = ptr_samp_tbl[1];
553 pre_filt_coeff->b2 = ptr_samp_tbl[2];
554 pre_filt_coeff->a1 = ptr_samp_tbl[3];
555 pre_filt_coeff->a2 = ptr_samp_tbl[4];
556 }
557
558 if (level_estim_k_weighting_type == 1 || level_estim_k_weighting_type == 2) {
559 rlb_filt_coeff->b0 = ptr_samp_tbl[5];
560 rlb_filt_coeff->b1 = ptr_samp_tbl[6];
561 rlb_filt_coeff->b2 = ptr_samp_tbl[7];
562 rlb_filt_coeff->a1 = ptr_samp_tbl[8];
563 rlb_filt_coeff->a2 = ptr_samp_tbl[9];
564 }
565
566 return 0;
567 }
568
impd_init_lvl_est_filt_subband(WORD32 level_estim_k_weighting_type,WORD32 sampling_rate,WORD32 sub_band_domain_mode,WORD32 sub_band_count,WORD32 sub_band_compensation_type,FLOAT32 * weighting_filt,ia_2nd_order_filt_coeff_struct * filt_coeff_subband)569 WORD32 impd_init_lvl_est_filt_subband(
570 WORD32 level_estim_k_weighting_type, WORD32 sampling_rate,
571 WORD32 sub_band_domain_mode, WORD32 sub_band_count,
572 WORD32 sub_band_compensation_type, FLOAT32* weighting_filt,
573 ia_2nd_order_filt_coeff_struct* filt_coeff_subband) {
574 FLOAT32 w0, alpha, sinw0, cosw0;
575 FLOAT32 b0, b1, b2, a0, a1, a2;
576 FLOAT32 num_real, num_imag, den_real, den_imag;
577 FLOAT32* f_bands_nrm;
578 WORD32 b;
579 WORD32 i;
580 const FLOAT32* ptr_samp_tbl;
581
582 switch (sampling_rate) {
583 case 96000:
584 i = 0;
585 break;
586 case 88200:
587 i = 1;
588 break;
589 case 64000:
590 i = 2;
591 break;
592 case 48000:
593 i = 3;
594 break;
595 case 44100:
596 i = 4;
597 break;
598 case 32000:
599 i = 5;
600 break;
601 case 24000:
602 i = 6;
603 break;
604 case 22050:
605 i = 7;
606 break;
607 case 16000:
608 i = 8;
609 break;
610 case 12000:
611 i = 9;
612 break;
613 case 11025:
614 i = 10;
615 break;
616 case 8000:
617 i = 11;
618 break;
619 case 7350:
620 i = 12;
621 break;
622 default:
623 i = 3;
624 break;
625 }
626
627 ptr_samp_tbl = samp_rate_tbl[i];
628
629 switch (sub_band_domain_mode) {
630 case SUBBAND_DOMAIN_MODE_QMF64:
631 f_bands_nrm = f_bands_nrm_QMF64;
632 break;
633 case SUBBAND_DOMAIN_MODE_QMF71:
634 f_bands_nrm = f_bands_nrm_QMF71;
635 break;
636 case SUBBAND_DOMAIN_MODE_STFT256:
637 f_bands_nrm = f_bands_nrm_STFT256;
638 break;
639 default:
640 return UNEXPECTED_ERROR;
641 break;
642 }
643
644 for (b = 0; b < sub_band_count; b++) {
645 weighting_filt[b] = 1.f;
646 }
647
648 if (level_estim_k_weighting_type == 2) {
649 b0 = ptr_samp_tbl[0];
650 b1 = ptr_samp_tbl[1];
651 b2 = ptr_samp_tbl[2];
652 a1 = ptr_samp_tbl[3];
653 a2 = ptr_samp_tbl[4];
654 a0 = 1.f;
655
656 for (b = 0; b < sub_band_count; b++) {
657 num_real = b0 + b1 * (FLOAT32)cos(PI * f_bands_nrm[b]) +
658 b2 * (FLOAT32)cos(PI * 2 * f_bands_nrm[b]);
659 num_imag = -b1 * (FLOAT32)sin(PI * f_bands_nrm[b]) -
660 b2 * (FLOAT32)sin(PI * 2 * f_bands_nrm[b]);
661 den_real = a0 + a1 * (FLOAT32)cos(PI * f_bands_nrm[b]) +
662 a2 * (FLOAT32)cos(PI * 2 * f_bands_nrm[b]);
663 den_imag = -a1 * (FLOAT32)sin(PI * f_bands_nrm[b]) -
664 a2 * (FLOAT32)sin(PI * 2 * f_bands_nrm[b]);
665
666 weighting_filt[b] *=
667 (FLOAT32)(sqrt((num_real * num_real + num_imag * num_imag) /
668 (den_real * den_real + den_imag * den_imag)));
669 }
670 }
671
672 if (level_estim_k_weighting_type == 1 || level_estim_k_weighting_type == 2) {
673 b0 = ptr_samp_tbl[5];
674 b1 = ptr_samp_tbl[6];
675 b2 = ptr_samp_tbl[7];
676 a1 = ptr_samp_tbl[8];
677 a2 = ptr_samp_tbl[9];
678 a0 = 1.f;
679
680 for (b = 0; b < sub_band_count; b++) {
681 if (!(sub_band_compensation_type == 1 && b == 0)) {
682 num_real = (FLOAT32)(b0 + b1 * cos(PI * f_bands_nrm[b]) +
683 b2 * cos(PI * 2 * f_bands_nrm[b]));
684 num_imag = (FLOAT32)(-b1 * sin(PI * f_bands_nrm[b]) -
685 b2 * sin(PI * 2 * f_bands_nrm[b]));
686 den_real = (FLOAT32)(a0 + a1 * cos(PI * f_bands_nrm[b]) +
687 a2 * cos(PI * 2 * f_bands_nrm[b]));
688 den_imag = (FLOAT32)(-a1 * sin(PI * f_bands_nrm[b]) -
689 a2 * sin(PI * 2 * f_bands_nrm[b]));
690
691 weighting_filt[b] *=
692 (FLOAT32)(sqrt((num_real * num_real + num_imag * num_imag) /
693 (den_real * den_real + den_imag * den_imag)));
694 }
695 }
696
697 if (sub_band_compensation_type == 1) {
698 w0 = 2.0f * PI * 38.0f / (FLOAT32)sampling_rate *
699 AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF64;
700 sinw0 = (FLOAT32)sin(w0);
701 cosw0 = (FLOAT32)cos(w0);
702 alpha = sinw0;
703
704 b0 = (1 + cosw0) / 2;
705 b1 = -(1 + cosw0);
706 b2 = (1 + cosw0) / 2;
707 a0 = 1 + alpha;
708 a1 = -2 * cosw0;
709 a2 = 1 - alpha;
710
711 filt_coeff_subband->b0 = b0 / a0;
712 filt_coeff_subband->b1 = b1 / a0;
713 filt_coeff_subband->b2 = b2 / a0;
714 filt_coeff_subband->a1 = a1 / a0;
715 filt_coeff_subband->a2 = a2 / a0;
716 }
717 }
718
719 return 0;
720 }
721
impd_parametric_ffwd_type_drc_reset(ia_parametric_drc_type_ff_params_struct * pstr_parametric_ffwd_type_drc_params)722 WORD32 impd_parametric_ffwd_type_drc_reset(
723 ia_parametric_drc_type_ff_params_struct*
724 pstr_parametric_ffwd_type_drc_params) {
725 WORD32 i = 0;
726
727 pstr_parametric_ffwd_type_drc_params->level_estim_frame_index = 0;
728 pstr_parametric_ffwd_type_drc_params->start_up_phase = 1;
729 for (i = 0; i < PARAM_DRC_TYPE_FF_LEVEL_ESTIM_FRAME_COUNT_MAX; i++) {
730 pstr_parametric_ffwd_type_drc_params->level[i] = 0.f;
731 }
732
733 for (i = 0; i < MAX_CHANNEL_COUNT; i++) {
734 pstr_parametric_ffwd_type_drc_params->pre_filt_state[i].z1 = 0.f;
735 pstr_parametric_ffwd_type_drc_params->pre_filt_state[i].z2 = 0.f;
736 pstr_parametric_ffwd_type_drc_params->rlb_filt_state[i].z1 = 0.f;
737 pstr_parametric_ffwd_type_drc_params->rlb_filt_state[i].z2 = 0.f;
738 pstr_parametric_ffwd_type_drc_params->filt_state_subband_real[i].z1 = 0.f;
739 pstr_parametric_ffwd_type_drc_params->filt_state_subband_real[i].z2 = 0.f;
740 pstr_parametric_ffwd_type_drc_params->filt_state_subband_imag[i].z1 = 0.f;
741 pstr_parametric_ffwd_type_drc_params->filt_state_subband_imag[i].z2 = 0.f;
742 }
743
744 pstr_parametric_ffwd_type_drc_params->db_level_smooth = -135.f;
745 pstr_parametric_ffwd_type_drc_params->db_gain_smooth = 0.f;
746 pstr_parametric_ffwd_type_drc_params->hold_counter = 0;
747
748 return 0;
749 }
750
impd_parametric_drc_instance_process(FLOAT32 * audio_in_out_buf[],FLOAT32 * audio_real_buff[],FLOAT32 * audio_imag_buff[],ia_parametric_drc_params_struct * p_parametricdrc_params,ia_parametric_drc_instance_params_struct * pstr_parametric_drc_instance_params)751 WORD32 impd_parametric_drc_instance_process(
752 FLOAT32* audio_in_out_buf[], FLOAT32* audio_real_buff[],
753 FLOAT32* audio_imag_buff[],
754 ia_parametric_drc_params_struct* p_parametricdrc_params,
755 ia_parametric_drc_instance_params_struct*
756 pstr_parametric_drc_instance_params) {
757 WORD32 err = 0, i = 0;
758
759 if (pstr_parametric_drc_instance_params->disable_paramteric_drc) {
760 for (i = 0; i < p_parametricdrc_params->num_nodes; i++) {
761 pstr_parametric_drc_instance_params->str_spline_nodes.str_node[i]
762 .loc_db_gain = 0.f;
763 pstr_parametric_drc_instance_params->str_spline_nodes.str_node[i].slope =
764 0.f;
765 pstr_parametric_drc_instance_params->str_spline_nodes.str_node[i].time =
766 (i + 1) * p_parametricdrc_params->parametric_drc_frame_size - 1;
767 }
768
769 } else {
770 if (pstr_parametric_drc_instance_params->parametric_drc_type ==
771 PARAM_DRC_TYPE_FF) {
772 ia_parametric_drc_type_ff_params_struct*
773 pstr_parametric_ffwd_type_drc_params =
774 &(pstr_parametric_drc_instance_params
775 ->str_parametric_drc_type_ff_params);
776 for (i = 0; i < p_parametricdrc_params->num_nodes; i++) {
777 err = impd_parametric_ffwd_type_drc_process(
778 audio_in_out_buf, audio_real_buff, audio_imag_buff, i,
779 pstr_parametric_ffwd_type_drc_params,
780 &pstr_parametric_drc_instance_params->str_spline_nodes);
781 if (err) return (err);
782 }
783
784 } else if (pstr_parametric_drc_instance_params->parametric_drc_type ==
785 PARAM_DRC_TYPE_LIM) {
786 return (UNEXPECTED_ERROR);
787
788 } else {
789 return (UNEXPECTED_ERROR);
790 }
791 }
792
793 return 0;
794 }
795
iir_second_order_filter(ia_2nd_order_filt_coeff_struct * coeff,ia_2nd_order_filt_state_struct * state,WORD32 frame_len,FLOAT32 * input,FLOAT32 * output)796 VOID iir_second_order_filter(ia_2nd_order_filt_coeff_struct* coeff,
797 ia_2nd_order_filt_state_struct* state,
798 WORD32 frame_len, FLOAT32* input,
799 FLOAT32* output) {
800 FLOAT32 z2 = state->z2;
801 FLOAT32 z1 = state->z1;
802 FLOAT32 z0;
803 WORD32 i;
804
805 for (i = 0; i < frame_len; i++) {
806 z0 = input[i] - coeff->a1 * z1 - coeff->a2 * z2;
807 output[i] = coeff->b0 * z0 + coeff->b1 * z1 + coeff->b2 * z2;
808 z2 = z1;
809 z1 = z0;
810 }
811 state->z1 = z1;
812 state->z2 = z2;
813 }
impd_parametric_ffwd_type_drc_process(FLOAT32 * audio_in_out_buf[],FLOAT32 * audio_real_buff[],FLOAT32 * audio_imag_buff[],WORD32 nodeIdx,ia_parametric_drc_type_ff_params_struct * pstr_parametric_ffwd_type_drc_params,ia_spline_nodes_struct * str_spline_nodes)814 WORD32 impd_parametric_ffwd_type_drc_process(
815 FLOAT32* audio_in_out_buf[], FLOAT32* audio_real_buff[],
816 FLOAT32* audio_imag_buff[], WORD32 nodeIdx,
817 ia_parametric_drc_type_ff_params_struct*
818 pstr_parametric_ffwd_type_drc_params,
819 ia_spline_nodes_struct* str_spline_nodes) {
820 WORD32 c, t, b, n, i, offset;
821 FLOAT32 x, y, channelLevel, level, levelDb, loc_db_gain, levelDelta, alpha;
822
823 WORD32 frame_size = pstr_parametric_ffwd_type_drc_params->frame_size;
824 WORD32 sub_band_count = pstr_parametric_ffwd_type_drc_params->sub_band_count;
825 FLOAT32* level_estim_ch_weight =
826 pstr_parametric_ffwd_type_drc_params->level_estim_ch_weight;
827 WORD32 level_estim_k_weighting_type =
828 pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type;
829
830 ia_2nd_order_filt_coeff_struct preC =
831 pstr_parametric_ffwd_type_drc_params->pre_filt_coeff;
832 ia_2nd_order_filt_coeff_struct rlbC =
833 pstr_parametric_ffwd_type_drc_params->rlb_filt_coeff;
834 ia_2nd_order_filt_state_struct* preS =
835 pstr_parametric_ffwd_type_drc_params->pre_filt_state;
836 ia_2nd_order_filt_state_struct* rlbS =
837 pstr_parametric_ffwd_type_drc_params->rlb_filt_state;
838
839 ia_2nd_order_filt_coeff_struct rlbC_sb =
840 pstr_parametric_ffwd_type_drc_params->filt_coeff_subband;
841 ia_2nd_order_filt_state_struct* rlbS_sbReal =
842 pstr_parametric_ffwd_type_drc_params->filt_state_subband_real;
843 ia_2nd_order_filt_state_struct* rlbS_sbImag =
844 pstr_parametric_ffwd_type_drc_params->filt_state_subband_imag;
845 FLOAT32* weighting_filt =
846 pstr_parametric_ffwd_type_drc_params->weighting_filt;
847 WORD32 sub_band_compensation_type =
848 pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type;
849
850 if (audio_in_out_buf != NULL) {
851 level = 0;
852 offset = nodeIdx * pstr_parametric_ffwd_type_drc_params->frame_size;
853 for (c = 0; c < pstr_parametric_ffwd_type_drc_params->audio_num_chan; c++) {
854 channelLevel = 0.f;
855
856 if (!level_estim_ch_weight[c]) continue;
857
858 if (level_estim_k_weighting_type == 0) {
859 for (t = 0; t < frame_size; t++) {
860 x = audio_in_out_buf[c][offset + t];
861
862 channelLevel += x * x;
863 }
864
865 } else if (level_estim_k_weighting_type == 1) {
866 for (t = 0; t < frame_size; t++) {
867 x = audio_in_out_buf[c][offset + t];
868
869 iir_second_order_filter(&rlbC, &rlbS[c], 1, &x, &x);
870
871 channelLevel += x * x;
872 }
873
874 } else if (level_estim_k_weighting_type == 2) {
875 for (t = 0; t < frame_size; t++) {
876 x = audio_in_out_buf[c][offset + t];
877
878 iir_second_order_filter(&preC, &preS[c], 1, &x, &x);
879
880 iir_second_order_filter(&rlbC, &rlbS[c], 1, &x, &x);
881
882 channelLevel += x * x;
883 }
884
885 } else {
886 return (UNEXPECTED_ERROR);
887 }
888
889 level += level_estim_ch_weight[c] * channelLevel;
890 }
891
892 } else {
893 level = 0;
894 offset = nodeIdx * pstr_parametric_ffwd_type_drc_params->sub_band_count;
895 for (c = 0; c < pstr_parametric_ffwd_type_drc_params->audio_num_chan; c++) {
896 channelLevel = 0.f;
897
898 if (!level_estim_ch_weight[c]) continue;
899
900 if (level_estim_k_weighting_type == 0) {
901 for (b = 0; b < sub_band_count; b++) {
902 x = audio_real_buff[c][offset + b];
903 y = audio_imag_buff[c][offset + b];
904
905 channelLevel += x * x + y * y;
906 }
907
908 } else if (level_estim_k_weighting_type == 1 ||
909 level_estim_k_weighting_type == 2) {
910 for (b = 0; b < sub_band_count; b++) {
911 x = audio_real_buff[c][offset + b] * weighting_filt[b];
912 y = audio_imag_buff[c][offset + b] * weighting_filt[b];
913
914 if (b == 0 && sub_band_compensation_type == 1) {
915 iir_second_order_filter(&rlbC_sb, &rlbS_sbReal[c], 1, &x, &x);
916
917 iir_second_order_filter(&rlbC_sb, &rlbS_sbImag[c], 1, &y, &y);
918 }
919
920 channelLevel += x * x + y * y;
921 }
922
923 } else {
924 return (UNEXPECTED_ERROR);
925 }
926
927 level += level_estim_ch_weight[c] * channelLevel;
928 }
929
930 level /= sub_band_count;
931 }
932 pstr_parametric_ffwd_type_drc_params
933 ->level[pstr_parametric_ffwd_type_drc_params->level_estim_frame_index] =
934 level;
935 pstr_parametric_ffwd_type_drc_params->level_estim_frame_index++;
936
937 level = 0.f;
938 if (pstr_parametric_ffwd_type_drc_params->start_up_phase) {
939 for (i = 0;
940 i < pstr_parametric_ffwd_type_drc_params->level_estim_frame_index;
941 i++) {
942 level += pstr_parametric_ffwd_type_drc_params->level[i];
943 }
944 level /= pstr_parametric_ffwd_type_drc_params->level_estim_frame_index *
945 pstr_parametric_ffwd_type_drc_params->frame_size;
946 } else {
947 for (i = 0;
948 i < pstr_parametric_ffwd_type_drc_params->level_estim_frame_count;
949 i++) {
950 level += pstr_parametric_ffwd_type_drc_params->level[i];
951 }
952 level /= pstr_parametric_ffwd_type_drc_params->level_estim_integration_time;
953 }
954 if (pstr_parametric_ffwd_type_drc_params->level_estim_frame_index ==
955 pstr_parametric_ffwd_type_drc_params->level_estim_frame_count) {
956 pstr_parametric_ffwd_type_drc_params->level_estim_frame_index = 0;
957 pstr_parametric_ffwd_type_drc_params->start_up_phase = 0;
958 }
959
960 if (level < 1e-10f) level = 1e-10f;
961 if (level_estim_k_weighting_type == 2) {
962 levelDb = -0.691f + 10 * (FLOAT32)log10(level) + 3;
963 } else {
964 levelDb = 10 * (FLOAT32)log10(level) + 3;
965 }
966 levelDb -= pstr_parametric_ffwd_type_drc_params->ref_level_parametric_drc;
967
968 for (n = 0; n < pstr_parametric_ffwd_type_drc_params->node_count; n++) {
969 if (levelDb <=
970 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_level[n]) {
971 break;
972 }
973 }
974 if (n == 0) {
975 loc_db_gain = (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_gain[n];
976 } else if (n == pstr_parametric_ffwd_type_drc_params->node_count) {
977 loc_db_gain =
978 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_gain[n - 1] -
979 levelDb +
980 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_level[n - 1];
981 } else {
982 loc_db_gain =
983 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_gain[n] +
984 (levelDb -
985 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_level[n]) /
986 (FLOAT32)(pstr_parametric_ffwd_type_drc_params->node_level[n - 1] -
987 pstr_parametric_ffwd_type_drc_params->node_level[n]) *
988 (FLOAT32)(pstr_parametric_ffwd_type_drc_params->node_gain[n - 1] -
989 pstr_parametric_ffwd_type_drc_params->node_gain[n]);
990 }
991
992 levelDelta = levelDb - pstr_parametric_ffwd_type_drc_params->db_level_smooth;
993 if (loc_db_gain < pstr_parametric_ffwd_type_drc_params->db_gain_smooth) {
994 if (levelDelta >
995 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_threshold) {
996 alpha =
997 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_fast;
998 } else {
999 alpha =
1000 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_slow;
1001 }
1002 } else {
1003 if (levelDelta <
1004 -pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_threshold) {
1005 alpha = pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_fast;
1006 } else {
1007 alpha = pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_slow;
1008 }
1009 }
1010 if (loc_db_gain < pstr_parametric_ffwd_type_drc_params->db_gain_smooth ||
1011 pstr_parametric_ffwd_type_drc_params->hold_counter == 0) {
1012 pstr_parametric_ffwd_type_drc_params->db_level_smooth =
1013 (1 - alpha) * pstr_parametric_ffwd_type_drc_params->db_level_smooth +
1014 alpha * levelDb;
1015 pstr_parametric_ffwd_type_drc_params->db_gain_smooth =
1016 (1 - alpha) * pstr_parametric_ffwd_type_drc_params->db_gain_smooth +
1017 alpha * loc_db_gain;
1018 }
1019 if (pstr_parametric_ffwd_type_drc_params->hold_counter) {
1020 pstr_parametric_ffwd_type_drc_params->hold_counter -= 1;
1021 }
1022 if (loc_db_gain < pstr_parametric_ffwd_type_drc_params->db_gain_smooth) {
1023 pstr_parametric_ffwd_type_drc_params->hold_counter =
1024 pstr_parametric_ffwd_type_drc_params->gain_smooth_hold_off_count;
1025 }
1026
1027 str_spline_nodes->str_node[nodeIdx].loc_db_gain =
1028 pstr_parametric_ffwd_type_drc_params->db_gain_smooth;
1029 str_spline_nodes->str_node[nodeIdx].slope = 0.f;
1030 str_spline_nodes->str_node[nodeIdx].time =
1031 pstr_parametric_ffwd_type_drc_params->frame_size + offset - 1;
1032
1033 return 0;
1034 }
1035
impd_parametric_lim_type_drc_process(FLOAT32 * samples[],FLOAT32 loudness_normalization_gain_db,ia_parametric_drc_type_lim_params_struct * pstr_parametric_lim_type_drc_params,FLOAT32 * lpcm_gains)1036 WORD32 impd_parametric_lim_type_drc_process(
1037 FLOAT32* samples[], FLOAT32 loudness_normalization_gain_db,
1038 ia_parametric_drc_type_lim_params_struct*
1039 pstr_parametric_lim_type_drc_params,
1040 FLOAT32* lpcm_gains) {
1041 WORD32 i, j;
1042 FLOAT32 tmp, gain;
1043 // FLOAT32 min_gain = 1;
1044 FLOAT32 maximum, sectionMaximum;
1045 FLOAT32 loudness_normalization_gain =
1046 (FLOAT32)pow(10.0f, 0.05f * loudness_normalization_gain_db);
1047 FLOAT32* level_estim_ch_weight =
1048 pstr_parametric_lim_type_drc_params->level_estim_ch_weight;
1049 WORD32 num_channels = pstr_parametric_lim_type_drc_params->channels;
1050 WORD32 attack_time_samples = pstr_parametric_lim_type_drc_params->attack;
1051 FLOAT32 attack_constant =
1052 pstr_parametric_lim_type_drc_params->attack_constant;
1053 FLOAT32 release_constant =
1054 pstr_parametric_lim_type_drc_params->release_constant;
1055 FLOAT32 limit_threshold = pstr_parametric_lim_type_drc_params->threshold;
1056 FLOAT32* max_buf = pstr_parametric_lim_type_drc_params->max_buf;
1057 FLOAT32 gain_modified = pstr_parametric_lim_type_drc_params->cor;
1058 FLOAT64 pre_smoothed_gain =
1059 pstr_parametric_lim_type_drc_params->smooth_state_0;
1060
1061 for (i = 0; i < pstr_parametric_lim_type_drc_params->frame_size; i++) {
1062 tmp = 0.0f;
1063 for (j = 0; j < num_channels; j++) {
1064 if (!level_estim_ch_weight[j]) continue;
1065 tmp =
1066 max(tmp, (FLOAT32)fabs(loudness_normalization_gain *
1067 (level_estim_ch_weight[j]) * (samples[j][i])));
1068 }
1069
1070 for (j = attack_time_samples; j > 0; j--) {
1071 max_buf[j] = max_buf[j - 1];
1072 }
1073 max_buf[0] = tmp;
1074 sectionMaximum = tmp;
1075 for (j = 1; j < (attack_time_samples + 1); j++) {
1076 if (max_buf[j] > sectionMaximum) sectionMaximum = max_buf[j];
1077 }
1078 maximum = sectionMaximum;
1079
1080 if (maximum > limit_threshold) {
1081 gain = limit_threshold / maximum;
1082 } else {
1083 gain = 1;
1084 }
1085
1086 if (gain < pre_smoothed_gain) {
1087 gain_modified =
1088 min(gain_modified,
1089 (gain - 0.1f * (FLOAT32)pre_smoothed_gain) * 1.11111111f);
1090 } else {
1091 gain_modified = gain;
1092 }
1093
1094 if (gain_modified < pre_smoothed_gain) {
1095 pre_smoothed_gain =
1096 attack_constant * (pre_smoothed_gain - gain_modified) + gain_modified;
1097 pre_smoothed_gain = max(pre_smoothed_gain, gain);
1098 } else {
1099 pre_smoothed_gain =
1100 release_constant * (pre_smoothed_gain - gain_modified) +
1101 gain_modified;
1102 }
1103
1104 gain = (FLOAT32)pre_smoothed_gain;
1105
1106 lpcm_gains[i] = gain;
1107 }
1108
1109 pstr_parametric_lim_type_drc_params->cor = gain_modified;
1110 pstr_parametric_lim_type_drc_params->smooth_state_0 = pre_smoothed_gain;
1111 return 0;
1112 }
1113