xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_stereo.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1*15dc779aSAndroid Build Coastguard Worker /******************************************************************************
2*15dc779aSAndroid Build Coastguard Worker  *                                                                            *
3*15dc779aSAndroid Build Coastguard Worker  * Copyright (C) 2018 The Android Open Source Project
4*15dc779aSAndroid Build Coastguard Worker  *
5*15dc779aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*15dc779aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*15dc779aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*15dc779aSAndroid Build Coastguard Worker  *
9*15dc779aSAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*15dc779aSAndroid Build Coastguard Worker  *
11*15dc779aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*15dc779aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*15dc779aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*15dc779aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*15dc779aSAndroid Build Coastguard Worker  * limitations under the License.
16*15dc779aSAndroid Build Coastguard Worker  *
17*15dc779aSAndroid Build Coastguard Worker  *****************************************************************************
18*15dc779aSAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*15dc779aSAndroid Build Coastguard Worker */
20*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
21*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
22*15dc779aSAndroid Build Coastguard Worker 
23*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops16.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops.h"
28*15dc779aSAndroid Build Coastguard Worker 
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_defines.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_aac_rom.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_common_rom.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_basic_funcs.h"
34*15dc779aSAndroid Build Coastguard Worker 
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_op.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_intrinsics.h"
37*15dc779aSAndroid Build Coastguard Worker 
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_pulsedata.h"
39*15dc779aSAndroid Build Coastguard Worker 
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_pns.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_data_struct.h"
42*15dc779aSAndroid Build Coastguard Worker 
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_lt_predict.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_cnst.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_channelinfo.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_channel.h"
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_dec.h"
50*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_audioobjtypes.h"
51*15dc779aSAndroid Build Coastguard Worker 
52*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_stereo.h"
53*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_ms_stereo_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info[2],ia_aac_dec_tables_struct * ptr_aac_tables)54*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_ms_stereo_process(
55*15dc779aSAndroid Build Coastguard Worker     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2],
56*15dc779aSAndroid Build Coastguard Worker     ia_aac_dec_tables_struct *ptr_aac_tables)
57*15dc779aSAndroid Build Coastguard Worker 
58*15dc779aSAndroid Build Coastguard Worker {
59*15dc779aSAndroid Build Coastguard Worker   WORD32 win_grp, grp_len, k;
60*15dc779aSAndroid Build Coastguard Worker   WORD32 *l_spec = ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff;
61*15dc779aSAndroid Build Coastguard Worker   WORD32 *r_spec = ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff;
62*15dc779aSAndroid Build Coastguard Worker   WORD16 maximum_bins_short =
63*15dc779aSAndroid Build Coastguard Worker       (ptr_aac_dec_channel_info[LEFT]->str_ics_info.frame_length) >> 3;
64*15dc779aSAndroid Build Coastguard Worker   WORD8 *ptr_group_len =
65*15dc779aSAndroid Build Coastguard Worker       ptr_aac_dec_channel_info[LEFT]->str_ics_info.window_group_length;
66*15dc779aSAndroid Build Coastguard Worker   const WORD8 *ptr_sfb_width =
67*15dc779aSAndroid Build Coastguard Worker       ptr_aac_tables
68*15dc779aSAndroid Build Coastguard Worker           ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT]
69*15dc779aSAndroid Build Coastguard Worker                                  ->str_ics_info.window_sequence]
70*15dc779aSAndroid Build Coastguard Worker           .sfb_width;
71*15dc779aSAndroid Build Coastguard Worker 
72*15dc779aSAndroid Build Coastguard Worker   UWORD8 *ptr_ms_used =
73*15dc779aSAndroid Build Coastguard Worker       &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0];
74*15dc779aSAndroid Build Coastguard Worker 
75*15dc779aSAndroid Build Coastguard Worker   for (win_grp = 0;
76*15dc779aSAndroid Build Coastguard Worker        win_grp < ptr_aac_dec_channel_info[LEFT]->str_ics_info.num_window_groups;
77*15dc779aSAndroid Build Coastguard Worker        win_grp++) {
78*15dc779aSAndroid Build Coastguard Worker     for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) {
79*15dc779aSAndroid Build Coastguard Worker       WORD32 sfb;
80*15dc779aSAndroid Build Coastguard Worker       WORD32 ixheaacd_drc_offset = 0;
81*15dc779aSAndroid Build Coastguard Worker 
82*15dc779aSAndroid Build Coastguard Worker       for (sfb = 0; sfb < ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb;
83*15dc779aSAndroid Build Coastguard Worker            sfb++) {
84*15dc779aSAndroid Build Coastguard Worker         ixheaacd_drc_offset += ptr_sfb_width[sfb];
85*15dc779aSAndroid Build Coastguard Worker 
86*15dc779aSAndroid Build Coastguard Worker         if (*ptr_ms_used++) {
87*15dc779aSAndroid Build Coastguard Worker           for (k = 0; k < ptr_sfb_width[sfb]; k = k + 2) {
88*15dc779aSAndroid Build Coastguard Worker             WORD32 left_coef = *l_spec;
89*15dc779aSAndroid Build Coastguard Worker             WORD32 right_coef = *r_spec;
90*15dc779aSAndroid Build Coastguard Worker             WORD32 left_coef2 = *(l_spec + 1);
91*15dc779aSAndroid Build Coastguard Worker             WORD32 right_coef2 = *(r_spec + 1);
92*15dc779aSAndroid Build Coastguard Worker 
93*15dc779aSAndroid Build Coastguard Worker             *l_spec++ = ixheaac_add32_sat(left_coef, right_coef);
94*15dc779aSAndroid Build Coastguard Worker             *r_spec++ = ixheaac_sub32_sat(left_coef, right_coef);
95*15dc779aSAndroid Build Coastguard Worker             *l_spec++ = ixheaac_add32_sat(left_coef2, right_coef2);
96*15dc779aSAndroid Build Coastguard Worker             *r_spec++ = ixheaac_sub32_sat(left_coef2, right_coef2);
97*15dc779aSAndroid Build Coastguard Worker           }
98*15dc779aSAndroid Build Coastguard Worker         } else {
99*15dc779aSAndroid Build Coastguard Worker           l_spec += ptr_sfb_width[sfb];
100*15dc779aSAndroid Build Coastguard Worker           r_spec += ptr_sfb_width[sfb];
101*15dc779aSAndroid Build Coastguard Worker         }
102*15dc779aSAndroid Build Coastguard Worker       }
103*15dc779aSAndroid Build Coastguard Worker       ptr_ms_used -= ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb;
104*15dc779aSAndroid Build Coastguard Worker 
105*15dc779aSAndroid Build Coastguard Worker       if (maximum_bins_short == 120) {
106*15dc779aSAndroid Build Coastguard Worker         l_spec = l_spec + maximum_bins_short - ixheaacd_drc_offset;
107*15dc779aSAndroid Build Coastguard Worker         r_spec = r_spec + maximum_bins_short - ixheaacd_drc_offset;
108*15dc779aSAndroid Build Coastguard Worker       } else {
109*15dc779aSAndroid Build Coastguard Worker         l_spec = l_spec + 128 - ixheaacd_drc_offset;
110*15dc779aSAndroid Build Coastguard Worker         r_spec = r_spec + 128 - ixheaacd_drc_offset;
111*15dc779aSAndroid Build Coastguard Worker       }
112*15dc779aSAndroid Build Coastguard Worker     }
113*15dc779aSAndroid Build Coastguard Worker 
114*15dc779aSAndroid Build Coastguard Worker     ptr_ms_used += JOINT_STEREO_MAX_BANDS;
115*15dc779aSAndroid Build Coastguard Worker   }
116*15dc779aSAndroid Build Coastguard Worker }
117*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mult32x16in32l(WORD32 a,WORD32 b)118*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32l(WORD32 a, WORD32 b) {
119*15dc779aSAndroid Build Coastguard Worker   WORD32 result;
120*15dc779aSAndroid Build Coastguard Worker   WORD64 temp_result;
121*15dc779aSAndroid Build Coastguard Worker 
122*15dc779aSAndroid Build Coastguard Worker   temp_result = (WORD64)a * (WORD64)b;
123*15dc779aSAndroid Build Coastguard Worker 
124*15dc779aSAndroid Build Coastguard Worker   result = (WORD32)(temp_result >> 16);
125*15dc779aSAndroid Build Coastguard Worker 
126*15dc779aSAndroid Build Coastguard Worker   return (result);
127*15dc779aSAndroid Build Coastguard Worker }
128*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_intensity_stereo_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info[2],ia_aac_dec_tables_struct * ptr_aac_tables,WORD32 object_type,WORD32 aac_sf_data_resil_flag,WORD16 framelength)129*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_intensity_stereo_process(
130*15dc779aSAndroid Build Coastguard Worker     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2],
131*15dc779aSAndroid Build Coastguard Worker     ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type,
132*15dc779aSAndroid Build Coastguard Worker     WORD32 aac_sf_data_resil_flag, WORD16 framelength) {
133*15dc779aSAndroid Build Coastguard Worker   UWORD8 *ptr_ms_used =
134*15dc779aSAndroid Build Coastguard Worker       &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0];
135*15dc779aSAndroid Build Coastguard Worker   WORD8 *ptr_code_book = &ptr_aac_dec_channel_info[RIGHT]->ptr_code_book[0];
136*15dc779aSAndroid Build Coastguard Worker   WORD16 *ptr_scale_factor =
137*15dc779aSAndroid Build Coastguard Worker       &ptr_aac_dec_channel_info[RIGHT]->ptr_scale_factor[0];
138*15dc779aSAndroid Build Coastguard Worker   WORD32 *r_spec = &ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff[0];
139*15dc779aSAndroid Build Coastguard Worker   WORD32 *l_spec = &ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff[0];
140*15dc779aSAndroid Build Coastguard Worker   WORD16 maximum_bins_short =
141*15dc779aSAndroid Build Coastguard Worker       (ptr_aac_dec_channel_info[LEFT]->str_ics_info.frame_length) >> 3;
142*15dc779aSAndroid Build Coastguard Worker   WORD8 *ptr_group_len =
143*15dc779aSAndroid Build Coastguard Worker       ptr_aac_dec_channel_info[RIGHT]->str_ics_info.window_group_length;
144*15dc779aSAndroid Build Coastguard Worker   const WORD8 *ptr_sfb_width =
145*15dc779aSAndroid Build Coastguard Worker       ptr_aac_tables
146*15dc779aSAndroid Build Coastguard Worker           ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT]
147*15dc779aSAndroid Build Coastguard Worker                                  ->str_ics_info.window_sequence]
148*15dc779aSAndroid Build Coastguard Worker           .sfb_width;
149*15dc779aSAndroid Build Coastguard Worker 
150*15dc779aSAndroid Build Coastguard Worker   WORD32 *ptr_scale_table;
151*15dc779aSAndroid Build Coastguard Worker 
152*15dc779aSAndroid Build Coastguard Worker   if (960 == framelength)
153*15dc779aSAndroid Build Coastguard Worker     ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table_960;
154*15dc779aSAndroid Build Coastguard Worker   else
155*15dc779aSAndroid Build Coastguard Worker     ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table;
156*15dc779aSAndroid Build Coastguard Worker 
157*15dc779aSAndroid Build Coastguard Worker   WORD32 win_grp, grp_len, k;
158*15dc779aSAndroid Build Coastguard Worker 
159*15dc779aSAndroid Build Coastguard Worker   for (win_grp = 0;
160*15dc779aSAndroid Build Coastguard Worker        win_grp <
161*15dc779aSAndroid Build Coastguard Worker        ptr_aac_dec_channel_info[RIGHT]->str_ics_info.num_window_groups;
162*15dc779aSAndroid Build Coastguard Worker        win_grp++) {
163*15dc779aSAndroid Build Coastguard Worker     for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) {
164*15dc779aSAndroid Build Coastguard Worker       WORD32 sfb;
165*15dc779aSAndroid Build Coastguard Worker       WORD32 ixheaacd_drc_offset = 0;
166*15dc779aSAndroid Build Coastguard Worker 
167*15dc779aSAndroid Build Coastguard Worker       for (sfb = 0; sfb < ptr_aac_dec_channel_info[RIGHT]->str_ics_info.max_sfb;
168*15dc779aSAndroid Build Coastguard Worker            sfb++) {
169*15dc779aSAndroid Build Coastguard Worker         WORD8 code_book = ptr_code_book[sfb];
170*15dc779aSAndroid Build Coastguard Worker         ixheaacd_drc_offset += ptr_sfb_width[sfb];
171*15dc779aSAndroid Build Coastguard Worker 
172*15dc779aSAndroid Build Coastguard Worker         if (((code_book >= INTENSITY_HCB2) &&
173*15dc779aSAndroid Build Coastguard Worker              ((object_type != AOT_ER_AAC_ELD) &&
174*15dc779aSAndroid Build Coastguard Worker               (object_type != AOT_ER_AAC_LD))) ||
175*15dc779aSAndroid Build Coastguard Worker             (((code_book == INTENSITY_HCB2) || (code_book == INTENSITY_HCB)) &&
176*15dc779aSAndroid Build Coastguard Worker              ((object_type == AOT_ER_AAC_ELD) ||
177*15dc779aSAndroid Build Coastguard Worker               (object_type == AOT_ER_AAC_LD))))
178*15dc779aSAndroid Build Coastguard Worker 
179*15dc779aSAndroid Build Coastguard Worker         {
180*15dc779aSAndroid Build Coastguard Worker           WORD32 sfb_factor, scale;
181*15dc779aSAndroid Build Coastguard Worker           WORD32 scf_exp;
182*15dc779aSAndroid Build Coastguard Worker 
183*15dc779aSAndroid Build Coastguard Worker           sfb_factor = (ptr_scale_factor[sfb]);
184*15dc779aSAndroid Build Coastguard Worker           if (aac_sf_data_resil_flag) sfb_factor = -sfb_factor;
185*15dc779aSAndroid Build Coastguard Worker 
186*15dc779aSAndroid Build Coastguard Worker           scf_exp = (sfb_factor >> 2);
187*15dc779aSAndroid Build Coastguard Worker           scale = *(ptr_scale_table + (sfb_factor & 3));
188*15dc779aSAndroid Build Coastguard Worker           if (!((ptr_ms_used[sfb]) ^ (code_book & 0x1))) {
189*15dc779aSAndroid Build Coastguard Worker             scale = ixheaac_negate32(scale);
190*15dc779aSAndroid Build Coastguard Worker           }
191*15dc779aSAndroid Build Coastguard Worker 
192*15dc779aSAndroid Build Coastguard Worker           scf_exp = -(scf_exp + 2);
193*15dc779aSAndroid Build Coastguard Worker 
194*15dc779aSAndroid Build Coastguard Worker           for (k = 0; k < ptr_sfb_width[sfb]; k++) {
195*15dc779aSAndroid Build Coastguard Worker             WORD32 temp, shift_val;
196*15dc779aSAndroid Build Coastguard Worker             temp = *l_spec++;
197*15dc779aSAndroid Build Coastguard Worker 
198*15dc779aSAndroid Build Coastguard Worker             shift_val = ixheaac_norm32(temp);
199*15dc779aSAndroid Build Coastguard Worker             temp = ixheaac_shl32(temp, shift_val);
200*15dc779aSAndroid Build Coastguard Worker 
201*15dc779aSAndroid Build Coastguard Worker             temp = ixheaacd_mult32x16in32l(temp, scale);
202*15dc779aSAndroid Build Coastguard Worker             shift_val = shift_val + scf_exp;
203*15dc779aSAndroid Build Coastguard Worker 
204*15dc779aSAndroid Build Coastguard Worker             if (shift_val < 0) {
205*15dc779aSAndroid Build Coastguard Worker               if (shift_val < -31) {
206*15dc779aSAndroid Build Coastguard Worker                 shift_val = -31;
207*15dc779aSAndroid Build Coastguard Worker               }
208*15dc779aSAndroid Build Coastguard Worker               temp = ixheaac_shl32_sat(temp, -shift_val);
209*15dc779aSAndroid Build Coastguard Worker             } else {
210*15dc779aSAndroid Build Coastguard Worker               if (shift_val > 31) {
211*15dc779aSAndroid Build Coastguard Worker                 shift_val = 31;
212*15dc779aSAndroid Build Coastguard Worker               }
213*15dc779aSAndroid Build Coastguard Worker               temp = ixheaac_shr32(temp, shift_val);
214*15dc779aSAndroid Build Coastguard Worker             }
215*15dc779aSAndroid Build Coastguard Worker             *r_spec++ = temp;
216*15dc779aSAndroid Build Coastguard Worker           }
217*15dc779aSAndroid Build Coastguard Worker 
218*15dc779aSAndroid Build Coastguard Worker         } else {
219*15dc779aSAndroid Build Coastguard Worker           l_spec += ptr_sfb_width[sfb];
220*15dc779aSAndroid Build Coastguard Worker           r_spec += ptr_sfb_width[sfb];
221*15dc779aSAndroid Build Coastguard Worker         }
222*15dc779aSAndroid Build Coastguard Worker       }
223*15dc779aSAndroid Build Coastguard Worker 
224*15dc779aSAndroid Build Coastguard Worker       if (maximum_bins_short == 120) {
225*15dc779aSAndroid Build Coastguard Worker         l_spec += maximum_bins_short - ixheaacd_drc_offset;
226*15dc779aSAndroid Build Coastguard Worker         r_spec += maximum_bins_short - ixheaacd_drc_offset;
227*15dc779aSAndroid Build Coastguard Worker       } else {
228*15dc779aSAndroid Build Coastguard Worker         l_spec += 128 - ixheaacd_drc_offset;
229*15dc779aSAndroid Build Coastguard Worker         r_spec += 128 - ixheaacd_drc_offset;
230*15dc779aSAndroid Build Coastguard Worker       }
231*15dc779aSAndroid Build Coastguard Worker     }
232*15dc779aSAndroid Build Coastguard Worker     ptr_ms_used += 64;
233*15dc779aSAndroid Build Coastguard Worker     ptr_code_book += 16;
234*15dc779aSAndroid Build Coastguard Worker     ptr_scale_factor += 16;
235*15dc779aSAndroid Build Coastguard Worker   }
236*15dc779aSAndroid Build Coastguard Worker }
237