Home | History | Annotate | Download | only in drc_src
      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 
     34 WORD32 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 */
    180 WORD32
    181 impd_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 
    356 WORD32
    357 impd_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 
    455 WORD32
    456 impd_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 
    476 WORD32
    477 impd_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 
    507 WORD32
    508 impd_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 
    524 WORD32
    525 impd_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 
    548 WORD32
    549 impd_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 
    564 WORD32
    565 impd_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