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 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 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)); 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*))); 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 = (pVOID)((SIZE_T)*mem_ptr + 226 (p_drc_params_struct->drc_frame_size * sizeof(FLOAT32))); 227 } 228 p_drc_gain_dec_structs->audio_band_buffer.multiband_audio_sig_count = 229 maxMultibandAudioSignalCount; 230 p_drc_gain_dec_structs->audio_band_buffer.frame_size = 231 p_drc_params_struct->drc_frame_size; 232 ; 233 234 if (p_drc_params_struct->sub_band_domain_mode == SUBBAND_DOMAIN_MODE_OFF && 235 p_audio_in_out_buf->audio_delay_samples) { 236 p_audio_in_out_buf->audio_io_buffer_delayed = *mem_ptr; 237 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 238 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*))); 239 p_audio_in_out_buf->audio_in_out_buf = *mem_ptr; 240 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 241 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*))); 242 243 for (i = 0; i < p_audio_in_out_buf->audio_num_chan; i++) { 244 p_audio_in_out_buf->audio_io_buffer_delayed[i] = *mem_ptr; 245 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 246 ((p_audio_in_out_buf->frame_size + 247 p_audio_in_out_buf->audio_delay_samples) * 248 sizeof(FLOAT32*))); 249 p_audio_in_out_buf->audio_in_out_buf[i] = 250 &p_audio_in_out_buf->audio_io_buffer_delayed 251 [i][p_audio_in_out_buf->audio_delay_samples]; 252 } 253 } 254 if (p_drc_params_struct->sub_band_domain_mode != SUBBAND_DOMAIN_MODE_OFF && 255 p_audio_in_out_buf->audio_delay_sub_band_samples) { 256 p_audio_in_out_buf->audio_buffer_delayed_real = *mem_ptr; 257 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 258 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*))); 259 p_audio_in_out_buf->audio_buffer_delayed_imag = *mem_ptr; 260 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 261 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*))); 262 p_audio_in_out_buf->audio_real_buff = *mem_ptr; 263 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 264 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*))); 265 p_audio_in_out_buf->audio_imag_buff = *mem_ptr; 266 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 267 (p_audio_in_out_buf->audio_num_chan * sizeof(FLOAT32*))); 268 269 for (i = 0; i < p_audio_in_out_buf->audio_num_chan; i++) { 270 p_audio_in_out_buf->audio_buffer_delayed_real[i] = *mem_ptr; 271 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 272 ((p_audio_in_out_buf->audio_sub_band_frame_size + 273 p_audio_in_out_buf->audio_delay_sub_band_samples) * 274 sizeof(FLOAT32*))); 275 p_audio_in_out_buf->audio_buffer_delayed_imag[i] = *mem_ptr; 276 *mem_ptr = (pVOID)((SIZE_T)*mem_ptr + 277 ((p_audio_in_out_buf->audio_sub_band_frame_size + 278 p_audio_in_out_buf->audio_delay_sub_band_samples) * 279 sizeof(FLOAT32*))); 280 281 p_audio_in_out_buf->audio_real_buff[i] = 282 &p_audio_in_out_buf->audio_buffer_delayed_real 283 [i][p_audio_in_out_buf->audio_delay_sub_band_samples * 284 p_audio_in_out_buf->audio_sub_band_count]; 285 p_audio_in_out_buf->audio_imag_buff[i] = 286 &p_audio_in_out_buf->audio_buffer_delayed_imag 287 [i][p_audio_in_out_buf->audio_delay_sub_band_samples * 288 p_audio_in_out_buf->audio_sub_band_count]; 289 } 290 } 291 292 return err_code; 293 } 294 295 IA_ERRORCODE impd_drc_process_time_domain( 296 ia_drc_gain_dec_struct* p_drc_gain_dec_structs, 297 ia_drc_config* pstr_drc_config, ia_drc_gain_struct* pstr_drc_gain, 298 FLOAT32* audio_in_out_buf[], FLOAT32 loudness_normalization_gain_db, 299 FLOAT32 boost, FLOAT32 compress, WORD32 drc_characteristic_target) { 300 WORD32 sel_drc_index; 301 IA_ERRORCODE err_code = 0; 302 WORD32 passThru; 303 ia_drc_instructions_struct* str_drc_instruction_str = 304 pstr_drc_config->str_drc_instruction_str; 305 306 if (p_drc_gain_dec_structs->eq_set) { 307 WORD32 ch; 308 FLOAT32* audio_channel; 309 for (ch = 0; ch < p_drc_gain_dec_structs->eq_set->audio_num_chan; ch++) { 310 audio_channel = audio_in_out_buf[ch]; 311 312 impd_process_eq_set_time_domain( 313 p_drc_gain_dec_structs->eq_set, ch, audio_channel, audio_channel, 314 p_drc_gain_dec_structs->ia_drc_params_struct.drc_frame_size); 315 } 316 } 317 318 err_code = impd_store_audio_io_buffer_time( 319 audio_in_out_buf, &p_drc_gain_dec_structs->audio_in_out_buf); 320 if (err_code != IA_NO_ERROR) return (err_code); 321 322 if (pstr_drc_config->apply_drc) { 323 for (sel_drc_index = 0; 324 sel_drc_index < 325 p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter; 326 sel_drc_index++) { 327 err_code = impd_get_drc_gain( 328 p_drc_gain_dec_structs, pstr_drc_config, pstr_drc_gain, compress, 329 boost, drc_characteristic_target, loudness_normalization_gain_db, 330 sel_drc_index, &p_drc_gain_dec_structs->drc_gain_buffers); 331 if (err_code != IA_NO_ERROR) return (err_code); 332 } 333 334 if (p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter == 0) { 335 err_code = impd_retrieve_audio_io_buffer_time( 336 audio_in_out_buf, &p_drc_gain_dec_structs->audio_in_out_buf); 337 if (err_code) return (err_code); 338 } else { 339 for (sel_drc_index = 0; 340 sel_drc_index < 341 p_drc_gain_dec_structs->ia_drc_params_struct.drc_set_counter; 342 sel_drc_index++) { 343 if (p_drc_gain_dec_structs->ia_drc_params_struct 344 .multiband_sel_drc_idx == sel_drc_index) { 345 passThru = 0; 346 } else { 347 passThru = 1; 348 } 349 err_code = impd_filter_banks_process( 350 str_drc_instruction_str, 351 p_drc_gain_dec_structs->ia_drc_params_struct 352 .sel_drc_array[sel_drc_index] 353 .drc_instructions_index, 354 &p_drc_gain_dec_structs->ia_drc_params_struct, 355 p_drc_gain_dec_structs->audio_in_out_buf.audio_io_buffer_delayed, 356 &p_drc_gain_dec_structs->audio_band_buffer, 357 &p_drc_gain_dec_structs->ia_filter_banks_struct, passThru); 358 if (err_code != IA_NO_ERROR) return (err_code); 359 360 err_code = impd_apply_gains_and_add( 361 str_drc_instruction_str, 362 p_drc_gain_dec_structs->ia_drc_params_struct 363 .sel_drc_array[sel_drc_index] 364 .drc_instructions_index, 365 &p_drc_gain_dec_structs->ia_drc_params_struct, 366 &(p_drc_gain_dec_structs->drc_gain_buffers 367 .pstr_gain_buf[sel_drc_index]), 368 p_drc_gain_dec_structs->shape_filter_block, 369 p_drc_gain_dec_structs->audio_band_buffer.non_interleaved_audio, 370 audio_in_out_buf, 1); 371 if (err_code != IA_NO_ERROR) return (err_code); 372 } 373 } 374 } 375 376 err_code = impd_advance_audio_io_buffer_time( 377 &p_drc_gain_dec_structs->audio_in_out_buf); 378 if (err_code != IA_NO_ERROR) return (err_code); 379 380 return err_code; 381 } 382 383 384 VOID impd_get_parametric_drc_delay( 385 ia_drc_gain_dec_struct* p_drc_gain_dec_structs, 386 ia_drc_config* pstr_drc_config, WORD32* parametric_drc_delay, 387 WORD32* parametric_drc_delay_max) { 388 *parametric_drc_delay = 389 p_drc_gain_dec_structs->ia_drc_params_struct.parametric_drc_delay; 390 391 if (pstr_drc_config->str_drc_config_ext.parametric_drc_present && 392 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 393 .parametric_drc_delay_max_present) { 394 *parametric_drc_delay_max = 395 pstr_drc_config->str_drc_config_ext.str_drc_coeff_param_drc 396 .parametric_drc_delay_max; 397 } else if (pstr_drc_config->str_drc_config_ext.parametric_drc_present == 0) { 398 *parametric_drc_delay_max = 0; 399 } else { 400 *parametric_drc_delay_max = -1; 401 } 402 403 return; 404 } 405 406 VOID impd_get_eq_delay(ia_drc_gain_dec_struct* p_drc_gain_dec_structs, 407 ia_drc_config* pstr_drc_config, WORD32* eq_delay, 408 WORD32* eq_delay_max) { 409 *eq_delay = p_drc_gain_dec_structs->ia_drc_params_struct.eq_delay; 410 411 if (pstr_drc_config->str_drc_config_ext.eq_flag && 412 pstr_drc_config->str_drc_config_ext.str_eq_coeff.eq_delay_max_present) { 413 *eq_delay_max = 414 pstr_drc_config->str_drc_config_ext.str_eq_coeff.eq_delay_max; 415 } else if (pstr_drc_config->str_drc_config_ext.eq_flag == 0) { 416 *eq_delay_max = 0; 417 } else { 418 *eq_delay_max = -1; 419 } 420 421 return; 422 } 423