xref: /aosp_15_r20/external/libxaac/decoder/drc_src/impd_drc_parametric_dec.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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