/src/libxaac/decoder/ixheaacd_usac_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 | | #include <string.h> |
21 | | #include <ixheaac_type_def.h> |
22 | | #include <ixheaac_constants.h> |
23 | | #include <ixheaac_basic_ops32.h> |
24 | | #include <ixheaac_basic_ops16.h> |
25 | | #include <ixheaac_basic_ops40.h> |
26 | | #include "ixheaacd_sbr_common.h" |
27 | | #include "ixheaacd_intrinsics.h" |
28 | | #include "ixheaacd_common_rom.h" |
29 | | #include "ixheaacd_sbrdecsettings.h" |
30 | | #include "ixheaacd_bitbuffer.h" |
31 | | #include "ixheaacd_defines.h" |
32 | | #include "ixheaacd_pns.h" |
33 | | #include <ixheaacd_aac_rom.h> |
34 | | #include "ixheaacd_pulsedata.h" |
35 | | #include "ixheaacd_lt_predict.h" |
36 | | #include "ixheaacd_cnst.h" |
37 | | #include "ixheaacd_drc_data_struct.h" |
38 | | #include "ixheaacd_ec_defines.h" |
39 | | #include "ixheaacd_ec_rom.h" |
40 | | #include "ixheaacd_ec_struct_def.h" |
41 | | #include "ixheaacd_channelinfo.h" |
42 | | #include "ixheaacd_interface.h" |
43 | | #include "ixheaacd_acelp_info.h" |
44 | | #include "ixheaacd_tns_usac.h" |
45 | | #include "ixheaacd_info.h" |
46 | | #include "ixheaacd_drc_dec.h" |
47 | | #include "ixheaacd_sbrdecoder.h" |
48 | | #include "ixheaacd_mps_polyphase.h" |
49 | | #include "ixheaac_sbr_const.h" |
50 | | #include "ixheaacd_ec_defines.h" |
51 | | #include "ixheaacd_ec_struct_def.h" |
52 | | #include "ixheaacd_main.h" |
53 | | #include "ixheaacd_acelp_com.h" |
54 | | |
55 | 0 | static WORD32 ixheaacd_usac_ec_get_win_seq(WORD32 prev_win_seq) { |
56 | 0 | if (prev_win_seq == LONG_START_SEQUENCE || prev_win_seq == EIGHT_SHORT_SEQUENCE) { |
57 | 0 | return LONG_STOP_SEQUENCE; |
58 | 0 | } else { |
59 | 0 | return ONLY_LONG_SEQUENCE; |
60 | 0 | } |
61 | 0 | } |
62 | | |
63 | | static VOID ixheaacd_usac_flip_spec_sign(WORD32 *ptr_spec_coeff, WORD32 samples_per_frame, |
64 | 0 | UWORD32 *seed_value) { |
65 | 0 | WORD32 i; |
66 | 0 | for (i = 0; i < samples_per_frame; i++) { |
67 | 0 | ptr_spec_coeff[i] = ixheaac_mult32x16in32_sat(ptr_spec_coeff[i], |
68 | 0 | (WORD16)ixheaacd_randomsign(seed_value)); |
69 | 0 | } |
70 | 0 | } |
71 | | |
72 | | static VOID iexheaace_ec_sfb_nrg_q(WORD32 *ptr_spectrum, ia_ec_sfb_str *pstr_ec_sfb, |
73 | 0 | WORD32 win_seq, WORD32 win_trans, WORD32 *ptr_sfb_enrg) { |
74 | 0 | WORD16 *ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long; |
75 | 0 | WORD32 l = 0, sfb, num_sfb = pstr_ec_sfb->num_sfb_long; |
76 | 0 | switch (win_seq) { |
77 | 0 | case EIGHT_SHORT_SEQUENCE: |
78 | 0 | if (win_trans == NO_TRANSITION) { |
79 | 0 | num_sfb = pstr_ec_sfb->num_sfb_short; |
80 | 0 | ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_short; |
81 | 0 | for (sfb = 0; sfb < num_sfb; sfb++) { |
82 | 0 | WORD64 accu = (WORD64)1; |
83 | 0 | WORD32 q_nrg = (sizeof(accu) << 3) - |
84 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
85 | 0 | for (; l < ptr_sfb_offset[sfb + 1]; l++) { |
86 | 0 | accu += ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg); |
87 | 0 | } |
88 | 0 | ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu); |
89 | 0 | } |
90 | 0 | } else { |
91 | 0 | num_sfb = pstr_ec_sfb->num_sfb_long; |
92 | 0 | ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long; |
93 | |
|
94 | 0 | for (sfb = 0; sfb < num_sfb; sfb++) { |
95 | 0 | WORD64 accu = (WORD64)1; |
96 | 0 | WORD32 q_nrg = (sizeof(accu) << 3) - |
97 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
98 | 0 | for (; l < ptr_sfb_offset[sfb + 1]; l++) { |
99 | 0 | accu += ixheaac_mul32_sh(ptr_spectrum[(l >> 3)], ptr_spectrum[(l >> 3)], q_nrg); |
100 | 0 | } |
101 | 0 | ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu); |
102 | 0 | } |
103 | 0 | } |
104 | 0 | break; |
105 | 0 | case ONLY_LONG_SEQUENCE: |
106 | 0 | case LONG_START_SEQUENCE: |
107 | 0 | case LONG_STOP_SEQUENCE: |
108 | 0 | if (win_trans == NO_TRANSITION) { |
109 | 0 | num_sfb = pstr_ec_sfb->num_sfb_long; |
110 | 0 | ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_long; |
111 | |
|
112 | 0 | for (sfb = 0; sfb < num_sfb; sfb++) { |
113 | 0 | WORD64 accu = (WORD64)1; |
114 | 0 | WORD32 q_nrg = (sizeof(accu) << 3) - |
115 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
116 | 0 | for (; l < ptr_sfb_offset[sfb + 1]; l++) { |
117 | 0 | accu += ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg); |
118 | 0 | } |
119 | 0 | ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu); |
120 | 0 | } |
121 | 0 | } else { |
122 | 0 | num_sfb = pstr_ec_sfb->num_sfb_short; |
123 | 0 | ptr_sfb_offset = pstr_ec_sfb->ptr_sfb_short; |
124 | |
|
125 | 0 | for (sfb = 0; sfb < num_sfb; sfb++) { |
126 | 0 | WORD64 accu = (WORD64)1; |
127 | 0 | WORD32 q_nrg = (sizeof(accu) << 3) - |
128 | 0 | ixheaac_norm32(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
129 | 0 | for (; l < ptr_sfb_offset[sfb + 1] << 3; l++) { |
130 | 0 | accu += (accu + (ixheaac_mul32_sh(ptr_spectrum[l], ptr_spectrum[l], q_nrg))) >> 3; |
131 | 0 | } |
132 | 0 | ptr_sfb_enrg[sfb] = ixheaac_norm32((WORD32)accu); |
133 | 0 | } |
134 | 0 | } |
135 | 0 | break; |
136 | 0 | } |
137 | 0 | } |
138 | | |
139 | | static VOID ixheaacd_usac_ec_interpolate(WORD32 *ptr_spectrum, WORD16 *pq_spec_coeff_prev, |
140 | | WORD16 *pq_spec_coeff_act, WORD16 *pq_spec_coeff_out, |
141 | | WORD32 *ptr_nrg_prev, WORD32 *ptr_nrg_act, |
142 | 0 | WORD32 num_sfb, WORD16 *ptr_sfb_offset) { |
143 | 0 | WORD32 sfb, l = 0; |
144 | 0 | WORD32 fac_shift; |
145 | 0 | WORD32 fac_mod; |
146 | |
|
147 | 0 | for (sfb = 0; sfb < num_sfb; sfb++) { |
148 | 0 | fac_shift = |
149 | 0 | ptr_nrg_prev[sfb] - ptr_nrg_act[sfb] + ((*pq_spec_coeff_act - *pq_spec_coeff_prev) << 1); |
150 | 0 | fac_mod = fac_shift & 3; |
151 | 0 | fac_shift = (fac_shift >> 2) + 1; |
152 | 0 | fac_shift += *pq_spec_coeff_prev - ixheaac_max16(*pq_spec_coeff_prev, *pq_spec_coeff_act); |
153 | 0 | fac_shift = ixheaac_max32(ixheaac_min32(fac_shift, INT_BITS - 1), -(INT_BITS - 1)); |
154 | |
|
155 | 0 | for (; l < ptr_sfb_offset[sfb + 1]; l++) { |
156 | 0 | WORD32 accu = ixheaac_shl32_sat( |
157 | 0 | ixheaac_mult32x32in32(ptr_spectrum[l], (WORD32)(ia_ec_interpolation_fac[fac_mod])), 1); |
158 | 0 | ptr_spectrum[l] = ixheaac_shl32_dir_sat((WORD32)accu, fac_shift); |
159 | 0 | } |
160 | 0 | } |
161 | 0 | *pq_spec_coeff_out = ixheaac_max16(*pq_spec_coeff_prev, *pq_spec_coeff_act); |
162 | 0 | } |
163 | | |
164 | | static VOID ixheaacd_usac_ec_interpolate_frame(ia_usac_data_struct *pstr_usac_data, |
165 | | ia_ec_state_str *pstr_ec_state, |
166 | | const ia_usac_samp_rate_info *pstr_samp_rate_info, |
167 | 0 | WORD32 frame_ok, WORD32 chn) { |
168 | 0 | WORD32 frame_length = pstr_usac_data->ccfl; |
169 | 0 | WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[chn]; |
170 | 0 | WORD16 *ptr_spec_sf = pstr_usac_data->spec_scale[chn]; |
171 | |
|
172 | 0 | WORD32 i; |
173 | 0 | ia_ec_scratch_str *pstr_ec_scratch = pstr_ec_state->pstr_ec_scratch; |
174 | 0 | WORD16 num_sfb_long; |
175 | 0 | WORD16 *ptr_sfb_long = NULL; |
176 | 0 | WORD16 num_sfb_short; |
177 | 0 | WORD16 *ptr_sfb_short = NULL; |
178 | |
|
179 | 0 | if (pstr_usac_data->core_mode == CORE_MODE_FD) { |
180 | 0 | num_sfb_long = pstr_samp_rate_info->num_sfb_1024; |
181 | 0 | ptr_sfb_long = (WORD16 *)pstr_samp_rate_info->ptr_sfb_1024; |
182 | 0 | num_sfb_short = pstr_samp_rate_info->num_sfb_128; |
183 | 0 | ptr_sfb_short = (WORD16 *)pstr_samp_rate_info->ptr_sfb_128; |
184 | 0 | if (pstr_usac_data->ccfl == WIN_LEN_768) { |
185 | 0 | num_sfb_long = pstr_samp_rate_info->num_sfb_768; |
186 | 0 | ptr_sfb_long = (WORD16 *)pstr_samp_rate_info->ptr_sfb_768; |
187 | 0 | num_sfb_short = pstr_samp_rate_info->num_sfb_96; |
188 | 0 | ptr_sfb_short = (WORD16 *)pstr_samp_rate_info->ptr_sfb_96; |
189 | 0 | } |
190 | 0 | pstr_ec_state->str_ec_sfb.num_sfb_long = num_sfb_long; |
191 | 0 | pstr_ec_state->str_ec_sfb.num_sfb_long = num_sfb_long; |
192 | 0 | pstr_ec_state->str_ec_sfb.ptr_sfb_long = ptr_sfb_long; |
193 | 0 | pstr_ec_state->str_ec_sfb.ptr_sfb_long = ptr_sfb_long; |
194 | |
|
195 | 0 | memset(pstr_ec_scratch->prev_sfb_nrg, 0, sizeof(pstr_ec_scratch->prev_sfb_nrg)); |
196 | 0 | memset(pstr_ec_scratch->pres_sfb_nrg, 0, sizeof(pstr_ec_scratch->pres_sfb_nrg)); |
197 | |
|
198 | 0 | if (!frame_ok) { |
199 | 0 | pstr_usac_data->window_shape[chn] = pstr_ec_state->win_shape; |
200 | 0 | pstr_usac_data->window_sequence[chn] = pstr_ec_state->win_seq; |
201 | 0 | memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff, |
202 | 0 | sizeof(*ptr_spec_coeff) * frame_length); |
203 | 0 | memcpy(ptr_spec_sf, pstr_ec_state->q_spec_coeff, sizeof(pstr_ec_state->q_spec_coeff)); |
204 | 0 | } |
205 | 0 | } |
206 | |
|
207 | 0 | if (!pstr_ec_state->prev_frame_ok[1]) { |
208 | 0 | if (frame_ok && pstr_ec_state->prev_frame_ok[0] && |
209 | 0 | pstr_usac_data->core_mode == CORE_MODE_FD) { |
210 | 0 | if (pstr_usac_data->window_sequence[chn] == EIGHT_SHORT_SEQUENCE) { |
211 | 0 | WORD32 wnd; |
212 | |
|
213 | 0 | if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) { |
214 | 0 | WORD32 num_sfb = num_sfb_short; |
215 | 0 | WORD16 *ptr_sfb_offset = ptr_sfb_short; |
216 | 0 | pstr_usac_data->window_shape[chn] = 1; |
217 | 0 | pstr_usac_data->window_sequence[chn] = EIGHT_SHORT_SEQUENCE; |
218 | |
|
219 | 0 | for (wnd = 0; wnd < 8; wnd++) { |
220 | 0 | iexheaace_ec_sfb_nrg_q(&ptr_spec_coeff[wnd * (frame_length >> 3)], |
221 | 0 | &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE, |
222 | 0 | NO_TRANSITION, pstr_ec_scratch->prev_sfb_nrg); |
223 | |
|
224 | 0 | iexheaace_ec_sfb_nrg_q(&pstr_ec_state->spectral_coeff[wnd * (frame_length >> 3)], |
225 | 0 | &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE, |
226 | 0 | NO_TRANSITION, pstr_ec_scratch->pres_sfb_nrg); |
227 | |
|
228 | 0 | ixheaacd_usac_ec_interpolate(&ptr_spec_coeff[wnd * (frame_length / 8)], |
229 | 0 | &ptr_spec_sf[wnd], &pstr_ec_state->q_spec_coeff[wnd], |
230 | 0 | &ptr_spec_sf[wnd], pstr_ec_scratch->prev_sfb_nrg, |
231 | 0 | pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset); |
232 | 0 | } |
233 | 0 | } else { |
234 | 0 | WORD32 num_sfb = num_sfb_long; |
235 | 0 | WORD16 *ptr_sfb_offset = ptr_sfb_long; |
236 | 0 | WORD16 q_spec_coeff_out; |
237 | |
|
238 | 0 | iexheaace_ec_sfb_nrg_q(&ptr_spec_coeff[frame_length - (frame_length >> 3)], |
239 | 0 | &pstr_ec_state->str_ec_sfb, EIGHT_SHORT_SEQUENCE, |
240 | 0 | TRANS_SHORT_LONG, pstr_ec_scratch->pres_sfb_nrg); |
241 | |
|
242 | 0 | iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb, |
243 | 0 | ONLY_LONG_SEQUENCE, NO_TRANSITION, |
244 | 0 | pstr_ec_scratch->prev_sfb_nrg); |
245 | |
|
246 | 0 | pstr_usac_data->window_shape[chn] = 0; |
247 | 0 | pstr_usac_data->window_sequence[chn] = LONG_STOP_SEQUENCE; |
248 | 0 | memcpy(&ptr_spec_coeff[0], pstr_ec_state->spectral_coeff, |
249 | 0 | frame_length * sizeof(ptr_spec_coeff[0])); |
250 | |
|
251 | 0 | for (i = 0; i < 8; i++) { |
252 | 0 | if (ptr_spec_sf[i] > ptr_spec_sf[0]) { |
253 | 0 | ptr_spec_sf[0] = ptr_spec_sf[i]; |
254 | 0 | } |
255 | 0 | } |
256 | |
|
257 | 0 | ixheaacd_usac_ec_interpolate(ptr_spec_coeff, &pstr_ec_state->q_spec_coeff[0], |
258 | 0 | &ptr_spec_sf[0], &q_spec_coeff_out, |
259 | 0 | pstr_ec_scratch->prev_sfb_nrg, |
260 | 0 | pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset); |
261 | |
|
262 | 0 | ptr_spec_sf[0] = q_spec_coeff_out; |
263 | 0 | } |
264 | 0 | } else { |
265 | 0 | WORD32 num_sfb = num_sfb_long; |
266 | 0 | WORD16 *ptr_sfb_offset = ptr_sfb_long; |
267 | 0 | WORD16 q_spec_coeff_act = pstr_ec_state->q_spec_coeff[0]; |
268 | |
|
269 | 0 | iexheaace_ec_sfb_nrg_q(ptr_spec_coeff, &pstr_ec_state->str_ec_sfb, ONLY_LONG_SEQUENCE, |
270 | 0 | NO_TRANSITION, pstr_ec_scratch->prev_sfb_nrg); |
271 | |
|
272 | 0 | if (pstr_ec_state->win_seq == EIGHT_SHORT_SEQUENCE) { |
273 | 0 | pstr_usac_data->window_shape[chn] = 1; |
274 | 0 | pstr_usac_data->window_sequence[chn] = LONG_START_SEQUENCE; |
275 | |
|
276 | 0 | for (i = 1; i < 8; i++) { |
277 | 0 | if (pstr_ec_state->q_spec_coeff[i] > q_spec_coeff_act) { |
278 | 0 | q_spec_coeff_act = pstr_ec_state->q_spec_coeff[i]; |
279 | 0 | } |
280 | 0 | } |
281 | |
|
282 | 0 | iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb, |
283 | 0 | EIGHT_SHORT_SEQUENCE, TRANS_SHORT_LONG, |
284 | 0 | pstr_ec_scratch->pres_sfb_nrg); |
285 | 0 | } else { |
286 | 0 | pstr_usac_data->window_shape[chn] = 0; |
287 | 0 | pstr_usac_data->window_sequence[chn] = ONLY_LONG_SEQUENCE; |
288 | 0 | iexheaace_ec_sfb_nrg_q(pstr_ec_state->spectral_coeff, &pstr_ec_state->str_ec_sfb, |
289 | 0 | ONLY_LONG_SEQUENCE, NO_TRANSITION, |
290 | 0 | pstr_ec_scratch->pres_sfb_nrg); |
291 | 0 | } |
292 | 0 | ixheaacd_usac_ec_interpolate(ptr_spec_coeff, &ptr_spec_sf[0], &q_spec_coeff_act, |
293 | 0 | &ptr_spec_sf[0], pstr_ec_scratch->prev_sfb_nrg, |
294 | 0 | pstr_ec_scratch->pres_sfb_nrg, num_sfb, ptr_sfb_offset); |
295 | 0 | } |
296 | 0 | } |
297 | 0 | ixheaacd_usac_flip_spec_sign(ptr_spec_coeff, frame_length, &pstr_usac_data->seed_value[chn]); |
298 | 0 | } |
299 | |
|
300 | 0 | if (FRAME_MUTE == pstr_ec_state->conceal_state) { |
301 | 0 | pstr_usac_data->window_shape[chn] = pstr_ec_state->win_shape; |
302 | 0 | pstr_usac_data->window_sequence[chn] = ixheaacd_usac_ec_get_win_seq(pstr_ec_state->win_seq); |
303 | 0 | pstr_ec_state->win_seq = pstr_usac_data->window_sequence[chn]; |
304 | 0 | memset(ptr_spec_coeff, 0, frame_length * sizeof(ptr_spec_coeff[0])); |
305 | 0 | } |
306 | |
|
307 | 0 | return; |
308 | 0 | } |
309 | | |
310 | 0 | static VOID ixheaacd_usac_lpc_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_ok) { |
311 | 0 | if (frame_ok == 0) { |
312 | 0 | if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) { |
313 | 0 | pstr_ec_state->fade_idx++; |
314 | 0 | } |
315 | 0 | pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE; |
316 | 0 | } else { |
317 | 0 | if (pstr_ec_state->fade_idx > 0) { |
318 | 0 | pstr_ec_state->fade_idx--; |
319 | 0 | } |
320 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
321 | 0 | } |
322 | 0 | if (pstr_ec_state->fade_idx >= MAX_FADE_FRAMES) { |
323 | 0 | pstr_ec_state->fade_idx = MAX_FADE_FRAMES; |
324 | 0 | pstr_ec_state->conceal_state = FRAME_MUTE; |
325 | 0 | } |
326 | 0 | if (pstr_ec_state->fade_idx < 0) { |
327 | 0 | pstr_ec_state->fade_idx = 0; |
328 | 0 | } |
329 | 0 | return; |
330 | 0 | } |
331 | | |
332 | 0 | static VOID ixheaacd_usac_ec_state(ia_ec_state_str *pstr_ec_state, WORD32 frame_ok) { |
333 | 0 | WORD32 ec_state_val = (pstr_ec_state->prev_frame_ok[0] << 2) + |
334 | 0 | (pstr_ec_state->prev_frame_ok[1] << 1) + (frame_ok); |
335 | |
|
336 | 0 | switch (ec_state_val) { |
337 | 0 | case 0: |
338 | 0 | case 4: |
339 | 0 | if (pstr_ec_state->fade_idx < MAX_FADE_FRAMES) { |
340 | 0 | pstr_ec_state->fade_idx++; |
341 | 0 | } |
342 | 0 | pstr_ec_state->conceal_state = FRAME_CONCEAL_SINGLE; |
343 | 0 | break; |
344 | 0 | case 1: |
345 | 0 | case 2: |
346 | 0 | if (pstr_ec_state->fade_idx > 0) { |
347 | 0 | pstr_ec_state->fade_idx--; |
348 | 0 | } |
349 | 0 | pstr_ec_state->conceal_state = FRAME_FADE; |
350 | 0 | break; |
351 | 0 | case 5: |
352 | 0 | if (pstr_ec_state->fade_idx > 0) { |
353 | 0 | pstr_ec_state->fade_idx--; |
354 | 0 | } |
355 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
356 | 0 | break; |
357 | 0 | break; |
358 | 0 | case 3: |
359 | 0 | case 6: |
360 | 0 | case 7: |
361 | 0 | if (pstr_ec_state->fade_idx > 0) { |
362 | 0 | pstr_ec_state->fade_idx--; |
363 | 0 | } |
364 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
365 | 0 | break; |
366 | 0 | default: |
367 | 0 | pstr_ec_state->conceal_state = FRAME_OKAY; |
368 | 0 | } |
369 | 0 | if (pstr_ec_state->fade_idx > MAX_FADE_FRAMES) { |
370 | 0 | pstr_ec_state->fade_idx = MAX_FADE_FRAMES; |
371 | 0 | } |
372 | 0 | if (pstr_ec_state->fade_idx == MAX_FADE_FRAMES) { |
373 | 0 | pstr_ec_state->conceal_state = FRAME_MUTE; |
374 | 0 | } |
375 | 0 | if (pstr_ec_state->fade_idx < 0) { |
376 | 0 | pstr_ec_state->fade_idx = 0; |
377 | 0 | } |
378 | 0 | } |
379 | | |
380 | 47.4k | VOID ixheaacd_usac_ec_init(ia_ec_state_str *pstr_ec_state, WORD32 core_coder_mode) { |
381 | 47.4k | pstr_ec_state->win_shape = 1; |
382 | 47.4k | pstr_ec_state->win_seq = ONLY_LONG_SEQUENCE; |
383 | 47.4k | pstr_ec_state->prev_win_group_len = 1; |
384 | | |
385 | 47.4k | pstr_ec_state->conceal_state = FRAME_OKAY; |
386 | | |
387 | 47.4k | memset(pstr_ec_state->spectral_coeff, 0, sizeof(pstr_ec_state->spectral_coeff)); |
388 | 47.4k | memset(pstr_ec_state->q_spec_coeff, 0, sizeof(pstr_ec_state->q_spec_coeff)); |
389 | | |
390 | 47.4k | pstr_ec_state->prev_frame_ok[0] = 1; |
391 | 47.4k | pstr_ec_state->prev_frame_ok[1] = 1; |
392 | | |
393 | 47.4k | pstr_ec_state->fade_idx = 0; |
394 | | |
395 | 47.4k | pstr_ec_state->prev_core_mode = core_coder_mode; |
396 | 47.4k | } |
397 | | |
398 | | VOID ixheaacd_usac_lpc_ec(FLOAT32 lsp[][ORDER], FLOAT32 *lpc4_lsf, FLOAT32 *lsf_adaptive_mean, |
399 | 0 | const WORD32 first_lpd_flag) { |
400 | 0 | WORD32 i, j; |
401 | |
|
402 | 0 | if (first_lpd_flag) { |
403 | 0 | memcpy(lsp[0], lsf_init, sizeof(lsf_init)); |
404 | 0 | memcpy(lpc4_lsf, lsf_init, sizeof(lsf_init)); |
405 | 0 | } else { |
406 | 0 | memcpy(lsp[0], lpc4_lsf, ORDER * sizeof(lpc4_lsf[0])); |
407 | 0 | } |
408 | |
|
409 | 0 | for (i = 0; i < ORDER; i++) { |
410 | 0 | FLOAT32 lsf_mean = (BETA * lsf_init[i]) + (ONE_BETA * lsf_adaptive_mean[i]); |
411 | 0 | lsp[1][i] = (BFI_FAC * lpc4_lsf[i]) + (ONE_BFI_FAC * lsf_mean); |
412 | 0 | } |
413 | |
|
414 | 0 | for (j = 2; j <= 4; j++) { |
415 | 0 | for (i = 0; i < ORDER; i++) { |
416 | 0 | FLOAT32 lsf_mean = ((BETA + (j * ONE_BFI_FAC)) * lsf_init[i]) + |
417 | 0 | ((ONE_BETA - (j * ONE_BFI_FAC)) * lsf_adaptive_mean[i]); |
418 | 0 | lsp[j][i] = (BFI_FAC * lsp[j - 1][i]) + (ONE_BFI_FAC * lsf_mean); |
419 | 0 | } |
420 | 0 | } |
421 | |
|
422 | 0 | memcpy(lpc4_lsf, lsp[4], ORDER * sizeof(lpc4_lsf[0])); |
423 | 0 | } |
424 | | |
425 | | VOID ixheaacd_usac_ec_save_states(ia_ec_state_str *pstr_ec_state, |
426 | 0 | ia_usac_data_struct *pstr_usac_data, WORD32 ch) { |
427 | 0 | if (pstr_usac_data->core_mode == CORE_MODE_FD && |
428 | 0 | (pstr_usac_data->frame_ok == 1 && pstr_ec_state->prev_frame_ok[1] == 1)) { |
429 | 0 | WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[ch]; |
430 | 0 | WORD16 *ptr_spec_scale = pstr_usac_data->spec_scale[ch]; |
431 | 0 | WORD16 q_spec_coeff[MAX_SPEC_SCALE_LEN_EC]; |
432 | 0 | UWORD8 win_shape = pstr_ec_state->win_shape; |
433 | 0 | UWORD8 win_shape_prev = pstr_ec_state->win_shape_prev; |
434 | 0 | WORD32 win_seq = pstr_ec_state->win_seq; |
435 | 0 | WORD32 td_frame_prev = pstr_ec_state->td_frame_prev; |
436 | 0 | WORD32 fac_data_present = pstr_ec_state->fac_data_present; |
437 | |
|
438 | 0 | ia_sfb_info_struct *sfb_info = |
439 | 0 | pstr_usac_data->pstr_usac_winmap[pstr_usac_data->window_sequence[ch]]; |
440 | 0 | WORD32 *ptr_scratch_buf = &pstr_ec_state->pstr_ec_scratch->spec_coeff[0]; |
441 | |
|
442 | 0 | memcpy(q_spec_coeff, pstr_ec_state->q_spec_coeff, sizeof(q_spec_coeff)); |
443 | 0 | pstr_ec_state->win_seq = pstr_usac_data->window_sequence[ch]; |
444 | 0 | pstr_ec_state->win_shape = pstr_usac_data->window_shape[ch]; |
445 | 0 | pstr_ec_state->td_frame_prev = pstr_usac_data->td_frame_prev[ch]; |
446 | 0 | pstr_ec_state->fac_data_present = pstr_usac_data->fac_data_present[ch]; |
447 | 0 | pstr_ec_state->win_shape_prev = pstr_usac_data->window_shape_prev[ch]; |
448 | 0 | pstr_ec_state->prev_win_group_len = (WORD32)sfb_info->group_len[sfb_info->num_groups - 1]; |
449 | |
|
450 | 0 | memcpy(pstr_ec_state->q_spec_coeff, ptr_spec_scale, sizeof(pstr_ec_state->q_spec_coeff)); |
451 | |
|
452 | 0 | memcpy(ptr_scratch_buf, ptr_spec_coeff, pstr_usac_data->ccfl * sizeof(ptr_scratch_buf[0])); |
453 | 0 | memcpy(ptr_spec_coeff, &pstr_ec_state->spectral_coeff[0], |
454 | 0 | pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0])); |
455 | 0 | memcpy(&pstr_ec_state->spectral_coeff[0], ptr_scratch_buf, |
456 | 0 | pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0])); |
457 | |
|
458 | 0 | if (!pstr_usac_data->first_frame) { |
459 | 0 | pstr_usac_data->window_sequence[ch] = win_seq; |
460 | 0 | pstr_usac_data->window_shape[ch] = win_shape; |
461 | 0 | pstr_usac_data->td_frame_prev_ec[ch] = td_frame_prev; |
462 | 0 | pstr_usac_data->fac_data_present[ch] = fac_data_present; |
463 | 0 | pstr_usac_data->window_shape_prev[ch] = win_shape_prev; |
464 | 0 | } |
465 | |
|
466 | 0 | memcpy(ptr_spec_scale, q_spec_coeff, sizeof(q_spec_coeff)); |
467 | 0 | } |
468 | 0 | } |
469 | | |
470 | | VOID ixheaacd_usac_apply_ec(ia_usac_data_struct *pstr_usac_data, |
471 | 0 | const ia_usac_samp_rate_info *pstr_samp_rate_info, WORD32 ch) { |
472 | 0 | WORD32 frame_ok = pstr_usac_data->frame_ok; |
473 | 0 | ia_ec_state_str *pstr_ec_state = &pstr_usac_data->str_error_concealment[ch]; |
474 | |
|
475 | 0 | if (pstr_usac_data->core_mode == CORE_MODE_FD) { |
476 | 0 | if (pstr_ec_state->win_shape == (UWORD8)-1) { |
477 | 0 | pstr_ec_state->win_shape = pstr_usac_data->window_shape[ch]; |
478 | 0 | } |
479 | |
|
480 | 0 | ixheaacd_usac_ec_state(pstr_ec_state, frame_ok); |
481 | |
|
482 | 0 | if (pstr_ec_state->conceal_state == FRAME_OKAY) { |
483 | 0 | pstr_ec_state->prev_core_mode = pstr_usac_data->core_mode; |
484 | 0 | ixheaacd_usac_ec_save_states(pstr_ec_state, pstr_usac_data, ch); |
485 | 0 | } else if (pstr_ec_state->conceal_state == FRAME_CONCEAL_SINGLE) { |
486 | 0 | ixheaacd_usac_ec_interpolate_frame(pstr_usac_data, pstr_ec_state, pstr_samp_rate_info, |
487 | 0 | frame_ok, ch); |
488 | 0 | } else { |
489 | 0 | } |
490 | 0 | if (!frame_ok) { |
491 | 0 | WORD32 *ptr_spec_coeff = pstr_usac_data->coef_fix[ch]; |
492 | 0 | WORD16 *ptr_spec_scale = pstr_usac_data->spec_scale[ch]; |
493 | |
|
494 | 0 | pstr_usac_data->window_sequence[ch] = pstr_ec_state->win_seq; |
495 | 0 | pstr_usac_data->window_shape[ch] = pstr_ec_state->win_shape; |
496 | |
|
497 | 0 | if (pstr_ec_state->conceal_state != FRAME_MUTE) { |
498 | 0 | memcpy(ptr_spec_scale, pstr_ec_state->q_spec_coeff, sizeof(pstr_ec_state->q_spec_coeff)); |
499 | 0 | memcpy(ptr_spec_coeff, pstr_ec_state->spectral_coeff, |
500 | 0 | sizeof(pstr_ec_state->spectral_coeff)); |
501 | 0 | } else { |
502 | 0 | memset(ptr_spec_scale, 0, MAX_SPEC_SCALE_LEN * sizeof(ptr_spec_scale[0])); |
503 | 0 | memset(ptr_spec_coeff, 0, pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0])); |
504 | 0 | } |
505 | 0 | } |
506 | 0 | } else { |
507 | 0 | ixheaacd_usac_lpc_ec_state(pstr_ec_state, frame_ok); |
508 | |
|
509 | 0 | if (pstr_ec_state->conceal_state == FRAME_OKAY) { |
510 | 0 | memcpy(pstr_ec_state->lsf4, pstr_usac_data->lpc4_lsf, sizeof(pstr_ec_state->lsf4)); |
511 | 0 | } else if (pstr_ec_state->conceal_state == FRAME_CONCEAL_SINGLE) { |
512 | 0 | WORD32 frame_length = pstr_usac_data->ccfl; |
513 | 0 | WORD32 *ptr_spec_coeff = pstr_usac_data->tcx_spec_coeffs[ch]; |
514 | |
|
515 | 0 | ixheaacd_usac_flip_spec_sign(ptr_spec_coeff, frame_length, |
516 | 0 | &pstr_usac_data->seed_value[ch]); |
517 | 0 | } else { |
518 | 0 | WORD32 *ptr_spec_coeff = pstr_usac_data->tcx_spec_coeffs[ch]; |
519 | 0 | memset(ptr_spec_coeff, 0, pstr_usac_data->ccfl * sizeof(ptr_spec_coeff[0])); |
520 | 0 | } |
521 | 0 | if (!frame_ok) { |
522 | 0 | memcpy(pstr_usac_data->lpc4_lsf, pstr_ec_state->lsf4, sizeof(pstr_usac_data->lpc4_lsf)); |
523 | 0 | } |
524 | 0 | } |
525 | |
|
526 | 0 | pstr_ec_state->prev_frame_ok[0] = pstr_ec_state->prev_frame_ok[1]; |
527 | 0 | pstr_ec_state->prev_frame_ok[1] = frame_ok; |
528 | |
|
529 | 0 | return; |
530 | 0 | } |
531 | | |
532 | 0 | static VOID ixheaacd_lpc_wt_tool(FLOAT32 a[], WORD32 l) { |
533 | 0 | WORD32 i; |
534 | |
|
535 | 0 | for (i = 0; i < l; i++) { |
536 | 0 | a[i] = a[i] * ixheaacd_gamma_table[i]; |
537 | 0 | } |
538 | |
|
539 | 0 | return; |
540 | 0 | } |
541 | | static VOID ixheaacd_lpc_coef_gen_ec(FLOAT32 lsf_old[], FLOAT32 lsf_new[], FLOAT32 a[], |
542 | 0 | WORD32 m) { |
543 | 0 | FLOAT32 lsf[ORDER], *ptr_a; |
544 | 0 | FLOAT32 inc, fnew, fold; |
545 | 0 | WORD32 i; |
546 | |
|
547 | 0 | ptr_a = a; |
548 | |
|
549 | 0 | inc = 1.0f / (FLOAT32)m; |
550 | 0 | fnew = 0.5f - (0.5f * inc); |
551 | 0 | fold = 1.0f - fnew; |
552 | |
|
553 | 0 | for (i = 0; i < ORDER; i++) { |
554 | 0 | lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew); |
555 | 0 | } |
556 | 0 | ixheaacd_lsp_to_lp_conversion(lsf, ptr_a); |
557 | |
|
558 | 0 | return; |
559 | 0 | } |
560 | | |
561 | | VOID ixheaacd_usac_tcx_ec(ia_usac_data_struct *pstr_usac_data, ia_usac_lpd_decoder_handle st, |
562 | 0 | FLOAT32 *ptr_lsp_curr, WORD32 frame_idx, FLOAT32 *lp_flt_coff_a) { |
563 | 0 | WORD32 ch = pstr_usac_data->present_chan; |
564 | 0 | FLOAT32 synth_buf[ORDER + LEN_FRAME], temp; |
565 | 0 | FLOAT32 exc_buf[MAX_PITCH + ORDER + 1 + LEN_FRAME]; |
566 | 0 | FLOAT32 *ptr_syn = synth_buf + ORDER; |
567 | 0 | FLOAT32 *ptr_exc = exc_buf + MAX_PITCH + ORDER + 1; |
568 | 0 | FLOAT32 est_fac_est = 0.1f; |
569 | 0 | WORD32 i, sf_idx; |
570 | 0 | FLOAT32 synth_sig_buf[LEN_SUBFR + 1]; |
571 | 0 | FLOAT32 *synth_signal = synth_sig_buf + 1; |
572 | 0 | WORD32 num_lost_frames = pstr_usac_data->num_lost_lpd_frames[ch]; |
573 | 0 | WORD32 len_subfrm = pstr_usac_data->len_subfrm; |
574 | 0 | FLOAT32 past_tcx_gain = pstr_usac_data->past_gain_tcx[ch]; |
575 | 0 | WORD32 l_div_part = MAX_PITCH + ORDER + 1 - len_subfrm; |
576 | 0 | FLOAT32 *synth = pstr_usac_data->synth_buf + MAX_PITCH - LEN_SUBFR; |
577 | 0 | FLOAT32 *ptr_synth = &synth[512 + frame_idx * len_subfrm]; |
578 | 0 | FLOAT32 syn_buf[MAX_PITCH + ORDER + 1]; |
579 | 0 | FLOAT32 *ptr_syn_buf = &syn_buf[ORDER]; |
580 | |
|
581 | 0 | memcpy(syn_buf, &ptr_synth[-(MAX_PITCH + ORDER + 1)], |
582 | 0 | sizeof(syn_buf)); |
583 | 0 | memcpy(st->synth_prev_ec, &syn_buf[MAX_PITCH + 1], sizeof(st->synth_prev_ec)); |
584 | 0 | ixheaacd_residual_tool_float(pstr_usac_data->lp_flt_coff_a_ec, ptr_syn_buf, st->xcitation_prev, |
585 | 0 | pstr_usac_data->len_subfrm, 1); |
586 | 0 | ixheaacd_residual_tool_float(lp_flt_coff_a, &syn_buf[l_div_part], |
587 | 0 | st->xcitation_prev + l_div_part, pstr_usac_data->len_subfrm, 1); |
588 | 0 | if (st->last_tcx_pitch > MAX_PITCH) { |
589 | 0 | st->last_tcx_pitch = MAX_PITCH; |
590 | 0 | } |
591 | |
|
592 | 0 | memcpy(synth_buf, st->synth_prev_ec, ORDER * sizeof(FLOAT32)); |
593 | 0 | memcpy(exc_buf, st->xcitation_prev, (MAX_PITCH + ORDER + 1) * sizeof(FLOAT32)); |
594 | |
|
595 | 0 | if (num_lost_frames <= 8) { |
596 | 0 | est_fac_est = ixheaacd_exc_fade_fac[num_lost_frames - 1]; |
597 | 0 | } |
598 | |
|
599 | 0 | for (i = 0; i < len_subfrm; i++) { |
600 | 0 | ptr_exc[i] = est_fac_est * ptr_exc[i - st->last_tcx_pitch]; |
601 | 0 | } |
602 | 0 | synth_signal[-1] = ptr_exc[-1]; |
603 | |
|
604 | 0 | for (sf_idx = 0; sf_idx < len_subfrm; sf_idx += LEN_SUBFR) { |
605 | 0 | FLOAT32 lp_coef[ORDER + 1]; |
606 | |
|
607 | 0 | ixheaacd_lpc_coef_gen_ec(st->lspold, ptr_lsp_curr, lp_coef, len_subfrm / LEN_SUBFR); |
608 | |
|
609 | 0 | ixheaacd_synthesis_tool_float(lp_coef, &ptr_exc[sf_idx], &ptr_syn[sf_idx], LEN_SUBFR, |
610 | 0 | synth_buf); |
611 | |
|
612 | 0 | ixheaacd_lpc_wt_tool(lp_coef, ORDER); |
613 | |
|
614 | 0 | ixheaacd_residual_tool_float(lp_coef, &ptr_syn[sf_idx], synth_signal, LEN_SUBFR, 1); |
615 | |
|
616 | 0 | ixheaacd_deemphsis_tool(synth_signal, LEN_SUBFR, synth_signal[-1]); |
617 | |
|
618 | 0 | temp = (est_fac_est * past_tcx_gain); |
619 | |
|
620 | 0 | for (i = 0; i < LEN_SUBFR; i++) { |
621 | 0 | if (synth_signal[i] > temp) { |
622 | 0 | synth_signal[i] = temp; |
623 | 0 | } else { |
624 | 0 | if (synth_signal[i] < -temp) { |
625 | 0 | synth_signal[i] = -temp; |
626 | 0 | } |
627 | 0 | } |
628 | 0 | } |
629 | |
|
630 | 0 | for (i = LEN_SUBFR - 1; i >= 0; i--) { |
631 | 0 | synth_signal[i] = (synth_signal[i] - (PREEMPH_FILT_FAC * synth_signal[i - 1])); |
632 | 0 | } |
633 | 0 | ixheaacd_synthesis_tool_float(lp_coef, synth_signal, &ptr_syn[sf_idx], LEN_SUBFR, synth_buf); |
634 | |
|
635 | 0 | memmove(&ptr_synth[sf_idx], &ptr_syn[sf_idx], LEN_SUBFR * sizeof(FLOAT32)); |
636 | 0 | } |
637 | |
|
638 | 0 | memcpy(st->xcitation_prev, ptr_exc + len_subfrm - (MAX_PITCH + ORDER + 1), |
639 | 0 | sizeof(FLOAT32) * (MAX_PITCH + ORDER + 1)); |
640 | 0 | memcpy(st->synth_prev_ec, synth_buf + len_subfrm, sizeof(FLOAT32) * ORDER); |
641 | 0 | return; |
642 | 0 | } |