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 if ((iEnd == iStart) && 134 (drc_gain_last == shape_filter_block[g].drc_gain_last)) 135 break; 136 iStart = iEnd; 137 } 138 } 139 } 140 } 141 } 142 } 143 144 signalIndex = 0; 145 146 if (str_drc_instruction_str->drc_set_id > 0) { 147 for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++) 148 149 { 150 g = str_drc_instruction_str->channel_group_of_ch[c]; 151 if (g >= 0) { 152 for (i = 0; i < ia_drc_params_struct->drc_frame_size; i++) { 153 sum = 0.0f; 154 for (b = 0; b < str_drc_instruction_str->band_count_of_ch_group[g]; 155 b++) { 156 sum += deinterleaved_audio[signalIndex + b][i]; 157 } 158 159 channel_audio[c][i] = sum; 160 } 161 signalIndex += str_drc_instruction_str->band_count_of_ch_group[g]; 162 } else { 163 for (i = 0; i < ia_drc_params_struct->drc_frame_size; i++) { 164 channel_audio[c][i] = deinterleaved_audio[signalIndex][i]; 165 } 166 signalIndex++; 167 } 168 } 169 } else { 170 for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++) 171 172 { 173 for (i = 0; i < ia_drc_params_struct->drc_frame_size; i++) { 174 channel_audio[c][i] = deinterleaved_audio[c][i]; 175 } 176 } 177 } 178 179 return (0); 180 } 181 182 WORD32 183 impd_filter_banks_process(ia_drc_instructions_struct* pstr_drc_instruction_arr, 184 const WORD32 drc_instructions_index, 185 ia_drc_params_struct* ia_drc_params_struct, 186 FLOAT32* audio_io_buf[], 187 ia_audio_band_buffer_struct* audio_band_buffer, 188 ia_filter_banks_struct* ia_filter_banks_struct, 189 const WORD32 passThru) { 190 WORD32 c, g, e, i, num_bands; 191 // WORD32 err = 0; 192 FLOAT32* audio_in; 193 FLOAT32** audio_out; 194 ia_drc_filter_bank_struct* str_drc_filter_bank; 195 ia_drc_instructions_struct* str_drc_instruction_str; 196 WORD32 drc_frame_size = ia_drc_params_struct->drc_frame_size; 197 198 if (drc_instructions_index >= 0) { 199 str_drc_instruction_str = 200 &(pstr_drc_instruction_arr[drc_instructions_index]); 201 } else { 202 return -1; 203 } 204 205 e = 0; 206 207 for (c = 0; c < str_drc_instruction_str->audio_num_chan; c++) 208 209 { 210 str_drc_filter_bank = NULL; 211 212 audio_in = audio_io_buf[c]; 213 214 audio_out = &(audio_band_buffer->non_interleaved_audio[e]); 215 if ((passThru == 0) && (drc_instructions_index >= 0)) { 216 if (str_drc_instruction_str->drc_set_id < 0) { 217 num_bands = 1; 218 } else { 219 g = str_drc_instruction_str->channel_group_of_ch[c]; 220 if (g == -1) { 221 num_bands = 1; 222 // if (ia_filter_banks_struct->str_drc_filter_bank != NULL) 223 //{ 224 str_drc_filter_bank = 225 &(ia_filter_banks_struct->str_drc_filter_bank 226 [str_drc_instruction_str->num_drc_ch_groups]); 227 //} 228 } else { 229 num_bands = str_drc_instruction_str->band_count_of_ch_group[g]; 230 // if (ia_filter_banks_struct->str_drc_filter_bank != NULL) 231 //{ 232 str_drc_filter_bank = 233 &(ia_filter_banks_struct->str_drc_filter_bank[g]); 234 //} 235 } 236 // if (ia_filter_banks_struct->str_drc_filter_bank != NULL) 237 //{ 238 // if (&str_drc_filter_bank->str_all_pass_cascade != NULL) 239 //{ 240 impd_all_pass_cascade_process( 241 &str_drc_filter_bank->str_all_pass_cascade, c, drc_frame_size, 242 audio_in); 243 //} 244 //} 245 } 246 } else { 247 num_bands = 1; 248 } 249 switch (num_bands) { 250 case 1: 251 for (i = 0; i < drc_frame_size; i++) { 252 audio_out[0][i] = audio_in[i]; 253 } 254 e++; 255 break; 256 case 2: 257 impd_two_band_filter_process(&str_drc_filter_bank->str_two_band_bank, c, 258 drc_frame_size, audio_in, audio_out); 259 e += 2; 260 break; 261 case 3: 262 impd_three_band_filter_process( 263 &str_drc_filter_bank->str_three_band_bank, c, drc_frame_size, 264 audio_in, audio_out); 265 e += 3; 266 break; 267 case 4: 268 impd_four_band_filter_process(&str_drc_filter_bank->str_four_band_bank, 269 c, drc_frame_size, audio_in, audio_out); 270 e += 4; 271 break; 272 default: 273 return (PARAM_ERROR); 274 break; 275 } 276 } 277 278 return (0); 279 } 280 281 WORD32 282 impd_store_audio_io_buffer_time(FLOAT32* audio_in_out_buf[], 283 ia_audio_in_out_buf* audio_io_buf_internal) { 284 WORD32 i, j; 285 286 if (audio_io_buf_internal->audio_delay_samples) { 287 for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) { 288 for (j = 0; j < audio_io_buf_internal->frame_size; j++) { 289 audio_io_buf_internal->audio_io_buffer_delayed 290 [i][audio_io_buf_internal->audio_delay_samples + j] = 291 audio_in_out_buf[i][j]; 292 } 293 } 294 } else { 295 audio_io_buf_internal->audio_io_buffer_delayed = audio_in_out_buf; 296 audio_io_buf_internal->audio_in_out_buf = audio_in_out_buf; 297 } 298 299 return 0; 300 } 301 302 WORD32 303 impd_retrieve_audio_io_buffer_time(FLOAT32* audio_in_out_buf[], 304 ia_audio_in_out_buf* audio_io_buf_internal) { 305 WORD32 i, j; 306 307 if (audio_io_buf_internal->audio_delay_samples) { 308 for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) { 309 for (j = 0; j < audio_io_buf_internal->frame_size; j++) { 310 audio_in_out_buf[i][j] = 311 audio_io_buf_internal->audio_io_buffer_delayed[i][j]; 312 } 313 } 314 } 315 316 return 0; 317 } 318 319 WORD32 320 impd_advance_audio_io_buffer_time(ia_audio_in_out_buf* audio_io_buf_internal) { 321 WORD32 i; 322 if (audio_io_buf_internal->audio_delay_samples) { 323 for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) { 324 memmove( 325 audio_io_buf_internal->audio_io_buffer_delayed[i], 326 &audio_io_buf_internal 327 ->audio_io_buffer_delayed[i][audio_io_buf_internal->frame_size], 328 sizeof(FLOAT32) * audio_io_buf_internal->audio_delay_samples); 329 } 330 } 331 332 return 0; 333 } 334