/src/libxaac/decoder/ixheaacd_stereo.c
Line | Count | Source |
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 "ixheaacd_sbr_common.h" |
21 | | #include "ixheaac_type_def.h" |
22 | | |
23 | | #include "ixheaac_constants.h" |
24 | | #include "ixheaac_basic_ops32.h" |
25 | | #include "ixheaac_basic_ops16.h" |
26 | | #include "ixheaac_basic_ops40.h" |
27 | | #include "ixheaac_basic_ops.h" |
28 | | |
29 | | #include "ixheaacd_defines.h" |
30 | | #include "ixheaacd_aac_rom.h" |
31 | | #include "ixheaacd_bitbuffer.h" |
32 | | #include "ixheaacd_common_rom.h" |
33 | | #include "ixheaacd_basic_funcs.h" |
34 | | |
35 | | #include "ixheaac_basic_op.h" |
36 | | #include "ixheaacd_intrinsics.h" |
37 | | |
38 | | #include "ixheaacd_pulsedata.h" |
39 | | |
40 | | #include "ixheaacd_pns.h" |
41 | | #include "ixheaacd_drc_data_struct.h" |
42 | | |
43 | | #include "ixheaacd_lt_predict.h" |
44 | | #include "ixheaacd_cnst.h" |
45 | | #include "ixheaacd_ec_defines.h" |
46 | | #include "ixheaacd_ec_struct_def.h" |
47 | | #include "ixheaacd_channelinfo.h" |
48 | | #include "ixheaacd_channel.h" |
49 | | #include "ixheaacd_drc_dec.h" |
50 | | #include "ixheaacd_audioobjtypes.h" |
51 | | |
52 | | #include "ixheaacd_stereo.h" |
53 | | |
54 | | VOID ixheaacd_ms_stereo_process( |
55 | | ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[CHANNELS], |
56 | | ia_aac_dec_tables_struct *ptr_aac_tables) |
57 | | |
58 | 29.5k | { |
59 | 29.5k | WORD32 win_grp, grp_len, k; |
60 | 29.5k | WORD32 *l_spec = ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff; |
61 | 29.5k | WORD32 *r_spec = ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff; |
62 | 29.5k | WORD16 maximum_bins_short = |
63 | 29.5k | (ptr_aac_dec_channel_info[LEFT]->str_ics_info.frame_length) >> 3; |
64 | 29.5k | WORD8 *ptr_group_len = |
65 | 29.5k | ptr_aac_dec_channel_info[LEFT]->str_ics_info.window_group_length; |
66 | 29.5k | const WORD8 *ptr_sfb_width = |
67 | 29.5k | ptr_aac_tables |
68 | 29.5k | ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT] |
69 | 29.5k | ->str_ics_info.window_sequence] |
70 | 29.5k | .sfb_width; |
71 | | |
72 | 29.5k | UWORD8 *ptr_ms_used = |
73 | 29.5k | &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0]; |
74 | | |
75 | 29.5k | for (win_grp = 0; |
76 | 109k | win_grp < ptr_aac_dec_channel_info[LEFT]->str_ics_info.num_window_groups; |
77 | 80.0k | win_grp++) { |
78 | 167k | for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) { |
79 | 87.5k | WORD32 sfb; |
80 | 87.5k | WORD32 ixheaacd_drc_offset = 0; |
81 | | |
82 | 208k | for (sfb = 0; sfb < ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb; |
83 | 120k | sfb++) { |
84 | 120k | ixheaacd_drc_offset += ptr_sfb_width[sfb]; |
85 | | |
86 | 120k | if (*ptr_ms_used++) { |
87 | 429k | for (k = 0; k < ptr_sfb_width[sfb]; k = k + 2) { |
88 | 348k | WORD32 left_coef = *l_spec; |
89 | 348k | WORD32 right_coef = *r_spec; |
90 | 348k | WORD32 left_coef2 = *(l_spec + 1); |
91 | 348k | WORD32 right_coef2 = *(r_spec + 1); |
92 | | |
93 | 348k | *l_spec++ = ixheaac_add32_sat(left_coef, right_coef); |
94 | 348k | *r_spec++ = ixheaac_sub32_sat(left_coef, right_coef); |
95 | 348k | *l_spec++ = ixheaac_add32_sat(left_coef2, right_coef2); |
96 | 348k | *r_spec++ = ixheaac_sub32_sat(left_coef2, right_coef2); |
97 | 348k | } |
98 | 81.1k | } else { |
99 | 39.3k | l_spec += ptr_sfb_width[sfb]; |
100 | 39.3k | r_spec += ptr_sfb_width[sfb]; |
101 | 39.3k | } |
102 | 120k | } |
103 | 87.5k | ptr_ms_used -= ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb; |
104 | | |
105 | 87.5k | if (maximum_bins_short == 120) { |
106 | 24.9k | l_spec = l_spec + maximum_bins_short - ixheaacd_drc_offset; |
107 | 24.9k | r_spec = r_spec + maximum_bins_short - ixheaacd_drc_offset; |
108 | 62.6k | } else { |
109 | 62.6k | l_spec = l_spec + 128 - ixheaacd_drc_offset; |
110 | 62.6k | r_spec = r_spec + 128 - ixheaacd_drc_offset; |
111 | 62.6k | } |
112 | 87.5k | } |
113 | | |
114 | 80.0k | ptr_ms_used += JOINT_STEREO_MAX_BANDS; |
115 | 80.0k | } |
116 | 29.5k | } |
117 | | |
118 | 215k | static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32l(WORD32 a, WORD32 b) { |
119 | 215k | WORD32 result; |
120 | 215k | WORD64 temp_result; |
121 | | |
122 | 215k | temp_result = (WORD64)a * (WORD64)b; |
123 | | |
124 | 215k | result = (WORD32)(temp_result >> 16); |
125 | | |
126 | 215k | return (result); |
127 | 215k | } |
128 | | |
129 | | VOID ixheaacd_intensity_stereo_process( |
130 | | ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[CHANNELS], |
131 | | ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type, WORD32 aac_sf_data_resil_flag, |
132 | 34.2k | WORD16 framelength) { |
133 | 34.2k | UWORD8 *ptr_ms_used = |
134 | 34.2k | &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0]; |
135 | 34.2k | WORD8 *ptr_code_book = &ptr_aac_dec_channel_info[RIGHT]->ptr_code_book[0]; |
136 | 34.2k | WORD16 *ptr_scale_factor = |
137 | 34.2k | &ptr_aac_dec_channel_info[RIGHT]->ptr_scale_factor[0]; |
138 | 34.2k | WORD32 *r_spec = &ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff[0]; |
139 | 34.2k | WORD32 *l_spec = &ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff[0]; |
140 | 34.2k | WORD16 maximum_bins_short = |
141 | 34.2k | (ptr_aac_dec_channel_info[LEFT]->str_ics_info.frame_length) >> 3; |
142 | 34.2k | WORD8 *ptr_group_len = |
143 | 34.2k | ptr_aac_dec_channel_info[RIGHT]->str_ics_info.window_group_length; |
144 | 34.2k | const WORD8 *ptr_sfb_width = |
145 | 34.2k | ptr_aac_tables |
146 | 34.2k | ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT] |
147 | 34.2k | ->str_ics_info.window_sequence] |
148 | 34.2k | .sfb_width; |
149 | | |
150 | 34.2k | WORD32 *ptr_scale_table; |
151 | | |
152 | 34.2k | if (960 == framelength) |
153 | 5.47k | ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table_960; |
154 | 28.7k | else |
155 | 28.7k | ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table; |
156 | | |
157 | 34.2k | WORD32 win_grp, grp_len, k; |
158 | | |
159 | 34.2k | for (win_grp = 0; |
160 | 119k | win_grp < |
161 | 119k | ptr_aac_dec_channel_info[RIGHT]->str_ics_info.num_window_groups; |
162 | 85.3k | win_grp++) { |
163 | 178k | for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) { |
164 | 93.1k | WORD32 sfb; |
165 | 93.1k | WORD32 ixheaacd_drc_offset = 0; |
166 | | |
167 | 227k | for (sfb = 0; sfb < ptr_aac_dec_channel_info[RIGHT]->str_ics_info.max_sfb; |
168 | 134k | sfb++) { |
169 | 134k | WORD8 code_book = ptr_code_book[sfb]; |
170 | 134k | ixheaacd_drc_offset += ptr_sfb_width[sfb]; |
171 | | |
172 | 134k | if (((code_book >= INTENSITY_HCB2) && |
173 | 47.5k | ((object_type != AOT_ER_AAC_ELD) && |
174 | 8.54k | (object_type != AOT_ER_AAC_LD))) || |
175 | 131k | (((code_book == INTENSITY_HCB2) || (code_book == INTENSITY_HCB)) && |
176 | 45.1k | ((object_type == AOT_ER_AAC_ELD) || |
177 | 6.22k | (object_type == AOT_ER_AAC_LD)))) |
178 | | |
179 | 47.4k | { |
180 | 47.4k | WORD32 sfb_factor, scale; |
181 | 47.4k | WORD32 scf_exp; |
182 | | |
183 | 47.4k | sfb_factor = (ptr_scale_factor[sfb]); |
184 | 47.4k | if (aac_sf_data_resil_flag) sfb_factor = -sfb_factor; |
185 | | |
186 | 47.4k | scf_exp = (sfb_factor >> 2); |
187 | 47.4k | scale = *(ptr_scale_table + (sfb_factor & 3)); |
188 | 47.4k | if (!((ptr_ms_used[sfb]) ^ (code_book & 0x1))) { |
189 | 2.34k | scale = ixheaac_negate32(scale); |
190 | 2.34k | } |
191 | | |
192 | 47.4k | scf_exp = -(scf_exp + 2); |
193 | | |
194 | 262k | for (k = 0; k < ptr_sfb_width[sfb]; k++) { |
195 | 215k | WORD32 temp, shift_val; |
196 | 215k | temp = *l_spec++; |
197 | | |
198 | 215k | shift_val = ixheaac_norm32(temp); |
199 | 215k | temp = ixheaac_shl32(temp, shift_val); |
200 | | |
201 | 215k | temp = ixheaacd_mult32x16in32l(temp, scale); |
202 | 215k | shift_val = shift_val + scf_exp; |
203 | | |
204 | 215k | if (shift_val < 0) { |
205 | 3.91k | if (shift_val < -31) { |
206 | 784 | shift_val = -31; |
207 | 784 | } |
208 | 3.91k | temp = ixheaac_shl32_sat(temp, -shift_val); |
209 | 211k | } else { |
210 | 211k | if (shift_val > 31) { |
211 | 5.75k | shift_val = 31; |
212 | 5.75k | } |
213 | 211k | temp = ixheaac_shr32(temp, shift_val); |
214 | 211k | } |
215 | 215k | *r_spec++ = temp; |
216 | 215k | } |
217 | | |
218 | 86.7k | } else { |
219 | 86.7k | l_spec += ptr_sfb_width[sfb]; |
220 | 86.7k | r_spec += ptr_sfb_width[sfb]; |
221 | 86.7k | } |
222 | 134k | } |
223 | | |
224 | 93.1k | if (maximum_bins_short == 120) { |
225 | 25.6k | l_spec += maximum_bins_short - ixheaacd_drc_offset; |
226 | 25.6k | r_spec += maximum_bins_short - ixheaacd_drc_offset; |
227 | 67.4k | } else { |
228 | 67.4k | l_spec += 128 - ixheaacd_drc_offset; |
229 | 67.4k | r_spec += 128 - ixheaacd_drc_offset; |
230 | 67.4k | } |
231 | 93.1k | } |
232 | 85.3k | ptr_ms_used += 64; |
233 | 85.3k | ptr_code_book += 16; |
234 | 85.3k | ptr_scale_factor += 16; |
235 | 85.3k | } |
236 | 34.2k | } |