• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <string.h>
24 
25 #include "impd_type_def.h"
26 #include "impd_error_standards.h"
27 #include "impd_drc_extr_delta_coded_info.h"
28 #include "impd_drc_common.h"
29 #include "impd_drc_struct.h"
30 #include "impd_parametric_drc_dec.h"
31 #include "impd_drc_gain_dec.h"
32 #include "impd_drc_filter_bank.h"
33 #include "impd_drc_multi_band.h"
34 #include "impd_drc_interface.h"
35 #include "impd_drc_gain_dec.h"
36 #include "impd_drc_eq.h"
37 #include "impd_drc_process_audio.h"
38 #include "impd_drc_gain_decoder.h"
39 #include "impd_drc_dec.h"
40 
impd_init_drc_decode(WORD32 frame_size,WORD32 sample_rate,WORD32 gain_delay_samples,WORD32 delay_mode,WORD32 sub_band_domain_mode,ia_drc_gain_dec_struct * p_drc_gain_dec_structs)41 IA_ERRORCODE impd_init_drc_decode(
42     WORD32 frame_size, WORD32 sample_rate, WORD32 gain_delay_samples,
43     WORD32 delay_mode, WORD32 sub_band_domain_mode,
44     ia_drc_gain_dec_struct* p_drc_gain_dec_structs) {
45   IA_ERRORCODE err_code = IA_NO_ERROR;
46 
47   err_code = impd_init_drc_params(
48       frame_size, sample_rate, gain_delay_samples, delay_mode,
49       sub_band_domain_mode, &p_drc_gain_dec_structs->ia_drc_params_struct);
50 
51   if (err_code != IA_NO_ERROR) return (err_code);
52 
53   impd_init_parametric_drc(
54       p_drc_gain_dec_structs->ia_drc_params_struct.drc_frame_size, sample_rate,
55       sub_band_domain_mode, &p_drc_gain_dec_structs->parametricdrc_params);
56 
57   if (err_code != IA_NO_ERROR) return (err_code);
58 
59   return err_code;
60 }
61 
impd_init_drc_decode_post_config(WORD32 audio_num_chan,WORD32 * drc_set_id_processed,WORD32 * downmix_id_processed,WORD32 num_sets_processed,WORD32 eq_set_id_processed,ia_drc_gain_dec_struct * p_drc_gain_dec_structs,ia_drc_config * pstr_drc_config,ia_drc_loudness_info_set_struct * pstr_loudness_info,pVOID * mem_ptr)62 IA_ERRORCODE impd_init_drc_decode_post_config(
63     WORD32 audio_num_chan, WORD32* drc_set_id_processed,
64     WORD32* downmix_id_processed, WORD32 num_sets_processed,
65     WORD32 eq_set_id_processed,
66 
67     ia_drc_gain_dec_struct* p_drc_gain_dec_structs,
68     ia_drc_config* pstr_drc_config,
69     ia_drc_loudness_info_set_struct* pstr_loudness_info, pVOID* mem_ptr) {
70   IA_ERRORCODE err_code = 0;
71   WORD32 i, j, k, maxMultibandAudioSignalCount = 0;
72   ia_drc_params_struct* p_drc_params_struct =
73       &p_drc_gain_dec_structs->ia_drc_params_struct;
74   ia_audio_in_out_buf* p_audio_in_out_buf =
75       &p_drc_gain_dec_structs->audio_in_out_buf;
76 
77   for (i = 0; i < num_sets_processed; i++) {
78     err_code = impd_init_selected_drc_set(
79         pstr_drc_config, p_drc_params_struct,
80         &p_drc_gain_dec_structs->parametricdrc_params, audio_num_chan,
81         drc_set_id_processed[i], downmix_id_processed[i],
82         &p_drc_gain_dec_structs->ia_filter_banks_struct,
83         &p_drc_gain_dec_structs->str_overlap_params,
84         p_drc_gain_dec_structs->shape_filter_block);
85     if (err_code) return (err_code);
86   }
87 
88   p_drc_gain_dec_structs->audio_num_chan = audio_num_chan;
89   p_drc_gain_dec_structs->ia_drc_params_struct.audio_delay_samples =
90       p_drc_gain_dec_structs->ia_drc_params_struct.parametric_drc_delay;
91   if (pstr_drc_config->str_drc_config_ext.parametric_drc_present) {
92     err_code = impd_init_parametric_drc_after_config(
93         pstr_drc_config, pstr_loudness_info,
94         &p_drc_gain_dec_structs->parametricdrc_params, mem_ptr);
95     if (err_code) return (err_code);
96   }
97 
98   p_audio_in_out_buf->audio_num_chan = audio_num_chan;
99   p_audio_in_out_buf->audio_delay_samples =
100       p_drc_params_struct->audio_delay_samples;
101   p_audio_in_out_buf->frame_size = p_drc_params_struct->drc_frame_size;
102 
103   if (p_drc_params_struct->sub_band_domain_mode == SUBBAND_DOMAIN_MODE_QMF64) {
104     p_audio_in_out_buf->audio_delay_sub_band_samples =
105         p_drc_params_struct->audio_delay_samples /
106         AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF64;
107     p_audio_in_out_buf->audio_sub_band_frame_size =
108         p_drc_params_struct->drc_frame_size /
109         AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF64;
110     p_audio_in_out_buf->audio_sub_band_count = AUDIO_CODEC_SUBBAND_COUNT_QMF64;
111   } else if (p_drc_params_struct->sub_band_domain_mode ==
112              SUBBAND_DOMAIN_MODE_QMF71) {
113     p_audio_in_out_buf->audio_delay_sub_band_samples =
114         p_drc_params_struct->audio_delay_samples /
115         AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF71;
116     p_audio_in_out_buf->audio_sub_band_frame_size =
117         p_drc_params_struct->drc_frame_size /
118         AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF71;
119     p_audio_in_out_buf->audio_sub_band_count = AUDIO_CODEC_SUBBAND_COUNT_QMF71;
120   } else if (p_drc_params_struct->sub_band_domain_mode ==
121              SUBBAND_DOMAIN_MODE_STFT256) {
122     p_audio_in_out_buf->audio_delay_sub_band_samples =
123         p_drc_params_struct->audio_delay_samples /
124         AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_STFT256;
125     p_audio_in_out_buf->audio_sub_band_frame_size =
126         p_drc_params_struct->drc_frame_size /
127         AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_STFT256;
128     p_audio_in_out_buf->audio_sub_band_count =
129         AUDIO_CODEC_SUBBAND_COUNT_STFT256;
130   } else {
131     p_audio_in_out_buf->audio_delay_sub_band_samples = 0;
132     p_audio_in_out_buf->audio_sub_band_frame_size = 0;
133     p_audio_in_out_buf->audio_sub_band_count = 0;
134   }
135 
136   for (k = 0; k < SEL_DRC_COUNT; k++) {
137     if (p_drc_params_struct->sel_drc_array[k].drc_instructions_index >= 0) {
138       ia_drc_instructions_struct* drc_instruction_str =
139           &(pstr_drc_config->str_drc_instruction_str
140                 [p_drc_params_struct->sel_drc_array[k].drc_instructions_index]);
141       if (drc_instruction_str->gain_element_count > 0) {
142         p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
143             .buf_interpolation = (ia_interp_buf_struct*)*mem_ptr;
144         *mem_ptr = (pVOID)((SIZE_T)*mem_ptr +
145                            drc_instruction_str->gain_element_count *
146                                sizeof(ia_interp_buf_struct) +
147                            32);
148         p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
149             .buf_interpolation_count = drc_instruction_str->gain_element_count;
150         for (i = 0;
151              i < p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
152                      .buf_interpolation_count;
153              i++) {
154           p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
155               .buf_interpolation[i]
156               .str_node.time = 0;
157           p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
158               .buf_interpolation[i]
159               .prev_node.time = -1;
160           p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
161               .buf_interpolation[i]
162               .str_node.loc_db_gain = 0.0f;
163           p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
164               .buf_interpolation[i]
165               .str_node.slope = 0.0f;
166 
167           for (j = 0; j < 2 * AUDIO_CODEC_FRAME_SIZE_MAX + MAX_SIGNAL_DELAY;
168                j++) {
169             p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[k]
170                 .buf_interpolation[i]
171                 .lpcm_gains[j] = 1.f;
172           }
173         }
174       }
175     }
176   }
177 
178   if (eq_set_id_processed > 0) {
179     for (i = 0; i < pstr_drc_config->str_drc_config_ext.eq_instructions_count;
180          i++) {
181       if (pstr_drc_config->str_drc_config_ext.str_eq_instructions[i]
182               .eq_set_id == eq_set_id_processed)
183         break;
184     }
185     if (i == pstr_drc_config->str_drc_config_ext.eq_instructions_count) {
186       return -1;
187     }
188 
189     p_drc_gain_dec_structs->eq_set = (ia_eq_set_struct*)*mem_ptr;
190     *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + sizeof(ia_eq_set_struct) + 32);
191 
192     if (err_code) return (err_code);
193 
194     err_code = impd_derive_eq_set(
195         &pstr_drc_config->str_drc_config_ext.str_eq_coeff,
196         &(pstr_drc_config->str_drc_config_ext.str_eq_instructions[i]),
197         (FLOAT32)p_drc_gain_dec_structs->ia_drc_params_struct.sample_rate,
198         p_drc_gain_dec_structs->ia_drc_params_struct.drc_frame_size,
199         p_drc_gain_dec_structs->ia_drc_params_struct.sub_band_domain_mode,
200         p_drc_gain_dec_structs->eq_set);
201     if (err_code) return (err_code);
202 
203     impd_get_eq_set_delay(
204         p_drc_gain_dec_structs->eq_set,
205         &p_drc_gain_dec_structs->ia_drc_params_struct.eq_delay);
206   }
207 
208   for (i = 0; i < p_drc_params_struct->drc_set_counter; i++) {
209     ia_drc_instructions_struct* drc_instruction_str;
210     drc_instruction_str =
211         &(pstr_drc_config->str_drc_instruction_str
212               [p_drc_params_struct->sel_drc_array[i].drc_instructions_index]);
213     maxMultibandAudioSignalCount =
214         max(maxMultibandAudioSignalCount,
215             drc_instruction_str->multiband_audio_sig_count);
216   }
217 
218   p_drc_gain_dec_structs->audio_band_buffer.non_interleaved_audio = *mem_ptr;
219   *mem_ptr = (pVOID)((SIZE_T)*mem_ptr +
220                      (maxMultibandAudioSignalCount * sizeof(FLOAT32*)) + 32);
221 
222   for (i = 0; i < maxMultibandAudioSignalCount; i++) {
223     p_drc_gain_dec_structs->audio_band_buffer.non_interleaved_audio[i] =
224         *mem_ptr;
225     *mem_ptr =
226         (pVOID)((SIZE_T)*mem_ptr +
227                 (p_drc_params_struct->drc_frame_size * sizeof(FLOAT32)) + 32);
228   }
229   p_drc_gain_dec_structs->audio_band_buffer.multiband_audio_sig_count =
230       maxMultibandAudioSignalCount;
231   p_drc_gain_dec_structs->audio_band_buffer.frame_size =
232       p_drc_params_struct->drc_frame_size;
233   ;
234 
235   if (p_drc_params_struct->sub_band_domain_mode == SUBBAND_DOMAIN_MODE_OFF &&
236       p_audio_in_out_buf->audio_delay_samples) {
237     p_audio_in_out_buf->audio_io_buffer_delayed = *mem_ptr;
238     *mem_ptr =
239         (pVOID)((SIZE_T)*mem_ptr +
240                 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*)) + 32);
241     p_audio_in_out_buf->audio_in_out_buf = *mem_ptr;
242     *mem_ptr =
243         (pVOID)((SIZE_T)*mem_ptr +
244                 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*)) + 32);
245 
246     for (i = 0; i < p_audio_in_out_buf->audio_num_chan; i++) {
247       p_audio_in_out_buf->audio_io_buffer_delayed[i] = *mem_ptr;
248       *mem_ptr = (pVOID)((SIZE_T)*mem_ptr +
249                          ((p_audio_in_out_buf->frame_size +
250                            p_audio_in_out_buf->audio_delay_samples) *
251                           sizeof(FLOAT32*)) +
252                          32);
253       p_audio_in_out_buf->audio_in_out_buf[i] =
254           &p_audio_in_out_buf->audio_io_buffer_delayed
255                [i][p_audio_in_out_buf->audio_delay_samples];
256     }
257   }
258   if (p_drc_params_struct->sub_band_domain_mode != SUBBAND_DOMAIN_MODE_OFF &&
259       p_audio_in_out_buf->audio_delay_sub_band_samples) {
260     p_audio_in_out_buf->audio_buffer_delayed_real = *mem_ptr;
261     *mem_ptr =
262         (pVOID)((SIZE_T)*mem_ptr +
263                 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*)) + 32);
264     p_audio_in_out_buf->audio_buffer_delayed_imag = *mem_ptr;
265     *mem_ptr =
266         (pVOID)((SIZE_T)*mem_ptr +
267                 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*)) + 32);
268     p_audio_in_out_buf->audio_real_buff = *mem_ptr;
269     *mem_ptr =
270         (pVOID)((SIZE_T)*mem_ptr +
271                 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*)) + 32);
272     p_audio_in_out_buf->audio_imag_buff = *mem_ptr;
273     *mem_ptr =
274         (pVOID)((SIZE_T)*mem_ptr +
275                 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*)) + 32);
276 
277     for (i = 0; i < p_audio_in_out_buf->audio_num_chan; i++) {
278       p_audio_in_out_buf->audio_buffer_delayed_real[i] = *mem_ptr;
279       *mem_ptr = (pVOID)((SIZE_T)*mem_ptr +
280                          ((p_audio_in_out_buf->audio_sub_band_frame_size +
281                            p_audio_in_out_buf->audio_delay_sub_band_samples) *
282                           sizeof(FLOAT32*)) +
283                          32);
284       p_audio_in_out_buf->audio_buffer_delayed_imag[i] = *mem_ptr;
285       *mem_ptr = (pVOID)((SIZE_T)*mem_ptr +
286                          ((p_audio_in_out_buf->audio_sub_band_frame_size +
287                            p_audio_in_out_buf->audio_delay_sub_band_samples) *
288                           sizeof(FLOAT32*)) +
289                          32);
290 
291       p_audio_in_out_buf->audio_real_buff[i] =
292           &p_audio_in_out_buf->audio_buffer_delayed_real
293                [i][p_audio_in_out_buf->audio_delay_sub_band_samples *
294                    p_audio_in_out_buf->audio_sub_band_count];
295       p_audio_in_out_buf->audio_imag_buff[i] =
296           &p_audio_in_out_buf->audio_buffer_delayed_imag
297                [i][p_audio_in_out_buf->audio_delay_sub_band_samples *
298                    p_audio_in_out_buf->audio_sub_band_count];
299     }
300   }
301 
302   return err_code;
303 }
304 
impd_drc_process_time_domain(ia_drc_gain_dec_struct * p_drc_gain_dec_structs,ia_drc_config * pstr_drc_config,ia_drc_gain_struct * pstr_drc_gain,FLOAT32 * audio_in_out_buf[],FLOAT32 loudness_normalization_gain_db,FLOAT32 boost,FLOAT32 compress,WORD32 drc_characteristic_target)305 IA_ERRORCODE impd_drc_process_time_domain(
306     ia_drc_gain_dec_struct* p_drc_gain_dec_structs,
307     ia_drc_config* pstr_drc_config, ia_drc_gain_struct* pstr_drc_gain,
308     FLOAT32* audio_in_out_buf[], FLOAT32 loudness_normalization_gain_db,
309     FLOAT32 boost, FLOAT32 compress, WORD32 drc_characteristic_target) {
310   WORD32 sel_drc_index;
311   IA_ERRORCODE err_code = 0;
312   WORD32 passThru;
313   ia_drc_instructions_struct* str_drc_instruction_str =
314       pstr_drc_config->str_drc_instruction_str;
315 
316   if (p_drc_gain_dec_structs->eq_set) {
317     WORD32 ch;
318     FLOAT32* audio_channel;
319     for (ch = 0; ch < p_drc_gain_dec_structs->eq_set->audio_num_chan; ch++) {
320       audio_channel = audio_in_out_buf[ch];
321 
322       impd_process_eq_set_time_domain(
323           p_drc_gain_dec_structs->eq_set, ch, audio_channel, audio_channel,
324           p_drc_gain_dec_structs->ia_drc_params_struct.drc_frame_size);
325     }
326   }
327 
328   err_code = impd_store_audio_io_buffer_time(
329       audio_in_out_buf, &p_drc_gain_dec_structs->audio_in_out_buf);
330   if (err_code != IA_NO_ERROR) return (err_code);
331 
332   if (pstr_drc_config->apply_drc) {
333     for (sel_drc_index = 0;
334          sel_drc_index <
335          p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter;
336          sel_drc_index++) {
337       err_code = impd_get_drc_gain(
338           p_drc_gain_dec_structs, pstr_drc_config, pstr_drc_gain, compress,
339           boost, drc_characteristic_target, loudness_normalization_gain_db,
340           sel_drc_index, &p_drc_gain_dec_structs->drc_gain_buffers);
341       if (err_code != IA_NO_ERROR) return (err_code);
342     }
343 
344     if (p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter == 0) {
345       err_code = impd_retrieve_audio_io_buffer_time(
346           audio_in_out_buf, &p_drc_gain_dec_structs->audio_in_out_buf);
347       if (err_code) return (err_code);
348     } else {
349       for (sel_drc_index = 0;
350            sel_drc_index <
351            p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter;
352            sel_drc_index++) {
353         if (p_drc_gain_dec_structs->ia_drc_params_struct
354                 .multiband_sel_drc_idx == sel_drc_index) {
355           passThru = 0;
356         } else {
357           passThru = 1;
358         }
359         err_code = impd_filter_banks_process(
360             str_drc_instruction_str,
361             p_drc_gain_dec_structs->ia_drc_params_struct
362                 .sel_drc_array[sel_drc_index]
363                 .drc_instructions_index,
364             &p_drc_gain_dec_structs->ia_drc_params_struct,
365             p_drc_gain_dec_structs->audio_in_out_buf.audio_io_buffer_delayed,
366             &p_drc_gain_dec_structs->audio_band_buffer,
367             &p_drc_gain_dec_structs->ia_filter_banks_struct, passThru);
368         if (err_code != IA_NO_ERROR) return (err_code);
369 
370         err_code = impd_apply_gains_and_add(
371             str_drc_instruction_str,
372             p_drc_gain_dec_structs->ia_drc_params_struct
373                 .sel_drc_array[sel_drc_index]
374                 .drc_instructions_index,
375             &p_drc_gain_dec_structs->ia_drc_params_struct,
376             &(p_drc_gain_dec_structs->drc_gain_buffers
377                   .pstr_gain_buf[sel_drc_index]),
378             p_drc_gain_dec_structs->shape_filter_block,
379             p_drc_gain_dec_structs->audio_band_buffer.non_interleaved_audio,
380             audio_in_out_buf, 1);
381         if (err_code != IA_NO_ERROR) return (err_code);
382       }
383     }
384   }
385 
386   err_code = impd_advance_audio_io_buffer_time(
387       &p_drc_gain_dec_structs->audio_in_out_buf);
388   if (err_code != IA_NO_ERROR) return (err_code);
389 
390   return err_code;
391 }
392 
impd_drc_process_freq_domain(ia_drc_gain_dec_struct * p_drc_gain_dec_structs,ia_drc_config * pstr_drc_config,ia_drc_gain_struct * pstr_drc_gain,FLOAT32 * audio_real_buff[],FLOAT32 * audio_imag_buff[],FLOAT32 loudness_normalization_gain_db,FLOAT32 boost,FLOAT32 compress,WORD32 drc_characteristic_target)393 IA_ERRORCODE impd_drc_process_freq_domain(
394     ia_drc_gain_dec_struct* p_drc_gain_dec_structs,
395     ia_drc_config* pstr_drc_config, ia_drc_gain_struct* pstr_drc_gain,
396     FLOAT32* audio_real_buff[], FLOAT32* audio_imag_buff[],
397     FLOAT32 loudness_normalization_gain_db, FLOAT32 boost, FLOAT32 compress,
398     WORD32 drc_characteristic_target) {
399   WORD32 sel_drc_index;
400   IA_ERRORCODE err_code = 0;
401   ia_drc_instructions_struct* str_drc_instruction_str =
402       pstr_drc_config->str_drc_instruction_str;
403 
404   if (p_drc_gain_dec_structs->eq_set) {
405     WORD32 ch;
406 
407     for (ch = 0; ch < p_drc_gain_dec_structs->eq_set->audio_num_chan; ch++) {
408       err_code = impd_process_eq_set_subband_domain(
409           p_drc_gain_dec_structs->eq_set, ch, audio_real_buff[ch],
410           audio_imag_buff[ch]);
411       if (err_code != IA_NO_ERROR) return (err_code);
412     }
413   }
414   err_code = impd_store_audio_io_buffer_freq(
415       audio_real_buff, audio_imag_buff,
416       &p_drc_gain_dec_structs->audio_in_out_buf);
417   if (err_code != IA_NO_ERROR) return (err_code);
418 
419   if (pstr_drc_config->apply_drc) {
420     for (sel_drc_index = 0;
421          sel_drc_index <
422          p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter;
423          sel_drc_index++) {
424       err_code = impd_get_drc_gain(
425           p_drc_gain_dec_structs, pstr_drc_config, pstr_drc_gain, compress,
426           boost, drc_characteristic_target, loudness_normalization_gain_db,
427           sel_drc_index, &p_drc_gain_dec_structs->drc_gain_buffers);
428       if (err_code != IA_NO_ERROR) return (err_code);
429     }
430 
431     if (p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter == 0) {
432       err_code = impd_retrieve_audio_buffer_freq(
433           audio_real_buff, audio_imag_buff,
434           &p_drc_gain_dec_structs->audio_in_out_buf);
435       if (err_code != IA_NO_ERROR) return (err_code);
436     } else {
437       for (sel_drc_index = 0;
438            sel_drc_index <
439            p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter;
440            sel_drc_index++) {
441         err_code = impd_apply_gains_subband(
442             str_drc_instruction_str,
443             p_drc_gain_dec_structs->ia_drc_params_struct
444                 .sel_drc_array[sel_drc_index]
445                 .drc_instructions_index,
446             &p_drc_gain_dec_structs->ia_drc_params_struct,
447             &(p_drc_gain_dec_structs->drc_gain_buffers
448                   .pstr_gain_buf[sel_drc_index]),
449             &p_drc_gain_dec_structs->str_overlap_params,
450             p_drc_gain_dec_structs->audio_in_out_buf.audio_buffer_delayed_real,
451             p_drc_gain_dec_structs->audio_in_out_buf.audio_buffer_delayed_imag,
452             audio_real_buff, audio_imag_buff);
453         if (err_code != IA_NO_ERROR) return (err_code);
454       }
455     }
456   }
457 
458   err_code =
459       impd_advance_audio_buff_freq(&p_drc_gain_dec_structs->audio_in_out_buf);
460 
461   return err_code;
462 }
463 
impd_get_parametric_drc_delay(ia_drc_gain_dec_struct * p_drc_gain_dec_structs,ia_drc_config * pstr_drc_config,WORD32 * parametric_drc_delay,WORD32 * parametric_drc_delay_max)464 VOID impd_get_parametric_drc_delay(
465     ia_drc_gain_dec_struct* p_drc_gain_dec_structs,
466     ia_drc_config* pstr_drc_config, WORD32* parametric_drc_delay,
467     WORD32* parametric_drc_delay_max) {
468   *parametric_drc_delay =
469       p_drc_gain_dec_structs->ia_drc_params_struct.parametric_drc_delay;
470 
471   if (pstr_drc_config->str_drc_config_ext.parametric_drc_present &&
472       pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
473           .parametric_drc_delay_max_present) {
474     *parametric_drc_delay_max =
475         pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc
476             .parametric_drc_delay_max;
477   } else if (pstr_drc_config->str_drc_config_ext.parametric_drc_present == 0) {
478     *parametric_drc_delay_max = 0;
479   } else {
480     *parametric_drc_delay_max = -1;
481   }
482 
483   return;
484 }
485 
impd_get_eq_delay(ia_drc_gain_dec_struct * p_drc_gain_dec_structs,ia_drc_config * pstr_drc_config,WORD32 * eq_delay,WORD32 * eq_delay_max)486 VOID impd_get_eq_delay(ia_drc_gain_dec_struct* p_drc_gain_dec_structs,
487                        ia_drc_config* pstr_drc_config, WORD32* eq_delay,
488                        WORD32* eq_delay_max) {
489   *eq_delay = p_drc_gain_dec_structs->ia_drc_params_struct.eq_delay;
490 
491   if (pstr_drc_config->str_drc_config_ext.eq_flag &&
492       pstr_drc_config->str_drc_config_ext.str_eq_coeff.eq_delay_max_present) {
493     *eq_delay_max =
494         pstr_drc_config->str_drc_config_ext.str_eq_coeff.eq_delay_max;
495   } else if (pstr_drc_config->str_drc_config_ext.eq_flag == 0) {
496     *eq_delay_max = 0;
497   } else {
498     *eq_delay_max = -1;
499   }
500 
501   return;
502 }
503