• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <string.h>
24 #include "impd_type_def.h"
25 #include "impd_drc_extr_delta_coded_info.h"
26 #include "impd_drc_common.h"
27 #include "impd_drc_struct.h"
28 #include "impd_parametric_drc_dec.h"
29 #include "impd_drc_filter_bank.h"
30 #include "impd_drc_rom.h"
31 
32 #define PI 3.14159265f
33 
34 #ifndef max
35 #define max(a, b) (((a) > (b)) ? (a) : (b))
36 #endif
37 #ifndef min
38 #define min(a, b) (((a) < (b)) ? (a) : (b))
39 #endif
40 
impd_init_parametric_drc(WORD32 drc_frame_size,WORD32 sampling_rate,WORD32 sub_band_domain_mode,ia_parametric_drc_params_struct * p_parametricdrc_params)41 WORD32 impd_init_parametric_drc(
42     WORD32 drc_frame_size, WORD32 sampling_rate, WORD32 sub_band_domain_mode,
43     ia_parametric_drc_params_struct* p_parametricdrc_params) {
44   WORD32 sub_band_count_tbl[4] = {0, 64, 71, 256};
45   p_parametricdrc_params->drc_frame_size = drc_frame_size;
46   p_parametricdrc_params->sampling_rate = sampling_rate;
47   p_parametricdrc_params->sub_band_domain_mode = sub_band_domain_mode;
48 
49   p_parametricdrc_params->sub_band_count =
50       sub_band_count_tbl[sub_band_domain_mode];
51 
52   return 0;
53 }
54 
impd_init_parametric_drc_feed_fwd(ia_drc_config * pstr_drc_config,WORD32 instance_idx,WORD32 ch_count_from_dwnmix_id,ia_parametric_drc_params_struct * p_parametricdrc_params)55 WORD32 impd_init_parametric_drc_feed_fwd(
56     ia_drc_config* pstr_drc_config, WORD32 instance_idx,
57     WORD32 ch_count_from_dwnmix_id,
58     ia_parametric_drc_params_struct* p_parametricdrc_params) {
59   WORD32 err = 0, i = 0;
60 
61   WORD32 parametric_drc_idx =
62       p_parametricdrc_params->parametric_drc_idx[instance_idx];
63   WORD32 gain_set_index = p_parametricdrc_params->gain_set_index[instance_idx];
64   WORD32* channel_map = p_parametricdrc_params->channel_map[instance_idx];
65 
66   ia_drc_coeff_parametric_drc_struct* hDrcCoefficientsParametricDrcBs =
67       &(pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc);
68   ia_parametric_drc_type_feed_forward_struct* hParametricDrcTypeFeedForwardBs =
69       &(pstr_drc_config->str_drc_config_ext
70             .str_parametric_drc_instructions[parametric_drc_idx]
71             .str_parametric_drc_type_feed_forward);
72   ia_parametric_drc_type_ff_params_struct*
73       pstr_parametric_ffwd_type_drc_params =
74           &(p_parametricdrc_params
75                 ->str_parametric_drc_instance_params[instance_idx]
76                 .str_parametric_drc_type_ff_params);
77 
78   /* level estimation */
79   pstr_parametric_ffwd_type_drc_params->frame_size =
80       p_parametricdrc_params->parametric_drc_frame_size;
81   pstr_parametric_ffwd_type_drc_params->sub_band_domain_mode =
82       p_parametricdrc_params->sub_band_domain_mode;
83   pstr_parametric_ffwd_type_drc_params->sub_band_count =
84       p_parametricdrc_params->sub_band_count;
85   pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type = 0;
86 
87   if (pstr_parametric_ffwd_type_drc_params->sub_band_domain_mode ==
88       SUBBAND_DOMAIN_MODE_QMF64) {
89     if (p_parametricdrc_params->sampling_rate == 48000) {
90       pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type = 1;
91     } else {
92       /* support of other sampling rates than 48000 might be missing */
93       return UNEXPECTED_ERROR;
94     }
95   }
96 
97   pstr_parametric_ffwd_type_drc_params->audio_num_chan =
98       p_parametricdrc_params->audio_num_chan;
99   pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type =
100       hParametricDrcTypeFeedForwardBs->level_estim_k_weighting_type;
101   pstr_parametric_ffwd_type_drc_params->level_estim_integration_time =
102       hParametricDrcTypeFeedForwardBs->level_estim_integration_time;
103   pstr_parametric_ffwd_type_drc_params->level_estim_frame_index = 0;
104   pstr_parametric_ffwd_type_drc_params->level_estim_frame_count =
105       hParametricDrcTypeFeedForwardBs->level_estim_integration_time /
106       pstr_parametric_ffwd_type_drc_params->frame_size;
107 
108   memset(pstr_parametric_ffwd_type_drc_params->level, 0,
109          PARAM_DRC_TYPE_FF_LEVEL_ESTIM_FRAME_COUNT_MAX * sizeof(FLOAT32));
110 
111   if (ch_count_from_dwnmix_id != 0) {
112     memcpy(pstr_parametric_ffwd_type_drc_params->level_estim_ch_weight,
113            hDrcCoefficientsParametricDrcBs
114                ->str_parametric_drc_gain_set_params[gain_set_index]
115                .level_estim_ch_weight,
116            ch_count_from_dwnmix_id * sizeof(FLOAT32));
117   } else {
118     for (i = 0; i < pstr_parametric_ffwd_type_drc_params->audio_num_chan; i++) {
119       pstr_parametric_ffwd_type_drc_params->level_estim_ch_weight[i] =
120           (FLOAT32)channel_map[i];
121     }
122   }
123 
124   if (pstr_parametric_ffwd_type_drc_params->sub_band_domain_mode ==
125       SUBBAND_DOMAIN_MODE_OFF) {
126     err = impd_init_lvl_est_filt_time(
127         pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type,
128         p_parametricdrc_params->sampling_rate,
129         &pstr_parametric_ffwd_type_drc_params->pre_filt_coeff,
130         &pstr_parametric_ffwd_type_drc_params->rlb_filt_coeff);
131 
132     if (err) return (err);
133   } else {
134     err = impd_init_lvl_est_filt_subband(
135         pstr_parametric_ffwd_type_drc_params->level_estim_k_weighting_type,
136         p_parametricdrc_params->sampling_rate,
137         p_parametricdrc_params->sub_band_domain_mode,
138         p_parametricdrc_params->sub_band_count,
139         pstr_parametric_ffwd_type_drc_params->sub_band_compensation_type,
140         pstr_parametric_ffwd_type_drc_params->weighting_filt,
141         &pstr_parametric_ffwd_type_drc_params->filt_coeff_subband);
142 
143     if (err) return (err);
144   }
145 
146   pstr_parametric_ffwd_type_drc_params->node_count =
147       hParametricDrcTypeFeedForwardBs->node_count;
148 
149   memcpy(pstr_parametric_ffwd_type_drc_params->node_level,
150          hParametricDrcTypeFeedForwardBs->node_level,
151          pstr_parametric_ffwd_type_drc_params->node_count * sizeof(WORD32));
152   memcpy(pstr_parametric_ffwd_type_drc_params->node_gain,
153          hParametricDrcTypeFeedForwardBs->node_gain,
154          pstr_parametric_ffwd_type_drc_params->node_count * sizeof(WORD32));
155 
156   pstr_parametric_ffwd_type_drc_params->ref_level_parametric_drc =
157       hDrcCoefficientsParametricDrcBs
158           ->str_parametric_drc_gain_set_params[gain_set_index]
159           .drc_input_loudness;
160 
161   {
162     WORD32 gain_smooth_attack_time_fast =
163         hParametricDrcTypeFeedForwardBs->gain_smooth_attack_time_fast;
164     WORD32 gain_smooth_release_time_fast =
165         hParametricDrcTypeFeedForwardBs->gain_smooth_release_time_fast;
166     WORD32 gain_smooth_attack_time_slow =
167         hParametricDrcTypeFeedForwardBs->gain_smooth_attack_time_slow;
168     WORD32 gain_smooth_release_time_slow =
169         hParametricDrcTypeFeedForwardBs->gain_smooth_release_time_slow;
170     WORD32 gain_smooth_hold_off =
171         hParametricDrcTypeFeedForwardBs->gain_smooth_hold_off;
172     WORD32 sampling_rate = p_parametricdrc_params->sampling_rate;
173     WORD32 parametric_drc_frame_size =
174         p_parametricdrc_params->parametric_drc_frame_size;
175 
176     pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_fast =
177         1 -
178         (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
179                      (gain_smooth_attack_time_fast * sampling_rate * 0.001));
180     pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_fast =
181         1 -
182         (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
183                      (gain_smooth_release_time_fast * sampling_rate * 0.001));
184     pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_alpha_slow =
185         1 -
186         (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
187                      (gain_smooth_attack_time_slow * sampling_rate * 0.001));
188     pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_alpha_slow =
189         1 -
190         (FLOAT32)exp(-1.0 * parametric_drc_frame_size /
191                      (gain_smooth_release_time_slow * sampling_rate * 0.001));
192     pstr_parametric_ffwd_type_drc_params->gain_smooth_hold_off_count =
193         gain_smooth_hold_off * 256 * sampling_rate /
194         (parametric_drc_frame_size * 48000);
195     pstr_parametric_ffwd_type_drc_params->gain_smooth_attack_threshold =
196         hParametricDrcTypeFeedForwardBs->gain_smooth_attack_threshold;
197     pstr_parametric_ffwd_type_drc_params->gain_smooth_rel_threshold =
198         hParametricDrcTypeFeedForwardBs->gain_smooth_rel_threshold;
199   }
200 
201   err =
202       impd_parametric_ffwd_type_drc_reset(pstr_parametric_ffwd_type_drc_params);
203 
204   if (err) return (err);
205 
206   return 0;
207 }
208 
impd_init_parametric_drc_lim(ia_drc_config * pstr_drc_config,WORD32 instance_idx,WORD32 ch_count_from_dwnmix_id,ia_parametric_drc_params_struct * p_parametricdrc_params,pVOID * mem_ptr)209 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 
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)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 
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)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 
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)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 
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)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   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 
impd_parametric_ffwd_type_drc_reset(ia_parametric_drc_type_ff_params_struct * pstr_parametric_ffwd_type_drc_params)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 
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)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 
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)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 }
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)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 
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)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