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 <math.h> 21 #include "impd_type_def.h" 22 #include "impd_memory_standards.h" 23 #include "impd_drc_peak_limiter.h" 24 #include "impd_drc_extr_delta_coded_info.h" 25 #include "impd_drc_common.h" 26 #include "impd_drc_struct.h" 27 #include "impd_drc_interface.h" 28 #include "impd_drc_bitbuffer.h" 29 #include "impd_drc_bitstream_dec_api.h" 30 #include "impd_drc_gain_dec.h" 31 #include "impd_drc_filter_bank.h" 32 #include "impd_drc_multi_band.h" 33 #include "impd_drc_process_audio.h" 34 #include "impd_parametric_drc_dec.h" 35 #include "impd_drc_eq.h" 36 #include "impd_drc_gain_decoder.h" 37 #include "impd_drc_selection_process.h" 38 #include "impd_drc_api_struct_def.h" 39 #include "impd_drc_hashdefines.h" 40 #include "impd_drc_rom.h" 41 42 VOID process_qmf_syn_filt_bank(ia_drc_qmf_filt_struct *qmf_filt, FLOAT64 *buff, 43 FLOAT32 *input_real, FLOAT32 *input_imag, 44 FLOAT32 *output) { 45 WORD32 i, j; 46 FLOAT64 U[10 * QMF_NUM_FILT_BANDS]; 47 FLOAT64 W[10 * QMF_NUM_FILT_BANDS]; 48 49 FLOAT64 tmp; 50 51 for (i = 20 * QMF_FILT_RESOLUTION - 1; i >= 2 * QMF_FILT_RESOLUTION; i--) { 52 buff[i] = buff[i - 2 * QMF_FILT_RESOLUTION]; 53 } 54 55 for (i = 0; i < 2 * QMF_FILT_RESOLUTION; i++) { 56 tmp = 0.0; 57 for (j = 0; j < QMF_FILT_RESOLUTION; j++) { 58 tmp = tmp + input_real[j] * qmf_filt->syn_tab_real[i][j] - 59 input_imag[j] * qmf_filt->syn_tab_imag[i][j]; 60 } 61 buff[i] = tmp; 62 } 63 64 for (i = 0; i < 5; i++) { 65 for (j = 0; j < QMF_FILT_RESOLUTION; j++) { 66 U[2 * QMF_FILT_RESOLUTION * i + j] = 67 buff[4 * QMF_FILT_RESOLUTION * i + j]; 68 U[2 * QMF_FILT_RESOLUTION * i + QMF_FILT_RESOLUTION + j] = 69 buff[4 * QMF_FILT_RESOLUTION * i + 3 * QMF_FILT_RESOLUTION + j]; 70 } 71 } 72 73 for (i = 0; i < 10 * QMF_FILT_RESOLUTION; i++) { 74 W[i] = U[i] * qmf_filter_coeff[i]; 75 } 76 77 for (i = 0; i < QMF_FILT_RESOLUTION; i++) { 78 tmp = 0.0; 79 for (j = 0; j < 10; j++) { 80 tmp = tmp + W[QMF_FILT_RESOLUTION * j + i]; 81 } 82 output[i] = (FLOAT32)tmp; 83 } 84 } 85 86 VOID process_qmf_ana_filt_bank(ia_drc_qmf_filt_struct *qmf_filt, FLOAT64 *buff, 87 FLOAT32 *input, FLOAT32 *output_real, 88 FLOAT32 *output_imag) { 89 WORD32 i, j; 90 FLOAT32 Z[10 * QMF_NUM_FILT_BANDS]; 91 FLOAT32 Y[2 * QMF_NUM_FILT_BANDS]; 92 93 for (i = 10 * QMF_FILT_RESOLUTION - 1; i >= QMF_FILT_RESOLUTION; i--) { 94 buff[i] = buff[i - QMF_FILT_RESOLUTION]; 95 } 96 97 for (i = QMF_FILT_RESOLUTION - 1; i >= 0; i--) { 98 buff[i] = input[QMF_FILT_RESOLUTION - 1 - i]; 99 } 100 101 for (i = 0; i < 10 * QMF_FILT_RESOLUTION; i++) { 102 Z[i] = (FLOAT32)(buff[i] * qmf_filter_coeff[i]); 103 } 104 105 for (i = 0; i < 2 * QMF_FILT_RESOLUTION; i++) { 106 Y[i] = 0.0f; 107 for (j = 0; j < 5; j++) { 108 Y[i] += Z[i + j * 2 * QMF_FILT_RESOLUTION]; 109 } 110 } 111 112 for (i = 0; i < QMF_FILT_RESOLUTION; i++) { 113 output_real[i] = 0.0f; 114 output_imag[i] = 0.0f; 115 for (j = 0; j < 2 * QMF_FILT_RESOLUTION; j++) { 116 output_real[i] += (FLOAT32)(Y[j] * qmf_filt->ana_tab_real[i][j]); 117 output_imag[i] += (FLOAT32)(Y[j] * qmf_filt->ana_tab_imag[i][j]); 118 } 119 } 120 } 121 122 static WORD32 impd_down_mix( 123 ia_drc_sel_proc_output_struct *uni_drc_sel_proc_output, 124 FLOAT32 **input_audio, WORD32 frame_len) { 125 WORD32 num_base_ch = uni_drc_sel_proc_output->base_channel_count; 126 WORD32 num_target_ch = uni_drc_sel_proc_output->target_channel_count; 127 WORD32 i, i_ch, o_ch; 128 FLOAT32 tmp_out[MAX_CHANNEL_COUNT]; 129 130 if (num_target_ch > MAX_CHANNEL_COUNT) return -1; 131 132 if (num_target_ch > num_base_ch) return -1; 133 134 for (i = 0; i < frame_len; i++) { 135 for (o_ch = 0; o_ch < num_target_ch; o_ch++) { 136 tmp_out[o_ch] = 0.0f; 137 for (i_ch = 0; i_ch < num_base_ch; i_ch++) { 138 tmp_out[o_ch] += input_audio[i_ch][i] * 139 uni_drc_sel_proc_output->downmix_matrix[i_ch][o_ch]; 140 } 141 } 142 for (o_ch = 0; o_ch < num_target_ch; o_ch++) { 143 input_audio[o_ch][i] = tmp_out[o_ch]; 144 } 145 for (; o_ch < num_base_ch; o_ch++) { 146 input_audio[o_ch][i] = 0.0f; 147 } 148 } 149 150 return 0; 151 } 152 153 WORD32 impd_init_process_audio_main_td_qmf(ia_drc_api_struct *p_obj_drc) 154 155 { 156 WORD32 error, i, j, num_samples_per_channel; 157 FLOAT32 *input_buffer; 158 WORD16 *input_buffer16, *output_buffer16; 159 FLOAT32 *output_buffer; 160 FLOAT32 *audio_io_buf_real[10]; 161 FLOAT32 *audio_io_buf_imag[10]; 162 FLOAT32 *audio_in_out_buf[10]; 163 FLOAT32 *scratch_buffer; 164 WORD32 last_frame = 0; 165 error = 0; 166 scratch_buffer = (FLOAT32 *)p_obj_drc->pp_mem[1]; 167 input_buffer = (FLOAT32 *)p_obj_drc->pp_mem[2]; 168 output_buffer = (FLOAT32 *)p_obj_drc->pp_mem[3]; 169 170 input_buffer16 = (WORD16 *)p_obj_drc->pp_mem[2]; 171 output_buffer16 = (WORD16 *)p_obj_drc->pp_mem[3]; 172 173 if (p_obj_drc->p_state->ui_in_bytes <= 0) { 174 p_obj_drc->p_state->ui_out_bytes = 0; 175 return 0; 176 } 177 178 if ((p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in / 179 (p_obj_drc->str_config.pcm_size >> 3)) < 180 (UWORD32)p_obj_drc->str_config.frame_size) 181 last_frame = 1; 182 183 for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) { 184 audio_in_out_buf[i] = scratch_buffer; 185 scratch_buffer = scratch_buffer + (p_obj_drc->str_config.frame_size + 32); 186 audio_io_buf_real[i] = 187 scratch_buffer + 188 (p_obj_drc->str_config.frame_size * p_obj_drc->str_config.num_ch_in + 189 512); 190 audio_io_buf_imag[i] = scratch_buffer + 191 2 * (p_obj_drc->str_config.frame_size * 192 p_obj_drc->str_config.num_ch_in + 193 512); 194 ; 195 for (j = 0; j < p_obj_drc->str_config.frame_size; j++) { 196 if (p_obj_drc->str_config.pcm_size == 16) { 197 audio_in_out_buf[i][j] = 198 ((FLOAT32)input_buffer16[j * p_obj_drc->str_config.num_ch_in + i]) / 199 32767.0f; 200 } else { 201 audio_in_out_buf[i][j] = 202 input_buffer[j * p_obj_drc->str_config.num_ch_in + i]; 203 } 204 } 205 } 206 207 error = impd_process_drc_bitstream_dec_gain( 208 p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf, 209 p_obj_drc->str_payload.pstr_drc_config, 210 p_obj_drc->str_payload.pstr_drc_gain, 211 &p_obj_drc->str_bit_handler 212 .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs], 213 p_obj_drc->str_bit_handler.num_bytes_bs, 214 p_obj_drc->str_bit_handler.num_bits_offset_bs, 215 &p_obj_drc->str_bit_handler.num_bits_read_bs); 216 217 if (error > PROC_COMPLETE) return -1; 218 219 p_obj_drc->str_bit_handler.num_bytes_read_bs = 220 (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3); 221 p_obj_drc->str_bit_handler.num_bits_offset_bs = 222 (p_obj_drc->str_bit_handler.num_bits_read_bs & 7); 223 p_obj_drc->str_bit_handler.byte_index_bs += 224 p_obj_drc->str_bit_handler.num_bytes_read_bs; 225 if (p_obj_drc->str_bit_handler.gain_stream_flag == 226 0) // ITTIAM: Flag for applying gain frame by frame 227 { 228 p_obj_drc->str_bit_handler.num_bytes_bs -= 229 p_obj_drc->str_bit_handler.num_bytes_read_bs; 230 } 231 if (p_obj_drc->str_config.bitstream_file_format == 232 BITSTREAM_FILE_FORMAT_SPLIT) { 233 /* shift over fill-bits for frame byte alignment */ 234 if (p_obj_drc->str_bit_handler.num_bits_offset_bs != 0) { 235 p_obj_drc->str_bit_handler.num_bits_read_bs = 236 p_obj_drc->str_bit_handler.num_bits_read_bs + 8 - 237 p_obj_drc->str_bit_handler.num_bits_offset_bs; 238 p_obj_drc->str_bit_handler.num_bytes_read_bs = 239 p_obj_drc->str_bit_handler.num_bytes_read_bs + 1; 240 p_obj_drc->str_bit_handler.num_bits_offset_bs = 0; 241 p_obj_drc->str_bit_handler.byte_index_bs = 242 p_obj_drc->str_bit_handler.byte_index_bs + 1; 243 if (p_obj_drc->str_bit_handler.gain_stream_flag == 244 0) // ITTIAM: Flag for applying gain frame by frame 245 { 246 p_obj_drc->str_bit_handler.num_bytes_bs = 247 p_obj_drc->str_bit_handler.num_bytes_bs - 1; 248 } 249 } 250 } 251 252 for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) { 253 for (j = 0; j < p_obj_drc->str_config.frame_size; j += 64) { 254 process_qmf_ana_filt_bank( 255 p_obj_drc->str_payload.pstr_qmf_filter, 256 p_obj_drc->str_payload.pstr_qmf_filter->ana_buff + 257 i * 4 * p_obj_drc->str_config.frame_size, 258 &(audio_in_out_buf[i][j]), &(audio_io_buf_real[i][j]), 259 &(audio_io_buf_imag[i][j])); 260 } 261 } 262 error = impd_drc_process_freq_domain( 263 p_obj_drc->str_payload.pstr_gain_dec[0], 264 p_obj_drc->str_payload.pstr_drc_config, 265 p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real, 266 audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output 267 ->loudness_normalization_gain_db, 268 p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost, 269 p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress, 270 p_obj_drc->str_payload.pstr_drc_sel_proc_output 271 ->drc_characteristic_target); 272 273 if (error) return error; 274 275 if (p_obj_drc->str_payload.pstr_drc_sel_proc_output->target_channel_count < 276 p_obj_drc->str_payload.pstr_drc_sel_proc_output->base_channel_count) { 277 error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output, 278 audio_io_buf_real, p_obj_drc->str_config.frame_size); 279 if (error) return error; 280 281 error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output, 282 audio_io_buf_imag, p_obj_drc->str_config.frame_size); 283 if (error) return error; 284 } 285 286 error = impd_drc_process_freq_domain( 287 p_obj_drc->str_payload.pstr_gain_dec[1], 288 p_obj_drc->str_payload.pstr_drc_config, 289 p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real, 290 audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output 291 ->loudness_normalization_gain_db, 292 p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost, 293 p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress, 294 p_obj_drc->str_payload.pstr_drc_sel_proc_output 295 ->drc_characteristic_target); 296 if (error) return -1; 297 for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) { 298 for (j = 0; j < p_obj_drc->str_config.frame_size; j += 64) { 299 process_qmf_syn_filt_bank( 300 p_obj_drc->str_payload.pstr_qmf_filter, 301 p_obj_drc->str_payload.pstr_qmf_filter->syn_buff + 302 i * 4 * p_obj_drc->str_config.frame_size, 303 &(audio_io_buf_real[i][j]), &(audio_io_buf_imag[i][j]), 304 &(audio_in_out_buf[i][j])); 305 } 306 } 307 308 if (p_obj_drc->str_payload.pstr_drc_sel_proc_output 309 ->loudness_normalization_gain_db != 0.0f) { 310 FLOAT32 loudness_normalization_gain = 311 (FLOAT32)pow(10.0, p_obj_drc->str_payload.pstr_drc_sel_proc_output 312 ->loudness_normalization_gain_db / 313 20.0); 314 for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) { 315 for (j = 0; j < p_obj_drc->str_config.frame_size; j++) { 316 audio_io_buf_real[i][j] *= loudness_normalization_gain; 317 audio_io_buf_imag[i][j] *= loudness_normalization_gain; 318 } 319 } 320 } 321 322 num_samples_per_channel = p_obj_drc->str_config.frame_size; 323 324 for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) { 325 for (j = 0; j < p_obj_drc->str_config.frame_size; j++) { 326 if (p_obj_drc->str_config.pcm_size == 16) { 327 output_buffer16[j * p_obj_drc->str_config.num_ch_out + i] = 328 (WORD16)(audio_in_out_buf[i][j] * 32767.0f); 329 } else { 330 output_buffer[j * p_obj_drc->str_config.num_ch_out + i] = 331 audio_in_out_buf[i][j]; 332 } 333 } 334 } 335 p_obj_drc->p_state->ui_out_bytes = 336 p_obj_drc->str_config.num_ch_out * 337 (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in); 338 339 if (p_obj_drc->str_config.bitstream_file_format != 340 BITSTREAM_FILE_FORMAT_SPLIT) { 341 error = impd_process_drc_bitstream_dec( 342 p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf, 343 p_obj_drc->str_payload.pstr_drc_config, 344 p_obj_drc->str_payload.pstr_loudness_info, 345 &p_obj_drc->str_bit_handler 346 .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs], 347 p_obj_drc->str_bit_handler.num_bytes_bs, 348 p_obj_drc->str_bit_handler.num_bits_offset_bs, 349 &p_obj_drc->str_bit_handler.num_bits_read_bs); 350 351 if (error > PROC_COMPLETE) return -1; 352 353 p_obj_drc->str_bit_handler.num_bytes_read_bs = 354 (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3); 355 p_obj_drc->str_bit_handler.num_bits_offset_bs = 356 (p_obj_drc->str_bit_handler.num_bits_read_bs & 7); 357 p_obj_drc->str_bit_handler.byte_index_bs += 358 p_obj_drc->str_bit_handler.num_bytes_read_bs; 359 p_obj_drc->str_bit_handler.num_bytes_bs -= 360 p_obj_drc->str_bit_handler.num_bytes_read_bs; 361 } 362 363 return error; 364 } 365