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 <stdio.h>
21#include <stdlib.h>
22#include <math.h>
23#include <string.h>
24
25#include "impd_type_def.h"
26#include "impd_drc_extr_delta_coded_info.h"
27#include "impd_drc_common.h"
28#include "impd_drc_struct.h"
29#include "impd_drc_filter_bank.h"
30#include "impd_drc_multi_band.h"
31#include "impd_drc_gain_dec.h"
32#include "impd_drc_process_audio.h"
33
34WORD32 impd_apply_gains_and_add(
35    ia_drc_instructions_struct* pstr_drc_instruction_arr,
36    const WORD32 drc_instructions_index,
37    ia_drc_params_struct* ia_drc_params_struct,
38    ia_gain_buffer_struct* pstr_gain_buf,
39    shape_filter_block shape_filter_block[], FLOAT32* deinterleaved_audio[],
40
41    FLOAT32* channel_audio[], WORD32 impd_apply_gains) {
42  WORD32 c, b, g, i;
43  WORD32 offset = 0, signalIndex = 0;
44  WORD32 gainIndexForGroup[CHANNEL_GROUP_COUNT_MAX];
45  WORD32 signalIndexForChannel[MAX_CHANNEL_COUNT];
46  FLOAT32* lpcm_gains;
47  FLOAT32 sum;
48  FLOAT32 drc_gain_last, gainThr;
49  WORD32 iEnd, iStart;
50  ia_drc_instructions_struct* str_drc_instruction_str =
51      &(pstr_drc_instruction_arr[drc_instructions_index]);
52
53  if (drc_instructions_index >= 0) {
54    str_drc_instruction_str =
55        &(pstr_drc_instruction_arr[drc_instructions_index]);
56    {
57      if (str_drc_instruction_str->drc_set_id > 0) {
58        if (ia_drc_params_struct->delay_mode == DELAY_MODE_LOW_DELAY) {
59          offset = ia_drc_params_struct->drc_frame_size;
60        }
61        gainIndexForGroup[0] = 0;
62        for (g = 0; g < str_drc_instruction_str->num_drc_ch_groups - 1; g++) {
63          gainIndexForGroup[g + 1] =
64              gainIndexForGroup[g] +
65              str_drc_instruction_str->band_count_of_ch_group[g];
66        }
67        signalIndexForChannel[0] = 0;
68        for (c = 0; c < str_drc_instruction_str->audio_num_chan - 1; c++) {
69          if (str_drc_instruction_str->channel_group_of_ch[c] >= 0) {
70            signalIndexForChannel[c + 1] =
71                signalIndexForChannel[c] +
72                str_drc_instruction_str->band_count_of_ch_group
73                    [str_drc_instruction_str->channel_group_of_ch[c]];
74          } else {
75            signalIndexForChannel[c + 1] = signalIndexForChannel[c] + 1;
76          }
77        }
78
79        for (g = 0; g < str_drc_instruction_str->num_drc_ch_groups; g++) {
80          for (b = 0; b < str_drc_instruction_str->band_count_of_ch_group[g];
81               b++) {
82            if (str_drc_instruction_str->ch_group_parametric_drc_flag[g] == 0) {
83              lpcm_gains =
84                  pstr_gain_buf->buf_interpolation[gainIndexForGroup[g] + b]
85                      .lpcm_gains +
86                  MAX_SIGNAL_DELAY - ia_drc_params_struct->gain_delay_samples -
87                  ia_drc_params_struct->audio_delay_samples + offset;
88            } else {
89              lpcm_gains =
90                  pstr_gain_buf->buf_interpolation[gainIndexForGroup[g] + b]
91                      .lpcm_gains +
92                  MAX_SIGNAL_DELAY +
93                  str_drc_instruction_str
94                      ->parametric_drc_look_ahead_samples[g] -
95                  ia_drc_params_struct->audio_delay_samples;
96            }
97            iEnd = 0;
98            iStart = 0;
99            while (iEnd < ia_drc_params_struct->drc_frame_size) {
100              if (shape_filter_block[g].shape_flter_block_flag) {
101                drc_gain_last = shape_filter_block[g].drc_gain_last;
102                gainThr = 0.0001f * drc_gain_last;
103                while ((iEnd < ia_drc_params_struct->drc_frame_size) &&
104                       (fabs(lpcm_gains[iEnd] - drc_gain_last) <= gainThr))
105                  iEnd++;
106              } else {
107                iEnd = ia_drc_params_struct->drc_frame_size;
108              }
109
110              for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++)
111
112              {
113                if (g == str_drc_instruction_str->channel_group_of_ch[c]) {
114                  signalIndex = signalIndexForChannel[c] + b;
115
116                  if (impd_apply_gains == 1) {
117                    impd_shape_filt_block_time_process(
118                        &shape_filter_block[g], &lpcm_gains[0], signalIndex,
119                        &deinterleaved_audio[signalIndex][0], iStart, iEnd);
120
121                  } else {
122                    for (i = iStart; i < iEnd; i++) {
123                      deinterleaved_audio[signalIndex][i] = lpcm_gains[i];
124                    }
125                  }
126                }
127              }
128              if ((iEnd < ia_drc_params_struct->drc_frame_size) &&
129                  (shape_filter_block[g].shape_flter_block_flag)) {
130                impd_shape_filt_block_adapt(lpcm_gains[iEnd],
131                                            &shape_filter_block[g]);
132              }
133              iStart = iEnd;
134            }
135          }
136        }
137      }
138    }
139  }
140
141  signalIndex = 0;
142
143  if (str_drc_instruction_str->drc_set_id > 0) {
144    for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++)
145
146    {
147      g = str_drc_instruction_str->channel_group_of_ch[c];
148      if (g >= 0) {
149        for (i = 0; i < ia_drc_params_struct->drc_frame_size; i++) {
150          sum = 0.0f;
151          for (b = 0; b < str_drc_instruction_str->band_count_of_ch_group[g];
152               b++) {
153            sum += deinterleaved_audio[signalIndex + b][i];
154          }
155
156          channel_audio[c][i] = sum;
157        }
158        signalIndex += str_drc_instruction_str->band_count_of_ch_group[g];
159      } else {
160        for (i = 0; i < ia_drc_params_struct->drc_frame_size; i++) {
161          channel_audio[c][i] = deinterleaved_audio[signalIndex][i];
162        }
163        signalIndex++;
164      }
165    }
166  } else {
167    for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++)
168
169    {
170      for (i = 0; i < ia_drc_params_struct->drc_frame_size; i++) {
171        channel_audio[c][i] = deinterleaved_audio[c][i];
172      }
173    }
174  }
175
176  return (0);
177}
178
179/* subband-domain DRC: in-place application of DRC gains to audio frame */
180WORD32
181impd_apply_gains_subband(ia_drc_instructions_struct* pstr_drc_instruction_arr,
182                         const WORD32 drc_instructions_index,
183                         ia_drc_params_struct* ia_drc_params_struct,
184                         ia_gain_buffer_struct* pstr_gain_buf,
185                         ia_overlap_params_struct* pstr_overlap_params,
186                         FLOAT32* deinterleaved_audio_delayed_re[],
187                         FLOAT32* deinterleaved_audio_delayed_im[],
188                         FLOAT32* deinterleaved_audio_re[],
189                         FLOAT32* deinterleaved_audio_im[]) {
190  WORD32 c, b, g, m, s;
191  WORD32 gainIndexForGroup[CHANNEL_GROUP_COUNT_MAX];
192  FLOAT32* lpcm_gains;
193  FLOAT32 gainSb, gainLr;
194  ia_drc_instructions_struct* str_drc_instruction_str;
195  WORD32 offset = 0, signalIndex = 0;
196  WORD32 drc_frame_sizeSb = 0;
197  WORD32 nDecoderSubbands = 0;
198  WORD32 L = 0; /* L: downsampling factor */
199  WORD32 analysisDelay = 0;
200  switch (ia_drc_params_struct->sub_band_domain_mode) {
201    case SUBBAND_DOMAIN_MODE_QMF64:
202      nDecoderSubbands = AUDIO_CODEC_SUBBAND_COUNT_QMF64;
203      L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF64;
204      analysisDelay = AUDIO_CODEC_SUBBAND_ANALYSE_DELAY_QMF64;
205      break;
206    case SUBBAND_DOMAIN_MODE_QMF71:
207      nDecoderSubbands = AUDIO_CODEC_SUBBAND_COUNT_QMF71;
208      L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_QMF71;
209      analysisDelay = AUDIO_CODEC_SUBBAND_ANALYSE_DELAY_QMF71;
210      break;
211    case SUBBAND_DOMAIN_MODE_STFT256:
212      nDecoderSubbands = AUDIO_CODEC_SUBBAND_COUNT_STFT256;
213      L = AUDIO_CODEC_SUBBAND_DOWNSAMPLING_FACTOR_STFT256;
214      analysisDelay = AUDIO_CODEC_SUBBAND_ANALYSE_DELAY_STFT256;
215      break;
216    default:
217      return -1;
218      break;
219  }
220  drc_frame_sizeSb = ia_drc_params_struct->drc_frame_size / L;
221
222  if (drc_instructions_index >= 0) {
223    str_drc_instruction_str =
224        &(pstr_drc_instruction_arr[drc_instructions_index]);
225    {
226      if (str_drc_instruction_str->drc_set_id > 0) {
227        if (ia_drc_params_struct->delay_mode == DELAY_MODE_LOW_DELAY) {
228          offset = ia_drc_params_struct->drc_frame_size;
229        }
230        gainIndexForGroup[0] = 0;
231        for (g = 0; g < str_drc_instruction_str->num_drc_ch_groups - 1; g++) {
232          gainIndexForGroup[g + 1] =
233              gainIndexForGroup[g] +
234              str_drc_instruction_str
235                  ->band_count_of_ch_group[g]; /* index of first gain sequence
236                                                  in channel group */
237        }
238
239        for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++)
240
241        {
242          g = str_drc_instruction_str->channel_group_of_ch[c];
243          if (g >= 0) {
244            for (m = 0; m < drc_frame_sizeSb; m++) {
245              if (str_drc_instruction_str->band_count_of_ch_group[g] >
246                  1) { /* multiband DRC */
247                for (s = 0; s < nDecoderSubbands; s++) {
248                  gainSb = 0.0f;
249                  for (b = 0;
250                       b < str_drc_instruction_str->band_count_of_ch_group[g];
251                       b++) {
252                    if (str_drc_instruction_str
253                            ->ch_group_parametric_drc_flag[g] == 0) {
254                      lpcm_gains =
255                          pstr_gain_buf
256                              ->buf_interpolation[gainIndexForGroup[g] + b]
257                              .lpcm_gains +
258                          MAX_SIGNAL_DELAY -
259                          ia_drc_params_struct->gain_delay_samples -
260                          ia_drc_params_struct->audio_delay_samples + offset;
261                    } else {
262                      lpcm_gains =
263                          pstr_gain_buf
264                              ->buf_interpolation[gainIndexForGroup[g] + b]
265                              .lpcm_gains +
266                          MAX_SIGNAL_DELAY +
267                          str_drc_instruction_str
268                              ->parametric_drc_look_ahead_samples[g] -
269                          ia_drc_params_struct->audio_delay_samples +
270                          analysisDelay;
271                    }
272                    /* get gain for this timeslot by downsampling */
273                    gainLr = lpcm_gains[(m * L + (L - 1) / 2)];
274                    gainSb += pstr_overlap_params->str_group_overlap_params[g]
275                                  .str_band_overlap_params[b]
276                                  .overlap_weight[s] *
277                              gainLr;
278                  }
279                  deinterleaved_audio_re[signalIndex][m * nDecoderSubbands +
280                                                      s] =
281                      gainSb *
282                      deinterleaved_audio_delayed_re[signalIndex]
283                                                    [m * nDecoderSubbands + s];
284                  if (ia_drc_params_struct->sub_band_domain_mode ==
285                      SUBBAND_DOMAIN_MODE_STFT256) { /* For STFT filterbank, the
286                                                        real value of the
287                                                        nyquist band is stored
288                                                        at the imag value of the
289                                                        first band */
290                    if (s != 0)
291                      deinterleaved_audio_im[signalIndex][m * nDecoderSubbands +
292                                                          s] =
293                          gainSb *
294                          deinterleaved_audio_delayed_im[signalIndex]
295                                                        [m * nDecoderSubbands +
296                                                         s];
297                    if (s == (nDecoderSubbands - 1))
298                      deinterleaved_audio_im[signalIndex][m * nDecoderSubbands +
299                                                          0] =
300                          gainSb *
301                          deinterleaved_audio_delayed_im[signalIndex]
302                                                        [m * nDecoderSubbands +
303                                                         0];
304                  } else {
305                    deinterleaved_audio_im[signalIndex][m * nDecoderSubbands +
306                                                        s] =
307                        gainSb *
308                        deinterleaved_audio_delayed_im[signalIndex]
309                                                      [m * nDecoderSubbands +
310                                                       s];
311                  }
312                }
313              } else { /* single-band DRC */
314                if (str_drc_instruction_str->ch_group_parametric_drc_flag[g] ==
315                    0) {
316                  lpcm_gains =
317                      pstr_gain_buf->buf_interpolation[gainIndexForGroup[g]]
318                          .lpcm_gains +
319                      MAX_SIGNAL_DELAY -
320                      ia_drc_params_struct->gain_delay_samples -
321                      ia_drc_params_struct->audio_delay_samples + offset;
322                } else {
323                  lpcm_gains =
324                      pstr_gain_buf->buf_interpolation[gainIndexForGroup[g]]
325                          .lpcm_gains +
326                      MAX_SIGNAL_DELAY +
327                      str_drc_instruction_str
328                          ->parametric_drc_look_ahead_samples[g] -
329                      ia_drc_params_struct->audio_delay_samples + analysisDelay;
330                }
331                /* get gain for this timeslot by downsampling */
332                gainSb = lpcm_gains[(m * L + (L - 1) / 2)];
333                for (s = 0; s < nDecoderSubbands; s++) {
334                  deinterleaved_audio_re[signalIndex][m * nDecoderSubbands +
335                                                      s] =
336                      gainSb *
337                      deinterleaved_audio_delayed_re[signalIndex]
338                                                    [m * nDecoderSubbands + s];
339                  deinterleaved_audio_im[signalIndex][m * nDecoderSubbands +
340                                                      s] =
341                      gainSb *
342                      deinterleaved_audio_delayed_im[signalIndex]
343                                                    [m * nDecoderSubbands + s];
344                }
345              }
346            }
347          }
348          signalIndex++;
349        }
350      }
351    }
352  }
353  return (0);
354}
355
356WORD32
357impd_filter_banks_process(ia_drc_instructions_struct* pstr_drc_instruction_arr,
358                          const WORD32 drc_instructions_index,
359                          ia_drc_params_struct* ia_drc_params_struct,
360                          FLOAT32* audio_io_buf[],
361                          ia_audio_band_buffer_struct* audio_band_buffer,
362                          ia_filter_banks_struct* ia_filter_banks_struct,
363                          const WORD32 passThru) {
364  WORD32 c, g, e, i, num_bands;
365  // WORD32 err = 0;
366  FLOAT32* audio_in;
367  FLOAT32** audio_out;
368  ia_drc_filter_bank_struct* str_drc_filter_bank;
369  ia_drc_instructions_struct* str_drc_instruction_str;
370  WORD32 drc_frame_size = ia_drc_params_struct->drc_frame_size;
371
372  if (drc_instructions_index >= 0) {
373    str_drc_instruction_str =
374        &(pstr_drc_instruction_arr[drc_instructions_index]);
375  } else {
376    return -1;
377  }
378
379  e = 0;
380
381  for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++)
382
383  {
384    str_drc_filter_bank = NULL;
385
386    audio_in = audio_io_buf[c];
387
388    audio_out = &(audio_band_buffer->non_interleaved_audio[e]);
389    if ((passThru == 0) && (drc_instructions_index >= 0)) {
390      if (str_drc_instruction_str->drc_set_id < 0) {
391        num_bands = 1;
392      } else {
393        g = str_drc_instruction_str->channel_group_of_ch[c];
394        if (g == -1) {
395          num_bands = 1;
396          // if (ia_filter_banks_struct->str_drc_filter_bank != NULL)
397          //{
398          str_drc_filter_bank =
399              &(ia_filter_banks_struct->str_drc_filter_bank
400                    [str_drc_instruction_str->num_drc_ch_groups]);
401          //}
402        } else {
403          num_bands = str_drc_instruction_str->band_count_of_ch_group[g];
404          // if (ia_filter_banks_struct->str_drc_filter_bank != NULL)
405          //{
406          str_drc_filter_bank =
407              &(ia_filter_banks_struct->str_drc_filter_bank[g]);
408          //}
409        }
410        // if (ia_filter_banks_struct->str_drc_filter_bank != NULL)
411        //{
412        // if (&str_drc_filter_bank->str_all_pass_cascade != NULL)
413        //{
414        impd_all_pass_cascade_process(
415            &str_drc_filter_bank->str_all_pass_cascade, c, drc_frame_size,
416            audio_in);
417        //}
418        //}
419      }
420    } else {
421      num_bands = 1;
422    }
423    switch (num_bands) {
424      case 1:
425        for (i = 0; i < drc_frame_size; i++) {
426          audio_out[0][i] = audio_in[i];
427        }
428        e++;
429        break;
430      case 2:
431        impd_two_band_filter_process(&str_drc_filter_bank->str_two_band_bank, c,
432                                     drc_frame_size, audio_in, audio_out);
433        e += 2;
434        break;
435      case 3:
436        impd_three_band_filter_process(
437            &str_drc_filter_bank->str_three_band_bank, c, drc_frame_size,
438            audio_in, audio_out);
439        e += 3;
440        break;
441      case 4:
442        impd_four_band_filter_process(&str_drc_filter_bank->str_four_band_bank,
443                                      c, drc_frame_size, audio_in, audio_out);
444        e += 4;
445        break;
446      default:
447        return (PARAM_ERROR);
448        break;
449    }
450  }
451
452  return (0);
453}
454
455WORD32
456impd_store_audio_io_buffer_time(FLOAT32* audio_in_out_buf[],
457                                ia_audio_in_out_buf* audio_io_buf_internal) {
458  WORD32 i, j;
459
460  if (audio_io_buf_internal->audio_delay_samples) {
461    for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
462      for (j = 0; j < audio_io_buf_internal->frame_size; j++) {
463        audio_io_buf_internal->audio_io_buffer_delayed
464            [i][audio_io_buf_internal->audio_delay_samples + j] =
465            audio_in_out_buf[i][j];
466      }
467    }
468  } else {
469    audio_io_buf_internal->audio_io_buffer_delayed = audio_in_out_buf;
470    audio_io_buf_internal->audio_in_out_buf = audio_in_out_buf;
471  }
472
473  return 0;
474}
475
476WORD32
477impd_store_audio_io_buffer_freq(FLOAT32* audio_real_buff[],
478                                FLOAT32* audio_imag_buff[],
479                                ia_audio_in_out_buf* audio_io_buf_internal) {
480  WORD32 i, j;
481
482  if (audio_io_buf_internal->audio_delay_sub_band_samples) {
483    for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
484      for (j = 0; j < audio_io_buf_internal->audio_sub_band_frame_size *
485                          audio_io_buf_internal->audio_sub_band_count;
486           j++) {
487        audio_io_buf_internal->audio_buffer_delayed_real
488            [i][audio_io_buf_internal->audio_delay_sub_band_samples *
489                    audio_io_buf_internal->audio_sub_band_count +
490                j] = audio_real_buff[i][j];
491        audio_io_buf_internal->audio_buffer_delayed_imag
492            [i][audio_io_buf_internal->audio_delay_sub_band_samples *
493                    audio_io_buf_internal->audio_sub_band_count +
494                j] = audio_imag_buff[i][j];
495      }
496    }
497  } else {
498    audio_io_buf_internal->audio_buffer_delayed_real = audio_real_buff;
499    audio_io_buf_internal->audio_buffer_delayed_imag = audio_imag_buff;
500    audio_io_buf_internal->audio_real_buff = audio_real_buff;
501    audio_io_buf_internal->audio_imag_buff = audio_imag_buff;
502  }
503
504  return 0;
505}
506
507WORD32
508impd_retrieve_audio_io_buffer_time(FLOAT32* audio_in_out_buf[],
509                                   ia_audio_in_out_buf* audio_io_buf_internal) {
510  WORD32 i, j;
511
512  if (audio_io_buf_internal->audio_delay_samples) {
513    for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
514      for (j = 0; j < audio_io_buf_internal->frame_size; j++) {
515        audio_in_out_buf[i][j] =
516            audio_io_buf_internal->audio_io_buffer_delayed[i][j];
517      }
518    }
519  }
520
521  return 0;
522}
523
524WORD32
525impd_retrieve_audio_buffer_freq(FLOAT32* audio_real_buff[],
526                                FLOAT32* audio_imag_buff[],
527                                ia_audio_in_out_buf* audio_io_buf_internal) {
528  WORD32 i, j;
529
530  if (audio_io_buf_internal->audio_delay_sub_band_samples) {
531    for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
532      for (j = 0; j < audio_io_buf_internal->audio_sub_band_frame_size *
533                          audio_io_buf_internal->audio_sub_band_count;
534           j++) {
535        audio_real_buff[i][j] =
536            audio_io_buf_internal->audio_buffer_delayed_real
537                [i][audio_io_buf_internal->audio_sub_band_count + j];
538        audio_imag_buff[i][j] =
539            audio_io_buf_internal->audio_buffer_delayed_imag
540                [i][audio_io_buf_internal->audio_sub_band_count + j];
541      }
542    }
543  }
544
545  return 0;
546}
547
548WORD32
549impd_advance_audio_io_buffer_time(ia_audio_in_out_buf* audio_io_buf_internal) {
550  WORD32 i;
551  if (audio_io_buf_internal->audio_delay_samples) {
552    for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
553      memmove(
554          audio_io_buf_internal->audio_io_buffer_delayed[i],
555          &audio_io_buf_internal
556               ->audio_io_buffer_delayed[i][audio_io_buf_internal->frame_size],
557          sizeof(FLOAT32) * audio_io_buf_internal->audio_delay_samples);
558    }
559  }
560
561  return 0;
562}
563
564WORD32
565impd_advance_audio_buff_freq(ia_audio_in_out_buf* audio_io_buf_internal) {
566  WORD32 i;
567  if (audio_io_buf_internal->audio_delay_sub_band_samples) {
568    for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
569      memmove(audio_io_buf_internal->audio_buffer_delayed_real[i],
570              &audio_io_buf_internal->audio_buffer_delayed_real
571                   [i][audio_io_buf_internal->audio_sub_band_frame_size *
572                       audio_io_buf_internal->audio_sub_band_count],
573              sizeof(FLOAT32) *
574                  audio_io_buf_internal->audio_delay_sub_band_samples *
575                  audio_io_buf_internal->audio_sub_band_count);
576      memmove(audio_io_buf_internal->audio_buffer_delayed_imag[i],
577              &audio_io_buf_internal->audio_buffer_delayed_imag
578                   [i][audio_io_buf_internal->audio_sub_band_frame_size *
579                       audio_io_buf_internal->audio_sub_band_count],
580              sizeof(FLOAT32) *
581                  audio_io_buf_internal->audio_delay_sub_band_samples *
582                  audio_io_buf_internal->audio_sub_band_count);
583    }
584  }
585  return 0;
586}
587