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 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 static const 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 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 209 VOID 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 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 295 WORD32 impd_init_parametric_drcInstance( 296 ia_drc_config* pstr_drc_config, WORD32 instance_idx, 297 WORD32 ch_count_from_dwnmix_id, 298 ia_parametric_drc_params_struct* p_parametricdrc_params, pVOID* mem_ptr) { 299 WORD32 err = 0; 300 301 WORD32 parametric_drc_idx = 302 p_parametricdrc_params->parametric_drc_idx[instance_idx]; 303 ia_parametric_drc_instructions_struct* hParametricDrcInstructions = 304 &(pstr_drc_config->str_drc_config_ext 305 .str_parametric_drc_instructions[parametric_drc_idx]); 306 307 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx] 308 .disable_paramteric_drc = 309 hParametricDrcInstructions->disable_paramteric_drc; 310 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx] 311 .parametric_drc_type = hParametricDrcInstructions->parametric_drc_type; 312 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx] 313 .str_spline_nodes.num_nodes = p_parametricdrc_params->num_nodes; 314 315 if (p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx] 316 .disable_paramteric_drc == 0) { 317 if (p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx] 318 .parametric_drc_type == PARAM_DRC_TYPE_FF) { 319 err = impd_init_parametric_drc_feed_fwd(pstr_drc_config, instance_idx, 320 ch_count_from_dwnmix_id, 321 p_parametricdrc_params); 322 323 if (err) return (err); 324 325 } else if (p_parametricdrc_params 326 ->str_parametric_drc_instance_params[instance_idx] 327 .parametric_drc_type == PARAM_DRC_TYPE_LIM) { 328 p_parametricdrc_params->str_parametric_drc_instance_params[instance_idx] 329 .str_spline_nodes.num_nodes = p_parametricdrc_params->drc_frame_size; 330 331 impd_init_parametric_drc_lim(pstr_drc_config, instance_idx, 332 ch_count_from_dwnmix_id, 333 p_parametricdrc_params, mem_ptr); 334 335 } else { 336 return (UNEXPECTED_ERROR); 337 } 338 } 339 340 return 0; 341 } 342 343 WORD32 impd_init_parametric_drc_after_config( 344 ia_drc_config* pstr_drc_config, 345 ia_drc_loudness_info_set_struct* pstr_loudness_info, 346 ia_parametric_drc_params_struct* p_parametricdrc_params, pVOID* mem_ptr) { 347 WORD32 err = 0, instance_idx = 0, gain_set_index = 0, 348 side_chain_config_type = 0, downmix_id = 0, 349 ch_count_from_dwnmix_id = 0, L = 0; 350 351 p_parametricdrc_params->parametric_drc_frame_size = 352 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 353 .parametric_drc_frame_size; 354 p_parametricdrc_params->reset_parametric_drc = 355 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 356 .reset_parametric_drc; 357 p_parametricdrc_params->num_nodes = 358 p_parametricdrc_params->drc_frame_size / 359 p_parametricdrc_params->parametric_drc_frame_size; 360 361 switch (p_parametricdrc_params->sub_band_domain_mode) { 362 case SUBBAND_DOMAIN_MODE_QMF64: 363 L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF64; 364 break; 365 case SUBBAND_DOMAIN_MODE_QMF71: 366 L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF71; 367 break; 368 case SUBBAND_DOMAIN_MODE_STFT256: 369 L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_STFT256; 370 break; 371 case SUBBAND_DOMAIN_MODE_OFF: 372 default: 373 L = 0; 374 break; 375 } 376 377 if (p_parametricdrc_params->sub_band_domain_mode != SUBBAND_DOMAIN_MODE_OFF && 378 p_parametricdrc_params->parametric_drc_frame_size != L) { 379 return (EXTERNAL_ERROR); 380 } 381 382 for (instance_idx = 0; 383 instance_idx < p_parametricdrc_params->parametric_drc_instance_count; 384 instance_idx++) { 385 gain_set_index = p_parametricdrc_params->gain_set_index[instance_idx]; 386 side_chain_config_type = 387 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 388 .str_parametric_drc_gain_set_params[gain_set_index] 389 .side_chain_config_type; 390 downmix_id = pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 391 .str_parametric_drc_gain_set_params[gain_set_index] 392 .downmix_id; 393 394 if (side_chain_config_type == 1 && 395 downmix_id == 396 p_parametricdrc_params 397 ->dwnmix_id_from_drc_instructions[instance_idx]) { 398 ch_count_from_dwnmix_id = 399 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 400 .str_parametric_drc_gain_set_params[gain_set_index] 401 .ch_count_from_dwnmix_id; 402 } else { 403 ch_count_from_dwnmix_id = 0; 404 } 405 406 if (pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 407 .str_parametric_drc_gain_set_params[gain_set_index] 408 .drc_input_loudness_present == 0) { 409 WORD32 n = 0, m = 0, drcInputLoudnessFound = 0; 410 FLOAT32 drc_input_loudness = 0.f; 411 412 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) { 413 ia_loudness_info_struct* loudness_info = 414 &pstr_loudness_info->loudness_info[n]; 415 if (p_parametricdrc_params 416 ->dwnmix_id_from_drc_instructions[instance_idx] == 417 loudness_info->downmix_id) { 418 if (0 == loudness_info->drc_set_id) { 419 for (m = 0; m < loudness_info->measurement_count; m++) { 420 if (loudness_info->loudness_measure[m].method_def == 421 METHOD_DEFINITION_PROGRAM_LOUDNESS) { 422 drc_input_loudness = 423 loudness_info->loudness_measure[m].method_val; 424 drcInputLoudnessFound = 1; 425 break; 426 } 427 } 428 if (drcInputLoudnessFound == 0) { 429 for (m = 0; m < loudness_info->measurement_count; m++) { 430 if (loudness_info->loudness_measure[m].method_def == 431 METHOD_DEFINITION_ANCHOR_LOUDNESS) { 432 drc_input_loudness = 433 loudness_info->loudness_measure[m].method_val; 434 drcInputLoudnessFound = 1; 435 break; 436 } 437 } 438 } 439 } 440 } 441 } 442 if (drcInputLoudnessFound == 0) { 443 for (n = 0; n < pstr_loudness_info->loudness_info_count; n++) { 444 ia_loudness_info_struct* loudness_info = 445 &pstr_loudness_info->loudness_info[n]; 446 if (0 == loudness_info->downmix_id) { 447 if (0 == loudness_info->drc_set_id) { 448 for (m = 0; m < loudness_info->measurement_count; m++) { 449 if (loudness_info->loudness_measure[m].method_def == 450 METHOD_DEFINITION_PROGRAM_LOUDNESS) { 451 drc_input_loudness = 452 loudness_info->loudness_measure[m].method_val; 453 drcInputLoudnessFound = 1; 454 break; 455 } 456 } 457 if (drcInputLoudnessFound == 0) { 458 for (m = 0; m < loudness_info->measurement_count; m++) { 459 if (loudness_info->loudness_measure[m].method_def == 460 METHOD_DEFINITION_ANCHOR_LOUDNESS) { 461 drc_input_loudness = 462 loudness_info->loudness_measure[m].method_val; 463 drcInputLoudnessFound = 1; 464 break; 465 } 466 } 467 } 468 } 469 } 470 } 471 } 472 if (drcInputLoudnessFound == 0) { 473 return (UNEXPECTED_ERROR); 474 } else { 475 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 476 .str_parametric_drc_gain_set_params[gain_set_index] 477 .drc_input_loudness = drc_input_loudness; 478 } 479 } 480 481 impd_init_parametric_drcInstance(pstr_drc_config, instance_idx, 482 ch_count_from_dwnmix_id, 483 p_parametricdrc_params, mem_ptr); 484 if (err) return (err); 485 } 486 487 return 0; 488 } 489 490 WORD32 impd_init_lvl_est_filt_time( 491 WORD32 level_estim_k_weighting_type, WORD32 sampling_rate, 492 ia_2nd_order_filt_coeff_struct* pre_filt_coeff, 493 ia_2nd_order_filt_coeff_struct* rlb_filt_coeff) { 494 WORD32 i; 495 const FLOAT32* ptr_samp_tbl; 496 497 switch (sampling_rate) { 498 case 96000: 499 i = 0; 500 break; 501 case 88200: 502 i = 1; 503 break; 504 case 64000: 505 i = 2; 506 break; 507 case 48000: 508 i = 3; 509 break; 510 case 44100: 511 i = 4; 512 break; 513 case 32000: 514 i = 5; 515 break; 516 case 24000: 517 i = 6; 518 break; 519 case 22050: 520 i = 7; 521 break; 522 case 16000: 523 i = 8; 524 break; 525 case 12000: 526 i = 9; 527 break; 528 case 11025: 529 i = 10; 530 break; 531 case 8000: 532 i = 11; 533 break; 534 case 7350: 535 i = 12; 536 break; 537 default: 538 i = 3; 539 break; 540 } 541 542 ptr_samp_tbl = samp_rate_tbl[i]; 543 544 if (level_estim_k_weighting_type == 2) { 545 pre_filt_coeff->b0 = ptr_samp_tbl[0]; 546 pre_filt_coeff->b1 = ptr_samp_tbl[1]; 547 pre_filt_coeff->b2 = ptr_samp_tbl[2]; 548 pre_filt_coeff->a1 = ptr_samp_tbl[3]; 549 pre_filt_coeff->a2 = ptr_samp_tbl[4]; 550 } 551 552 if (level_estim_k_weighting_type == 1 || level_estim_k_weighting_type == 2) { 553 rlb_filt_coeff->b0 = ptr_samp_tbl[5]; 554 rlb_filt_coeff->b1 = ptr_samp_tbl[6]; 555 rlb_filt_coeff->b2 = ptr_samp_tbl[7]; 556 rlb_filt_coeff->a1 = ptr_samp_tbl[8]; 557 rlb_filt_coeff->a2 = ptr_samp_tbl[9]; 558 } 559 560 return 0; 561 } 562 563 WORD32 impd_init_lvl_est_filt_subband( 564 WORD32 level_estim_k_weighting_type, WORD32 sampling_rate, 565 WORD32 sub_band_domain_mode, WORD32 sub_band_count, 566 WORD32 sub_band_compensation_type, FLOAT32* weighting_filt, 567 ia_2nd_order_filt_coeff_struct* filt_coeff_subband) { 568 FLOAT32 w0, alpha, sinw0, cosw0; 569 FLOAT32 b0, b1, b2, a0, a1, a2; 570 FLOAT32 num_real, num_imag, den_real, den_imag; 571 const FLOAT32* f_bands_nrm; 572 WORD32 b; 573 WORD32 i; 574 const FLOAT32* ptr_samp_tbl; 575 576 switch (sampling_rate) { 577 case 96000: 578 i = 0; 579 break; 580 case 88200: 581 i = 1; 582 break; 583 case 64000: 584 i = 2; 585 break; 586 case 48000: 587 i = 3; 588 break; 589 case 44100: 590 i = 4; 591 break; 592 case 32000: 593 i = 5; 594 break; 595 case 24000: 596 i = 6; 597 break; 598 case 22050: 599 i = 7; 600 break; 601 case 16000: 602 i = 8; 603 break; 604 case 12000: 605 i = 9; 606 break; 607 case 11025: 608 i = 10; 609 break; 610 case 8000: 611 i = 11; 612 break; 613 case 7350: 614 i = 12; 615 break; 616 default: 617 i = 3; 618 break; 619 } 620 621 ptr_samp_tbl = samp_rate_tbl[i]; 622 623 switch (sub_band_domain_mode) { 624 case SUBBAND_DOMAIN_MODE_QMF64: 625 f_bands_nrm = f_bands_nrm_QMF64; 626 break; 627 case SUBBAND_DOMAIN_MODE_QMF71: 628 f_bands_nrm = f_bands_nrm_QMF71; 629 break; 630 case SUBBAND_DOMAIN_MODE_STFT256: 631 f_bands_nrm = f_bands_nrm_STFT256; 632 break; 633 default: 634 return UNEXPECTED_ERROR; 635 break; 636 } 637 638 for (b = 0; b < sub_band_count; b++) { 639 weighting_filt[b] = 1.f; 640 } 641 642 if (level_estim_k_weighting_type == 2) { 643 b0 = ptr_samp_tbl[0]; 644 b1 = ptr_samp_tbl[1]; 645 b2 = ptr_samp_tbl[2]; 646 a1 = ptr_samp_tbl[3]; 647 a2 = ptr_samp_tbl[4]; 648 a0 = 1.f; 649 650 for (b = 0; b < sub_band_count; b++) { 651 num_real = b0 + b1 * (FLOAT32)cos(PI * f_bands_nrm[b]) + 652 b2 * (FLOAT32)cos(PI * 2 * f_bands_nrm[b]); 653 num_imag = -b1 * (FLOAT32)sin(PI * f_bands_nrm[b]) - 654 b2 * (FLOAT32)sin(PI * 2 * f_bands_nrm[b]); 655 den_real = a0 + a1 * (FLOAT32)cos(PI * f_bands_nrm[b]) + 656 a2 * (FLOAT32)cos(PI * 2 * f_bands_nrm[b]); 657 den_imag = -a1 * (FLOAT32)sin(PI * f_bands_nrm[b]) - 658 a2 * (FLOAT32)sin(PI * 2 * f_bands_nrm[b]); 659 660 weighting_filt[b] *= 661 (FLOAT32)(sqrt((num_real * num_real + num_imag * num_imag) / 662 (den_real * den_real + den_imag * den_imag))); 663 } 664 } 665 666 if (level_estim_k_weighting_type == 1 || level_estim_k_weighting_type == 2) { 667 b0 = ptr_samp_tbl[5]; 668 b1 = ptr_samp_tbl[6]; 669 b2 = ptr_samp_tbl[7]; 670 a1 = ptr_samp_tbl[8]; 671 a2 = ptr_samp_tbl[9]; 672 a0 = 1.f; 673 674 for (b = 0; b < sub_band_count; b++) { 675 if (!(sub_band_compensation_type == 1 && b == 0)) { 676 num_real = (FLOAT32)(b0 + b1 * cos(PI * f_bands_nrm[b]) + 677 b2 * cos(PI * 2 * f_bands_nrm[b])); 678 num_imag = (FLOAT32)(-b1 * sin(PI * f_bands_nrm[b]) - 679 b2 * sin(PI * 2 * f_bands_nrm[b])); 680 den_real = (FLOAT32)(a0 + a1 * cos(PI * f_bands_nrm[b]) + 681 a2 * cos(PI * 2 * f_bands_nrm[b])); 682 den_imag = (FLOAT32)(-a1 * sin(PI * f_bands_nrm[b]) - 683 a2 * sin(PI * 2 * f_bands_nrm[b])); 684 685 weighting_filt[b] *= 686 (FLOAT32)(sqrt((num_real * num_real + num_imag * num_imag) / 687 (den_real * den_real + den_imag * den_imag))); 688 } 689 } 690 691 if (sub_band_compensation_type == 1) { 692 w0 = 2.0f * PI * 38.0f / (FLOAT32)sampling_rate * 693 AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF64; 694 sinw0 = (FLOAT32)sin(w0); 695 cosw0 = (FLOAT32)cos(w0); 696 alpha = sinw0; 697 698 b0 = (1 + cosw0) / 2; 699 b1 = -(1 + cosw0); 700 b2 = (1 + cosw0) / 2; 701 a0 = 1 + alpha; 702 a1 = -2 * cosw0; 703 a2 = 1 - alpha; 704 705 filt_coeff_subband->b0 = b0 / a0; 706 filt_coeff_subband->b1 = b1 / a0; 707 filt_coeff_subband->b2 = b2 / a0; 708 filt_coeff_subband->a1 = a1 / a0; 709 filt_coeff_subband->a2 = a2 / a0; 710 } 711 } 712 713 return 0; 714 } 715 716 WORD32 impd_parametric_ffwd_type_drc_reset( 717 ia_parametric_drc_type_ff_params_struct* 718 pstr_parametric_ffwd_type_drc_params) { 719 WORD32 i = 0; 720 721 pstr_parametric_ffwd_type_drc_params->level_estim_frame_index = 0; 722 pstr_parametric_ffwd_type_drc_params->start_up_phase = 1; 723 for (i = 0; i < PARAM_DRC_TYPE_FF_LEVEL_ESTIM_FRAME_COUNT_MAX; i++) { 724 pstr_parametric_ffwd_type_drc_params->level[i] = 0.f; 725 } 726 727 for (i = 0; i < MAX_CHANNEL_COUNT; i++) { 728 pstr_parametric_ffwd_type_drc_params->pre_filt_state[i].z1 = 0.f; 729 pstr_parametric_ffwd_type_drc_params->pre_filt_state[i].z2 = 0.f; 730 pstr_parametric_ffwd_type_drc_params->rlb_filt_state[i].z1 = 0.f; 731 pstr_parametric_ffwd_type_drc_params->rlb_filt_state[i].z2 = 0.f; 732 pstr_parametric_ffwd_type_drc_params->filt_state_subband_real[i].z1 = 0.f; 733 pstr_parametric_ffwd_type_drc_params->filt_state_subband_real[i].z2 = 0.f; 734 pstr_parametric_ffwd_type_drc_params->filt_state_subband_imag[i].z1 = 0.f; 735 pstr_parametric_ffwd_type_drc_params->filt_state_subband_imag[i].z2 = 0.f; 736 } 737 738 pstr_parametric_ffwd_type_drc_params->db_level_smooth = -135.f; 739 pstr_parametric_ffwd_type_drc_params->db_gain_smooth = 0.f; 740 pstr_parametric_ffwd_type_drc_params->hold_counter = 0; 741 742 return 0; 743 } 744 745 WORD32 impd_parametric_drc_instance_process( 746 FLOAT32* audio_in_out_buf[], FLOAT32* audio_real_buff[], 747 FLOAT32* audio_imag_buff[], 748 ia_parametric_drc_params_struct* p_parametricdrc_params, 749 ia_parametric_drc_instance_params_struct* 750 pstr_parametric_drc_instance_params) { 751 WORD32 err = 0, i = 0; 752 753 if (pstr_parametric_drc_instance_params->disable_paramteric_drc) { 754 for (i = 0; i < p_parametricdrc_params->num_nodes; i++) { 755 pstr_parametric_drc_instance_params->str_spline_nodes.str_node[i] 756 .loc_db_gain = 0.f; 757 pstr_parametric_drc_instance_params->str_spline_nodes.str_node[i].slope = 758 0.f; 759 pstr_parametric_drc_instance_params->str_spline_nodes.str_node[i].time = 760 (i + 1) * p_parametricdrc_params->parametric_drc_frame_size - 1; 761 } 762 763 } else { 764 if (pstr_parametric_drc_instance_params->parametric_drc_type == 765 PARAM_DRC_TYPE_FF) { 766 ia_parametric_drc_type_ff_params_struct* 767 pstr_parametric_ffwd_type_drc_params = 768 &(pstr_parametric_drc_instance_params 769 ->str_parametric_drc_type_ff_params); 770 for (i = 0; i < p_parametricdrc_params->num_nodes; i++) { 771 err = impd_parametric_ffwd_type_drc_process( 772 audio_in_out_buf, audio_real_buff, audio_imag_buff, i, 773 pstr_parametric_ffwd_type_drc_params, 774 &pstr_parametric_drc_instance_params->str_spline_nodes); 775 if (err) return (err); 776 } 777 778 } else if (pstr_parametric_drc_instance_params->parametric_drc_type == 779 PARAM_DRC_TYPE_LIM) { 780 return (UNEXPECTED_ERROR); 781 782 } else { 783 return (UNEXPECTED_ERROR); 784 } 785 } 786 787 return 0; 788 } 789 790 VOID iir_second_order_filter(ia_2nd_order_filt_coeff_struct* coeff, 791 ia_2nd_order_filt_state_struct* state, 792 WORD32 frame_len, FLOAT32* input, 793 FLOAT32* output) { 794 FLOAT32 z2 = state->z2; 795 FLOAT32 z1 = state->z1; 796 FLOAT32 z0; 797 WORD32 i; 798 799 for (i = 0; i < frame_len; i++) { 800 z0 = input[i] - coeff->a1 * z1 - coeff->a2 * z2; 801 output[i] = coeff->b0 * z0 + coeff->b1 * z1 + coeff->b2 * z2; 802 z2 = z1; 803 z1 = z0; 804 } 805 state->z1 = z1; 806 state->z2 = z2; 807 } 808 WORD32 impd_parametric_ffwd_type_drc_process( 809 FLOAT32* audio_in_out_buf[], FLOAT32* audio_real_buff[], 810 FLOAT32* audio_imag_buff[], WORD32 nodeIdx, 811 ia_parametric_drc_type_ff_params_struct* 812 pstr_parametric_ffwd_type_drc_params, 813 ia_spline_nodes_struct* str_spline_nodes) { 814 WORD32 c, t, b, n, i, offset; 815 FLOAT32 x, y, channelLevel, level, levelDb, loc_db_gain, levelDelta, alpha; 816 817 WORD32 frame_size = pstr_parametric_ffwd_type_drc_params->frame_size; 818 WORD32 sub_band_count = pstr_parametric_ffwd_type_drc_params->sub_band_count; 819 FLOAT32* level_estim_ch_weight = 820 pstr_parametric_ffwd_type_drc_params->level_estim_ch_weight; 821 WORD32 level_estim_k_weighting_type = 822 pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type; 823 824 ia_2nd_order_filt_coeff_struct preC = 825 pstr_parametric_ffwd_type_drc_params->pre_filt_coeff; 826 ia_2nd_order_filt_coeff_struct rlbC = 827 pstr_parametric_ffwd_type_drc_params->rlb_filt_coeff; 828 ia_2nd_order_filt_state_struct* preS = 829 pstr_parametric_ffwd_type_drc_params->pre_filt_state; 830 ia_2nd_order_filt_state_struct* rlbS = 831 pstr_parametric_ffwd_type_drc_params->rlb_filt_state; 832 833 ia_2nd_order_filt_coeff_struct rlbC_sb = 834 pstr_parametric_ffwd_type_drc_params->filt_coeff_subband; 835 ia_2nd_order_filt_state_struct* rlbS_sbReal = 836 pstr_parametric_ffwd_type_drc_params->filt_state_subband_real; 837 ia_2nd_order_filt_state_struct* rlbS_sbImag = 838 pstr_parametric_ffwd_type_drc_params->filt_state_subband_imag; 839 FLOAT32* weighting_filt = 840 pstr_parametric_ffwd_type_drc_params->weighting_filt; 841 WORD32 sub_band_compensation_type = 842 pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type; 843 844 if (audio_in_out_buf != NULL) { 845 level = 0; 846 offset = nodeIdx * pstr_parametric_ffwd_type_drc_params->frame_size; 847 for (c = 0; c < pstr_parametric_ffwd_type_drc_params->audio_num_chan; c++) { 848 channelLevel = 0.f; 849 850 if (!level_estim_ch_weight[c]) continue; 851 852 if (level_estim_k_weighting_type == 0) { 853 for (t = 0; t < frame_size; t++) { 854 x = audio_in_out_buf[c][offset + t]; 855 856 channelLevel += x * x; 857 } 858 859 } else if (level_estim_k_weighting_type == 1) { 860 for (t = 0; t < frame_size; t++) { 861 x = audio_in_out_buf[c][offset + t]; 862 863 iir_second_order_filter(&rlbC, &rlbS[c], 1, &x, &x); 864 865 channelLevel += x * x; 866 } 867 868 } else if (level_estim_k_weighting_type == 2) { 869 for (t = 0; t < frame_size; t++) { 870 x = audio_in_out_buf[c][offset + t]; 871 872 iir_second_order_filter(&preC, &preS[c], 1, &x, &x); 873 874 iir_second_order_filter(&rlbC, &rlbS[c], 1, &x, &x); 875 876 channelLevel += x * x; 877 } 878 879 } else { 880 return (UNEXPECTED_ERROR); 881 } 882 883 level += level_estim_ch_weight[c] * channelLevel; 884 } 885 886 } else { 887 level = 0; 888 offset = nodeIdx * pstr_parametric_ffwd_type_drc_params->sub_band_count; 889 for (c = 0; c < pstr_parametric_ffwd_type_drc_params->audio_num_chan; c++) { 890 channelLevel = 0.f; 891 892 if (!level_estim_ch_weight[c]) continue; 893 894 if (level_estim_k_weighting_type == 0) { 895 for (b = 0; b < sub_band_count; b++) { 896 x = audio_real_buff[c][offset + b]; 897 y = audio_imag_buff[c][offset + b]; 898 899 channelLevel += x * x + y * y; 900 } 901 902 } else if (level_estim_k_weighting_type == 1 || 903 level_estim_k_weighting_type == 2) { 904 for (b = 0; b < sub_band_count; b++) { 905 x = audio_real_buff[c][offset + b] * weighting_filt[b]; 906 y = audio_imag_buff[c][offset + b] * weighting_filt[b]; 907 908 if (b == 0 && sub_band_compensation_type == 1) { 909 iir_second_order_filter(&rlbC_sb, &rlbS_sbReal[c], 1, &x, &x); 910 911 iir_second_order_filter(&rlbC_sb, &rlbS_sbImag[c], 1, &y, &y); 912 } 913 914 channelLevel += x * x + y * y; 915 } 916 917 } else { 918 return (UNEXPECTED_ERROR); 919 } 920 921 level += level_estim_ch_weight[c] * channelLevel; 922 } 923 924 level /= sub_band_count; 925 } 926 pstr_parametric_ffwd_type_drc_params 927 ->level[pstr_parametric_ffwd_type_drc_params->level_estim_frame_index] = 928 level; 929 pstr_parametric_ffwd_type_drc_params->level_estim_frame_index++; 930 931 level = 0.f; 932 if (pstr_parametric_ffwd_type_drc_params->start_up_phase) { 933 for (i = 0; 934 i < pstr_parametric_ffwd_type_drc_params->level_estim_frame_index; 935 i++) { 936 level += pstr_parametric_ffwd_type_drc_params->level[i]; 937 } 938 level /= pstr_parametric_ffwd_type_drc_params->level_estim_frame_index * 939 pstr_parametric_ffwd_type_drc_params->frame_size; 940 } else { 941 for (i = 0; 942 i < pstr_parametric_ffwd_type_drc_params->level_estim_frame_count; 943 i++) { 944 level += pstr_parametric_ffwd_type_drc_params->level[i]; 945 } 946 level /= pstr_parametric_ffwd_type_drc_params->level_estim_integration_time; 947 } 948 if (pstr_parametric_ffwd_type_drc_params->level_estim_frame_index == 949 pstr_parametric_ffwd_type_drc_params->level_estim_frame_count) { 950 pstr_parametric_ffwd_type_drc_params->level_estim_frame_index = 0; 951 pstr_parametric_ffwd_type_drc_params->start_up_phase = 0; 952 } 953 954 if (level < 1e-10f) level = 1e-10f; 955 if (level_estim_k_weighting_type == 2) { 956 levelDb = -0.691f + 10 * (FLOAT32)log10(level) + 3; 957 } else { 958 levelDb = 10 * (FLOAT32)log10(level) + 3; 959 } 960 levelDb -= pstr_parametric_ffwd_type_drc_params->ref_level_parametric_drc; 961 962 for (n = 0; n < pstr_parametric_ffwd_type_drc_params->node_count; n++) { 963 if (levelDb <= 964 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_level[n]) { 965 break; 966 } 967 } 968 if (n == 0) { 969 loc_db_gain = (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_gain[n]; 970 } else if (n == pstr_parametric_ffwd_type_drc_params->node_count) { 971 loc_db_gain = 972 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_gain[n - 1] - 973 levelDb + 974 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_level[n - 1]; 975 } else { 976 loc_db_gain = 977 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_gain[n] + 978 (levelDb - 979 (FLOAT32)pstr_parametric_ffwd_type_drc_params->node_level[n]) / 980 (FLOAT32)(pstr_parametric_ffwd_type_drc_params->node_level[n - 1] - 981 pstr_parametric_ffwd_type_drc_params->node_level[n]) * 982 (FLOAT32)(pstr_parametric_ffwd_type_drc_params->node_gain[n - 1] - 983 pstr_parametric_ffwd_type_drc_params->node_gain[n]); 984 } 985 986 levelDelta = levelDb - pstr_parametric_ffwd_type_drc_params->db_level_smooth; 987 if (loc_db_gain < pstr_parametric_ffwd_type_drc_params->db_gain_smooth) { 988 if (levelDelta > 989 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_threshold) { 990 alpha = 991 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_fast; 992 } else { 993 alpha = 994 pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_slow; 995 } 996 } else { 997 if (levelDelta < 998 -pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_threshold) { 999 alpha = pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_fast; 1000 } else { 1001 alpha = pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_slow; 1002 } 1003 } 1004 if (loc_db_gain < pstr_parametric_ffwd_type_drc_params->db_gain_smooth || 1005 pstr_parametric_ffwd_type_drc_params->hold_counter == 0) { 1006 pstr_parametric_ffwd_type_drc_params->db_level_smooth = 1007 (1 - alpha) * pstr_parametric_ffwd_type_drc_params->db_level_smooth + 1008 alpha * levelDb; 1009 pstr_parametric_ffwd_type_drc_params->db_gain_smooth = 1010 (1 - alpha) * pstr_parametric_ffwd_type_drc_params->db_gain_smooth + 1011 alpha * loc_db_gain; 1012 } 1013 if (pstr_parametric_ffwd_type_drc_params->hold_counter) { 1014 pstr_parametric_ffwd_type_drc_params->hold_counter -= 1; 1015 } 1016 if (loc_db_gain < pstr_parametric_ffwd_type_drc_params->db_gain_smooth) { 1017 pstr_parametric_ffwd_type_drc_params->hold_counter = 1018 pstr_parametric_ffwd_type_drc_params->gain_smooth_hold_off_count; 1019 } 1020 1021 str_spline_nodes->str_node[nodeIdx].loc_db_gain = 1022 pstr_parametric_ffwd_type_drc_params->db_gain_smooth; 1023 str_spline_nodes->str_node[nodeIdx].slope = 0.f; 1024 str_spline_nodes->str_node[nodeIdx].time = 1025 pstr_parametric_ffwd_type_drc_params->frame_size + offset - 1; 1026 1027 return 0; 1028 } 1029 1030 WORD32 impd_parametric_lim_type_drc_process( 1031 FLOAT32* samples[], FLOAT32 loudness_normalization_gain_db, 1032 ia_parametric_drc_type_lim_params_struct* 1033 pstr_parametric_lim_type_drc_params, 1034 FLOAT32* lpcm_gains) { 1035 WORD32 i, j; 1036 FLOAT32 tmp, gain; 1037 // FLOAT32 min_gain = 1; 1038 FLOAT32 maximum, sectionMaximum; 1039 FLOAT32 loudness_normalization_gain = 1040 (FLOAT32)pow(10.0f, 0.05f * loudness_normalization_gain_db); 1041 FLOAT32* level_estim_ch_weight = 1042 pstr_parametric_lim_type_drc_params->level_estim_ch_weight; 1043 WORD32 num_channels = pstr_parametric_lim_type_drc_params->channels; 1044 WORD32 attack_time_samples = pstr_parametric_lim_type_drc_params->attack; 1045 FLOAT32 attack_constant = 1046 pstr_parametric_lim_type_drc_params->attack_constant; 1047 FLOAT32 release_constant = 1048 pstr_parametric_lim_type_drc_params->release_constant; 1049 FLOAT32 limit_threshold = pstr_parametric_lim_type_drc_params->threshold; 1050 FLOAT32* max_buf = pstr_parametric_lim_type_drc_params->max_buf; 1051 FLOAT32 gain_modified = pstr_parametric_lim_type_drc_params->cor; 1052 FLOAT64 pre_smoothed_gain = 1053 pstr_parametric_lim_type_drc_params->smooth_state_0; 1054 1055 for (i = 0; i < pstr_parametric_lim_type_drc_params->frame_size; i++) { 1056 tmp = 0.0f; 1057 for (j = 0; j < num_channels; j++) { 1058 if (!level_estim_ch_weight[j]) continue; 1059 tmp = 1060 max(tmp, (FLOAT32)fabs(loudness_normalization_gain * 1061 (level_estim_ch_weight[j]) * (samples[j][i]))); 1062 } 1063 1064 for (j = attack_time_samples; j > 0; j--) { 1065 max_buf[j] = max_buf[j - 1]; 1066 } 1067 max_buf[0] = tmp; 1068 sectionMaximum = tmp; 1069 for (j = 1; j < (attack_time_samples + 1); j++) { 1070 if (max_buf[j] > sectionMaximum) sectionMaximum = max_buf[j]; 1071 } 1072 maximum = sectionMaximum; 1073 1074 if (maximum > limit_threshold) { 1075 gain = limit_threshold / maximum; 1076 } else { 1077 gain = 1; 1078 } 1079 1080 if (gain < pre_smoothed_gain) { 1081 gain_modified = 1082 min(gain_modified, 1083 (gain - 0.1f * (FLOAT32)pre_smoothed_gain) * 1.11111111f); 1084 } else { 1085 gain_modified = gain; 1086 } 1087 1088 if (gain_modified < pre_smoothed_gain) { 1089 pre_smoothed_gain = 1090 attack_constant * (pre_smoothed_gain - gain_modified) + gain_modified; 1091 pre_smoothed_gain = max(pre_smoothed_gain, gain); 1092 } else { 1093 pre_smoothed_gain = 1094 release_constant * (pre_smoothed_gain - gain_modified) + 1095 gain_modified; 1096 } 1097 1098 gain = (FLOAT32)pre_smoothed_gain; 1099 1100 lpcm_gains[i] = gain; 1101 } 1102 1103 pstr_parametric_lim_type_drc_params->cor = gain_modified; 1104 pstr_parametric_lim_type_drc_params->smooth_state_0 = pre_smoothed_gain; 1105 return 0; 1106 } 1107