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 <float.h>
22 #include <memory.h>
23
24 #include <assert.h>
25
26 #include "ixheaacd_type_def.h"
27 #include "ixheaacd_bitbuffer.h"
28 #include "ixheaacd_config.h"
29 #include "ixheaacd_mps_polyphase.h"
30 #include "ixheaacd_mps_dec.h"
31 #include "ixheaacd_mps_interface.h"
32
33 #include "ixheaacd_mps_process.h"
34
35 #include "ixheaacd_common_rom.h"
36 #include "ixheaacd_defines.h"
37
38 #include "ixheaacd_pns.h"
39
40 #include "ixheaacd_aac_rom.h"
41 #include "ixheaacd_pulsedata.h"
42
43 #include "ixheaacd_sbrdecsettings.h"
44 #include "ixheaacd_sbr_scale.h"
45 #include "ixheaacd_lpp_tran.h"
46 #include "ixheaacd_env_extr_part.h"
47 #include "ixheaacd_sbr_rom.h"
48 #include "ixheaacd_hybrid.h"
49 #include "ixheaacd_ps_dec.h"
50 #include "ixheaacd_env_extr.h"
51
52 #include "ixheaacd_qmf_dec.h"
53
54 #include "ixheaacd_env_calc.h"
55 #include "ixheaacd_sbr_const.h"
56 #include "ixheaacd_pvc_dec.h"
57 #include "ixheaacd_sbr_dec.h"
58
59 #define HP_SIZE (9)
60
61 #define STP_LPF_COEFF1 (0.950f)
62 #define STP_LPF_COEFF2 (0.450f)
63 #define STP_UPDATE_ENERGY_RATE (32)
64 #define STP_SCALE_LIMIT (2.82f)
65 #define STP_DAMP (0.1f)
66
67 #define max(a, b) ((a > b) ? (a) : (b))
68 #define min(a, b) ((a < b) ? (a) : (b))
69
70 static const FLOAT32 ixheaacd_bp[BP_SIZE] = {
71 0.0000f, 0.0005f, 0.0092f, 0.0587f, 0.2580f, 0.7392f, 0.9791f,
72 0.9993f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.9999f, 0.9984f,
73 0.9908f, 0.9639f, 0.8952f, 0.7711f, 0.6127f, 0.4609f, 0.3391f,
74 0.2493f, 0.1848f, 0.1387f, 0.1053f};
75
76 static const FLOAT32 ixheaacd_gf[BP_SIZE] = {
77 0.f, 0.f, 0.f, 0.f, 0.f,
78 0.f, 1e-008f, 8.1e-007f, 3.61e-006f, 8.41e-006f,
79 1.6e-005f, 2.704e-005f, 3.969e-005f, 5.625e-005f, 7.396e-005f,
80 9.801e-005f, 0.00012321f, 0.00015625f, 0.00019881f, 0.00024964f,
81 0.00032041f, 0.00041209f, 0.00053824f, 0.00070756f, 0.00094249f};
82
ixheaacd_mps_temp_process_scale_calc(ia_mps_dec_state_struct * self,WORD32 ts,FLOAT32 * scale)83 static VOID ixheaacd_mps_temp_process_scale_calc(ia_mps_dec_state_struct* self,
84 WORD32 ts, FLOAT32* scale) {
85 FLOAT32 dir_energy;
86 FLOAT32 diff_energy[2];
87 FLOAT32 temp;
88
89 WORD32 ch, n;
90 WORD32 left_ch = 0, right_ch = 1;
91
92 if (self->subband_var.init_flag == 0) {
93 for (ch = 0; ch < 2; ch++) {
94 self->subband_var.tp_scale_last[ch] = 1.0f;
95 self->subband_var.nrg_diff_prev[ch] = 32768 * 32768;
96 }
97
98 self->subband_var.nrg_dir_prev = 32768 * 32768;
99 self->subband_var.init_flag = 1;
100 }
101
102 if (self->subband_var.update_old_ener == STP_UPDATE_ENERGY_RATE) {
103 self->subband_var.update_old_ener = 1;
104 self->subband_var.nrg_dir_prev = self->subband_var.nrg_dir;
105 for (ch = 0; ch < self->out_ch_count; ch++)
106 self->subband_var.nrg_diff_prev[ch] = self->subband_var.nrg_diff[ch];
107 } else
108 self->subband_var.update_old_ener++;
109
110 dir_energy = 0;
111
112 for (n = 6; n < BP_SIZE; n++) {
113 FLOAT32 dir_left_re = self->hyb_dir_out[left_ch][ts][n + 7].re;
114 FLOAT32 dir_right_re = self->hyb_dir_out[right_ch][ts][n + 7].re;
115 FLOAT32 dir_left_im = self->hyb_dir_out[left_ch][ts][n + 7].im;
116 FLOAT32 dir_right_im = self->hyb_dir_out[right_ch][ts][n + 7].im;
117
118 temp = ((dir_left_re + dir_right_re) * (dir_left_re + dir_right_re)) +
119 ((dir_left_im + dir_right_im) * (dir_left_im + dir_right_im));
120 dir_energy += temp * ixheaacd_bp[n] * ixheaacd_bp[n] * ixheaacd_gf[n] *
121 ixheaacd_gf[n];
122 }
123
124 self->subband_var.nrg_dir =
125 (FLOAT32)(STP_LPF_COEFF1 * self->subband_var.nrg_dir +
126 (1.0 - STP_LPF_COEFF1) * dir_energy);
127
128 dir_energy /= (self->subband_var.nrg_dir_prev + ABS_THR);
129
130 for (ch = 0; ch < self->out_ch_count; ch++) {
131 diff_energy[ch] = 0;
132 for (n = 6; n < BP_SIZE; n++) {
133 FLOAT32 diff_re = self->hyb_diff_out[ch][ts][n + 7].re;
134 FLOAT32 diff_im = self->hyb_diff_out[ch][ts][n + 7].im;
135
136 temp = (diff_re * diff_re) + (diff_im * diff_im);
137 diff_energy[ch] += temp * ixheaacd_bp[n] * ixheaacd_bp[n] *
138 ixheaacd_gf[n] * ixheaacd_gf[n];
139 }
140
141 self->subband_var.nrg_diff[ch] =
142 (FLOAT32)(STP_LPF_COEFF1 * self->subband_var.nrg_diff[ch] +
143 (1.0 - STP_LPF_COEFF1) * diff_energy[ch]);
144 diff_energy[ch] /= (self->subband_var.nrg_diff_prev[ch] + ABS_THR);
145 }
146
147 scale[left_ch] = (FLOAT32)sqrt((dir_energy) / (diff_energy[left_ch] + 1e-9));
148 scale[right_ch] =
149 (FLOAT32)sqrt((dir_energy) / (diff_energy[right_ch] + 1e-9));
150
151 for (ch = 0; ch < self->out_ch_count; ch++) {
152 scale[ch] = STP_DAMP + (1 - STP_DAMP) * scale[ch];
153 }
154
155 for (ch = 0; ch < self->out_ch_count; ch++) {
156 scale[ch] =
157 min(max(scale[ch], (FLOAT32)(1.0 / STP_SCALE_LIMIT)), STP_SCALE_LIMIT);
158 }
159
160 for (ch = 0; ch < self->out_ch_count; ch++) {
161 scale[ch] =
162 (FLOAT32)(STP_LPF_COEFF2 * scale[ch] +
163 (1.0 - STP_LPF_COEFF2) * self->subband_var.tp_scale_last[ch]);
164 self->subband_var.tp_scale_last[ch] = scale[ch];
165 }
166 }
167
ixheaacd_mps_subbandtp(ia_mps_dec_state_struct * self,WORD32 ts)168 static VOID ixheaacd_mps_subbandtp(ia_mps_dec_state_struct* self, WORD32 ts) {
169 FLOAT32 scale[2];
170 WORD32 ch, n;
171 WORD32 no_scaling;
172 FLOAT32 temp;
173 const WORD32 ixheaacd_hybrid_to_qmf_map[] = {0, 0, 0, 0, 0, 0, 1, 1, 2, 2};
174
175 ixheaacd_mps_temp_process_scale_calc(self, ts, scale);
176
177 for (ch = 0; ch < self->out_ch_count; ch++) {
178 no_scaling = 1;
179
180 if ((self->config->bs_temp_shape_config == 1) ||
181 (self->config->bs_temp_shape_config == 2))
182 no_scaling = !self->temp_shape_enable_ch_stp[ch];
183
184 if (no_scaling == 1) {
185 for (n = 0; n < self->hyb_band_count; n++) {
186 self->hyb_dir_out[ch][ts][n].re += self->hyb_diff_out[ch][ts][n].re;
187 self->hyb_dir_out[ch][ts][n].im += self->hyb_diff_out[ch][ts][n].im;
188 }
189 } else {
190 for (n = 0; n < 10; n++) {
191 temp =
192 (FLOAT32)(scale[ch] * ixheaacd_bp[ixheaacd_hybrid_to_qmf_map[n]]);
193 self->hyb_dir_out[ch][ts][n].re +=
194 (self->hyb_diff_out[ch][ts][n].re * temp);
195 self->hyb_dir_out[ch][ts][n].im +=
196 (self->hyb_diff_out[ch][ts][n].im * temp);
197 }
198 for (; n < HP_SIZE - 3 + 10; n++) {
199 temp = (FLOAT32)(scale[ch] * ixheaacd_bp[n + 3 - 10]);
200 self->hyb_dir_out[ch][ts][n].re +=
201 (self->hyb_diff_out[ch][ts][n].re * temp);
202 self->hyb_dir_out[ch][ts][n].im +=
203 (self->hyb_diff_out[ch][ts][n].im * temp);
204 }
205 for (; n < self->hyb_band_count; n++) {
206 temp = (FLOAT32)(scale[ch]);
207 self->hyb_dir_out[ch][ts][n].re +=
208 (self->hyb_diff_out[ch][ts][n].re * temp);
209 self->hyb_dir_out[ch][ts][n].im +=
210 (self->hyb_diff_out[ch][ts][n].im * temp);
211 }
212 }
213 }
214 }
215
ixheaacd_mps_temp_process(ia_mps_dec_state_struct * self)216 WORD32 ixheaacd_mps_temp_process(ia_mps_dec_state_struct* self) {
217 WORD32 ch, ts, hyb;
218 WORD32 err = 0;
219
220 for (ch = 0; ch < self->out_ch_count; ch++) {
221 for (ts = 0; ts < self->time_slots; ts++) {
222 for (hyb = 0; hyb < HYBRID_BAND_BORDER; hyb++) {
223 self->hyb_dir_out[ch][ts][hyb].re += self->hyb_diff_out[ch][ts][hyb].re;
224 self->hyb_dir_out[ch][ts][hyb].im += self->hyb_diff_out[ch][ts][hyb].im;
225 self->hyb_diff_out[ch][ts][hyb].re = 0;
226 self->hyb_diff_out[ch][ts][hyb].im = 0;
227 }
228 }
229 }
230
231 for (ts = 0; ts < self->time_slots; ts++) ixheaacd_mps_subbandtp(self, ts);
232
233 ixheaacd_mps_qmf_hyb_synthesis(self);
234
235 for (ch = 0; ch < self->out_ch_count; ch++) {
236 err = ixheaacd_sbr_dec_from_mps(&self->qmf_out_dir[ch][0][0].re,
237 self->p_sbr_dec[ch], self->p_sbr_frame[ch],
238 self->p_sbr_header[ch]);
239 if (err) return err;
240 }
241
242 ixheaacd_mps_synt_calc(self);
243 return err;
244 }