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