• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
process_qmf_syn_filt_bank(ia_drc_qmf_filt_struct * qmf_filt,FLOAT64 * buff,FLOAT32 * input_real,FLOAT32 * input_imag,FLOAT32 * output)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 
process_qmf_ana_filt_bank(ia_drc_qmf_filt_struct * qmf_filt,FLOAT64 * buff,FLOAT32 * input,FLOAT32 * output_real,FLOAT32 * output_imag)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 
impd_down_mix(ia_drc_sel_proc_output_struct * uni_drc_sel_proc_output,FLOAT32 ** input_audio,WORD32 frame_len)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 
impd_init_process_audio_main_td_qmf(ia_drc_api_struct * p_obj_drc)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