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_bitbuffer.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_peak_limiter.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
40 #define BITSTREAM_FILE_FORMAT_SPLIT 1
41
impd_down_mix(ia_drc_sel_proc_output_struct * uni_drc_sel_proc_output,FLOAT32 ** input_audio,WORD32 frame_len)42 static WORD32 impd_down_mix(
43 ia_drc_sel_proc_output_struct *uni_drc_sel_proc_output,
44 FLOAT32 **input_audio, WORD32 frame_len) {
45 WORD32 num_base_ch = uni_drc_sel_proc_output->base_channel_count;
46 WORD32 num_target_ch = uni_drc_sel_proc_output->target_channel_count;
47 WORD32 i, i_ch, o_ch;
48 FLOAT32 tmp_out[MAX_CHANNEL_COUNT];
49
50 if (uni_drc_sel_proc_output->downmix_matrix_present == 0) return 0;
51
52 if (input_audio == 0) return 0;
53
54 if (num_target_ch > MAX_CHANNEL_COUNT) return -1;
55
56 if (num_target_ch > num_base_ch) return -1;
57
58 for (i = 0; i < frame_len; i++) {
59 for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
60 tmp_out[o_ch] = 0.0f;
61 for (i_ch = 0; i_ch < num_base_ch; i_ch++) {
62 tmp_out[o_ch] += input_audio[i_ch][i] *
63 uni_drc_sel_proc_output->downmix_matrix[i_ch][o_ch];
64 }
65 }
66 for (o_ch = 0; o_ch < num_target_ch; o_ch++) {
67 input_audio[o_ch][i] = tmp_out[o_ch];
68 }
69 for (; o_ch < num_base_ch; o_ch++) {
70 input_audio[o_ch][i] = 0.0f;
71 }
72 }
73
74 return 0;
75 }
76
impd_init_process_audio_main_stft(ia_drc_api_struct * p_obj_drc)77 WORD32 impd_init_process_audio_main_stft(ia_drc_api_struct *p_obj_drc)
78
79 {
80 WORD32 error = 0, i, j, num_samples_per_channel;
81 FLOAT32 *input_buffer;
82 FLOAT32 *output_buffer;
83 FLOAT32 *audio_io_buf_real[10];
84 FLOAT32 *audio_io_buf_imag[10];
85 FLOAT32 *scratch_buffer;
86 WORD32 last_frame = 0;
87 scratch_buffer = (FLOAT32 *)p_obj_drc->pp_mem[1];
88 input_buffer = (FLOAT32 *)p_obj_drc->pp_mem[2];
89 output_buffer = (FLOAT32 *)p_obj_drc->pp_mem[3];
90
91 if (p_obj_drc->p_state->ui_in_bytes <= 0) {
92 p_obj_drc->p_state->ui_out_bytes = 0;
93 return 0;
94 }
95
96 if ((p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in /
97 (p_obj_drc->str_config.pcm_size >> 3)) <
98 (UWORD32)p_obj_drc->str_config.frame_size)
99 last_frame = 1;
100 for (i = 0; i < p_obj_drc->str_config.num_ch_in; i++) {
101 audio_io_buf_real[i] =
102 scratch_buffer + i * (p_obj_drc->str_config.frame_size + 32);
103 audio_io_buf_imag[i] =
104 scratch_buffer +
105 p_obj_drc->str_config.num_ch_in * p_obj_drc->str_config.frame_size +
106 p_obj_drc->str_config.num_ch_in * 64 +
107 i * (p_obj_drc->str_config.frame_size + 64);
108 for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
109 audio_io_buf_real[i][j] =
110 input_buffer[j * p_obj_drc->str_config.num_ch_in + i];
111 audio_io_buf_imag[i][j] =
112 input_buffer[p_obj_drc->str_config.num_ch_in *
113 p_obj_drc->str_config.frame_size +
114 j * p_obj_drc->str_config.num_ch_in + i];
115 }
116 }
117
118 error = impd_process_drc_bitstream_dec_gain(
119 p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
120 p_obj_drc->str_payload.pstr_drc_config,
121 p_obj_drc->str_payload.pstr_drc_gain,
122 &p_obj_drc->str_bit_handler
123 .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
124 p_obj_drc->str_bit_handler.num_bytes_bs,
125 p_obj_drc->str_bit_handler.num_bits_offset_bs,
126 &p_obj_drc->str_bit_handler.num_bits_read_bs);
127
128 if (error > PROC_COMPLETE) return -1;
129
130 p_obj_drc->str_bit_handler.num_bytes_read_bs =
131 (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
132 p_obj_drc->str_bit_handler.num_bits_offset_bs =
133 (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
134 p_obj_drc->str_bit_handler.byte_index_bs +=
135 p_obj_drc->str_bit_handler.num_bytes_read_bs;
136 if (p_obj_drc->str_bit_handler.gain_stream_flag ==
137 0) // ITTIAM: Flag for applying gain frame by frame
138 {
139 p_obj_drc->str_bit_handler.num_bytes_bs -=
140 p_obj_drc->str_bit_handler.num_bytes_read_bs;
141 }
142
143 if (p_obj_drc->str_config.bitstream_file_format ==
144 BITSTREAM_FILE_FORMAT_SPLIT) {
145 if (p_obj_drc->str_bit_handler.num_bits_offset_bs != 0) {
146 p_obj_drc->str_bit_handler.num_bits_read_bs =
147 p_obj_drc->str_bit_handler.num_bits_read_bs + 8 -
148 p_obj_drc->str_bit_handler.num_bits_offset_bs;
149 p_obj_drc->str_bit_handler.num_bytes_read_bs =
150 p_obj_drc->str_bit_handler.num_bytes_read_bs + 1;
151 p_obj_drc->str_bit_handler.num_bits_offset_bs = 0;
152 p_obj_drc->str_bit_handler.byte_index_bs =
153 p_obj_drc->str_bit_handler.byte_index_bs + 1;
154 if (p_obj_drc->str_bit_handler.gain_stream_flag ==
155 0) // ITTIAM: Flag for applying gain frame by frame
156 {
157 p_obj_drc->str_bit_handler.num_bytes_bs =
158 p_obj_drc->str_bit_handler.num_bytes_bs - 1;
159 }
160 }
161 }
162
163 error = impd_drc_process_freq_domain(
164 p_obj_drc->str_payload.pstr_gain_dec[0],
165 p_obj_drc->str_payload.pstr_drc_config,
166 p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real,
167 audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output
168 ->loudness_normalization_gain_db,
169 p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
170 p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
171 p_obj_drc->str_payload.pstr_drc_sel_proc_output
172 ->drc_characteristic_target);
173 if (error) return -1;
174
175 error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
176 audio_io_buf_real, p_obj_drc->str_config.frame_size);
177 if (error) return -1;
178
179 error = impd_down_mix(p_obj_drc->str_payload.pstr_drc_sel_proc_output,
180 audio_io_buf_imag, p_obj_drc->str_config.frame_size);
181 if (error) return -1;
182
183 error = impd_drc_process_freq_domain(
184 p_obj_drc->str_payload.pstr_gain_dec[1],
185 p_obj_drc->str_payload.pstr_drc_config,
186 p_obj_drc->str_payload.pstr_drc_gain, audio_io_buf_real,
187 audio_io_buf_imag, p_obj_drc->str_payload.pstr_drc_sel_proc_output
188 ->loudness_normalization_gain_db,
189 p_obj_drc->str_payload.pstr_drc_sel_proc_output->boost,
190 p_obj_drc->str_payload.pstr_drc_sel_proc_output->compress,
191 p_obj_drc->str_payload.pstr_drc_sel_proc_output
192 ->drc_characteristic_target);
193 if (error) return -1;
194
195 if (p_obj_drc->str_payload.pstr_drc_sel_proc_output
196 ->loudness_normalization_gain_db != 0.0f) {
197 FLOAT32 loudness_normalization_gain =
198 (FLOAT32)pow(10.0, p_obj_drc->str_payload.pstr_drc_sel_proc_output
199 ->loudness_normalization_gain_db /
200 20.0);
201 for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
202 for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
203 audio_io_buf_real[i][j] *= loudness_normalization_gain;
204 audio_io_buf_imag[i][j] *= loudness_normalization_gain;
205 }
206 }
207 }
208
209 num_samples_per_channel = p_obj_drc->str_config.frame_size;
210
211 for (i = 0; i < p_obj_drc->str_config.num_ch_out; i++) {
212 for (j = 0; j < p_obj_drc->str_config.frame_size; j++) {
213 output_buffer[j * p_obj_drc->str_config.num_ch_out + i] =
214 audio_io_buf_real[i][j];
215 output_buffer[p_obj_drc->str_config.frame_size *
216 p_obj_drc->str_config.num_ch_in +
217 j * p_obj_drc->str_config.num_ch_out + i] =
218 audio_io_buf_imag[i][j];
219 }
220 }
221 p_obj_drc->p_state->ui_out_bytes =
222 p_obj_drc->str_config.num_ch_out * (p_obj_drc->str_config.frame_size) * 4;
223 p_obj_drc->p_state->ui_out_bytes =
224 p_obj_drc->str_config.num_ch_out *
225 (p_obj_drc->p_state->ui_in_bytes / p_obj_drc->str_config.num_ch_in);
226
227 if (last_frame == 0) {
228 if (p_obj_drc->str_config.bitstream_file_format !=
229 BITSTREAM_FILE_FORMAT_SPLIT) {
230 error = impd_process_drc_bitstream_dec(
231 p_obj_drc->str_payload.pstr_bitstream_dec, p_obj_drc->pstr_bit_buf,
232 p_obj_drc->str_payload.pstr_drc_config,
233 p_obj_drc->str_payload.pstr_loudness_info,
234 &p_obj_drc->str_bit_handler
235 .it_bit_buf[p_obj_drc->str_bit_handler.byte_index_bs],
236 p_obj_drc->str_bit_handler.num_bytes_bs,
237 p_obj_drc->str_bit_handler.num_bits_offset_bs,
238 &p_obj_drc->str_bit_handler.num_bits_read_bs);
239
240 if (error > PROC_COMPLETE) return -1;
241
242 p_obj_drc->str_bit_handler.num_bytes_read_bs =
243 (p_obj_drc->str_bit_handler.num_bits_read_bs >> 3);
244 p_obj_drc->str_bit_handler.num_bits_offset_bs =
245 (p_obj_drc->str_bit_handler.num_bits_read_bs & 7);
246 p_obj_drc->str_bit_handler.byte_index_bs +=
247 p_obj_drc->str_bit_handler.num_bytes_read_bs;
248 p_obj_drc->str_bit_handler.num_bytes_bs -=
249 p_obj_drc->str_bit_handler.num_bytes_read_bs;
250 }
251 }
252
253 return error;
254 }
255