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