/src/libxaac/decoder/drc_src/impd_drc_dec.c
Line | Count | Source |
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 "impd_type_def.h" |
22 | | #include "impd_drc_extr_delta_coded_info.h" |
23 | | #include "impd_drc_common.h" |
24 | | #include "impd_drc_struct.h" |
25 | | #include "impd_parametric_drc_dec.h" |
26 | | #include "impd_drc_gain_dec.h" |
27 | | #include "impd_drc_filter_bank.h" |
28 | | #include "impd_drc_multi_band.h" |
29 | | |
30 | | WORD32 impd_init_drc_params(WORD32 frame_size, WORD32 sample_rate, |
31 | | WORD32 gain_delay_samples, WORD32 delay_mode, |
32 | | WORD32 sub_band_domain_mode, |
33 | 4.44k | ia_drc_params_struct* ia_drc_params_struct) { |
34 | 4.44k | WORD32 k; |
35 | 4.44k | if (frame_size < 1 || frame_size > AUDIO_CODEC_FRAME_SIZE_MAX) { |
36 | 0 | return -1; |
37 | 0 | } |
38 | | |
39 | 4.44k | if (sample_rate < 1000) { |
40 | 0 | return -1; |
41 | 0 | } |
42 | | |
43 | 4.44k | ia_drc_params_struct->drc_frame_size = frame_size; |
44 | | |
45 | 4.44k | if (ia_drc_params_struct->drc_frame_size < 0.001f * sample_rate) { |
46 | 0 | return -1; |
47 | 0 | } |
48 | | |
49 | 4.44k | ia_drc_params_struct->sample_rate = sample_rate; |
50 | | |
51 | 4.44k | ia_drc_params_struct->delta_tmin_default = impd_get_delta_tmin(sample_rate); |
52 | | |
53 | 4.44k | if (ia_drc_params_struct->delta_tmin_default > |
54 | 4.44k | ia_drc_params_struct->drc_frame_size) { |
55 | 0 | return -1; |
56 | 0 | } |
57 | | |
58 | 4.44k | if ((delay_mode != DELAY_MODE_REGULAR_DELAY) && |
59 | 0 | (delay_mode != DELAY_MODE_LOW_DELAY)) { |
60 | 0 | return -1; |
61 | 0 | } |
62 | | |
63 | 4.44k | ia_drc_params_struct->delay_mode = delay_mode; |
64 | | |
65 | 4.44k | ia_drc_params_struct->drc_set_counter = 0; |
66 | 4.44k | ia_drc_params_struct->multiband_sel_drc_idx = -1; |
67 | | |
68 | 17.7k | for (k = 0; k < SEL_DRC_COUNT; k++) { |
69 | 13.3k | ia_drc_params_struct->sel_drc_array[k].drc_instructions_index = -1; |
70 | 13.3k | ia_drc_params_struct->sel_drc_array[k].dwnmix_instructions_index = -1; |
71 | 13.3k | ia_drc_params_struct->sel_drc_array[k].drc_coeff_idx = -1; |
72 | 13.3k | } |
73 | | |
74 | 4.44k | if ((gain_delay_samples > MAX_SIGNAL_DELAY) || (gain_delay_samples < 0)) { |
75 | 0 | return -1; |
76 | 4.44k | } else { |
77 | 4.44k | ia_drc_params_struct->gain_delay_samples = gain_delay_samples; |
78 | 4.44k | } |
79 | | |
80 | 4.44k | switch (sub_band_domain_mode) { |
81 | 4.44k | case SUBBAND_DOMAIN_MODE_OFF: |
82 | 4.44k | case SUBBAND_DOMAIN_MODE_QMF64: |
83 | 4.44k | case SUBBAND_DOMAIN_MODE_QMF71: |
84 | 4.44k | case SUBBAND_DOMAIN_MODE_STFT256: |
85 | 4.44k | ia_drc_params_struct->sub_band_domain_mode = sub_band_domain_mode; |
86 | 4.44k | break; |
87 | 0 | default: |
88 | 0 | return -1; |
89 | 0 | break; |
90 | 4.44k | } |
91 | | |
92 | 4.44k | ia_drc_params_struct->parametric_drc_delay = 0; |
93 | 4.44k | ia_drc_params_struct->eq_delay = 0; |
94 | | |
95 | 4.44k | return 0; |
96 | 4.44k | } |
97 | | |
98 | | WORD32 impd_select_drc_coefficients( |
99 | | ia_drc_config* drc_config, ia_uni_drc_coeffs_struct** drc_coefficients_drc, |
100 | 253 | WORD32* drc_coefficients_selected) { |
101 | 253 | WORD32 i; |
102 | 253 | WORD32 cof1 = -1; |
103 | 253 | WORD32 cof0 = -1; |
104 | 506 | for (i = 0; i < drc_config->drc_coefficients_drc_count; i++) { |
105 | 253 | if (drc_config->str_p_loc_drc_coefficients_uni_drc[i].drc_location == 1) { |
106 | 253 | if (drc_config->str_p_loc_drc_coefficients_uni_drc[i].version == 0) { |
107 | 0 | cof0 = i; |
108 | 0 | *drc_coefficients_selected = cof0; |
109 | 253 | } else { |
110 | 253 | cof1 = i; |
111 | 253 | *drc_coefficients_selected = cof1; |
112 | 253 | } |
113 | 253 | } |
114 | 253 | } |
115 | | |
116 | 253 | if (cof1 >= 0) { |
117 | 253 | *drc_coefficients_drc = |
118 | 253 | &(drc_config->str_p_loc_drc_coefficients_uni_drc[cof1]); |
119 | 253 | } else if (cof0 >= 0) { |
120 | 0 | *drc_coefficients_drc = |
121 | 0 | &(drc_config->str_p_loc_drc_coefficients_uni_drc[cof0]); |
122 | 0 | } else { |
123 | 0 | *drc_coefficients_drc = NULL; |
124 | 0 | } |
125 | | |
126 | 253 | return 0; |
127 | 253 | } |
128 | | |
129 | | WORD32 impd_init_selected_drc_set( |
130 | | ia_drc_config* drc_config, ia_drc_params_struct* ia_drc_params_struct, |
131 | | ia_parametric_drc_params_struct* p_parametric_drc_params, |
132 | | WORD32 audio_num_chan, WORD32 drc_set_id_selected, |
133 | | WORD32 downmix_id_selected, ia_filter_banks_struct* ia_filter_banks_struct, |
134 | | ia_overlap_params_struct* pstr_overlap_params |
135 | | |
136 | | , |
137 | 253 | shape_filter_block* shape_filter_block) { |
138 | 253 | WORD32 g, n, c, err = 0; |
139 | 253 | WORD32 channel_count = 0; |
140 | 253 | WORD32 i; |
141 | | |
142 | 253 | ia_drc_instructions_struct* drc_instructions_uni_drc = NULL; |
143 | 253 | ia_uni_drc_coeffs_struct* drc_coefficients_uni_drc = NULL; |
144 | 253 | WORD32 selected_drc_is_multiband = 0; |
145 | 253 | WORD32 drc_instructions_selected = -1; |
146 | 253 | WORD32 downmix_instructions_selected = -1; |
147 | 253 | WORD32 drc_coefficients_selected = -1; |
148 | 253 | p_parametric_drc_params->parametric_drc_instance_count = 0; |
149 | | |
150 | 253 | if (drc_config->drc_coefficients_drc_count && |
151 | 253 | drc_config->str_p_loc_drc_coefficients_uni_drc->drc_frame_size_present) { |
152 | 0 | if (drc_config->str_p_loc_drc_coefficients_uni_drc->drc_frame_size != |
153 | 0 | ia_drc_params_struct->drc_frame_size) { |
154 | 0 | return -1; |
155 | 0 | } |
156 | 0 | } |
157 | | |
158 | 690 | for (n = 0; n < drc_config->drc_instructions_count_plus; n++) { |
159 | 690 | if (drc_config->str_drc_instruction_str[n].drc_set_id == |
160 | 690 | drc_set_id_selected) |
161 | 253 | break; |
162 | 690 | } |
163 | 253 | if (n == drc_config->drc_instructions_count_plus) { |
164 | 0 | return -1; |
165 | 0 | } |
166 | 253 | drc_instructions_selected = n; |
167 | 253 | drc_instructions_uni_drc = |
168 | 253 | &(drc_config->str_drc_instruction_str[drc_instructions_selected]); |
169 | | |
170 | 253 | if (downmix_id_selected == ID_FOR_BASE_LAYOUT) { |
171 | 253 | channel_count = drc_config->channel_layout.base_channel_count; |
172 | 253 | } else if (downmix_id_selected == ID_FOR_ANY_DOWNMIX) { |
173 | 0 | channel_count = audio_num_chan; |
174 | 0 | } else { |
175 | 0 | for (n = 0; n < drc_config->dwnmix_instructions_count; n++) { |
176 | 0 | if (drc_config->dwnmix_instructions[n].downmix_id == downmix_id_selected) |
177 | 0 | break; |
178 | 0 | } |
179 | 0 | if (n == drc_config->dwnmix_instructions_count) { |
180 | 0 | return (UNEXPECTED_ERROR); |
181 | 0 | } |
182 | 0 | channel_count = drc_config->dwnmix_instructions[n].target_channel_count; |
183 | |
|
184 | 0 | downmix_instructions_selected = n; |
185 | 0 | } |
186 | 253 | drc_instructions_uni_drc->audio_num_chan = channel_count; |
187 | | |
188 | 253 | if (drc_instructions_uni_drc->drc_set_id <= 0) { |
189 | 0 | drc_coefficients_selected = 0; |
190 | 253 | } else { |
191 | 253 | err = impd_select_drc_coefficients(drc_config, &drc_coefficients_uni_drc, |
192 | 253 | &drc_coefficients_selected); |
193 | 253 | if (err) return err; |
194 | 253 | } |
195 | | |
196 | 253 | ia_drc_params_struct->sel_drc_array[ia_drc_params_struct->drc_set_counter] |
197 | 253 | .drc_instructions_index = drc_instructions_selected; |
198 | 253 | ia_drc_params_struct->sel_drc_array[ia_drc_params_struct->drc_set_counter] |
199 | 253 | .dwnmix_instructions_index = downmix_instructions_selected; |
200 | 253 | ia_drc_params_struct->sel_drc_array[ia_drc_params_struct->drc_set_counter] |
201 | 253 | .drc_coeff_idx = drc_coefficients_selected; |
202 | | |
203 | 253 | if ((drc_instructions_uni_drc->downmix_id[0] == ID_FOR_ANY_DOWNMIX) || |
204 | 253 | (drc_instructions_uni_drc->dwnmix_id_count > 1)) { |
205 | 0 | WORD32 idx = drc_instructions_uni_drc->gain_set_index[0]; |
206 | 0 | for (c = 0; c < drc_instructions_uni_drc->audio_num_chan; c++) { |
207 | 0 | drc_instructions_uni_drc->channel_group_of_ch[c] = (idx >= 0) ? 0 : -1; |
208 | 0 | } |
209 | 0 | } |
210 | | |
211 | 759 | for (g = 0; g < drc_instructions_uni_drc->num_drc_ch_groups; g++) { |
212 | 506 | drc_instructions_uni_drc->num_chan_per_ch_group[g] = 0; |
213 | 1.26k | for (c = 0; c < drc_instructions_uni_drc->audio_num_chan; c++) { |
214 | 754 | if (drc_instructions_uni_drc->channel_group_of_ch[c] == g) { |
215 | 377 | drc_instructions_uni_drc->num_chan_per_ch_group[g]++; |
216 | 377 | } |
217 | 754 | } |
218 | 506 | } |
219 | | |
220 | 253 | if (drc_instructions_uni_drc->drc_set_effect & |
221 | 253 | (EFFECT_BIT_DUCK_OTHER | EFFECT_BIT_DUCK_SELF)) { |
222 | 0 | drc_instructions_uni_drc->multiband_audio_sig_count = |
223 | 0 | drc_instructions_uni_drc->audio_num_chan; |
224 | 253 | } else { |
225 | 253 | drc_instructions_uni_drc->multiband_audio_sig_count = 0; |
226 | 630 | for (c = 0; c < drc_instructions_uni_drc->audio_num_chan; c++) { |
227 | 377 | g = drc_instructions_uni_drc->channel_group_of_ch[c]; |
228 | 377 | if (g < 0) { |
229 | 0 | drc_instructions_uni_drc->multiband_audio_sig_count++; |
230 | 377 | } else { |
231 | 377 | drc_instructions_uni_drc->multiband_audio_sig_count += |
232 | 377 | drc_instructions_uni_drc->band_count_of_ch_group[g]; |
233 | 377 | } |
234 | 377 | } |
235 | 253 | } |
236 | | |
237 | 759 | for (g = 0; g < drc_instructions_uni_drc->num_drc_ch_groups; g++) { |
238 | 506 | if (g == 0) { |
239 | 253 | drc_instructions_uni_drc->parametric_drc_look_ahead_samples_max = 0; |
240 | 253 | } |
241 | 506 | if (drc_instructions_uni_drc->ch_group_parametric_drc_flag[g] == 0) { |
242 | 506 | if (drc_instructions_uni_drc->band_count_of_ch_group[g] > 1) { |
243 | 0 | if (ia_drc_params_struct->multiband_sel_drc_idx != -1) { |
244 | 0 | return (UNEXPECTED_ERROR); |
245 | 0 | } |
246 | 0 | selected_drc_is_multiband = 1; |
247 | 0 | } |
248 | 506 | } else { |
249 | 0 | WORD32 gain_set_index = |
250 | 0 | drc_instructions_uni_drc->gain_set_idx_of_ch_group_parametric_drc[g]; |
251 | 0 | WORD32 parametric_drc_id = |
252 | 0 | drc_config->str_drc_config_ext.str_drc_coeff_param_drc |
253 | 0 | .str_parametric_drc_gain_set_params[gain_set_index] |
254 | 0 | .parametric_drc_id; |
255 | 0 | WORD32 parametric_drc_look_ahead_samples = 0; |
256 | 0 | ia_parametric_drc_instructions_struct* str_parametric_drc_instructions; |
257 | |
|
258 | 0 | for (i = 0; |
259 | 0 | i < drc_config->str_drc_config_ext.parametric_drc_instructions_count; |
260 | 0 | i++) { |
261 | 0 | if (parametric_drc_id == |
262 | 0 | drc_config->str_drc_config_ext.str_parametric_drc_instructions[i] |
263 | 0 | .parametric_drc_id) |
264 | 0 | break; |
265 | 0 | } |
266 | 0 | if (i == |
267 | 0 | drc_config->str_drc_config_ext.parametric_drc_instructions_count) { |
268 | 0 | return (UNEXPECTED_ERROR); |
269 | 0 | } |
270 | 0 | str_parametric_drc_instructions = |
271 | 0 | &drc_config->str_drc_config_ext.str_parametric_drc_instructions[i]; |
272 | |
|
273 | 0 | p_parametric_drc_params->parametric_drc_idx |
274 | 0 | [p_parametric_drc_params->parametric_drc_instance_count] = i; |
275 | 0 | p_parametric_drc_params->gain_set_index |
276 | 0 | [p_parametric_drc_params->parametric_drc_instance_count] = |
277 | 0 | gain_set_index; |
278 | 0 | if (drc_instructions_uni_drc->drc_apply_to_dwnmix == 0) { |
279 | 0 | p_parametric_drc_params->dwnmix_id_from_drc_instructions |
280 | 0 | [p_parametric_drc_params->parametric_drc_instance_count] = |
281 | 0 | ID_FOR_BASE_LAYOUT; |
282 | 0 | } else { |
283 | 0 | if (drc_instructions_uni_drc->dwnmix_id_count > 1) { |
284 | 0 | p_parametric_drc_params->dwnmix_id_from_drc_instructions |
285 | 0 | [p_parametric_drc_params->parametric_drc_instance_count] = |
286 | 0 | ID_FOR_ANY_DOWNMIX; |
287 | 0 | } else { |
288 | 0 | p_parametric_drc_params->dwnmix_id_from_drc_instructions |
289 | 0 | [p_parametric_drc_params->parametric_drc_instance_count] = |
290 | 0 | drc_instructions_uni_drc->downmix_id[0]; |
291 | 0 | } |
292 | 0 | } |
293 | 0 | p_parametric_drc_params->audio_num_chan = channel_count; |
294 | 0 | for (i = 0; i < p_parametric_drc_params->audio_num_chan; i++) { |
295 | 0 | if (drc_instructions_uni_drc->channel_group_of_ch[i] == g) { |
296 | 0 | p_parametric_drc_params->channel_map |
297 | 0 | [p_parametric_drc_params->parametric_drc_instance_count][i] = 1; |
298 | 0 | } else { |
299 | 0 | p_parametric_drc_params->channel_map |
300 | 0 | [p_parametric_drc_params->parametric_drc_instance_count][i] = 0; |
301 | 0 | } |
302 | 0 | } |
303 | 0 | drc_instructions_uni_drc->parametric_drc_look_ahead_samples[g] = 0; |
304 | 0 | if (str_parametric_drc_instructions->parametric_drc_look_ahead_flag) { |
305 | 0 | parametric_drc_look_ahead_samples = (WORD32)( |
306 | 0 | (FLOAT32) |
307 | 0 | str_parametric_drc_instructions->parametric_drc_look_ahead * |
308 | 0 | (FLOAT32)p_parametric_drc_params->sampling_rate * 0.001f); |
309 | 0 | } else { |
310 | 0 | if (str_parametric_drc_instructions->parametric_drc_type == |
311 | 0 | PARAM_DRC_TYPE_FF) { |
312 | 0 | parametric_drc_look_ahead_samples = (WORD32)( |
313 | 0 | 10.0f * (FLOAT32)p_parametric_drc_params->sampling_rate * 0.001f); |
314 | 0 | } else if (str_parametric_drc_instructions->parametric_drc_type == |
315 | 0 | PARAM_DRC_TYPE_LIM) { |
316 | 0 | parametric_drc_look_ahead_samples = (WORD32)( |
317 | 0 | 5.0f * (FLOAT32)p_parametric_drc_params->sampling_rate * 0.001f); |
318 | 0 | } else { |
319 | 0 | return (UNEXPECTED_ERROR); |
320 | 0 | } |
321 | 0 | } |
322 | 0 | drc_instructions_uni_drc->parametric_drc_look_ahead_samples[g] = |
323 | 0 | parametric_drc_look_ahead_samples; |
324 | 0 | if (drc_instructions_uni_drc->parametric_drc_look_ahead_samples_max < |
325 | 0 | drc_instructions_uni_drc->parametric_drc_look_ahead_samples[g]) { |
326 | 0 | drc_instructions_uni_drc->parametric_drc_look_ahead_samples_max = |
327 | 0 | drc_instructions_uni_drc->parametric_drc_look_ahead_samples[g]; |
328 | 0 | } |
329 | 0 | p_parametric_drc_params->parametric_drc_instance_count += 1; |
330 | 0 | selected_drc_is_multiband = 0; |
331 | 0 | } |
332 | 506 | } |
333 | 253 | ia_drc_params_struct->parametric_drc_delay += |
334 | 253 | drc_instructions_uni_drc->parametric_drc_look_ahead_samples_max; |
335 | | |
336 | 253 | if (selected_drc_is_multiband == 1) { |
337 | 0 | ia_drc_params_struct->multiband_sel_drc_idx = |
338 | 0 | ia_drc_params_struct->drc_set_counter; |
339 | 0 | err = impd_init_all_filter_banks( |
340 | 0 | drc_coefficients_uni_drc, |
341 | 0 | &(drc_config->str_drc_instruction_str[drc_instructions_selected]), |
342 | 0 | ia_filter_banks_struct); |
343 | 0 | if (err) return (err); |
344 | | |
345 | 0 | impd_init_overlap_weight( |
346 | 0 | drc_coefficients_uni_drc, |
347 | 0 | &(drc_config->str_drc_instruction_str[drc_instructions_selected]), |
348 | 0 | ia_drc_params_struct->sub_band_domain_mode, pstr_overlap_params); |
349 | |
|
350 | 253 | } else { |
351 | 253 | ia_gain_modifiers_struct* gain_modifiers = |
352 | 253 | drc_config->str_drc_instruction_str->str_gain_modifiers_of_ch_group; |
353 | 759 | for (g = 0; g < drc_instructions_uni_drc->num_drc_ch_groups; g++) { |
354 | 506 | if (gain_modifiers[g].shape_filter_flag == 1) { |
355 | 0 | impd_shape_filt_block_init( |
356 | 0 | &drc_coefficients_uni_drc->str_shape_filter_block_params |
357 | 0 | [gain_modifiers[g].shape_filter_idx], |
358 | 0 | &shape_filter_block[g]); |
359 | 506 | } else { |
360 | 506 | shape_filter_block[g].shape_flter_block_flag = 0; |
361 | 506 | } |
362 | 506 | } |
363 | 253 | } |
364 | | |
365 | 253 | ia_drc_params_struct->drc_set_counter++; |
366 | | |
367 | 253 | return (0); |
368 | 253 | } |