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
41IA_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
62IA_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[i]
152                     .buf_interpolation_count;
153             i++) {
154          p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[i]
155              .buf_interpolation[i]
156              .str_node.time = 0;
157          p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[i]
158              .buf_interpolation[i]
159              .prev_node.time = -1;
160          p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[i]
161              .buf_interpolation[i]
162              .str_node.loc_db_gain = 0.0f;
163          p_drc_gain_dec_structs->drc_gain_buffers.pstr_gain_buf[i]
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[i]
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
305IA_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
393IA_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
464VOID 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
486VOID 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