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_type_def.h>
21 #include "ixheaacd_bitbuffer.h"
22 #include "ixheaacd_config.h"
23 #include "ixheaacd_mps_polyphase.h"
24 #include "ixheaacd_mps_dec.h"
25 #include "ixheaacd_mps_interface.h"
26 #include <math.h>
27 #include <stdlib.h>
28 #include <ixheaacd_type_def.h>
29 #include "ixheaacd_constants.h"
30 #include <ixheaacd_basic_ops32.h>
31 #include <ixheaacd_basic_ops40.h>
32
ixheaacd_mps_pre_matrix_mix_matrix_smoothing(ia_mps_dec_state_struct * self)33 VOID ixheaacd_mps_pre_matrix_mix_matrix_smoothing(
34 ia_mps_dec_state_struct *self) {
35 int smooth_band;
36 int delta, one_minus_delta;
37
38 int ps = 0, pb, row, col;
39 int res_bands = 0;
40 int *p_smoothing_data;
41
42 if (self->residual_coding) res_bands = self->max_res_bands;
43
44 p_smoothing_data = &self->smoothing_data[ps][res_bands];
45
46 delta = self->param_slot_diff[ps] * self->inv_smoothing_time[ps];
47 one_minus_delta = 1073741824 - delta;
48
49 for (pb = res_bands; pb < self->bs_param_bands; pb++) {
50 smooth_band = *p_smoothing_data++;
51 if (smooth_band) {
52 for (row = 0; row < MAX_M_OUTPUT; row++) {
53 for (col = 0; col < MAX_M_INPUT; col++) {
54 self->m1_param_re[ps][pb][row][col] =
55 (ixheaacd_mult32(delta, self->m1_param_re[ps][pb][row][col]) +
56 ixheaacd_mult32(one_minus_delta,
57 self->m1_param_re_prev[pb][row][col]))
58 << 2;
59 self->m1_param_im[ps][pb][row][col] =
60 (ixheaacd_mult32(delta, self->m1_param_im[ps][pb][row][col]) +
61 ixheaacd_mult32(one_minus_delta,
62 self->m1_param_im_prev[pb][row][col]))
63 << 2;
64 self->m2_decor_re[ps][pb][row][col] =
65 (ixheaacd_mult32(delta, self->m2_decor_re[ps][pb][row][col]) +
66 ixheaacd_mult32(one_minus_delta,
67 self->m2_decor_re_prev[pb][row][col]))
68 << 2;
69 self->m2_decor_im[ps][pb][row][col] =
70 (ixheaacd_mult32(delta, self->m2_decor_im[ps][pb][row][col]) +
71 ixheaacd_mult32(one_minus_delta,
72 self->m2_decor_im_prev[pb][row][col]))
73 << 2;
74 self->m2_resid_re[ps][pb][row][col] =
75 (ixheaacd_mult32(delta, self->m2_resid_re[ps][pb][row][col]) +
76 ixheaacd_mult32(one_minus_delta,
77 self->m2_resid_re_prev[pb][row][col]))
78 << 2;
79 self->m2_resid_im[ps][pb][row][col] =
80 (ixheaacd_mult32(delta, self->m2_resid_im[ps][pb][row][col]) +
81 ixheaacd_mult32(one_minus_delta,
82 self->m2_resid_im_prev[pb][row][col]))
83 << 2;
84 }
85 }
86 }
87 }
88
89 for (ps = 1; ps < self->num_parameter_sets; ps++) {
90 delta = self->param_slot_diff[ps] * self->inv_smoothing_time[ps];
91 one_minus_delta = 1073741824 - delta;
92
93 p_smoothing_data = &self->smoothing_data[ps][res_bands];
94
95 for (pb = res_bands; pb < self->bs_param_bands; pb++) {
96 smooth_band = *p_smoothing_data++;
97 if (smooth_band) {
98 for (row = 0; row < MAX_M_OUTPUT; row++) {
99 for (col = 0; col < MAX_M_INPUT; col++) {
100 self->m1_param_re[ps][pb][row][col] =
101 (ixheaacd_mult32(delta, self->m1_param_re[ps][pb][row][col]) +
102 ixheaacd_mult32(one_minus_delta,
103 self->m1_param_re[ps - 1][pb][row][col]))
104 << 2;
105 self->m1_param_im[ps][pb][row][col] =
106 (ixheaacd_mult32(delta, self->m1_param_im[ps][pb][row][col]) +
107 ixheaacd_mult32(one_minus_delta,
108 self->m1_param_im[ps - 1][pb][row][col]))
109 << 2;
110 self->m2_resid_re[ps][pb][row][col] =
111 (ixheaacd_mult32(delta, self->m2_resid_re[ps][pb][row][col]) +
112 ixheaacd_mult32(one_minus_delta,
113 self->m2_resid_re[ps - 1][pb][row][col]))
114 << 2;
115 self->m2_decor_re[ps][pb][row][col] =
116 (ixheaacd_mult32(delta, self->m2_decor_re[ps][pb][row][col]) +
117 ixheaacd_mult32(one_minus_delta,
118 self->m2_decor_re[ps - 1][pb][row][col]))
119 << 2;
120 self->m2_decor_im[ps][pb][row][col] =
121 (ixheaacd_mult32(delta, self->m2_decor_im[ps][pb][row][col]) +
122 ixheaacd_mult32(one_minus_delta,
123 self->m2_decor_im[ps - 1][pb][row][col]))
124 << 2;
125 self->m2_resid_im[ps][pb][row][col] =
126 (ixheaacd_mult32(delta, self->m2_resid_im[ps][pb][row][col]) +
127 ixheaacd_mult32(one_minus_delta,
128 self->m2_resid_im[ps - 1][pb][row][col]))
129 << 2;
130 }
131 }
132 }
133 }
134 }
135 }
136
137 #define ONE_BY_128_IN_Q30 (8388608)
138 #define ONE_IN_Q30 (1073741824)
139 #define PI_IN_Q27 (421657440)
140 #define FIFTY_X_PI_BY_180_Q27 (117127067)
141 #define TWENTY_FIVE_X_PI_BY_180_Q27 (58563533)
142
ixheaacd_mps_smoothing_opd(ia_mps_dec_state_struct * self)143 VOID ixheaacd_mps_smoothing_opd(ia_mps_dec_state_struct *self) {
144 int ps, pb;
145 int delta, one_minus_delta;
146
147 if (self->opd_smoothing_mode == 0) {
148 for (pb = 0; pb < self->bs_param_bands; pb++) {
149 self->opd_smooth.smooth_l_phase[pb] =
150 self->phase_l_fix[self->num_parameter_sets - 1][pb] >> 1;
151 self->opd_smooth.smooth_r_phase[pb] =
152 self->phase_r_fix[self->num_parameter_sets - 1][pb] >> 1;
153 }
154 return;
155 }
156 for (ps = 0; ps < self->num_parameter_sets; ps++) {
157 int thr = self->bs_frame.ipd_data.bs_quant_coarse_xxx[ps]
158 ? FIFTY_X_PI_BY_180_Q27
159 : TWENTY_FIVE_X_PI_BY_180_Q27;
160
161 delta = self->param_slot_diff[ps] * ONE_BY_128_IN_Q30;
162 one_minus_delta = ONE_IN_Q30 - delta;
163
164 for (pb = 0; pb < self->bs_param_bands; pb++) {
165 int ltemp, rtemp, tmp;
166
167 ltemp = self->phase_l_fix[ps][pb] >> 1;
168 rtemp = self->phase_r_fix[ps][pb] >> 1;
169
170 while (ltemp > self->opd_smooth.smooth_l_phase[pb] + PI_IN_Q27)
171 ltemp -= 2 * PI_IN_Q27;
172 while (ltemp < self->opd_smooth.smooth_l_phase[pb] - PI_IN_Q27)
173 ltemp += 2 * PI_IN_Q27;
174 while (rtemp > self->opd_smooth.smooth_r_phase[pb] + PI_IN_Q27)
175 rtemp -= 2 * PI_IN_Q27;
176 while (rtemp < self->opd_smooth.smooth_r_phase[pb] - PI_IN_Q27)
177 rtemp += 2 * PI_IN_Q27;
178
179 self->opd_smooth.smooth_l_phase[pb] =
180 (ixheaacd_mult32_shl(delta, ltemp) +
181 ixheaacd_mult32_shl(one_minus_delta,
182 self->opd_smooth.smooth_l_phase[pb]))
183 << 1;
184 self->opd_smooth.smooth_r_phase[pb] =
185 (ixheaacd_mult32_shl(delta, rtemp) +
186 ixheaacd_mult32_shl(one_minus_delta,
187 self->opd_smooth.smooth_r_phase[pb]))
188 << 1;
189
190 tmp = (ltemp - rtemp) - (self->opd_smooth.smooth_l_phase[pb] -
191 self->opd_smooth.smooth_r_phase[pb]);
192 while (tmp > PI_IN_Q27) tmp -= 2 * PI_IN_Q27;
193 while (tmp < -PI_IN_Q27) tmp += 2 * PI_IN_Q27;
194
195 if (ixheaacd_abs32(tmp) > thr) {
196 self->opd_smooth.smooth_l_phase[pb] = ltemp;
197 self->opd_smooth.smooth_r_phase[pb] = rtemp;
198 }
199
200 while (self->opd_smooth.smooth_l_phase[pb] > 2 * PI_IN_Q27)
201 self->opd_smooth.smooth_l_phase[pb] -= 2 * PI_IN_Q27;
202 while (self->opd_smooth.smooth_l_phase[pb] < 0)
203 self->opd_smooth.smooth_l_phase[pb] += 2 * PI_IN_Q27;
204 while (self->opd_smooth.smooth_r_phase[pb] > 2 * PI_IN_Q27)
205 self->opd_smooth.smooth_r_phase[pb] -= 2 * PI_IN_Q27;
206 while (self->opd_smooth.smooth_r_phase[pb] < 0)
207 self->opd_smooth.smooth_r_phase[pb] += 2 * PI_IN_Q27;
208
209 self->phase_l_fix[ps][pb] = self->opd_smooth.smooth_l_phase[pb] << 1;
210 self->phase_r_fix[ps][pb] = self->opd_smooth.smooth_r_phase[pb] << 1;
211 }
212 }
213 }
214