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 <math.h>
22#include "impd_type_def.h"
23#include "impd_error_standards.h"
24
25#include "impd_drc_extr_delta_coded_info.h"
26#include "impd_drc_common.h"
27#include "impd_drc_struct.h"
28#include "impd_drc_interface.h"
29#include "impd_memory_standards.h"
30#include "impd_drc_peak_limiter.h"
31#include "impd_drc_bitbuffer.h"
32#include "impd_drc_bitstream_dec_api.h"
33#include "impd_drc_gain_dec.h"
34#include "impd_drc_filter_bank.h"
35#include "impd_drc_multi_band.h"
36#include "impd_drc_process_audio.h"
37#include "impd_parametric_drc_dec.h"
38#include "impd_drc_eq.h"
39#include "impd_drc_gain_decoder.h"
40#include "impd_drc_selection_process.h"
41#include "impd_drc_api_struct_def.h"
42#include "impd_drc_peak_limiter.h"
43#include "impd_drc_host_params.h"
44
45#define PARAMETRIC_DRC_DELAY_MAX_DEFAULT 4096
46#define EQ_DELAY_MAX_DEFAULT 256
47
48IA_ERRORCODE impd_drc_mem_api(ia_drc_api_struct *p_obj_drc, WORD32 iCmd,
49                              WORD32 iIdx, pVOID pvValue);
50
51IA_ERRORCODE impd_drc_fill_mem_tables(ia_drc_api_struct *p_obj_drc);
52
53WORD32
54impd_drc_dec_interface_process(ia_bit_buf_struct *it_bit_buff,
55                               ia_drc_interface_struct *pstr_drc_interface,
56                               UWORD8 *it_bit_buf, WORD32 num_bit_stream_bits,
57                               WORD32 *num_bits_read);
58
59WORD32
60impd_drc_dec_interface_add_effect_type(
61    ia_drc_interface_struct *pstr_drc_interface, WORD32 drc_effect_type,
62    WORD32 target_loudness, WORD32 loud_norm);
63
64#define NUM_GAIN_DEC_INSTANCES 2
65
66#define BITSTREAM_FILE_FORMAT_SPLIT 1
67#define LIM_DEFAULT_THRESHOLD (0.89125094f)
68
69static WORD32 impd_match_downmix(WORD32 downmix_id, WORD32 dec_downmix_id) {
70  WORD32 id_match = 0;
71
72  switch (dec_downmix_id) {
73    case 0:
74      id_match = (downmix_id == 0);
75      break;
76    case 1:
77      id_match = ((downmix_id == 0) || (downmix_id == 0x7F));
78      break;
79    case 2:
80      id_match = (downmix_id == 0x7F);
81      break;
82    case 3:
83      id_match = ((downmix_id != 0) && (downmix_id != 0x7F));
84      break;
85    case 4:
86      id_match = (downmix_id != 0);
87      break;
88  }
89  return id_match;
90}
91
92IA_ERRORCODE impd_drc_set_default_config(ia_drc_api_struct *p_obj_drc) {
93  p_obj_drc->str_config.bitstream_file_format = 0;
94  p_obj_drc->str_config.dec_type = 0;
95  p_obj_drc->str_config.sub_band_domain_mode = 0;
96  p_obj_drc->str_config.sub_band_count = 0;
97  p_obj_drc->str_config.sub_band_down_sampling_factor = 0;
98  p_obj_drc->str_config.sampling_rate = 0;
99  p_obj_drc->str_config.frame_size = 1024;
100  p_obj_drc->str_config.num_ch_in = -1;
101  p_obj_drc->str_config.num_ch_out = -1;
102  p_obj_drc->str_config.control_parameter_index = -1;
103  p_obj_drc->str_config.peak_limiter = 0;
104  p_obj_drc->str_config.delay_mode = 0;
105  p_obj_drc->str_config.interface_bitstream_present = 0;
106  p_obj_drc->str_config.gain_delay_samples = 0;
107  p_obj_drc->str_config.absorb_delay_on = 1;
108  p_obj_drc->str_config.subband_domain_io_flag = 0;
109  p_obj_drc->str_config.constant_delay_on = 0;
110  p_obj_drc->str_config.audio_delay_samples = 0;
111  p_obj_drc->str_config.effect_type = 0;
112  p_obj_drc->str_config.target_loudness = -24;
113  p_obj_drc->str_config.loud_norm_flag = 0;
114  p_obj_drc->str_bit_handler.byte_index_bs = 0;
115  p_obj_drc->str_bit_handler.num_bytes_bs = 0;
116  p_obj_drc->str_bit_handler.num_bits_offset_bs = 0;
117  p_obj_drc->str_bit_handler.num_bits_read_bs = 0;
118  p_obj_drc->str_bit_handler.cpy_over = 0;
119  p_obj_drc->str_bit_handler.num_bytes_bs_drc_config = 0;
120  p_obj_drc->str_bit_handler.cpy_over_ic = 0;
121  p_obj_drc->str_bit_handler.num_bytes_bs_loudness_info = 0;
122  p_obj_drc->str_bit_handler.cpy_over_il = 0;
123  p_obj_drc->str_bit_handler.num_bytes_bs_unidrc_interface = 0;
124  p_obj_drc->str_bit_handler.num_bits_read_bs_unidrc_interface = 0;
125  p_obj_drc->str_bit_handler.cpy_over_in = 0;
126  p_obj_drc->str_bit_handler.gain_stream_flag = 0;
127
128  return IA_NO_ERROR;
129}
130
131IA_ERRORCODE impd_drc_set_default_bitstream_config(
132    ia_drc_config *pstr_drc_config) {
133  WORD32 i;
134
135  pstr_drc_config->sample_rate_present = 0;
136  pstr_drc_config->sampling_rate = 0;
137  pstr_drc_config->dwnmix_instructions_count = 0;
138  pstr_drc_config->drc_coefficients_drc_count = 1;
139  pstr_drc_config->drc_instructions_uni_drc_count = 4;
140  pstr_drc_config->drc_instructions_count_plus = 5;
141  pstr_drc_config->drc_description_basic_present = 0;
142  pstr_drc_config->drc_coefficients_basic_count = 0;
143  pstr_drc_config->drc_instructions_basic_count = 0;
144  pstr_drc_config->drc_config_ext_present = 1;
145  pstr_drc_config->apply_drc = 0;
146  pstr_drc_config->str_drc_config_ext.drc_config_ext_type[0] = 2;
147  pstr_drc_config->str_drc_config_ext.ext_bit_size[0] = 345;
148  pstr_drc_config->str_drc_config_ext.parametric_drc_present = 0;
149  pstr_drc_config->str_drc_config_ext.drc_extension_v1_present = 1;
150  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0].version = 1;
151  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0].drc_location = 1;
152  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0].gain_set_count = 4;
153  for (i = 0;
154       i <
155       pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0].gain_set_count;
156       i++) {
157    pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0]
158        .gain_set_params[i]
159        .gain_interpolation_type = 1;
160    pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0]
161        .gain_set_params[i]
162        .band_count = 1;
163  }
164  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0].gain_sequence_count =
165      4;
166  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0]
167      .gain_set_params_index_for_gain_sequence[0] = 0;
168  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0]
169      .gain_set_params_index_for_gain_sequence[1] = 1;
170  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0]
171      .gain_set_params_index_for_gain_sequence[2] = 2;
172  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0]
173      .gain_set_params_index_for_gain_sequence[3] = 3;
174  pstr_drc_config->str_p_loc_drc_coefficients_uni_drc[0].gain_set_count_plus =
175      4;
176  pstr_drc_config->str_drc_instruction_str[0].drc_set_id = 1;
177  pstr_drc_config->str_drc_instruction_str[0].drc_set_complexity_level = 2;
178  pstr_drc_config->str_drc_instruction_str[0].drc_location = 1;
179  pstr_drc_config->str_drc_instruction_str[0].dwnmix_id_count = 1;
180  pstr_drc_config->str_drc_instruction_str[0].drc_set_effect = 1;
181  pstr_drc_config->str_drc_instruction_str[0].gain_set_index[1] = 1;
182  pstr_drc_config->str_drc_instruction_str[0]
183      .drc_set_target_loudness_value_lower = -63;
184  pstr_drc_config->str_drc_instruction_str[0].num_drc_ch_groups = 2;
185  pstr_drc_config->str_drc_instruction_str[0]
186      .gain_set_index_for_channel_group[1] = 1;
187  pstr_drc_config->str_drc_instruction_str[0].band_count_of_ch_group[0] = 1;
188  pstr_drc_config->str_drc_instruction_str[0].band_count_of_ch_group[1] = 1;
189  pstr_drc_config->str_drc_instruction_str[0]
190      .gain_interpolation_type_for_channel_group[0] = 1;
191  pstr_drc_config->str_drc_instruction_str[0]
192      .gain_interpolation_type_for_channel_group[1] = 1;
193  pstr_drc_config->str_drc_instruction_str[0]
194      .time_delta_min_for_channel_group[0] = 32;
195  pstr_drc_config->str_drc_instruction_str[0]
196      .time_delta_min_for_channel_group[1] = 32;
197  pstr_drc_config->str_drc_instruction_str[0].channel_group_of_ch[1] = 1;
198  pstr_drc_config->str_drc_instruction_str[0].gain_element_count = 2;
199
200  pstr_drc_config->str_drc_instruction_str[1].drc_set_id = 2;
201  pstr_drc_config->str_drc_instruction_str[1].drc_set_complexity_level = 2;
202  pstr_drc_config->str_drc_instruction_str[1].drc_location = 1;
203  pstr_drc_config->str_drc_instruction_str[1].dwnmix_id_count = 1;
204  pstr_drc_config->str_drc_instruction_str[1].drc_set_effect = 2;
205  pstr_drc_config->str_drc_instruction_str[1].gain_set_index[0] = 1;
206  pstr_drc_config->str_drc_instruction_str[1].gain_set_index[1] = 2;
207  pstr_drc_config->str_drc_instruction_str[1]
208      .drc_set_target_loudness_value_lower = -63;
209  pstr_drc_config->str_drc_instruction_str[1].num_drc_ch_groups = 2;
210  pstr_drc_config->str_drc_instruction_str[1]
211      .gain_set_index_for_channel_group[0] = 1;
212  pstr_drc_config->str_drc_instruction_str[1]
213      .gain_set_index_for_channel_group[1] = 2;
214  pstr_drc_config->str_drc_instruction_str[1].band_count_of_ch_group[0] = 1;
215  pstr_drc_config->str_drc_instruction_str[1].band_count_of_ch_group[1] = 1;
216  pstr_drc_config->str_drc_instruction_str[1]
217      .gain_interpolation_type_for_channel_group[0] = 1;
218  pstr_drc_config->str_drc_instruction_str[1]
219      .gain_interpolation_type_for_channel_group[1] = 1;
220  pstr_drc_config->str_drc_instruction_str[1]
221      .time_delta_min_for_channel_group[0] = 32;
222  pstr_drc_config->str_drc_instruction_str[1]
223      .time_delta_min_for_channel_group[1] = 32;
224  pstr_drc_config->str_drc_instruction_str[1].channel_group_of_ch[1] = 1;
225  pstr_drc_config->str_drc_instruction_str[1].gain_element_count = 2;
226
227  pstr_drc_config->str_drc_instruction_str[2].drc_set_id = 3;
228  pstr_drc_config->str_drc_instruction_str[2].drc_set_complexity_level = 2;
229  pstr_drc_config->str_drc_instruction_str[2].drc_location = 1;
230  pstr_drc_config->str_drc_instruction_str[2].dwnmix_id_count = 1;
231  pstr_drc_config->str_drc_instruction_str[2].drc_set_effect = 4;
232  pstr_drc_config->str_drc_instruction_str[2].gain_set_index[0] = 2;
233  pstr_drc_config->str_drc_instruction_str[2].gain_set_index[1] = 3;
234  pstr_drc_config->str_drc_instruction_str[2]
235      .drc_set_target_loudness_value_lower = -63;
236  pstr_drc_config->str_drc_instruction_str[2].num_drc_ch_groups = 2;
237  pstr_drc_config->str_drc_instruction_str[2]
238      .gain_set_index_for_channel_group[0] = 2;
239  pstr_drc_config->str_drc_instruction_str[2]
240      .gain_set_index_for_channel_group[1] = 3;
241  pstr_drc_config->str_drc_instruction_str[2].band_count_of_ch_group[0] = 1;
242  pstr_drc_config->str_drc_instruction_str[2].band_count_of_ch_group[1] = 1;
243  pstr_drc_config->str_drc_instruction_str[2]
244      .gain_interpolation_type_for_channel_group[0] = 1;
245  pstr_drc_config->str_drc_instruction_str[2]
246      .gain_interpolation_type_for_channel_group[1] = 1;
247  pstr_drc_config->str_drc_instruction_str[2]
248      .time_delta_min_for_channel_group[0] = 32;
249  pstr_drc_config->str_drc_instruction_str[2]
250      .time_delta_min_for_channel_group[1] = 32;
251  pstr_drc_config->str_drc_instruction_str[2].channel_group_of_ch[1] = 1;
252  pstr_drc_config->str_drc_instruction_str[2].gain_element_count = 2;
253
254  pstr_drc_config->str_drc_instruction_str[3].drc_set_id = 4;
255  pstr_drc_config->str_drc_instruction_str[3].drc_set_complexity_level = 2;
256  pstr_drc_config->str_drc_instruction_str[3].drc_location = 1;
257  pstr_drc_config->str_drc_instruction_str[3].dwnmix_id_count = 1;
258  pstr_drc_config->str_drc_instruction_str[3].drc_set_effect = 32;
259  pstr_drc_config->str_drc_instruction_str[3].gain_set_index[0] = 3;
260  pstr_drc_config->str_drc_instruction_str[3].gain_set_index[1] = 0;
261  pstr_drc_config->str_drc_instruction_str[3]
262      .drc_set_target_loudness_value_lower = -63;
263  pstr_drc_config->str_drc_instruction_str[3].num_drc_ch_groups = 2;
264  pstr_drc_config->str_drc_instruction_str[3]
265      .gain_set_index_for_channel_group[0] = 3;
266  pstr_drc_config->str_drc_instruction_str[3]
267      .gain_set_index_for_channel_group[1] = 0;
268  pstr_drc_config->str_drc_instruction_str[3].band_count_of_ch_group[0] = 1;
269  pstr_drc_config->str_drc_instruction_str[3].band_count_of_ch_group[1] = 1;
270  pstr_drc_config->str_drc_instruction_str[3]
271      .gain_interpolation_type_for_channel_group[0] = 1;
272  pstr_drc_config->str_drc_instruction_str[3]
273      .gain_interpolation_type_for_channel_group[1] = 1;
274  pstr_drc_config->str_drc_instruction_str[3]
275      .time_delta_min_for_channel_group[0] = 32;
276  pstr_drc_config->str_drc_instruction_str[3]
277      .time_delta_min_for_channel_group[1] = 32;
278  pstr_drc_config->str_drc_instruction_str[3].channel_group_of_ch[1] = 1;
279  pstr_drc_config->str_drc_instruction_str[3].gain_element_count = 2;
280
281  pstr_drc_config->str_drc_instruction_str[4].drc_set_id = -1;
282  pstr_drc_config->str_drc_instruction_str[4].dwnmix_id_count = 1;
283  pstr_drc_config->channel_layout.base_channel_count = 2;
284
285  return IA_NO_ERROR;
286}
287
288IA_ERRORCODE impd_drc_set_struct_pointer(ia_drc_api_struct *p_obj_drc) {
289  SIZE_T persistant_ptr = (SIZE_T)p_obj_drc->p_state->persistant_ptr;
290
291  p_obj_drc->str_payload.pstr_bitstream_dec =
292      (ia_drc_bits_dec_struct *)persistant_ptr;
293  persistant_ptr = (SIZE_T)persistant_ptr + sizeof(ia_drc_bits_dec_struct) + 32;
294
295  p_obj_drc->str_payload.pstr_gain_dec[0] =
296      (ia_drc_gain_dec_struct *)persistant_ptr;
297  persistant_ptr = (SIZE_T)persistant_ptr + sizeof(ia_drc_gain_dec_struct) + 32;
298
299  p_obj_drc->str_payload.pstr_gain_dec[1] =
300      (ia_drc_gain_dec_struct *)persistant_ptr;
301  persistant_ptr = (SIZE_T)persistant_ptr + sizeof(ia_drc_gain_dec_struct) + 32;
302
303  p_obj_drc->str_payload.pstr_loudness_info =
304      (ia_drc_loudness_info_set_struct *)persistant_ptr;
305  persistant_ptr =
306      (SIZE_T)persistant_ptr + sizeof(ia_drc_loudness_info_set_struct) + 32;
307
308  p_obj_drc->str_payload.pstr_drc_gain = (ia_drc_gain_struct *)persistant_ptr;
309  ;
310  persistant_ptr = (SIZE_T)persistant_ptr + sizeof(ia_drc_gain_struct) + 32;
311
312  p_obj_drc->str_payload.pstr_drc_interface =
313      (ia_drc_interface_struct *)persistant_ptr;
314  persistant_ptr =
315      (SIZE_T)persistant_ptr + sizeof(ia_drc_interface_struct) + 32;
316
317  p_obj_drc->str_payload.pstr_drc_config = (ia_drc_config *)persistant_ptr;
318  persistant_ptr = (SIZE_T)persistant_ptr + sizeof(ia_drc_config) + 32;
319
320  p_obj_drc->str_payload.pstr_selection_proc =
321      (ia_drc_sel_pro_struct *)persistant_ptr;
322  persistant_ptr = (SIZE_T)persistant_ptr + sizeof(ia_drc_sel_pro_struct) + 32;
323
324  p_obj_drc->str_bit_handler.it_bit_buf = (UWORD8 *)persistant_ptr;
325  persistant_ptr = (SIZE_T)persistant_ptr + 32 * 1024; /*varify the sizelater*/
326
327  p_obj_drc->str_payload.pstr_drc_sel_proc_params =
328      (ia_drc_sel_proc_params_struct *)persistant_ptr;
329  persistant_ptr =
330      (SIZE_T)persistant_ptr + sizeof(ia_drc_sel_proc_params_struct);
331
332  p_obj_drc->str_payload.pstr_drc_sel_proc_output =
333      (ia_drc_sel_proc_output_struct *)persistant_ptr;
334  persistant_ptr = (SIZE_T)persistant_ptr +
335                   sizeof(ia_drc_sel_proc_output_struct) + 16 * 1024;
336
337  p_obj_drc->str_bit_handler.bitstream_drc_config = (UWORD8 *)persistant_ptr;
338  persistant_ptr = (SIZE_T)persistant_ptr + 8 * 1024;
339
340  p_obj_drc->str_bit_handler.bitstream_loudness_info = (UWORD8 *)persistant_ptr;
341  persistant_ptr = (SIZE_T)persistant_ptr + 8 * 1024;
342
343  p_obj_drc->str_bit_handler.bitstream_unidrc_interface =
344      (UWORD8 *)persistant_ptr;
345  persistant_ptr = (SIZE_T)persistant_ptr + 8 * 1024;
346
347  p_obj_drc->str_payload.pstr_peak_limiter =
348      (ia_drc_peak_limiter_struct *)persistant_ptr;
349  persistant_ptr =
350      (SIZE_T)persistant_ptr + sizeof(ia_drc_peak_limiter_struct) + 32;
351
352  p_obj_drc->str_payload.pstr_peak_limiter->buffer =
353      (FLOAT32 *)((SIZE_T)p_obj_drc->str_payload.pstr_peak_limiter +
354                  sizeof(ia_drc_peak_limiter_struct) + 32);
355  persistant_ptr = (SIZE_T)persistant_ptr + 16 * 1024;
356
357  p_obj_drc->str_payload.pstr_qmf_filter =
358      (ia_drc_qmf_filt_struct *)persistant_ptr;
359  persistant_ptr = (SIZE_T)persistant_ptr + sizeof(ia_drc_qmf_filt_struct) + 32;
360
361  p_obj_drc->str_payload.pstr_qmf_filter->ana_buff = (FLOAT64 *)persistant_ptr;
362  persistant_ptr = (SIZE_T)persistant_ptr + 16 * 1024;
363
364  p_obj_drc->str_payload.pstr_qmf_filter->syn_buff = (FLOAT64 *)persistant_ptr;
365  persistant_ptr = (SIZE_T)persistant_ptr + 16 * 1024;
366
367  p_obj_drc->p_state->persistant_ptr = (pVOID)persistant_ptr;
368  return IA_NO_ERROR;
369}
370
371VOID init_qmf_filt_bank(ia_drc_qmf_filt_struct *qmf_filt) {
372  WORD32 l, k;
373
374  FLOAT64 gain_ana = 64.0 / QMF_FILT_RESOLUTION;
375  FLOAT64 gain_syn = 1.0 / 64.0;
376  for (l = 0; l < 2 * QMF_FILT_RESOLUTION; l++) {
377    for (k = 0; k < QMF_FILT_RESOLUTION; k++) {
378      qmf_filt->syn_tab_real[l][k] =
379          gain_syn * cos((0.0245436926) * (k + 0.5) * (2 * l - 255.0));
380      qmf_filt->syn_tab_imag[l][k] =
381          gain_syn * sin((0.0245436926) * (k + 0.5) * (2 * l - 255.0));
382      qmf_filt->ana_tab_real[k][l] =
383          gain_ana * cos((0.0245436926) * (k + 0.5) * (2 * l - 1.0));
384      qmf_filt->ana_tab_imag[k][l] =
385          gain_ana * sin((0.0245436926) * (k + 0.5) * (2 * l - 1.0));
386    }
387  }
388}
389
390IA_ERRORCODE impd_drc_init(ia_drc_api_struct *p_obj_drc) {
391  IA_ERRORCODE err_code = IA_NO_ERROR;
392  WORD32 i, j;
393
394  pVOID persistant_ptr = p_obj_drc->p_state->persistant_ptr;
395
396  struct ia_bit_buf_struct *it_bit_buff;
397
398  WORD32 decDownmixIdList[NUM_GAIN_DEC_INSTANCES] = {0, 4};
399
400  p_obj_drc->p_state->delay_in_output = 0;
401  p_obj_drc->str_payload.pstr_selection_proc->first_frame = 1;
402
403  p_obj_drc->pstr_bit_buf = impd_create_init_bit_buf(
404      &p_obj_drc->str_bit_buf, p_obj_drc->str_bit_handler.it_bit_buf,
405      p_obj_drc->str_bit_handler.num_bytes_bs / 8);
406  it_bit_buff = p_obj_drc->pstr_bit_buf;
407
408  err_code = impd_init_drc_bitstream_dec(
409      p_obj_drc->str_payload.pstr_bitstream_dec,
410      p_obj_drc->str_config.sampling_rate, p_obj_drc->str_config.frame_size,
411      p_obj_drc->str_config.delay_mode, -1, 0);
412
413  for (i = 0; i < NUM_GAIN_DEC_INSTANCES; i++) {
414    err_code = impd_init_drc_decode(p_obj_drc->str_config.frame_size,
415                                    p_obj_drc->str_config.sampling_rate,
416                                    p_obj_drc->str_config.gain_delay_samples,
417                                    p_obj_drc->str_config.delay_mode,
418                                    p_obj_drc->str_config.sub_band_domain_mode,
419                                    p_obj_drc->str_payload.pstr_gain_dec[i]);
420  }
421
422  if (p_obj_drc->str_config.interface_bitstream_present) {
423    err_code = impd_drc_dec_interface_add_effect_type(
424        p_obj_drc->str_payload.pstr_drc_interface,
425        p_obj_drc->str_config.effect_type,
426        p_obj_drc->str_config.target_loudness,
427        p_obj_drc->str_config.loud_norm_flag);
428
429    if (err_code != IA_NO_ERROR) return err_code;
430
431    err_code = impd_drc_uni_selction_proc_init(
432        p_obj_drc->str_payload.pstr_selection_proc, 0,
433        p_obj_drc->str_payload.pstr_drc_interface,
434        p_obj_drc->str_config.sub_band_domain_mode);
435    if (err_code != IA_NO_ERROR) return err_code;
436
437    if (p_obj_drc->str_payload.pstr_drc_interface
438            ->loudness_norm_parameter_interface_flag &&
439        p_obj_drc->str_payload.pstr_drc_interface->loudness_norm_param_interface
440            .peak_limiter) {
441      p_obj_drc->str_config.peak_limiter = 1;
442    }
443  } else {
444    err_code = impd_set_default_params_selection_process(
445        p_obj_drc->str_payload.pstr_drc_sel_proc_params);
446    if (err_code != IA_NO_ERROR) return err_code;
447    err_code =
448        impd_set_custom_params(p_obj_drc->str_config.control_parameter_index,
449                               p_obj_drc->str_payload.pstr_drc_sel_proc_params);
450    if (err_code != IA_NO_ERROR) return err_code;
451    err_code = impd_eval_custom_params_selection_process(
452        p_obj_drc->str_payload.pstr_drc_sel_proc_params);
453    if (err_code != IA_NO_ERROR) return err_code;
454    err_code = impd_drc_uni_selction_proc_init(
455        p_obj_drc->str_payload.pstr_selection_proc,
456        p_obj_drc->str_payload.pstr_drc_sel_proc_params, 0,
457        p_obj_drc->str_config.sub_band_domain_mode);
458    if (err_code != IA_NO_ERROR) return err_code;
459
460    if (p_obj_drc->str_payload.pstr_drc_sel_proc_params->peak_limiter) {
461      p_obj_drc->str_config.peak_limiter = 1;
462    }
463  }
464  p_obj_drc->str_payload.pstr_loudness_info->loudness_info_album_count = 0;
465  p_obj_drc->str_payload.pstr_loudness_info->loudness_info_count = 0;
466  p_obj_drc->str_payload.pstr_loudness_info->loudness_info_set_ext_present = 0;
467  p_obj_drc->p_state->ui_exe_done = 0;
468
469  if (p_obj_drc->str_config.bitstream_file_format ==
470      BITSTREAM_FILE_FORMAT_SPLIT) {
471    err_code = impd_process_drc_bitstream_dec_config(
472        p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
473        p_obj_drc->str_payload.pstr_drc_config,
474        &p_obj_drc->str_bit_handler.bitstream_drc_config[0],
475        p_obj_drc->str_bit_handler.num_bytes_bs_drc_config);
476
477    if (err_code == 1) {
478      err_code = impd_drc_set_default_bitstream_config(
479          p_obj_drc->str_payload.pstr_drc_config);
480      p_obj_drc->str_payload.pstr_drc_config->channel_layout
481          .base_channel_count = p_obj_drc->str_config.num_ch_in;
482    }
483
484    if (err_code != IA_NO_ERROR) return err_code;
485    err_code = impd_process_drc_bitstream_dec_loudness_info_set(
486        p_obj_drc->pstr_bit_buf, p_obj_drc->str_payload.pstr_loudness_info,
487        &p_obj_drc->str_bit_handler.bitstream_loudness_info[0],
488        p_obj_drc->str_bit_handler.num_bytes_bs_loudness_info);
489    if (err_code != IA_NO_ERROR) return err_code;
490
491  } else {
492    err_code = impd_process_drc_bitstream_dec(
493        p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
494        p_obj_drc->str_payload.pstr_drc_config,
495        p_obj_drc->str_payload.pstr_loudness_info,
496        &p_obj_drc->str_bit_handler
497             .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
498        p_obj_drc->str_bit_handler.num_bytes_bs,
499        p_obj_drc->str_bit_handler.num_bits_offset_bs,
500        &p_obj_drc->str_bit_handler.num_bits_read_bs);
501
502    if (err_code > PROC_COMPLETE) return -1;
503
504    p_obj_drc->str_bit_handler.num_bytes_read_bs =
505        (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
506    p_obj_drc->str_bit_handler.num_bits_offset_bs =
507        (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
508    p_obj_drc->str_bit_handler.byte_index_bs +=
509        p_obj_drc->str_bit_handler.num_bytes_read_bs;
510    p_obj_drc->str_bit_handler.num_bytes_bs -=
511        p_obj_drc->str_bit_handler.num_bytes_read_bs;
512  }
513
514  err_code = impd_drc_uni_sel_proc_process(
515      p_obj_drc->str_payload.pstr_selection_proc,
516      p_obj_drc->str_payload.pstr_drc_config,
517      p_obj_drc->str_payload.pstr_loudness_info,
518      p_obj_drc->str_payload.pstr_drc_sel_proc_output);
519  if (err_code != IA_NO_ERROR) return err_code;
520
521  for (i = 0; i < NUM_GAIN_DEC_INSTANCES; i++) {
522    WORD32 audio_num_chan = 0;
523    WORD32 numMatchingDrcSets = 0;
524    WORD32 matchingDrcSetIds[3], matchingDownmixIds[3];
525    for (j = 0;
526         j < p_obj_drc->str_payload.pstr_drc_sel_proc_output->num_sel_drc_sets;
527         j++) {
528      if (impd_match_downmix(p_obj_drc->str_payload.pstr_drc_sel_proc_output
529                                 ->sel_downmix_ids[j],
530                             decDownmixIdList[i])) {
531        matchingDrcSetIds[numMatchingDrcSets] =
532            p_obj_drc->str_payload.pstr_drc_sel_proc_output->sel_drc_set_ids[j];
533        matchingDownmixIds[numMatchingDrcSets] =
534            p_obj_drc->str_payload.pstr_drc_sel_proc_output->sel_downmix_ids[j];
535        numMatchingDrcSets++;
536      }
537    }
538    if (i == 0) {
539      if (p_obj_drc->str_config.num_ch_in !=
540          p_obj_drc->str_payload.pstr_drc_sel_proc_output->base_channel_count)
541
542        return -1;
543      audio_num_chan = p_obj_drc->str_config.num_ch_in;
544    } else if (i == 1) {
545      p_obj_drc->str_config.num_ch_out =
546          p_obj_drc->str_payload.pstr_drc_sel_proc_output->target_channel_count;
547      audio_num_chan = p_obj_drc->str_config.num_ch_out;
548    }
549
550    err_code = impd_init_drc_decode_post_config(
551        audio_num_chan, matchingDrcSetIds, matchingDownmixIds,
552        numMatchingDrcSets,
553        p_obj_drc->str_payload.pstr_drc_sel_proc_output->sel_eq_set_ids[i]
554
555        ,
556        p_obj_drc->str_payload.pstr_gain_dec[i],
557        p_obj_drc->str_payload.pstr_drc_config,
558        p_obj_drc->str_payload.pstr_loudness_info, &persistant_ptr);
559
560    impd_get_parametric_drc_delay(
561        p_obj_drc->str_payload.pstr_gain_dec[i],
562        p_obj_drc->str_payload.pstr_drc_config,
563        &p_obj_drc->str_config.parametric_drc_delay_gain_dec_instance,
564        &p_obj_drc->str_config.parametric_drc_delay_max);
565    impd_get_eq_delay(p_obj_drc->str_payload.pstr_gain_dec[i],
566                      p_obj_drc->str_payload.pstr_drc_config,
567                      &p_obj_drc->str_config.eq_delay_gain_dec_instance,
568                      &p_obj_drc->str_config.eq_delay_max);
569    p_obj_drc->str_config.parametric_drc_delay +=
570        p_obj_drc->str_config.parametric_drc_delay_gain_dec_instance;
571    p_obj_drc->str_config.eq_delay +=
572        p_obj_drc->str_config.eq_delay_gain_dec_instance;
573  }
574
575  {
576    if (p_obj_drc->str_config.parametric_drc_delay_max == -1) {
577      p_obj_drc->str_config.parametric_drc_delay_max =
578          PARAMETRIC_DRC_DELAY_MAX_DEFAULT;
579    }
580    if (p_obj_drc->str_config.eq_delay_max == -1) {
581      p_obj_drc->str_config.eq_delay_max = EQ_DELAY_MAX_DEFAULT;
582    }
583
584    if (!p_obj_drc->str_config.constant_delay_on) {
585      p_obj_drc->p_state->delay_in_output +=
586          p_obj_drc->str_config.parametric_drc_delay +
587          p_obj_drc->str_config.eq_delay +
588          p_obj_drc->str_config.audio_delay_samples;
589      p_obj_drc->str_config.delay_line_samples =
590          p_obj_drc->str_config.audio_delay_samples;
591
592      if (!p_obj_drc->str_config.absorb_delay_on) {
593        p_obj_drc->p_state->delay_in_output = 0;
594      }
595    } else {
596      p_obj_drc->p_state->delay_in_output +=
597          p_obj_drc->str_config.parametric_drc_delay_max +
598          p_obj_drc->str_config.eq_delay_max +
599          p_obj_drc->str_config.audio_delay_samples;
600      p_obj_drc->str_config.delay_line_samples =
601          p_obj_drc->p_state->delay_in_output -
602          p_obj_drc->str_config.parametric_drc_delay +
603          p_obj_drc->str_config.eq_delay;
604
605      if (!p_obj_drc->str_config.absorb_delay_on) {
606        p_obj_drc->p_state->delay_in_output = 0;
607      }
608    }
609  }
610  if (p_obj_drc->str_config.dec_type == 1) {
611    init_qmf_filt_bank(p_obj_drc->str_payload.pstr_qmf_filter);
612  }
613
614  if (p_obj_drc->str_config.peak_limiter) {
615    impd_peak_limiter_init(
616        p_obj_drc->str_payload.pstr_peak_limiter, DEFAULT_ATTACK_TIME_MS,
617        DEFAULT_RELEASE_TIME_MS, LIM_DEFAULT_THRESHOLD,
618        p_obj_drc->str_config.num_ch_out, p_obj_drc->str_config.sampling_rate,
619        p_obj_drc->str_payload.pstr_peak_limiter->buffer);
620  }
621
622  return IA_NO_ERROR;
623}
624