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