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