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 <ixheaacd_type_def.h>
22
23#include "ixheaacd_constants.h"
24#include <ixheaacd_basic_ops32.h>
25#include <ixheaacd_basic_ops16.h>
26#include <ixheaacd_basic_ops40.h>
27#include "ixheaacd_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 <ixheaacd_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_channelinfo.h"
45#include "ixheaacd_channel.h"
46#include "ixheaacd_drc_dec.h"
47#include "ixheaacd_audioobjtypes.h"
48
49#include "ixheaacd_stereo.h"
50
51VOID ixheaacd_ms_stereo_process(
52    ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2],
53    ia_aac_dec_tables_struct *ptr_aac_tables)
54
55{
56  WORD32 win_grp, grp_len, k;
57  WORD32 *l_spec = ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff;
58  WORD32 *r_spec = ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff;
59  WORD8 *ptr_group_len =
60      ptr_aac_dec_channel_info[LEFT]->str_ics_info.window_group_length;
61  const WORD8 *ptr_sfb_width =
62      ptr_aac_tables
63          ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT]
64                                 ->str_ics_info.window_sequence]
65          .sfb_width;
66
67  UWORD8 *ptr_ms_used =
68      &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0];
69
70  for (win_grp = 0;
71       win_grp < ptr_aac_dec_channel_info[LEFT]->str_ics_info.num_window_groups;
72       win_grp++) {
73    for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) {
74      WORD32 sfb;
75      WORD32 ixheaacd_drc_offset = 0;
76
77      for (sfb = 0; sfb < ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb;
78           sfb++) {
79        ixheaacd_drc_offset += ptr_sfb_width[sfb];
80
81        if (*ptr_ms_used++) {
82          for (k = 0; k < ptr_sfb_width[sfb]; k = k + 2) {
83            WORD32 left_coef = *l_spec;
84            WORD32 right_coef = *r_spec;
85            WORD32 left_coef2 = *(l_spec + 1);
86            WORD32 right_coef2 = *(r_spec + 1);
87
88            *l_spec++ = ixheaacd_add32_sat(left_coef, right_coef);
89            *r_spec++ = ixheaacd_sub32_sat(left_coef, right_coef);
90            *l_spec++ = ixheaacd_add32_sat(left_coef2, right_coef2);
91            *r_spec++ = ixheaacd_sub32_sat(left_coef2, right_coef2);
92          }
93        } else {
94          l_spec += ptr_sfb_width[sfb];
95          r_spec += ptr_sfb_width[sfb];
96        }
97      }
98      ptr_ms_used -= ptr_aac_dec_channel_info[LEFT]->str_ics_info.max_sfb;
99      l_spec = l_spec + 128 - ixheaacd_drc_offset;
100      r_spec = r_spec + 128 - ixheaacd_drc_offset;
101    }
102
103    ptr_ms_used += JOINT_STEREO_MAX_BANDS;
104  }
105}
106
107static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32l(WORD32 a, WORD32 b) {
108  WORD32 result;
109  WORD64 temp_result;
110
111  temp_result = (WORD64)a * (WORD64)b;
112
113  result = (WORD32)(temp_result >> 16);
114
115  return (result);
116}
117
118VOID ixheaacd_intensity_stereo_process(
119    ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[2],
120    ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type,
121    WORD32 aac_sf_data_resil_flag) {
122  UWORD8 *ptr_ms_used =
123      &ptr_aac_dec_channel_info[LEFT]->pstr_stereo_info->ms_used[0][0];
124  WORD8 *ptr_code_book = &ptr_aac_dec_channel_info[RIGHT]->ptr_code_book[0];
125  WORD16 *ptr_scale_factor =
126      &ptr_aac_dec_channel_info[RIGHT]->ptr_scale_factor[0];
127  WORD32 *r_spec = &ptr_aac_dec_channel_info[RIGHT]->ptr_spec_coeff[0];
128  WORD32 *l_spec = &ptr_aac_dec_channel_info[LEFT]->ptr_spec_coeff[0];
129  WORD8 *ptr_group_len =
130      ptr_aac_dec_channel_info[RIGHT]->str_ics_info.window_group_length;
131  const WORD8 *ptr_sfb_width =
132      ptr_aac_tables
133          ->str_aac_sfb_info[ptr_aac_dec_channel_info[RIGHT]
134                                 ->str_ics_info.window_sequence]
135          .sfb_width;
136  WORD32 *ptr_scale_table = ptr_aac_tables->pstr_block_tables->scale_table;
137  WORD32 win_grp, grp_len, k;
138
139  for (win_grp = 0;
140       win_grp <
141       ptr_aac_dec_channel_info[RIGHT]->str_ics_info.num_window_groups;
142       win_grp++) {
143    for (grp_len = 0; grp_len < ptr_group_len[win_grp]; grp_len++) {
144      WORD32 sfb;
145      WORD32 ixheaacd_drc_offset = 0;
146
147      for (sfb = 0; sfb < ptr_aac_dec_channel_info[RIGHT]->str_ics_info.max_sfb;
148           sfb++) {
149        WORD8 code_book = ptr_code_book[sfb];
150        ixheaacd_drc_offset += ptr_sfb_width[sfb];
151
152        if (((code_book >= INTENSITY_HCB2) &&
153             ((object_type != AOT_ER_AAC_ELD) &&
154              (object_type != AOT_ER_AAC_LD))) ||
155            (((code_book == INTENSITY_HCB2) || (code_book == INTENSITY_HCB)) &&
156             ((object_type == AOT_ER_AAC_ELD) ||
157              (object_type == AOT_ER_AAC_LD))))
158
159        {
160          WORD32 sfb_factor, scale;
161          WORD32 scf_exp;
162
163          sfb_factor = (ptr_scale_factor[sfb]);
164          if (aac_sf_data_resil_flag) sfb_factor = -sfb_factor;
165
166          scf_exp = (sfb_factor >> 2);
167          scale = *(ptr_scale_table + (sfb_factor & 3));
168          if (!((ptr_ms_used[sfb]) ^ (code_book & 0x1))) {
169            scale = ixheaacd_negate32(scale);
170          }
171
172          scf_exp = -(scf_exp + 2);
173
174          for (k = 0; k < ptr_sfb_width[sfb]; k++) {
175            WORD32 temp, shift_val;
176            temp = *l_spec++;
177
178            shift_val = ixheaacd_norm32(temp);
179            temp = ixheaacd_shl32(temp, shift_val);
180
181            temp = ixheaacd_mult32x16in32l(temp, scale);
182            shift_val = shift_val + scf_exp;
183
184            if (shift_val < 0) {
185              temp = ixheaacd_shl32_sat(temp, -shift_val);
186            } else {
187              temp = ixheaacd_shr32(temp, shift_val);
188            }
189            *r_spec++ = temp;
190          }
191
192        } else {
193          l_spec += ptr_sfb_width[sfb];
194          r_spec += ptr_sfb_width[sfb];
195        }
196      }
197      l_spec += 128 - ixheaacd_drc_offset;
198      r_spec += 128 - ixheaacd_drc_offset;
199    }
200    ptr_ms_used += 64;
201    ptr_code_book += 16;
202    ptr_scale_factor += 16;
203  }
204}
205