• 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 #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