/src/libxaac/decoder/ixheaacd_acelp_decode.c
Line | Count | Source (jump to first uncovered line) |
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 <float.h> |
21 | | #include <stdlib.h> |
22 | | #include <stdio.h> |
23 | | #include <math.h> |
24 | | #include <string.h> |
25 | | |
26 | | #include "ixheaac_type_def.h" |
27 | | |
28 | | #include "ixheaacd_bitbuffer.h" |
29 | | |
30 | | #include "ixheaacd_interface.h" |
31 | | |
32 | | #include "ixheaacd_tns_usac.h" |
33 | | #include "ixheaacd_cnst.h" |
34 | | |
35 | | #include "ixheaacd_acelp_info.h" |
36 | | |
37 | | #include "ixheaacd_td_mdct.h" |
38 | | |
39 | | #include "ixheaacd_sbrdecsettings.h" |
40 | | #include "ixheaacd_info.h" |
41 | | #include "ixheaacd_sbr_common.h" |
42 | | #include "ixheaacd_drc_data_struct.h" |
43 | | #include "ixheaacd_drc_dec.h" |
44 | | #include "ixheaacd_sbrdecoder.h" |
45 | | #include "ixheaacd_mps_polyphase.h" |
46 | | #include "ixheaac_sbr_const.h" |
47 | | #include "ixheaacd_ec_defines.h" |
48 | | #include "ixheaacd_ec_struct_def.h" |
49 | | #include "ixheaacd_main.h" |
50 | | #include "ixheaacd_arith_dec.h" |
51 | | #include "ixheaacd_func_def.h" |
52 | | |
53 | | #include "ixheaacd_acelp_com.h" |
54 | | |
55 | 10.5M | #define F_PIT_SHARP 0.85F |
56 | | #define MEAN_ENER 30 |
57 | | |
58 | | extern const FLOAT32 ixheaacd_interpol_filt[INTER_LP_FIL_LEN]; |
59 | | |
60 | 675k | VOID ixheaacd_acelp_pitch_sharpening(FLOAT32 *x, WORD32 pit_lag) { |
61 | 675k | WORD32 i; |
62 | 11.2M | for (i = pit_lag; i < LEN_SUBFR; i++) { |
63 | 10.5M | x[i] += x[i - pit_lag] * F_PIT_SHARP; |
64 | 10.5M | } |
65 | 675k | return; |
66 | 675k | } |
67 | | |
68 | | static VOID ixheaacd_acelp_decode_1sp_per_track(WORD32 idx_1p, WORD32 M, |
69 | | WORD32 ixheaacd_drc_offset, |
70 | | WORD32 track, |
71 | 1.95M | FLOAT32 code_vec[]) { |
72 | 1.95M | WORD32 sign_index, mask, m; |
73 | 1.95M | WORD32 sp_pos; |
74 | 1.95M | mask = ((1 << M) - 1); |
75 | | |
76 | 1.95M | sp_pos = (idx_1p & mask) + ixheaacd_drc_offset; |
77 | 1.95M | sign_index = ((idx_1p >> M) & 1); |
78 | | |
79 | 1.95M | m = (sp_pos << 2) + track; |
80 | 1.95M | if (sign_index == 1) |
81 | 465k | code_vec[m] = (code_vec[m] - 1.0f); |
82 | 1.48M | else |
83 | 1.48M | code_vec[m] = (code_vec[m] + 1.0f); |
84 | | |
85 | 1.95M | return; |
86 | 1.95M | } |
87 | | |
88 | | static VOID ixheaacd_acelp_decode_2sp_per_track(WORD32 idx_2p, WORD32 M, |
89 | | WORD32 ixheaacd_drc_offset, |
90 | | WORD32 track, |
91 | 1.24M | FLOAT32 code_vec[]) { |
92 | 1.24M | WORD32 sign_index; |
93 | 1.24M | WORD32 mask, m0, m1; |
94 | 1.24M | WORD32 sp_pos[2]; |
95 | 1.24M | mask = ((1 << M) - 1); |
96 | | |
97 | 1.24M | sp_pos[0] = (((idx_2p >> M) & mask) + ixheaacd_drc_offset); |
98 | 1.24M | sp_pos[1] = ((idx_2p & mask) + ixheaacd_drc_offset); |
99 | | |
100 | 1.24M | sign_index = (idx_2p >> 2 * M) & 1; |
101 | | |
102 | 1.24M | m0 = (sp_pos[0] << 2) + track; |
103 | 1.24M | m1 = (sp_pos[1] << 2) + track; |
104 | | |
105 | 1.24M | if ((sp_pos[1] - sp_pos[0]) < 0) { |
106 | 526k | if (sign_index == 1) { |
107 | 215k | code_vec[m0] = (code_vec[m0] - 1.0f); |
108 | 215k | code_vec[m1] = (code_vec[m1] + 1.0f); |
109 | 311k | } else { |
110 | 311k | code_vec[m0] = (code_vec[m0] + 1.0f); |
111 | 311k | code_vec[m1] = (code_vec[m1] - 1.0f); |
112 | 311k | } |
113 | 719k | } else { |
114 | 719k | if (sign_index == 1) { |
115 | 274k | code_vec[m0] = (code_vec[m0] - 1.0f); |
116 | 274k | code_vec[m1] = (code_vec[m1] - 1.0f); |
117 | 445k | } else { |
118 | 445k | code_vec[m0] = (code_vec[m0] + 1.0f); |
119 | 445k | code_vec[m1] = (code_vec[m1] + 1.0f); |
120 | 445k | } |
121 | 719k | } |
122 | 1.24M | return; |
123 | 1.24M | } |
124 | | |
125 | | static VOID ixheaacd_acelp_decode_3sp_per_track(WORD32 idx_3p, WORD32 M, |
126 | | WORD32 ixheaacd_drc_offset, |
127 | | WORD32 track, |
128 | 532k | FLOAT32 code_vec[]) { |
129 | 532k | WORD32 j, mask, idx_2p, idx_1p; |
130 | | |
131 | 532k | mask = ((1 << (2 * M - 1)) - 1); |
132 | 532k | idx_2p = idx_3p & mask; |
133 | 532k | j = ixheaacd_drc_offset; |
134 | 532k | if (((idx_3p >> ((2 * M) - 1)) & 1) == 1) { |
135 | 193k | j += (1 << (M - 1)); |
136 | 193k | } |
137 | 532k | ixheaacd_acelp_decode_2sp_per_track(idx_2p, M - 1, j, track, code_vec); |
138 | 532k | mask = ((1 << (M + 1)) - 1); |
139 | 532k | idx_1p = (idx_3p >> 2 * M) & mask; |
140 | 532k | ixheaacd_acelp_decode_1sp_per_track(idx_1p, M, ixheaacd_drc_offset, track, |
141 | 532k | code_vec); |
142 | 532k | return; |
143 | 532k | } |
144 | | |
145 | | static VOID ixheaacd_d_acelp_decode_4sp_per_track_section( |
146 | | WORD32 index, WORD32 ixheaacd_drc_offset, WORD32 track, |
147 | 82.2k | FLOAT32 code_vec[]) { |
148 | 82.2k | WORD32 j, idx_2p; |
149 | | |
150 | 82.2k | idx_2p = index & 31; |
151 | 82.2k | j = ixheaacd_drc_offset; |
152 | 82.2k | if (((index >> 5) & 1) == 1) { |
153 | 25.8k | j += 4; |
154 | 25.8k | } |
155 | 82.2k | ixheaacd_acelp_decode_2sp_per_track(idx_2p, 2, j, track, code_vec); |
156 | 82.2k | idx_2p = (index >> 6) & 127; |
157 | 82.2k | ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, ixheaacd_drc_offset, track, |
158 | 82.2k | code_vec); |
159 | 82.2k | return; |
160 | 82.2k | } |
161 | | |
162 | | static VOID ixheaacd_acelp_decode_4sp_per_track(WORD32 idx_4p, WORD32 track, |
163 | 247k | FLOAT32 code_vec[]) { |
164 | 247k | WORD32 idx_1p, idx_2p, idx_3p; |
165 | | |
166 | 247k | switch ((idx_4p >> 14) & 3) { |
167 | 82.2k | case 0: |
168 | 82.2k | if (((idx_4p >> 13) & 1) == 0) |
169 | 57.4k | ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 0, track, |
170 | 57.4k | code_vec); |
171 | 24.8k | else |
172 | 24.8k | ixheaacd_d_acelp_decode_4sp_per_track_section(idx_4p, 8, track, |
173 | 24.8k | code_vec); |
174 | 82.2k | break; |
175 | 71.4k | case 1: |
176 | 71.4k | idx_1p = idx_4p >> 10; |
177 | 71.4k | ixheaacd_acelp_decode_1sp_per_track(idx_1p, 3, 0, track, code_vec); |
178 | 71.4k | ixheaacd_acelp_decode_3sp_per_track(idx_4p, 3, 8, track, code_vec); |
179 | 71.4k | break; |
180 | 70.5k | case 2: |
181 | 70.5k | idx_2p = idx_4p >> 7; |
182 | 70.5k | ixheaacd_acelp_decode_2sp_per_track(idx_2p, 3, 0, track, code_vec); |
183 | 70.5k | ixheaacd_acelp_decode_2sp_per_track(idx_4p, 3, 8, track, code_vec); |
184 | 70.5k | break; |
185 | 23.0k | case 3: |
186 | 23.0k | idx_3p = idx_4p >> 4; |
187 | 23.0k | ixheaacd_acelp_decode_3sp_per_track(idx_3p, 3, 0, track, code_vec); |
188 | 23.0k | ixheaacd_acelp_decode_1sp_per_track(idx_4p, 3, 8, track, code_vec); |
189 | 23.0k | break; |
190 | 247k | } |
191 | 247k | return; |
192 | 247k | } |
193 | | |
194 | | static VOID ixheaacd_d_acelp_add_pulse(WORD32 pos[], WORD32 nb_pulse, |
195 | 184k | WORD32 track, FLOAT32 code[]) { |
196 | 184k | WORD32 i, k; |
197 | 368k | for (k = 0; k < nb_pulse; k++) { |
198 | 184k | i = ((pos[k] & (16 - 1)) << 2) + track; |
199 | 184k | if ((pos[k] & 16) == 0) { |
200 | 103k | code[i] = (WORD16)(code[i] + 1.0f); |
201 | 103k | } else { |
202 | 80.5k | code[i] = (WORD16)(code[i] - 1.0f); |
203 | 80.5k | } |
204 | 184k | } |
205 | 184k | return; |
206 | 184k | } |
207 | | |
208 | | static VOID ixheaacd_d_acelp_decode_1p_n1(WORD32 index, WORD32 N, |
209 | | WORD32 ixheaacd_drc_offset, |
210 | 184k | WORD32 pos[]) { |
211 | 184k | WORD32 i, pos1, mask; |
212 | 184k | mask = ((1 << N) - 1); |
213 | | |
214 | 184k | pos1 = ((index & mask) + ixheaacd_drc_offset); |
215 | 184k | i = ((index >> N) & 1); |
216 | 184k | if (i == 1) { |
217 | 80.5k | pos1 += 16; |
218 | 80.5k | } |
219 | 184k | pos[0] = pos1; |
220 | 184k | return; |
221 | 184k | } |
222 | | |
223 | | VOID ixheaacd_acelp_decode_pulses_per_track(WORD32 cb_index[], |
224 | | const WORD16 code_bits, |
225 | 675k | FLOAT32 code_vec[]) { |
226 | 675k | WORD32 track_idx, index, ixheaacd_drc_offset, pos[6], i; |
227 | 675k | memset(code_vec, 0, 64 * sizeof(FLOAT32)); |
228 | | |
229 | 675k | if (code_bits == 12) { |
230 | 88.2k | for (track_idx = 0; track_idx < 4; track_idx += 2) { |
231 | 58.8k | ixheaacd_drc_offset = cb_index[2 * (track_idx / 2)]; |
232 | 58.8k | index = cb_index[2 * (track_idx / 2) + 1]; |
233 | 58.8k | ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos); |
234 | 58.8k | ixheaacd_d_acelp_add_pulse( |
235 | 58.8k | pos, 1, 2 * ixheaacd_drc_offset + track_idx / 2, code_vec); |
236 | 58.8k | } |
237 | 646k | } else if (code_bits == 16) { |
238 | 41.8k | i = 0; |
239 | 41.8k | ixheaacd_drc_offset = cb_index[i++]; |
240 | 41.8k | ixheaacd_drc_offset = (ixheaacd_drc_offset == 0) ? 1 : 3; |
241 | 209k | for (track_idx = 0; track_idx < 4; track_idx++) { |
242 | 167k | if (track_idx != ixheaacd_drc_offset) { |
243 | 125k | index = cb_index[i++]; |
244 | 125k | ixheaacd_d_acelp_decode_1p_n1(index, 4, 0, pos); |
245 | 125k | ixheaacd_d_acelp_add_pulse(pos, 1, track_idx, code_vec); |
246 | 125k | } |
247 | 167k | } |
248 | 604k | } else if (code_bits == 20) { |
249 | 1.56M | for (track_idx = 0; track_idx < 4; track_idx++) { |
250 | 1.25M | index = cb_index[track_idx]; |
251 | 1.25M | ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec); |
252 | 1.25M | } |
253 | 313k | } else if (code_bits == 28) { |
254 | 106k | for (track_idx = 0; track_idx < 2; track_idx++) { |
255 | 71.0k | index = cb_index[track_idx]; |
256 | 71.0k | ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec); |
257 | 71.0k | } |
258 | 106k | for (track_idx = 2; track_idx < 4; track_idx++) { |
259 | 71.0k | index = cb_index[track_idx]; |
260 | 71.0k | ixheaacd_acelp_decode_1sp_per_track(index, 4, 0, track_idx, code_vec); |
261 | 71.0k | } |
262 | 255k | } else if (code_bits == 36) { |
263 | 277k | for (track_idx = 0; track_idx < 4; track_idx++) { |
264 | 221k | index = cb_index[track_idx]; |
265 | 221k | ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec); |
266 | 221k | } |
267 | 200k | } else if (code_bits == 44) { |
268 | 173k | for (track_idx = 0; track_idx < 2; track_idx++) { |
269 | 115k | index = cb_index[track_idx]; |
270 | 115k | ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec); |
271 | 115k | } |
272 | 173k | for (track_idx = 2; track_idx < 4; track_idx++) { |
273 | 115k | index = cb_index[track_idx]; |
274 | 115k | ixheaacd_acelp_decode_2sp_per_track(index, 4, 0, track_idx, code_vec); |
275 | 115k | } |
276 | 142k | } else if (code_bits == 52) { |
277 | 402k | for (track_idx = 0; track_idx < 4; track_idx++) { |
278 | 321k | index = cb_index[track_idx]; |
279 | 321k | ixheaacd_acelp_decode_3sp_per_track(index, 4, 0, track_idx, code_vec); |
280 | 321k | } |
281 | 80.4k | } else if (code_bits == 64) { |
282 | 309k | for (track_idx = 0; track_idx < 4; track_idx++) { |
283 | 247k | index = ((cb_index[track_idx] << 14) + cb_index[track_idx + 4]); |
284 | 247k | ixheaacd_acelp_decode_4sp_per_track(index, track_idx, code_vec); |
285 | 247k | } |
286 | 61.8k | } |
287 | 675k | return; |
288 | 675k | } |
289 | | |
290 | | static void ixheaacd_acelp_decode_gains(WORD32 index, FLOAT32 code_vec[], |
291 | | FLOAT32 *pitch_gain, |
292 | | FLOAT32 *codebook_gain, |
293 | | FLOAT32 mean_exc_energy, |
294 | 675k | FLOAT32 *energy) { |
295 | 675k | WORD32 i; |
296 | 675k | FLOAT32 avg_innov_energy, est_gain; |
297 | 675k | const FLOAT32 *gain_table = ixheaacd_int_leave_gain_table; |
298 | | |
299 | 675k | avg_innov_energy = 0.01f; |
300 | 43.9M | for (i = 0; i < LEN_SUBFR; i++) { |
301 | 43.2M | avg_innov_energy += code_vec[i] * code_vec[i]; |
302 | 43.2M | } |
303 | 675k | *energy = avg_innov_energy; |
304 | | |
305 | 675k | avg_innov_energy = |
306 | 675k | (FLOAT32)(10.0 * log10(avg_innov_energy / (FLOAT32)LEN_SUBFR)); |
307 | | |
308 | 675k | est_gain = mean_exc_energy - avg_innov_energy; |
309 | | |
310 | 675k | est_gain = (FLOAT32)pow(10.0, 0.05 * est_gain); |
311 | 675k | *pitch_gain = gain_table[index * 2]; |
312 | | |
313 | 675k | *codebook_gain = gain_table[index * 2 + 1] * est_gain; |
314 | | |
315 | 675k | return; |
316 | 675k | } |
317 | | |
318 | | static VOID ixheaacd_acelp_decode_gains_with_ec(WORD32 index, FLOAT32 code_vec[], |
319 | | FLOAT32 *pitch_gain, FLOAT32 *codebook_gain, |
320 | | FLOAT32 mean_exc_energy, FLOAT32 *energy, |
321 | | FLOAT32 *past_pitch_gain, FLOAT32 *past_gain_code, |
322 | 0 | WORD32 bfi) { |
323 | 0 | WORD32 i; |
324 | 0 | FLOAT32 avg_innov_energy, est_gain, gain_inov; |
325 | 0 | const FLOAT32 *gain_table = ixheaacd_int_leave_gain_table; |
326 | |
|
327 | 0 | avg_innov_energy = 0.01f; |
328 | 0 | for (i = 0; i < LEN_SUBFR; i++) { |
329 | 0 | avg_innov_energy += code_vec[i] * code_vec[i]; |
330 | 0 | } |
331 | 0 | *energy = avg_innov_energy; |
332 | 0 | gain_inov = (FLOAT32)(1 / sqrt(avg_innov_energy / LEN_SUBFR)); |
333 | |
|
334 | 0 | if (bfi) { |
335 | 0 | FLOAT32 tgpit = (*past_pitch_gain); |
336 | |
|
337 | 0 | if (tgpit > 0.95f) { |
338 | 0 | tgpit = 0.95f; |
339 | 0 | } else if (tgpit < 0.5f) { |
340 | 0 | tgpit = 0.5f; |
341 | 0 | } |
342 | 0 | *pitch_gain = (FLOAT32)tgpit; |
343 | 0 | tgpit = tgpit * 0.95f; |
344 | 0 | *past_pitch_gain = (FLOAT32)tgpit; |
345 | |
|
346 | 0 | tgpit = 1.4f - tgpit; |
347 | 0 | tgpit = *past_gain_code * tgpit; |
348 | 0 | *codebook_gain = tgpit * gain_inov; |
349 | |
|
350 | 0 | *past_gain_code = tgpit; |
351 | 0 | return; |
352 | 0 | } |
353 | | |
354 | 0 | avg_innov_energy = (FLOAT32)(10.0 * log10(avg_innov_energy / (FLOAT32)LEN_SUBFR)); |
355 | 0 | est_gain = mean_exc_energy - avg_innov_energy; |
356 | |
|
357 | 0 | est_gain = (FLOAT32)pow(10.0, 0.05 * est_gain); |
358 | 0 | if (!bfi) { |
359 | 0 | *pitch_gain = gain_table[index * 2]; |
360 | 0 | *past_pitch_gain = *pitch_gain; |
361 | 0 | } |
362 | |
|
363 | 0 | *codebook_gain = gain_table[index * 2 + 1] * est_gain; |
364 | 0 | *past_gain_code = (*codebook_gain) / gain_inov; |
365 | |
|
366 | 0 | return; |
367 | 0 | } |
368 | | |
369 | | static VOID ixheaacd_cb_exc_calc(FLOAT32 xcitation_curr[], WORD32 pitch_lag, |
370 | 675k | WORD32 frac) { |
371 | 675k | WORD32 i, j; |
372 | 675k | FLOAT32 s, *x0, *x1, *x2; |
373 | 675k | const FLOAT32 *c1, *c2; |
374 | | |
375 | 675k | x0 = &xcitation_curr[-pitch_lag]; |
376 | 675k | frac = -frac; |
377 | 675k | if (frac < 0) { |
378 | 309k | frac += UP_SAMP; |
379 | 309k | x0--; |
380 | 309k | } |
381 | 44.6M | for (j = 0; j < LEN_SUBFR + 1; j++) { |
382 | 43.9M | x1 = x0++; |
383 | 43.9M | x2 = x1 + 1; |
384 | 43.9M | c1 = &ixheaacd_interpol_filt[frac]; |
385 | 43.9M | c2 = &ixheaacd_interpol_filt[UP_SAMP - frac]; |
386 | 43.9M | s = 0.0; |
387 | 746M | for (i = 0; i < INTER_LP_FIL_ORDER; i++, c1 += UP_SAMP, c2 += UP_SAMP) { |
388 | 702M | s += (*x1--) * (*c1) + (*x2++) * (*c2); |
389 | 702M | } |
390 | 43.9M | xcitation_curr[j] = s; |
391 | 43.9M | } |
392 | 675k | return; |
393 | 675k | } |
394 | | |
395 | | VOID ixheaacd_acelp_alias_cnx(ia_usac_data_struct *usac_data, |
396 | | ia_td_frame_data_struct *pstr_td_frame_data, WORD32 k, |
397 | | FLOAT32 lp_filt_coeff[], FLOAT32 stability_factor, |
398 | 185k | ia_usac_lpd_decoder_handle st) { |
399 | 185k | WORD32 i, subfr_idx; |
400 | 185k | WORD32 pitch_lag = 0, pitch_lag_frac = 0, index, pitch_flag, pitch_lag_max; |
401 | 185k | WORD32 pitch_lag_min = 0; |
402 | 185k | FLOAT32 tmp, pitch_gain, gain_code, voicing_factor, r_v, innov_energy, |
403 | 185k | pitch_energy, mean_ener_code; |
404 | 185k | FLOAT32 gain_smooth, gain_code0, cpe; |
405 | 185k | FLOAT32 code[LEN_SUBFR] = {0}, synth_temp[128 + 16] = {0}; |
406 | 185k | FLOAT32 post_process_exc[LEN_SUBFR] = {0}; |
407 | 185k | FLOAT32 gain_smooth_factor; |
408 | 185k | FLOAT32 *ptr_lp_filt_coeff; |
409 | 185k | WORD32 pitch_min; |
410 | 185k | WORD32 pitch_fr2; |
411 | 185k | WORD32 pitch_fr1; |
412 | 185k | WORD32 pitch_max; |
413 | 185k | WORD32 subfr_nb = 0; |
414 | 185k | const WORD16 num_codebits_table[8] = {20, 28, 36, 44, 52, 64, 12, 16}; |
415 | 185k | FLOAT32 x[FAC_LENGTH] = {0}, xn2[2 * FAC_LENGTH + 16] = {0}; |
416 | 185k | WORD32 int_x[FAC_LENGTH] = {0}; |
417 | 185k | WORD32 TTT; |
418 | 185k | WORD32 len_subfr = usac_data->len_subfrm; |
419 | 185k | WORD32 fac_length; |
420 | 185k | WORD8 shiftp; |
421 | 185k | WORD32 preshift; |
422 | 185k | WORD32 *ptr_scratch = &usac_data->scratch_buffer[0]; |
423 | 185k | WORD32 *int_xn2 = &usac_data->x_ac_dec[0]; |
424 | 185k | WORD32 loop_count = 0; |
425 | 185k | WORD32 core_mode = pstr_td_frame_data->acelp_core_mode; |
426 | 185k | FLOAT32 *synth_signal = |
427 | 185k | &usac_data->synth_buf[len_subfr * k + MAX_PITCH + |
428 | 185k | (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1) * |
429 | 185k | LEN_SUBFR]; |
430 | 185k | FLOAT32 *xcitation_curr = |
431 | 185k | &usac_data->exc_buf[len_subfr * k + MAX_PITCH + (INTER_LP_FIL_ORDER + 1)]; |
432 | 185k | FLOAT32 *ptr_pitch_gain = |
433 | 185k | &usac_data->pitch_gain[k * usac_data->num_subfrm + |
434 | 185k | (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)]; |
435 | 185k | WORD32 *ptr_pitch = |
436 | 185k | &usac_data->pitch[k * usac_data->num_subfrm + |
437 | 185k | (((NUM_FRAMES * usac_data->num_subfrm) / 2) - 1)]; |
438 | 185k | fac_length = len_subfr / 2; |
439 | | |
440 | 185k | WORD32 bfi = (usac_data->num_lost_lpd_frames[usac_data->present_chan] > 0) ? 1 : 0; |
441 | 185k | WORD32 i_offset = |
442 | 185k | (usac_data->str_tddec[usac_data->present_chan]->fscale * TMIN + (FSCALE_DENOM / 2)) / |
443 | 185k | FSCALE_DENOM - |
444 | 185k | TMIN; |
445 | 185k | const WORD32 pitch_max_val = TMAX + (6 * i_offset); |
446 | 185k | WORD16 code_t[LEN_SUBFR]; |
447 | | |
448 | 185k | if (st->mode_prev > 0) { |
449 | 4.31M | for (i = 0; i < fac_length / 2; i++) { |
450 | 4.24M | x[i] = st->fac_gain * pstr_td_frame_data->fac[k * FAC_LENGTH + 2 * i]; |
451 | 4.24M | x[fac_length / 2 + i] = |
452 | 4.24M | st->fac_gain * |
453 | 4.24M | pstr_td_frame_data->fac[k * FAC_LENGTH + fac_length - 2 * i - 1]; |
454 | 4.24M | } |
455 | 1.13M | for (i = 0; i < fac_length / 8; i++) { |
456 | 1.06M | x[i] *= st->fac_fd_data[2 * i]; |
457 | 1.06M | x[fac_length - i - 1] *= st->fac_fd_data[2 * i + 1]; |
458 | 1.06M | } |
459 | | |
460 | 73.0k | preshift = 0; |
461 | 73.0k | shiftp = ixheaacd_float2fix(x, int_x, fac_length); |
462 | | |
463 | 73.0k | ixheaacd_acelp_mdct(int_x, int_xn2, &preshift, fac_length, ptr_scratch); |
464 | | |
465 | 73.0k | ixheaacd_fix2float(int_xn2, xn2 + fac_length, fac_length, &shiftp, |
466 | 73.0k | &preshift); |
467 | | |
468 | 73.0k | ixheaacd_vec_cnst_mul((2.0f / (FLOAT32)fac_length), xn2 + fac_length, |
469 | 73.0k | xn2 + fac_length, fac_length); |
470 | | |
471 | 73.0k | memset(xn2, 0, fac_length * sizeof(FLOAT32)); |
472 | | |
473 | 73.0k | ixheaacd_lpc_wt_synthesis_tool(st->lp_flt_coeff_a_prev, xn2 + fac_length, |
474 | 73.0k | fac_length); |
475 | | |
476 | 17.0M | for (i = 0; i < 2 * fac_length; i++) |
477 | 16.9M | xn2[i] += synth_signal[i - (2 * fac_length)]; |
478 | | |
479 | 73.0k | memcpy(synth_signal - fac_length, xn2 + fac_length, |
480 | 73.0k | fac_length * sizeof(FLOAT32)); |
481 | | |
482 | 73.0k | tmp = 0.0; |
483 | 73.0k | ixheaacd_preemphsis_tool_float(xn2, PREEMPH_FILT_FAC, 2 * fac_length, tmp); |
484 | | |
485 | 73.0k | ptr_lp_filt_coeff = st->lp_flt_coeff_a_prev; |
486 | 73.0k | TTT = fac_length % LEN_SUBFR; |
487 | 73.0k | if (TTT != 0) { |
488 | 26.6k | ixheaacd_residual_tool_float( |
489 | 26.6k | ptr_lp_filt_coeff, &xn2[fac_length], |
490 | 26.6k | &xcitation_curr[fac_length - (2 * fac_length)], TTT, 1); |
491 | 26.6k | ptr_lp_filt_coeff += (ORDER + 1); |
492 | 26.6k | } |
493 | | |
494 | 73.0k | loop_count = (fac_length + TTT) / LEN_SUBFR; |
495 | 73.0k | ixheaacd_residual_tool_float(ptr_lp_filt_coeff, &xn2[fac_length + TTT], |
496 | 73.0k | &xcitation_curr[TTT - fac_length], LEN_SUBFR, |
497 | 73.0k | loop_count); |
498 | 73.0k | } |
499 | | |
500 | 3.15M | for (i = 0; i < ORDER; i++) |
501 | 2.96M | synth_temp[i] = synth_signal[i - ORDER] - |
502 | 2.96M | (PREEMPH_FILT_FAC * synth_signal[i - ORDER - 1]); |
503 | | |
504 | 185k | i = (((st->fscale * TMIN) + (FSCALE_DENOM / 2)) / FSCALE_DENOM) - TMIN; |
505 | 185k | pitch_min = TMIN + i; |
506 | 185k | pitch_fr2 = TFR2 - i; |
507 | 185k | pitch_fr1 = TFR1; |
508 | 185k | pitch_max = TMAX + (6 * i); |
509 | | |
510 | 185k | ptr_lp_filt_coeff = lp_filt_coeff; |
511 | 861k | for (subfr_idx = 0; subfr_idx < len_subfr; subfr_idx += LEN_SUBFR) { |
512 | 675k | pitch_flag = subfr_idx; |
513 | 675k | if ((len_subfr == 256) && (subfr_idx == (2 * LEN_SUBFR))) { |
514 | 119k | pitch_flag = 0; |
515 | 119k | } |
516 | 675k | index = pstr_td_frame_data->acb_index[k * 4 + subfr_nb]; |
517 | | |
518 | 675k | if (pitch_flag == 0) { |
519 | 304k | if (index < (pitch_fr2 - pitch_min) * 4) { |
520 | 255k | pitch_lag = pitch_min + (index / 4); |
521 | 255k | pitch_lag_frac = index - (pitch_lag - pitch_min) * 4; |
522 | 255k | } else if (index < |
523 | 48.8k | ((pitch_fr2 - pitch_min) * 4 + (pitch_fr1 - pitch_fr2) * 2)) { |
524 | 27.9k | index -= (pitch_fr2 - pitch_min) * 4; |
525 | 27.9k | pitch_lag = pitch_fr2 + (index / 2); |
526 | 27.9k | pitch_lag_frac = index - (pitch_lag - pitch_fr2) * 2; |
527 | 27.9k | pitch_lag_frac *= 2; |
528 | 27.9k | } else { |
529 | 20.8k | pitch_lag = index + pitch_fr1 - ((pitch_fr2 - pitch_min) * 4) - |
530 | 20.8k | ((pitch_fr1 - pitch_fr2) * 2); |
531 | 20.8k | pitch_lag_frac = 0; |
532 | 20.8k | } |
533 | 304k | pitch_lag_min = pitch_lag - 8; |
534 | 304k | if (pitch_lag_min < pitch_min) pitch_lag_min = pitch_min; |
535 | | |
536 | 304k | pitch_lag_max = pitch_lag_min + 15; |
537 | 304k | if (pitch_lag_max > pitch_max) { |
538 | 30.7k | pitch_lag_max = pitch_max; |
539 | 30.7k | pitch_lag_min = pitch_lag_max - 15; |
540 | 30.7k | } |
541 | 371k | } else { |
542 | 371k | pitch_lag = pitch_lag_min + index / 4; |
543 | 371k | pitch_lag_frac = index - (pitch_lag - pitch_lag_min) * 4; |
544 | 371k | } |
545 | | |
546 | 675k | if (usac_data->ec_flag) { |
547 | 0 | if (bfi) { |
548 | 0 | if (usac_data->pitch_lag_old >= pitch_max_val) { |
549 | 0 | usac_data->pitch_lag_old = (pitch_max_val - 5); |
550 | 0 | } |
551 | 0 | pitch_lag = usac_data->pitch_lag_old; |
552 | 0 | pitch_lag_frac = usac_data->pitch_lag_frac_old; |
553 | 0 | } |
554 | 0 | } |
555 | 675k | ixheaacd_cb_exc_calc(&xcitation_curr[subfr_idx], pitch_lag, pitch_lag_frac); |
556 | | |
557 | 675k | mean_ener_code = |
558 | 675k | (((FLOAT32)pstr_td_frame_data->mean_energy[k]) * 12.0f) + 18.0f; |
559 | | |
560 | 675k | if (pstr_td_frame_data->ltp_filtering_flag[k * 4 + subfr_nb] == 0) { |
561 | 31.7M | for (i = 0; i < LEN_SUBFR; i++) |
562 | 31.2M | code[i] = (FLOAT32)(0.18 * xcitation_curr[i - 1 + subfr_idx] + |
563 | 31.2M | 0.64 * xcitation_curr[i + subfr_idx] + |
564 | 31.2M | 0.18 * xcitation_curr[i + 1 + subfr_idx]); |
565 | | |
566 | 489k | ixheaacd_mem_cpy(code, &xcitation_curr[subfr_idx], LEN_SUBFR); |
567 | 489k | } |
568 | 675k | if (usac_data->frame_ok == 1) { |
569 | 675k | ixheaacd_acelp_decode_pulses_per_track( |
570 | 675k | &(pstr_td_frame_data->icb_index[k * 4 + subfr_nb][0]), num_codebits_table[core_mode], |
571 | 675k | code); |
572 | 675k | } else { |
573 | 0 | if (usac_data->ec_flag) { |
574 | 0 | WORD32 idx; |
575 | 0 | if (bfi) { |
576 | 0 | for (idx = 0; idx < LEN_SUBFR; idx++) { |
577 | 0 | usac_data->seed_ace = ((((WORD32)usac_data->seed_ace * 31821) >> 1) + 13849); |
578 | 0 | code_t[idx] = (WORD16)((usac_data->seed_ace) >> 4); |
579 | 0 | code[idx] = ((FLOAT32)code_t[idx] / 512); |
580 | 0 | } |
581 | 0 | } |
582 | 0 | } |
583 | 0 | } |
584 | | |
585 | 675k | tmp = 0.0; |
586 | 675k | ixheaacd_preemphsis_tool_float(code, TILT_CODE, LEN_SUBFR, tmp); |
587 | 675k | i = pitch_lag; |
588 | 675k | if (pitch_lag_frac > 2) i++; |
589 | 675k | if (i >= 0) ixheaacd_acelp_pitch_sharpening(code, i); |
590 | | |
591 | 675k | index = pstr_td_frame_data->gains[k * 4 + subfr_nb]; |
592 | 675k | if (usac_data->ec_flag) { |
593 | 0 | ixheaacd_acelp_decode_gains_with_ec(index, code, &pitch_gain, &gain_code, mean_ener_code, |
594 | 0 | &innov_energy, &usac_data->past_pitch_gain, |
595 | 0 | &usac_data->past_gain_code, bfi); |
596 | 675k | } else { |
597 | 675k | ixheaacd_acelp_decode_gains(index, code, &pitch_gain, &gain_code, mean_ener_code, |
598 | 675k | &innov_energy); |
599 | 675k | } |
600 | | |
601 | 675k | pitch_energy = 0.0; |
602 | 43.9M | for (i = 0; i < LEN_SUBFR; i++) |
603 | 43.2M | pitch_energy += |
604 | 43.2M | xcitation_curr[i + subfr_idx] * xcitation_curr[i + subfr_idx]; |
605 | | |
606 | 675k | pitch_energy *= (pitch_gain * pitch_gain); |
607 | | |
608 | 675k | innov_energy *= gain_code * gain_code; |
609 | | |
610 | 675k | r_v = (FLOAT32)((pitch_energy - innov_energy) / |
611 | 675k | (pitch_energy + innov_energy)); |
612 | | |
613 | 43.9M | for (i = 0; i < LEN_SUBFR; i++) |
614 | 43.2M | post_process_exc[i] = pitch_gain * xcitation_curr[i + subfr_idx]; |
615 | | |
616 | 43.9M | for (i = 0; i < LEN_SUBFR; i++) |
617 | 43.2M | xcitation_curr[i + subfr_idx] = |
618 | 43.2M | pitch_gain * xcitation_curr[i + subfr_idx] + gain_code * code[i]; |
619 | | |
620 | 675k | i = pitch_lag; |
621 | 675k | if (pitch_lag_frac > 2) i++; |
622 | | |
623 | 675k | if (i > pitch_max) i = pitch_max; |
624 | | |
625 | 675k | *ptr_pitch++ = i; |
626 | 675k | *ptr_pitch_gain++ = pitch_gain; |
627 | | |
628 | 675k | voicing_factor = (FLOAT32)(0.5 * (1.0 - r_v)); |
629 | 675k | gain_smooth_factor = stability_factor * voicing_factor; |
630 | 675k | gain_code0 = gain_code; |
631 | 675k | if (gain_code0 < st->gain_threshold) { |
632 | 319k | gain_code0 = (FLOAT32)(gain_code0 * 1.19); |
633 | 319k | if (gain_code0 > st->gain_threshold) gain_code0 = st->gain_threshold; |
634 | 356k | } else { |
635 | 356k | gain_code0 = (FLOAT32)(gain_code0 / 1.19); |
636 | 356k | if (gain_code0 < st->gain_threshold) gain_code0 = st->gain_threshold; |
637 | 356k | } |
638 | 675k | st->gain_threshold = gain_code0; |
639 | 675k | gain_smooth = (FLOAT32)((gain_smooth_factor * gain_code0) + |
640 | 675k | ((1.0 - gain_smooth_factor) * gain_code)); |
641 | 43.9M | for (i = 0; i < LEN_SUBFR; i++) code[i] *= gain_smooth; |
642 | | |
643 | 675k | cpe = (FLOAT32)(0.125 * (1.0 + r_v)); |
644 | | |
645 | 675k | post_process_exc[0] += code[0] - (cpe * code[1]); |
646 | | |
647 | 42.5M | for (i = 1; i < LEN_SUBFR - 1; i++) |
648 | 41.9M | post_process_exc[i] += code[i] - (cpe * (code[i - 1] + code[i + 1])); |
649 | | |
650 | 675k | post_process_exc[LEN_SUBFR - 1] += |
651 | 675k | code[LEN_SUBFR - 1] - (cpe * code[LEN_SUBFR - 2]); |
652 | | |
653 | 675k | ixheaacd_synthesis_tool_float(ptr_lp_filt_coeff, post_process_exc, |
654 | 675k | &synth_signal[subfr_idx], LEN_SUBFR, |
655 | 675k | synth_temp); |
656 | 675k | memcpy(synth_temp, &synth_signal[subfr_idx + LEN_SUBFR - ORDER], |
657 | 675k | ORDER * sizeof(FLOAT32)); |
658 | | |
659 | 675k | ptr_lp_filt_coeff += (ORDER + 1); |
660 | 675k | subfr_nb++; |
661 | 675k | } |
662 | | |
663 | 185k | ixheaacd_deemphsis_tool(synth_signal, len_subfr, synth_signal[-1]); |
664 | | |
665 | 185k | memset(synth_temp + 16, 0, 128 * sizeof(FLOAT32)); |
666 | 185k | ixheaacd_synthesis_tool_float1(ptr_lp_filt_coeff, synth_temp + 16, 128); |
667 | | |
668 | 185k | ptr_lp_filt_coeff -= (2 * (ORDER + 1)); |
669 | 185k | memcpy(st->lp_flt_coeff_a_prev, ptr_lp_filt_coeff, |
670 | 185k | (2 * (ORDER + 1)) * sizeof(FLOAT32)); |
671 | | |
672 | 185k | memcpy(st->exc_prev, synth_signal + len_subfr - (1 + fac_length), |
673 | 185k | (1 + fac_length) * sizeof(FLOAT32)); |
674 | | |
675 | 185k | memcpy(st->exc_prev + 1 + fac_length, synth_temp + 16, |
676 | 185k | fac_length * sizeof(FLOAT32)); |
677 | 185k | ixheaacd_deemphsis_tool(st->exc_prev + 1 + fac_length, fac_length, |
678 | 185k | synth_signal[len_subfr - 1]); |
679 | | |
680 | 185k | if (usac_data->ec_flag) { |
681 | 0 | usac_data->pitch_lag_old = pitch_lag; |
682 | 0 | usac_data->pitch_lag_frac_old = pitch_lag_frac; |
683 | 0 | } |
684 | 185k | return; |
685 | 185k | } |