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
impd_apply_gains_and_add(ia_drc_instructions_struct * pstr_drc_instruction_arr,const WORD32 drc_instructions_index,ia_drc_params_struct * ia_drc_params_struct,ia_gain_buffer_struct * pstr_gain_buf,shape_filter_block shape_filter_block[],FLOAT32 * deinterleaved_audio[],FLOAT32 * channel_audio[],WORD32 impd_apply_gains)34 VOID 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, signal_index = 0;
44 WORD32 gain_index_for_group[CHANNEL_GROUP_COUNT_MAX];
45 WORD32 signal_index_for_channel[MAX_CHANNEL_COUNT];
46 FLOAT32* lpcm_gains;
47 FLOAT32 sum;
48 FLOAT32 drc_gain_last = 0, gain_thr;
49 WORD32 i_end, i_start;
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 gain_index_for_group[0] = 0;
62 for (g = 0; g < str_drc_instruction_str->num_drc_ch_groups - 1; g++) {
63 gain_index_for_group[g + 1] =
64 gain_index_for_group[g] +
65 str_drc_instruction_str->band_count_of_ch_group[g];
66 }
67 signal_index_for_channel[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 signal_index_for_channel[c + 1] =
71 signal_index_for_channel[c] +
72 str_drc_instruction_str->band_count_of_ch_group
73 [str_drc_instruction_str->channel_group_of_ch[c]];
74 } else {
75 signal_index_for_channel[c + 1] = signal_index_for_channel[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[gain_index_for_group[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[gain_index_for_group[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 i_end = 0;
98 i_start = 0;
99 while (i_end < 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 gain_thr = 0.0001f * drc_gain_last;
103 while ((i_end < ia_drc_params_struct->drc_frame_size) &&
104 (fabs(lpcm_gains[i_end] - drc_gain_last) <= gain_thr))
105 i_end++;
106 } else {
107 i_end = 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 signal_index = signal_index_for_channel[c] + b;
115
116 if (impd_apply_gains == 1) {
117 impd_shape_filt_block_time_process(
118 &shape_filter_block[g], &lpcm_gains[0], signal_index,
119 &deinterleaved_audio[signal_index][0], i_start, i_end);
120
121 } else {
122 for (i = i_start; i < i_end; i++) {
123 deinterleaved_audio[signal_index][i] = lpcm_gains[i];
124 }
125 }
126 }
127 }
128 if ((i_end < ia_drc_params_struct->drc_frame_size) &&
129 (shape_filter_block[g].shape_flter_block_flag)) {
130 impd_shape_filt_block_adapt(lpcm_gains[i_end],
131 &shape_filter_block[g]);
132 }
133 if ((i_end == i_start) &&
134 (drc_gain_last == shape_filter_block[g].drc_gain_last))
135 break;
136 i_start = i_end;
137 }
138 }
139 }
140 }
141 }
142 }
143
144 signal_index = 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[signal_index + b][i];
157 }
158
159 channel_audio[c][i] = sum;
160 }
161 signal_index += 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[signal_index][i];
165 }
166 signal_index++;
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;
180 }
181
182 WORD32
impd_filter_banks_process(ia_drc_instructions_struct * pstr_drc_instruction_arr,const WORD32 drc_instructions_index,ia_drc_params_struct * ia_drc_params_struct,FLOAT32 * audio_io_buf[],ia_audio_band_buffer_struct * audio_band_buffer,ia_filter_banks_struct * ia_filter_banks_struct,const WORD32 passThru)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
impd_store_audio_io_buffer_time(FLOAT32 * audio_in_out_buf[],ia_audio_in_out_buf * audio_io_buf_internal)281 VOID impd_store_audio_io_buffer_time(
282 FLOAT32* audio_in_out_buf[], ia_audio_in_out_buf* audio_io_buf_internal) {
283 WORD32 i, j;
284
285 if (audio_io_buf_internal->audio_delay_samples) {
286 for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
287 for (j = 0; j < audio_io_buf_internal->frame_size; j++) {
288 audio_io_buf_internal->audio_io_buffer_delayed
289 [i][audio_io_buf_internal->audio_delay_samples + j] =
290 audio_in_out_buf[i][j];
291 }
292 }
293 } else {
294 audio_io_buf_internal->audio_io_buffer_delayed = audio_in_out_buf;
295 audio_io_buf_internal->audio_in_out_buf = audio_in_out_buf;
296 }
297
298 return;
299 }
300
impd_retrieve_audio_io_buffer_time(FLOAT32 * audio_in_out_buf[],ia_audio_in_out_buf * audio_io_buf_internal)301 VOID impd_retrieve_audio_io_buffer_time(
302 FLOAT32* audio_in_out_buf[], ia_audio_in_out_buf* audio_io_buf_internal) {
303 WORD32 i, j;
304
305 if (audio_io_buf_internal->audio_delay_samples) {
306 for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
307 for (j = 0; j < audio_io_buf_internal->frame_size; j++) {
308 audio_in_out_buf[i][j] =
309 audio_io_buf_internal->audio_io_buffer_delayed[i][j];
310 }
311 }
312 }
313
314 return;
315 }
316
impd_advance_audio_io_buffer_time(ia_audio_in_out_buf * audio_io_buf_internal)317 VOID impd_advance_audio_io_buffer_time(
318 ia_audio_in_out_buf* audio_io_buf_internal) {
319 WORD32 i;
320 if (audio_io_buf_internal->audio_delay_samples) {
321 for (i = 0; i < audio_io_buf_internal->audio_num_chan; i++) {
322 memmove(
323 audio_io_buf_internal->audio_io_buffer_delayed[i],
324 &audio_io_buf_internal
325 ->audio_io_buffer_delayed[i][audio_io_buf_internal->frame_size],
326 sizeof(FLOAT32) * audio_io_buf_internal->audio_delay_samples);
327 }
328 }
329
330 return;
331 }
332