/src/libxaac/decoder/ixheaacd_aac_ec.c
Line | Count | Source |
1 | | /****************************************************************************** |
2 | | * * |
3 | | * Copyright (C) 2023 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 | | |
21 | | #include <stdio.h> |
22 | | #include <string.h> |
23 | | #include <math.h> |
24 | | #include "ixheaac_type_def.h" |
25 | | #include "ixheaac_constants.h" |
26 | | #include "ixheaac_basic_ops32.h" |
27 | | #include "ixheaac_basic_ops16.h" |
28 | | #include "ixheaac_basic_ops40.h" |
29 | | #include "ixheaac_basic_ops.h" |
30 | | #include "ixheaacd_sbr_common.h" |
31 | | #include "ixheaac_error_standards.h" |
32 | | |
33 | | #include <ixheaacd_cnst.h> |
34 | | #include "ixheaac_constants.h" |
35 | | #include "ixheaacd_intrinsics.h" |
36 | | #include "ixheaacd_common_rom.h" |
37 | | #include "ixheaacd_sbrdecsettings.h" |
38 | | #include "ixheaacd_bitbuffer.h" |
39 | | #include "ixheaacd_defines.h" |
40 | | |
41 | | #include "ixheaacd_pns.h" |
42 | | |
43 | | #include <ixheaacd_aac_rom.h> |
44 | | #include "ixheaacd_pulsedata.h" |
45 | | |
46 | | #include "ixheaacd_drc_data_struct.h" |
47 | | |
48 | | #include "ixheaacd_interface.h" |
49 | | #include "ixheaacd_info.h" |
50 | | #include "ixheaacd_lt_predict.h" |
51 | | #include "ixheaacd_ec_defines.h" |
52 | | #include "ixheaacd_ec_rom.h" |
53 | | #include "ixheaacd_ec_struct_def.h" |
54 | | #include "ixheaacd_channelinfo.h" |
55 | | #include "ixheaac_error_standards.h" |
56 | | |
57 | | #include "ixheaacd_aac_rom.h" |
58 | | |
59 | 0 | static WORD32 ixheaacd_aac_ec_get_win_seq(WORD32 prev_win_seq) { |
60 | 0 | WORD32 new_win_seq = ONLY_LONG_SEQUENCE; |
61 | |
|
62 | 0 | if (prev_win_seq == LONG_START_SEQUENCE || prev_win_seq == EIGHT_SHORT_SEQUENCE) { |
63 | 0 | new_win_seq = LONG_STOP_SEQUENCE; |
64 | 0 | } |
65 | |
|
66 | 0 | return new_win_seq; |
67 | 0 | } |
68 | | |
69 | 0 | static VOID ixheaacd_aac_ec_flip_spec_sign(WORD32 *ptr_spec_coeff, WORD32 num_samples) { |
70 | 0 | WORD32 idx; |
71 | 0 | WORD32 random_value; |
72 | |
|
73 | 0 | for (idx = 0; idx < num_samples; idx++) { |
74 | 0 | random_value = ptr_spec_coeff[idx] ^ idx; |
75 | 0 | if ((random_value & 1) == 0) { |
76 | 0 | ptr_spec_coeff[idx] = ixheaac_negate32_sat(ptr_spec_coeff[idx]); |
77 | 0 | } |
78 | 0 | } |
79 | 0 | } |
80 | | |
81 | | static VOID ixheaacd_aac_ec_store(ia_ec_state_str *pstr_ec_state, |
82 | | ia_aac_dec_channel_info_struct *pstr_aac_dec_channel_info, |
83 | 0 | ia_ics_info_struct *pstr_ics_info) { |
84 | 0 | WORD32 *ptr_spec_coeff = pstr_aac_dec_channel_info->ptr_spec_coeff; |
85 | 0 | WORD16 *ptr_spec_scale = pstr_aac_dec_channel_info->ptr_scale_factor; |
86 | 0 | UWORD8 win_shape = pstr_ec_state->win_shape; |
87 | 0 | WORD32 win_seq = pstr_ec_state->win_seq; |
88 | 0 | WORD16 q_spec_scale[MAX_SPEC_SCALE_LEN]; |
89 | 0 | WORD32 *ptr_temp_spec_coeff = &pstr_ec_state->str_ec_scratch.spec_coeff[0]; |
90 | |
|
91 | 0 | memcpy(q_spec_scale, pstr_ec_state->q_spec_coeff, sizeof(q_spec_scale)); |
92 | |
|
93 | 0 | pstr_ec_state->win_seq = pstr_ics_info->window_sequence; |
94 | 0 | pstr_ec_state->win_shape = (UWORD8)pstr_ics_info->window_shape; |
95 | 0 | pstr_ec_state->prev_win_group_len = |
96 | 0 | *(pstr_ics_info->window_group_length + pstr_ics_info->num_window_groups - 1); |
97 | |
|
98 | 0 | memcpy(pstr_ec_state->q_spec_coeff, ptr_spec_scale, sizeof(pstr_ec_state->q_spec_coeff)); |
99 | |
|
100 | 0 | memcpy(ptr_temp_spec_coeff, ptr_spec_coeff, LEN_SUPERFRAME * sizeof(ptr_temp_spec_coeff[0])); |
101 | 0 | memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff, |
102 | 0 | LEN_SUPERFRAME * sizeof(ptr_spec_coeff[0])); |
103 | 0 | memcpy(pstr_ec_state->spectral_coeff, ptr_temp_spec_coeff, |
104 | 0 | sizeof(pstr_ec_state->spectral_coeff)); |
105 | 0 | pstr_ics_info->window_sequence = win_seq; |
106 | 0 | pstr_ics_info->window_shape = win_shape; |
107 | |
|
108 | 0 | memcpy(ptr_spec_scale, q_spec_scale, MAX_SPEC_SCALE_LEN * sizeof(ptr_spec_scale[0])); |
109 | 0 | } |
110 | | |
111 | | static VOID ixheaacd_aac_ec_calc_sfb_nrg(WORD32 *ptr_spec_coeff, |
112 | | const ia_usac_samp_rate_info *pstr_samp_rate_info, |
113 | | const WORD32 win_seq, WORD32 win_trans, |
114 | 0 | WORD32 *ptr_sfb_energy) { |
115 | 0 | const WORD16 *ptr_sfb_offset; |
116 | 0 | WORD32 line = 0, sfb, total_scale_factor_bands = 0; |
117 | |
|
118 | 0 | switch (win_seq) { |
119 | 0 | case EIGHT_SHORT_SEQUENCE: |
120 | |
|
121 | 0 | if (win_trans == NO_TRANSITION) { |
122 | 0 | total_scale_factor_bands = pstr_samp_rate_info->num_sfb_128 - 1; |
123 | 0 | ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_128; |
124 | |
|
125 | 0 | for (sfb = 0; sfb < total_scale_factor_bands; sfb++) { |
126 | 0 | WORD32 accu = 1; |
127 | 0 | WORD32 q_nrg; |
128 | 0 | if (sfb == 0) { |
129 | 0 | q_nrg = (sizeof(accu) << 3) - ixheaac_norm32(ptr_sfb_offset[sfb] - 0); |
130 | 0 | for (; line < ptr_sfb_offset[sfb]; line++) { |
131 | 0 | accu += ixheaac_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg; |
132 | 0 | } |
133 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
134 | 0 | } |
135 | 0 | q_nrg = (sizeof(accu) << 3) - |
136 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
137 | 0 | for (; line < ptr_sfb_offset[sfb + 1]; line++) { |
138 | 0 | accu += ixheaac_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg; |
139 | 0 | } |
140 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
141 | 0 | } |
142 | 0 | } else { |
143 | 0 | total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1; |
144 | 0 | ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024; |
145 | |
|
146 | 0 | for (sfb = 0; sfb < total_scale_factor_bands; sfb++) { |
147 | 0 | WORD32 accu = 1; |
148 | 0 | WORD32 q_nrg; |
149 | 0 | if (sfb == 0) { |
150 | 0 | q_nrg = (sizeof(accu) << 3) - ixheaac_norm32(ptr_sfb_offset[sfb] - 0); |
151 | 0 | for (; line < ptr_sfb_offset[sfb]; line++) { |
152 | 0 | accu += |
153 | 0 | ixheaac_mult32(ptr_spec_coeff[line >> 3], ptr_spec_coeff[line >> 3]) >> q_nrg; |
154 | 0 | } |
155 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
156 | 0 | } |
157 | 0 | q_nrg = (sizeof(accu) << 3) - |
158 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
159 | 0 | for (; line < ptr_sfb_offset[sfb + 1]; line++) { |
160 | 0 | accu += |
161 | 0 | ixheaac_mult32(ptr_spec_coeff[line >> 3], ptr_spec_coeff[line >> 3]) >> q_nrg; |
162 | 0 | } |
163 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
164 | 0 | } |
165 | 0 | } |
166 | 0 | break; |
167 | | |
168 | 0 | case ONLY_LONG_SEQUENCE: |
169 | 0 | case LONG_START_SEQUENCE: |
170 | 0 | case LONG_STOP_SEQUENCE: |
171 | |
|
172 | 0 | if (win_trans == NO_TRANSITION) { |
173 | 0 | total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1; |
174 | 0 | ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024; |
175 | |
|
176 | 0 | for (sfb = 0; sfb < total_scale_factor_bands; sfb++) { |
177 | 0 | WORD32 accu = 1; |
178 | 0 | WORD32 q_nrg; |
179 | 0 | if (sfb == 0) { |
180 | 0 | q_nrg = (sizeof(accu) << 3) - ixheaac_norm32(ptr_sfb_offset[sfb] - 0); |
181 | 0 | for (; line < ptr_sfb_offset[sfb]; line++) { |
182 | 0 | accu += ixheaac_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg; |
183 | 0 | } |
184 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
185 | 0 | } |
186 | 0 | q_nrg = (sizeof(accu) << 3) - |
187 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
188 | 0 | for (; line < ptr_sfb_offset[sfb + 1]; line++) { |
189 | 0 | accu += ixheaac_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg; |
190 | 0 | } |
191 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
192 | 0 | } |
193 | 0 | } else { |
194 | 0 | total_scale_factor_bands = pstr_samp_rate_info->num_sfb_128 - 1; |
195 | 0 | ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_128; |
196 | |
|
197 | 0 | for (sfb = 0; sfb < total_scale_factor_bands; sfb++) { |
198 | 0 | WORD32 accu = 1; |
199 | 0 | WORD32 q_nrg; |
200 | 0 | if (sfb == 0) { |
201 | 0 | q_nrg = (sizeof(accu) << 3) - ixheaac_norm32(ptr_sfb_offset[sfb] - 0); |
202 | 0 | for (; line < ptr_sfb_offset[sfb] << 3; line++) { |
203 | 0 | accu += (accu + |
204 | 0 | (ixheaac_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg)) >> |
205 | 0 | 3; |
206 | 0 | } |
207 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
208 | 0 | } |
209 | 0 | q_nrg = (sizeof(accu) << 3) - |
210 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
211 | 0 | for (; line < ptr_sfb_offset[sfb + 1] << 3; line++) { |
212 | 0 | accu += |
213 | 0 | (accu + (ixheaac_mult32(ptr_spec_coeff[line], ptr_spec_coeff[line]) >> q_nrg)) >> |
214 | 0 | 3; |
215 | 0 | } |
216 | 0 | ptr_sfb_energy[sfb] = ixheaac_norm32(accu); |
217 | 0 | } |
218 | 0 | } |
219 | 0 | break; |
220 | 0 | } |
221 | 0 | } |
222 | | |
223 | | static VOID ixheaacd_aac_ec_interpolate(WORD32 *ptr_spec_coeff, WORD16 *ptr_spec_scale_prev, |
224 | | WORD16 *ptr_spec_scale_act, WORD16 *ptr_spec_scale_out, |
225 | | WORD32 *nrg_prev, WORD32 *nrg_act, WORD32 num_sfb, |
226 | 0 | const WORD16 *ptr_sfb_offset) { |
227 | 0 | WORD32 sfb, line = 0; |
228 | 0 | WORD32 fac_shift; |
229 | 0 | WORD32 fac_mod; |
230 | |
|
231 | 0 | for (sfb = 0; sfb < num_sfb; sfb++) { |
232 | 0 | fac_shift = |
233 | 0 | nrg_prev[sfb] - nrg_act[sfb] + ((*ptr_spec_scale_act - *ptr_spec_scale_prev) << 1); |
234 | 0 | fac_mod = fac_shift & 3; |
235 | 0 | fac_shift = (fac_shift >> 2) + 1; |
236 | 0 | fac_shift += *ptr_spec_scale_prev - max(*ptr_spec_scale_prev, *ptr_spec_scale_act); |
237 | 0 | fac_shift = max(min(fac_shift, INT_BITS - 1), -(INT_BITS - 1)); |
238 | |
|
239 | 0 | for (; line < ptr_sfb_offset[sfb]; line++) { |
240 | 0 | WORD32 accu = |
241 | 0 | ixheaac_mult32x16in32_shl(ptr_spec_coeff[line], ia_ec_interpolation_fac[fac_mod]); |
242 | 0 | ptr_spec_coeff[line] = ixheaac_shl32_dir_sat(accu, fac_shift); |
243 | 0 | } |
244 | 0 | } |
245 | 0 | *ptr_spec_scale_out = max(*ptr_spec_scale_prev, *ptr_spec_scale_act); |
246 | 0 | } |
247 | | |
248 | 0 | static VOID ixheaacd_aac_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_status) { |
249 | 0 | WORD32 ec_state_val = (pstr_ec_state->prev_frame_ok[0] << 2) + |
250 | 0 | (pstr_ec_state->prev_frame_ok[1] << 1) + (frame_status); |
251 | |
|
252 | 0 | switch (ec_state_val) { |
253 | 0 | case 0: |
254 | 0 | case 4: |
255 | 0 | if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) { |
256 | 0 | pstr_ec_state->fade_idx++; |
257 | 0 | } |
258 | 0 | pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE; |
259 | 0 | break; |
260 | 0 | case 1: |
261 | 0 | case 2: |
262 | 0 | if (pstr_ec_state->fade_idx > 0) { |
263 | 0 | pstr_ec_state->fade_idx--; |
264 | 0 | } |
265 | 0 | pstr_ec_state->conceal_state = FRAME_FADE; |
266 | 0 | break; |
267 | 0 | case 5: |
268 | 0 | if (pstr_ec_state->fade_idx > 0) { |
269 | 0 | pstr_ec_state->fade_idx--; |
270 | 0 | } |
271 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
272 | 0 | break; |
273 | 0 | break; |
274 | 0 | case 3: |
275 | 0 | case 6: |
276 | 0 | case 7: |
277 | 0 | if (pstr_ec_state->fade_idx > 0) { |
278 | 0 | pstr_ec_state->fade_idx--; |
279 | 0 | } |
280 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
281 | 0 | break; |
282 | 0 | default: |
283 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
284 | 0 | } |
285 | 0 | if (pstr_ec_state->fade_idx > MAX_FADE_FRAMES) { |
286 | 0 | pstr_ec_state->fade_idx = MAX_FADE_FRAMES; |
287 | 0 | } |
288 | 0 | if (pstr_ec_state->fade_idx == MAX_FADE_FRAMES) { |
289 | 0 | pstr_ec_state->conceal_state = FRAME_MUTE; |
290 | 0 | } |
291 | 0 | if (pstr_ec_state->fade_idx < 0) { |
292 | 0 | pstr_ec_state->fade_idx = 0; |
293 | 0 | } |
294 | 0 | } |
295 | | |
296 | | static VOID ixheaacd_aac_ec_interpolate_frame( |
297 | | ia_ec_state_str *pstr_ec_state, ia_aac_dec_channel_info_struct *pstr_aac_dec_channel_info, |
298 | | const ia_usac_samp_rate_info *pstr_samp_rate_info, const WORD32 num_samples, |
299 | 0 | const WORD32 frame_status, ia_ics_info_struct *pstr_ics_info) { |
300 | 0 | WORD32 *ptr_spec_coeff = pstr_aac_dec_channel_info->ptr_spec_coeff; |
301 | 0 | WORD16 *ptr_spec_scale = pstr_aac_dec_channel_info->ptr_scale_factor; |
302 | |
|
303 | 0 | WORD32 sfb_nrg_prev[WIN_LEN_64]; |
304 | 0 | WORD32 sfb_nrg_act[WIN_LEN_64]; |
305 | |
|
306 | 0 | WORD32 idx; |
307 | |
|
308 | 0 | memset(sfb_nrg_prev, 0, sizeof(sfb_nrg_prev)); |
309 | 0 | memset(sfb_nrg_act, 0, sizeof(sfb_nrg_act)); |
310 | |
|
311 | 0 | if (!frame_status) { |
312 | 0 | pstr_ics_info->window_shape = pstr_ec_state->win_shape; |
313 | 0 | pstr_ics_info->window_sequence = pstr_ec_state->win_seq; |
314 | |
|
315 | 0 | for (idx = 0; idx < num_samples; idx++) { |
316 | 0 | ptr_spec_coeff[idx] = pstr_ec_state->spectral_coeff[idx]; |
317 | 0 | } |
318 | |
|
319 | 0 | memcpy(ptr_spec_scale, pstr_ec_state->q_spec_coeff, 8 * sizeof(ptr_spec_scale[0])); |
320 | 0 | } |
321 | |
|
322 | 0 | if (!pstr_ec_state->prev_frame_ok[1]) { |
323 | 0 | if (frame_status && pstr_ec_state->prev_frame_ok[0]) { |
324 | 0 | if (pstr_ics_info->window_sequence == EIGHT_SHORT_SEQUENCE) { |
325 | 0 | WORD32 window; |
326 | 0 | if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) { |
327 | 0 | WORD32 total_scale_factor_bands = pstr_samp_rate_info->num_sfb_128 - 1; |
328 | 0 | const WORD16 *ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_128; |
329 | 0 | pstr_ics_info->window_shape = 1; |
330 | 0 | pstr_ics_info->window_sequence = EIGHT_SHORT_SEQUENCE; |
331 | |
|
332 | 0 | for (window = 0; window < 8; window++) { |
333 | 0 | ixheaacd_aac_ec_calc_sfb_nrg(&ptr_spec_coeff[window * (num_samples / 8)], |
334 | 0 | pstr_samp_rate_info, EIGHT_SHORT_SEQUENCE, NO_TRANSITION, |
335 | 0 | sfb_nrg_prev); |
336 | |
|
337 | 0 | ixheaacd_aac_ec_calc_sfb_nrg( |
338 | 0 | &pstr_ec_state->spectral_coeff[window * (num_samples / 8)], pstr_samp_rate_info, |
339 | 0 | EIGHT_SHORT_SEQUENCE, NO_TRANSITION, sfb_nrg_act); |
340 | |
|
341 | 0 | ixheaacd_aac_ec_interpolate( |
342 | 0 | &ptr_spec_coeff[window * (num_samples / 8)], &ptr_spec_scale[window], |
343 | 0 | &pstr_ec_state->q_spec_coeff[window], &ptr_spec_scale[window], sfb_nrg_prev, |
344 | 0 | sfb_nrg_act, total_scale_factor_bands, ptr_sfb_offset); |
345 | 0 | } |
346 | 0 | } else { |
347 | 0 | WORD32 total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1; |
348 | 0 | const WORD16 *ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024; |
349 | 0 | WORD16 spec_scale_out; |
350 | |
|
351 | 0 | ixheaacd_aac_ec_calc_sfb_nrg(&ptr_spec_coeff[num_samples - (num_samples / 8)], |
352 | 0 | pstr_samp_rate_info, EIGHT_SHORT_SEQUENCE, |
353 | 0 | TRANS_SHORT_LONG, sfb_nrg_act); |
354 | |
|
355 | 0 | ixheaacd_aac_ec_calc_sfb_nrg(pstr_ec_state->spectral_coeff, pstr_samp_rate_info, |
356 | 0 | ONLY_LONG_SEQUENCE, NO_TRANSITION, sfb_nrg_prev); |
357 | |
|
358 | 0 | pstr_ics_info->window_shape = 0; |
359 | 0 | pstr_ics_info->window_sequence = LONG_STOP_SEQUENCE; |
360 | |
|
361 | 0 | for (idx = 0; idx < num_samples; idx++) { |
362 | 0 | ptr_spec_coeff[idx] = pstr_ec_state->spectral_coeff[idx]; |
363 | 0 | } |
364 | |
|
365 | 0 | for (idx = 0; idx < 8; idx++) { |
366 | 0 | if (ptr_spec_scale[idx] > ptr_spec_scale[0]) { |
367 | 0 | ptr_spec_scale[0] = ptr_spec_scale[idx]; |
368 | 0 | } |
369 | 0 | } |
370 | |
|
371 | 0 | ixheaacd_aac_ec_interpolate(ptr_spec_coeff, &pstr_ec_state->q_spec_coeff[0], |
372 | 0 | &ptr_spec_scale[0], &spec_scale_out, sfb_nrg_prev, |
373 | 0 | sfb_nrg_act, total_scale_factor_bands, ptr_sfb_offset); |
374 | |
|
375 | 0 | ptr_spec_scale[0] = spec_scale_out; |
376 | 0 | } |
377 | 0 | } else { |
378 | 0 | WORD32 total_scale_factor_bands = pstr_samp_rate_info->num_sfb_1024 - 1; |
379 | 0 | const WORD16 *ptr_sfb_offset = pstr_samp_rate_info->ptr_sfb_1024; |
380 | 0 | WORD16 spec_scale_act = pstr_ec_state->q_spec_coeff[0]; |
381 | |
|
382 | 0 | ixheaacd_aac_ec_calc_sfb_nrg(ptr_spec_coeff, pstr_samp_rate_info, ONLY_LONG_SEQUENCE, |
383 | 0 | NO_TRANSITION, sfb_nrg_prev); |
384 | |
|
385 | 0 | if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) { |
386 | 0 | pstr_ics_info->window_shape = 1; |
387 | 0 | pstr_ics_info->window_sequence = LONG_START_SEQUENCE; |
388 | |
|
389 | 0 | for (idx = 1; idx < 8; idx++) { |
390 | 0 | if (pstr_ec_state->q_spec_coeff[idx] > spec_scale_act) { |
391 | 0 | spec_scale_act = pstr_ec_state->q_spec_coeff[idx]; |
392 | 0 | } |
393 | 0 | } |
394 | |
|
395 | 0 | ixheaacd_aac_ec_calc_sfb_nrg(pstr_ec_state->spectral_coeff, pstr_samp_rate_info, |
396 | 0 | EIGHT_SHORT_SEQUENCE, TRANS_SHORT_LONG, sfb_nrg_act); |
397 | 0 | } else { |
398 | 0 | pstr_ics_info->window_shape = 0; |
399 | 0 | pstr_ics_info->window_sequence = ONLY_LONG_SEQUENCE; |
400 | |
|
401 | 0 | ixheaacd_aac_ec_calc_sfb_nrg(pstr_ec_state->spectral_coeff, pstr_samp_rate_info, |
402 | 0 | ONLY_LONG_SEQUENCE, NO_TRANSITION, sfb_nrg_act); |
403 | 0 | } |
404 | |
|
405 | 0 | ixheaacd_aac_ec_interpolate(ptr_spec_coeff, &ptr_spec_scale[0], &spec_scale_act, |
406 | 0 | &ptr_spec_scale[0], sfb_nrg_prev, sfb_nrg_act, |
407 | 0 | total_scale_factor_bands, ptr_sfb_offset); |
408 | 0 | } |
409 | 0 | } |
410 | |
|
411 | 0 | ixheaacd_aac_ec_flip_spec_sign(ptr_spec_coeff, num_samples); |
412 | 0 | } |
413 | |
|
414 | 0 | if (FRAME_MUTE == pstr_ec_state->conceal_state) { |
415 | 0 | pstr_ics_info->window_shape = pstr_ec_state->win_shape; |
416 | 0 | pstr_ics_info->window_sequence = ixheaacd_aac_ec_get_win_seq(pstr_ec_state->win_seq); |
417 | 0 | pstr_ec_state->win_seq = pstr_ics_info->window_sequence; |
418 | 0 | memset(ptr_spec_coeff, 0, num_samples * sizeof(ptr_spec_coeff[0])); |
419 | 0 | } |
420 | 0 | } |
421 | | |
422 | 0 | VOID ixheaacd_aac_ec_init(ia_ec_state_str *pstr_ec_state) { |
423 | 0 | pstr_ec_state->win_shape = CONCEAL_NOT_DEFINED; |
424 | 0 | pstr_ec_state->win_seq = ONLY_LONG_SEQUENCE; |
425 | 0 | pstr_ec_state->prev_win_group_len = 1; |
426 | |
|
427 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
428 | |
|
429 | 0 | memset(pstr_ec_state->spectral_coeff, 0, sizeof(pstr_ec_state->spectral_coeff)); |
430 | 0 | memset(pstr_ec_state->q_spec_coeff, 0, sizeof(pstr_ec_state->q_spec_coeff)); |
431 | |
|
432 | 0 | pstr_ec_state->prev_frame_ok[0] = 1; |
433 | 0 | pstr_ec_state->prev_frame_ok[1] = 1; |
434 | 0 | pstr_ec_state->fade_idx = 0; |
435 | 0 | } |
436 | | |
437 | | VOID ixheaacd_aac_apply_ec(ia_ec_state_str *pstr_ec_state, |
438 | | ia_aac_dec_channel_info_struct *pstr_aac_dec_channel_info, |
439 | | const ia_usac_samp_rate_info *pstr_samp_rate_info, |
440 | | const WORD32 num_samples, ia_ics_info_struct *pstr_ics_info, |
441 | 0 | const WORD32 frame_status) { |
442 | 0 | if (pstr_ec_state->win_shape == CONCEAL_NOT_DEFINED) { |
443 | 0 | pstr_ec_state->win_shape = (UWORD8)pstr_ics_info->window_shape; |
444 | 0 | } |
445 | |
|
446 | 0 | if (frame_status && pstr_ec_state->prev_frame_ok[1]) { |
447 | 0 | ixheaacd_aac_ec_store(pstr_ec_state, pstr_aac_dec_channel_info, pstr_ics_info); |
448 | 0 | } |
449 | |
|
450 | 0 | ixheaacd_aac_ec_state(pstr_ec_state, frame_status); |
451 | |
|
452 | 0 | ixheaacd_aac_ec_interpolate_frame(pstr_ec_state, pstr_aac_dec_channel_info, pstr_samp_rate_info, |
453 | 0 | num_samples, frame_status, pstr_ics_info); |
454 | |
|
455 | 0 | pstr_ec_state->prev_frame_ok[0] = pstr_ec_state->prev_frame_ok[1]; |
456 | 0 | pstr_ec_state->prev_frame_ok[1] = frame_status; |
457 | 0 | } |