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 <string.h>
22 #include <math.h>
23 #include "ixheaac_type_def.h"
24 #include "ixheaace_adjust_threshold_data.h"
25 #include "iusace_bitbuffer.h"
26
27 /* DRC */
28 #include "impd_drc_common_enc.h"
29 #include "impd_drc_uni_drc.h"
30 #include "impd_drc_tables.h"
31 #include "impd_drc_api.h"
32 #include "impd_drc_uni_drc_eq.h"
33 #include "impd_drc_uni_drc_filter_bank.h"
34 #include "impd_drc_gain_enc.h"
35 #include "impd_drc_struct_def.h"
36
37 #include "iusace_cnst.h"
38 #include "iusace_tns_usac.h"
39 #include "iusace_psy_mod.h"
40 #include "iusace_tns_usac.h"
41 #include "iusace_config.h"
42 #include "iusace_fft.h"
43 #include "iusace_tcx_mdct.h"
44 #include "iusace_arith_enc.h"
45 #include "iusace_fd_qc_util.h"
46 #include "iusace_fd_quant.h"
47 #include "iusace_block_switch_const.h"
48 #include "iusace_block_switch_struct_def.h"
49 #include "iusace_ms.h"
50 #include "iusace_signal_classifier.h"
51 #include "ixheaace_sbr_header.h"
52 #include "ixheaace_config.h"
53 #include "ixheaace_asc_write.h"
54 #include "iusace_main.h"
55 #include "iusace_lpd_rom.h"
56 #include "iusace_lpd.h"
57 #include "iusace_avq_enc.h"
58 #include "ixheaace_common_utils.h"
59
60 const UWORD32 iusace_pow10_gain_div28[128] = {
61 1024, 1112, 1207, 1311, 1423, 1545, 1677, 1821, 1977,
62 2146, 2330, 2530, 2747, 2983, 3238, 3516, 3817, 4144,
63 4499, 4885, 5304, 5758, 6252, 6788, 7370, 8001, 8687,
64 9432, 10240, 11118, 12071, 13105, 14228, 15448, 16772, 18210,
65 19770, 21465, 23305, 25302, 27471, 29825, 32382, 35157, 38171,
66 41442, 44994, 48851, 53038, 57584, 62519, 67878, 73696, 80012,
67 86870, 94316, 102400, 111177, 120706, 131052, 142284, 154480, 167720,
68 182096, 197703, 214649, 233047, 253021, 274708, 298254, 323817, 351572,
69 381706, 414422, 449943, 488508, 530378, 575838, 625193, 678779, 736958,
70 800124, 868703, 943161, 1024000, 1111768, 1207059, 1310517, 1422843, 1544797,
71 1677203, 1820958, 1977034, 2146488, 2330466, 2530213, 2747080, 2982536, 3238172,
72 3515720, 3817056, 4144220, 4499426, 4885077, 5303782, 5758375, 6251932, 6787792,
73 7369581, 8001236, 8687031, 9431606, 10240000, 11117682, 12070591, 13105175, 14228434,
74 15447969, 16772032, 18209581, 19770345, 21464883, 23304662, 25302131, 27470805, 29825358,
75 32381723, 35157197};
76
77 static const FLOAT64 iusace_lpc_pre_twid_cos[ORDER + 1] = {1.0,
78 0.99969881867944277,
79 0.99879545613814691,
80 0.99729045666498317,
81 0.99518472640441780,
82 0.99247953486470630,
83 0.98917650991010153,
84 0.98527764316379052,
85 0.98078527933727178,
86 0.97570212991605565,
87 0.97003125425052761,
88 0.96377606826277584,
89 0.95694033551585822,
90 0.94952817722361749,
91 0.94154406823678738,
92 0.93299279849944938,
93 0.92387952832938047};
94
95 static const FLOAT64 iusace_lpc_pre_twid_sin[ORDER + 1] = {0,
96 0.024541229205697054,
97 0.049067675691753569,
98 0.073564563785488826,
99 0.098017143048367339,
100 0.12241067304257494,
101 0.14673047482398086,
102 0.17096188429473480,
103 0.19509032737506427,
104 0.21910124070226658,
105 0.24298017568754085,
106 0.26671274855909161,
107 0.29028467796767482,
108 0.31368175059826858,
109 0.33688984485751389,
110 0.35989503740419343,
111 0.38268344246110436};
112
iusace_lpc_mdct(FLOAT32 * ptr_lpc_coeffs,FLOAT32 * mdct_gains,WORD32 length,iusace_scratch_mem * pstr_scratch)113 static VOID iusace_lpc_mdct(FLOAT32 *ptr_lpc_coeffs, FLOAT32 *mdct_gains, WORD32 length,
114 iusace_scratch_mem *pstr_scratch) {
115 FLOAT32 *in_out = pstr_scratch->p_in_out_tcx;
116 WORD32 i;
117
118 for (i = 0; i < ORDER + 1; i++) {
119 in_out[2 * i] = (FLOAT32)(ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_cos[i]);
120 in_out[2 * i + 1] = (FLOAT32)(-ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_sin[i]);
121 }
122 for (; i < length; i++) {
123 in_out[2 * i] = 0.f;
124 in_out[2 * i + 1] = 0.f;
125 }
126
127 iusace_complex_fft(in_out, length, pstr_scratch);
128
129 for (i = 0; i<length>> 1; i++) {
130 mdct_gains[i] = (FLOAT32)(
131 1.0f / sqrt(in_out[2 * i] * in_out[2 * i] + in_out[2 * i + 1] * in_out[2 * i + 1]));
132 }
133
134 return;
135 }
136
iusace_rounded_sqrt(UWORD32 pos_num)137 UWORD32 iusace_rounded_sqrt(UWORD32 pos_num) {
138 UWORD32 num = pos_num;
139 UWORD32 value = 0;
140 UWORD32 bit_set = 1 << 30;
141
142 while (bit_set > num) {
143 bit_set >>= 2;
144 }
145 while (bit_set) {
146 if (num >= value + bit_set) {
147 num -= value + bit_set;
148 value += bit_set << 1;
149 }
150 value >>= 1;
151 bit_set >>= 2;
152 }
153 num = value + 1;
154 if (num * num - pos_num < pos_num - value * value) {
155 return num;
156 }
157 return value;
158 }
159
iusace_noise_shaping(FLOAT32 * rr,WORD32 lg,WORD32 M,FLOAT32 * gain1,FLOAT32 * gain2)160 static VOID iusace_noise_shaping(FLOAT32 *rr, WORD32 lg, WORD32 M, FLOAT32 *gain1,
161 FLOAT32 *gain2) {
162 WORD32 i, k;
163 FLOAT32 r, r_prev, g1, g2, a = 0, b = 0;
164
165 k = lg/M;
166
167 r_prev = 0;
168 for (i = 0; i < lg; i++) {
169 if ((i % k) == 0) {
170 g1 = gain1[i / k];
171 g2 = gain2[i / k];
172 a = 2.0f * g1 * g2 / (g1 + g2);
173 b = (g2 - g1) / (g1 + g2);
174 }
175
176 r = a * rr[i] + b * r_prev;
177
178 rr[i] = r;
179 r_prev = r;
180 }
181
182 return;
183 }
184
iusace_pre_shaping(FLOAT32 * rr,WORD32 lg,WORD32 M,FLOAT32 * gain1,FLOAT32 * gain2)185 static VOID iusace_pre_shaping(FLOAT32 *rr, WORD32 lg, WORD32 M, FLOAT32 *gain1, FLOAT32 *gain2) {
186 WORD32 i, k;
187 FLOAT32 r, r_prev, g1, g2, a = 0, b = 0;
188
189 k = lg / M;
190
191 r_prev = 0;
192 for (i = 0; i < lg; i++) {
193 if ((i % k) == 0) {
194 g1 = gain1[i / k];
195 g2 = gain2[i / k];
196
197 a = (g1 + g2) / (2.0f * g1 * g2);
198 b = (g1 - g2) / (2.0f * g1 * g2);
199 }
200
201 r = a * rr[i] + b * r_prev;
202
203 r_prev = rr[i];
204 rr[i] = r;
205 }
206
207 return;
208 }
209
iusace_adapt_lo_freq_emph(FLOAT32 * signal,WORD32 length)210 static VOID iusace_adapt_lo_freq_emph(FLOAT32 *signal, WORD32 length) {
211 WORD32 i, j, i_max;
212 FLOAT32 max_energy, factor, temp;
213
214 i_max = length >> 2;
215
216 max_energy = 0.01f;
217 for (i = 0; i < i_max; i += 8) {
218 temp = 0.01f;
219 for (j = i; j < i + 8; j++) {
220 temp += signal[j] * signal[j];
221 }
222 if (temp > max_energy) {
223 max_energy = temp;
224 }
225 }
226
227 factor = 10.0f;
228 for (i = 0; i < i_max; i += 8) {
229 temp = 0.01f;
230 for (j = i; j < i + 8; j++) {
231 temp += signal[j] * signal[j];
232 }
233 temp = (FLOAT32)sqrt(sqrt(max_energy / temp));
234 if (temp < factor) {
235 factor = temp;
236 }
237 for (j = i; j < i + 8; j++) {
238 signal[j] *= factor;
239 }
240 }
241 return;
242 }
243
iusace_adapt_lo_freq_deemph(FLOAT32 * signal,WORD32 length,FLOAT32 * gains)244 static VOID iusace_adapt_lo_freq_deemph(FLOAT32 *signal, WORD32 length, FLOAT32 *gains) {
245 WORD32 i, j, i_max;
246 FLOAT32 max_energy, factor, energy, rm;
247
248 i_max = length >> 2;
249
250 max_energy = 0.01f;
251 for (i = 0; i < i_max; i += 8) {
252 energy = 0.01f;
253 for (j = i; j < i + 8; j++) {
254 energy += signal[j] * signal[j];
255 }
256 if (energy > max_energy) {
257 max_energy = energy;
258 }
259 }
260
261 factor = 0.1f;
262 for (i = 0; i < i_max; i += 8) {
263 energy = 0.01f;
264 for (j = i; j < i + 8; j++) {
265 energy += signal[j] * signal[j];
266 }
267
268 rm = (FLOAT32)sqrt(energy / max_energy);
269 if (rm > factor) {
270 factor = rm;
271 }
272 for (j = i; j < i + 8; j++) {
273 signal[j] *= factor;
274 }
275 gains[i / 8] = factor;
276 }
277
278 return;
279 }
280
iusace_tcx_fac_encode(ia_usac_data_struct * usac_data,FLOAT32 * lpc_coeffs,FLOAT32 * lpc_coeffs_quant,FLOAT32 * speech,WORD32 frame_len,WORD32 num_bits_per_supfrm,ia_usac_lpd_state_struct * lpd_state,WORD32 * params,WORD32 * n_param,WORD32 ch_idx,WORD32 k_idx)281 VOID iusace_tcx_fac_encode(ia_usac_data_struct *usac_data, FLOAT32 *lpc_coeffs,
282 FLOAT32 *lpc_coeffs_quant, FLOAT32 *speech, WORD32 frame_len,
283 WORD32 num_bits_per_supfrm, ia_usac_lpd_state_struct *lpd_state,
284 WORD32 *params, WORD32 *n_param, WORD32 ch_idx, WORD32 k_idx) {
285 ia_usac_td_encoder_struct *st = usac_data->td_encoder[ch_idx];
286 iusace_scratch_mem *pstr_scratch = &usac_data->str_scratch;
287 FLOAT32 *weighted_sig = &pstr_scratch->p_wsig_buf[k_idx * st->len_subfrm];
288 FLOAT32 *wsynth = pstr_scratch->p_wsyn_tcx_buf;
289 FLOAT32 *synth = pstr_scratch->p_synth_tcx_buf;
290 WORD32 i, k, n, mode, i_subfr, lg, lext, index, target_bits;
291 FLOAT32 tmp, gain, fac_ns, energy, gain_tcx, nsfill_en_thres;
292 FLOAT32 *ptr_lp_flt_coeffs, lp_flt_coeffs[ORDER + 1];
293 const FLOAT32 *sine_window_prev, *sine_window;
294 FLOAT32 mem_tcx_q;
295 FLOAT32 *xn;
296 FLOAT32 *xn1 = pstr_scratch->p_xn1_tcx;
297 FLOAT32 *xn_buf = pstr_scratch->p_xn_buf_tcx;
298 FLOAT32 *x = pstr_scratch->p_x_tcx;
299 FLOAT32 *x_tmp = pstr_scratch->p_x_tmp_tcx;
300 FLOAT32 *en = pstr_scratch->p_en_tcx;
301 FLOAT32 sq_gain;
302 FLOAT32 gain_prev, gain_next;
303 FLOAT32 *alfd_gains = pstr_scratch->p_alfd_gains_tcx;
304 FLOAT32 *sq_enc = pstr_scratch->p_sq_enc_tcx;
305 WORD32 *sq_quant = pstr_scratch->p_sq_quant_tcx;
306 FLOAT32 sq_err_energy;
307 WORD32 max_k;
308 FLOAT32 *gain1 = pstr_scratch->p_gain1_tcx;
309 FLOAT32 *gain2 = pstr_scratch->p_gain2_tcx;
310 FLOAT32 *facelp = pstr_scratch->p_facelp_tcx;
311 FLOAT32 *xn2 = pstr_scratch->p_xn2_tcx;
312 FLOAT32 *fac_window = pstr_scratch->p_fac_window_tcx;
313 FLOAT32 *x1 = pstr_scratch->p_x1_tcx;
314 FLOAT32 *x2 = pstr_scratch->p_x2_tcx;
315 WORD32 *y = pstr_scratch->p_y_tcx;
316
317 WORD32 TTT;
318 FLOAT32 corr = 0;
319 WORD32 len_subfrm = st->len_subfrm;
320 WORD32 fac_length = len_subfrm >> 1;
321 WORD32 fac_len_prev, fac_len;
322
323 if (frame_len == 4 * st->len_subfrm) {
324 if (st->last_was_short) {
325 fac_len_prev = (st->len_frame) / 16;
326 } else {
327 fac_len_prev = st->len_subfrm / 2;
328 }
329 if (st->next_is_short) {
330 fac_len = (st->len_frame) / 16;
331 } else {
332 fac_len = st->len_subfrm / 2;
333 }
334 } else if (frame_len == 2 * st->len_subfrm) {
335 if (k_idx == 0 && st->last_was_short) {
336 fac_len_prev = (st->len_frame) / 16;
337 } else {
338 fac_len_prev = st->len_subfrm / 2;
339 }
340 if (k_idx == 2 && st->next_is_short) {
341 fac_len = (st->len_frame) / 16;
342 } else {
343 fac_len = st->len_subfrm / 2;
344 }
345 } else {
346 if (k_idx == 0 && st->last_was_short) {
347 fac_len_prev = (st->len_frame) / 16;
348 } else {
349 fac_len_prev = st->len_subfrm / 2;
350 }
351 if (k_idx == 3 && st->next_is_short) {
352 fac_len = (st->len_frame) / 16;
353 } else {
354 fac_len = st->len_subfrm / 2;
355 }
356 }
357
358 memset(xn_buf, 0, (128 + frame_len + 128) * sizeof(FLOAT32));
359
360 mode = frame_len / len_subfrm;
361
362 if (mode > 2) {
363 mode = 3;
364 }
365
366 if (lpd_state->mode == 0) {
367 params += fac_len_prev;
368 }
369 switch (fac_len_prev) {
370 case 64:
371 sine_window_prev = iusace_sin_window_128;
372 break;
373 default:
374 sine_window_prev = iusace_sin_window_256;
375 break;
376 }
377 switch (fac_len) {
378 case 64:
379 sine_window = iusace_sin_window_128;
380 break;
381 default:
382 sine_window = iusace_sin_window_256;
383 break;
384 }
385
386 lg = frame_len;
387 lext = fac_length;
388 xn = xn_buf + fac_length;
389
390 *n_param = lg;
391
392 target_bits = num_bits_per_supfrm - 10;
393
394 for (i = 0; i < fac_length; i++) {
395 xn_buf[i] = lpd_state->tcx_mem[i + 128 - fac_length];
396 }
397
398 memcpy(xn, speech, (frame_len + fac_length) * sizeof(FLOAT32));
399
400 tmp = xn[-1];
401
402 iusace_apply_deemph(xn, TILT_FAC, frame_len, &tmp);
403
404 memcpy(lpd_state->tcx_mem, &xn[frame_len - 128], 128 * sizeof(FLOAT32));
405
406 memcpy(&xn[frame_len], &speech[frame_len], lext * sizeof(FLOAT32));
407 iusace_apply_deemph(&xn[frame_len], TILT_FAC, lext, &tmp);
408
409 for (i = 0; i < ORDER + fac_len_prev; i++) {
410 xn1[i] = xn_buf[fac_length - ORDER + i];
411 }
412 for (i = 0; i < ORDER + fac_len; i++) {
413 xn2[i] = xn_buf[frame_len - ORDER + i];
414 }
415
416 if (lpd_state->mode >= -1) {
417 for (i = 0; i < fac_length - fac_len_prev; i++) {
418 xn_buf[i] = 0.0f;
419 }
420 for (i = fac_length - fac_len_prev; i < (fac_length + fac_len_prev); i++) {
421 xn_buf[i] *= sine_window_prev[i - fac_length + fac_len_prev];
422 }
423 for (i = 0; i < (2 * fac_len); i++) {
424 xn_buf[frame_len + fac_length - fac_len + i] *= sine_window[(2 * fac_len) - 1 - i];
425 }
426 for (i = 0; i < fac_length - fac_len; i++) {
427 xn_buf[frame_len + fac_length + fac_len + i] = 0.0f;
428 }
429 }
430
431 iusace_tcx_mdct_main(xn_buf, x, (2 * fac_length), frame_len - (2 * fac_length),
432 (2 * fac_length), pstr_scratch);
433
434 iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs);
435 iusace_lpc_mdct(lp_flt_coeffs, gain1, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1,
436 pstr_scratch);
437
438 iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs);
439 iusace_lpc_mdct(lp_flt_coeffs, gain2, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1,
440 pstr_scratch);
441
442 iusace_pre_shaping(x, lg, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME), gain1, gain2);
443
444 for (i = 0; i < lg; i++) {
445 x_tmp[i] = x[i];
446 }
447
448 iusace_adapt_lo_freq_emph(x, lg);
449
450 sq_gain = iusace_calc_sq_gain(x, target_bits, lg, pstr_scratch->p_sq_gain_en);
451
452 for (i = 0; i < lg; i++) {
453 sq_enc[i] = x[i] / sq_gain;
454
455 if (sq_enc[i] > 0.f)
456 sq_quant[i] = ((WORD32)(0.5f + sq_enc[i]));
457 else
458 sq_quant[i] = ((WORD32)(-0.5f + sq_enc[i]));
459 }
460
461 for (i = 0; i < lg; i++) {
462 params[i + 2] = sq_quant[i];
463 x[i] = (FLOAT32)sq_quant[i];
464 }
465
466 for (i = 0; i < lg; i++) {
467 en[i] = x[i] * x[i];
468 }
469 if (mode == 3) {
470 tmp = 0.9441f;
471 } else if (mode == 2) {
472 tmp = 0.8913f;
473 } else {
474 tmp = 0.7943f;
475 }
476 energy = 0.0f;
477 for (i = 0; i < lg; i++) {
478 if (en[i] > energy) {
479 energy = en[i];
480 }
481 en[i] = energy;
482 energy *= tmp;
483 }
484 energy = 0.0f;
485 for (i = lg - 1; i >= 0; i--) {
486 if (en[i] > energy) {
487 energy = en[i];
488 }
489 en[i] = energy;
490 energy *= tmp;
491 }
492
493 nsfill_en_thres = 0.707f;
494
495 tmp = 0.0625f;
496 k = 1;
497 for (i = 0; i < lg; i++) {
498 if (en[i] <= nsfill_en_thres) {
499 tmp += sq_enc[i] * sq_enc[i];
500 k++;
501 }
502 }
503
504 iusace_adapt_lo_freq_deemph(x, lg, alfd_gains);
505
506 energy = 1e-6f;
507 for (i = 0; i < lg; i++) {
508 corr += x_tmp[i] * x[i];
509 energy += x[i] * x[i];
510 }
511 gain_tcx = (corr / energy);
512
513 if (gain_tcx == 0.0f) {
514 gain_tcx = sq_gain;
515 }
516
517 energy = 0.0001f;
518 for (i = 0; i < lg; i++) {
519 tmp = x_tmp[i] - gain_tcx * x[i];
520 energy += tmp * tmp;
521 }
522
523 tmp = (FLOAT32)sqrt((energy * (2.0f / (FLOAT32)lg)) / (FLOAT32)lg);
524
525 for (i = 0; i < frame_len; i++) {
526 wsynth[i] = weighted_sig[i] + tmp;
527 }
528
529 energy = 0.01f;
530 for (i = 0; i < lg; i++) {
531 energy += x[i] * x[i];
532 }
533
534 tmp = (FLOAT32)(2.0f * sqrt(energy) / (FLOAT32)lg);
535 gain = gain_tcx * tmp;
536
537 index = (WORD32)floor(0.5f + (28.0f * (FLOAT32)log10(gain)));
538 if (index < 0) {
539 index = 0;
540 }
541 if (index > 127) {
542 index = 127;
543 }
544 params[1] = index;
545
546 gain_tcx = (FLOAT32)pow(10.0f, ((FLOAT32)index) / 28.0f) / tmp;
547 st->gain_tcx = gain_tcx;
548
549 sq_err_energy = 0.f;
550 n = 0;
551 for (k = lg / 2; k < lg;) {
552 tmp = 0.f;
553
554 max_k = MIN(lg, k + 8);
555 for (i = k; i < max_k; i++) {
556 tmp += (FLOAT32)sq_quant[i] * sq_quant[i];
557 }
558 if (tmp == 0.f) {
559 tmp = 0.f;
560 for (i = k; i < max_k; i++) {
561 tmp += sq_enc[i] * sq_enc[i];
562 }
563
564 sq_err_energy += (FLOAT32)log10((tmp / (FLOAT64)8) + 0.000000001);
565 n += 1;
566 }
567 k = max_k;
568 }
569 if (n > 0) {
570 fac_ns = (FLOAT32)pow(10., sq_err_energy / (FLOAT64)(2 * n));
571 } else {
572 fac_ns = 0.f;
573 }
574
575 tmp = 8.0f - (16.0f * fac_ns);
576
577 index = (WORD32)floor(tmp + 0.5);
578 if (index < 0) {
579 index = 0;
580 }
581 if (index > 7) {
582 index = 7;
583 }
584
585 params[0] = index;
586
587 iusace_noise_shaping(x, lg, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME), gain1, gain2);
588
589 iusace_tcx_imdct(x, xn_buf, (2 * fac_length), frame_len - (2 * fac_length), (2 * fac_length),
590 pstr_scratch);
591 for (i = 0; i < frame_len + (2 * fac_length); i++) {
592 xn_buf[i] = xn_buf[i] * (2.0f / lg);
593 }
594
595 for (i = 0; i < fac_len_prev; i++) {
596 fac_window[i] = sine_window_prev[i] * sine_window_prev[(2 * fac_len_prev) - 1 - i];
597 fac_window[fac_len_prev + i] =
598 1.0f - (sine_window_prev[fac_len_prev + i] * sine_window_prev[fac_len_prev + i]);
599 }
600
601 for (i = 0; i < fac_len_prev; i++) {
602 xn1[ORDER + i] -= sq_gain * xn_buf[fac_length + i] * sine_window_prev[fac_len_prev + i];
603 }
604 for (i = 0; i < fac_len; i++) {
605 xn2[ORDER + i] -= sq_gain * xn_buf[i + frame_len] * sine_window[(2 * fac_len) - 1 - i];
606 }
607
608 for (i = 0; i < ORDER; i++) {
609 xn1[i] -= lpd_state->tcx_quant[1 + 128 - ORDER + i];
610 xn2[i] -= sq_gain * xn_buf[frame_len - ORDER + i];
611 }
612
613 for (i = 0; i < fac_len_prev; i++) {
614 facelp[i] = lpd_state->tcx_quant[1 + 128 + i] * fac_window[fac_len_prev + i] +
615 lpd_state->tcx_quant[1 + 128 - 1 - i] * fac_window[fac_len_prev - 1 - i];
616 }
617
618 energy = 0.0f;
619 for (i = 0; i < fac_len_prev; i++) energy += xn1[ORDER + i] * xn1[ORDER + i];
620 energy *= 2.0f;
621 tmp = 0.0f;
622 for (i = 0; i < fac_len_prev; i++) tmp += facelp[i] * facelp[i];
623 if (tmp > energy)
624 gain = (FLOAT32)sqrt(energy / tmp);
625 else
626 gain = 1.0f;
627
628 for (i = 0; i < fac_len_prev; i++) {
629 xn1[ORDER + i] -= gain * facelp[i];
630 }
631
632 iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs);
633 iusace_compute_lp_residual(lp_flt_coeffs, xn1 + ORDER, x1, fac_len_prev);
634
635 iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs);
636 iusace_compute_lp_residual(lp_flt_coeffs, xn2 + ORDER, x2, fac_len);
637
638 iusace_tcx_mdct(x1, x1, fac_len_prev, pstr_scratch);
639 iusace_tcx_mdct(x2, x2, fac_len, pstr_scratch);
640
641 gain_prev = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len));
642 gain_next = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len));
643
644 for (i = 0; i < fac_len_prev; i++) {
645 x1[i] /= gain_prev;
646 }
647 for (i = 0; i < fac_len; i++) {
648 x2[i] /= gain_next;
649 }
650 for (i = 0; i < fac_len_prev / 4; i++) {
651 k = i * lg / (8 * fac_len_prev);
652 x1[i] /= alfd_gains[k];
653 }
654 for (i = 0; i < fac_len / 4; i++) {
655 k = i * lg / (8 * fac_len);
656 x2[i] /= alfd_gains[k];
657 }
658
659 for (i = 0; i < fac_len; i += 8) {
660 iusace_find_nearest_neighbor(&x2[i], &y[i]);
661 }
662 for (i = 0; i < fac_len; i++) {
663 lpd_state->avq_params[i] = y[i];
664 x2[i] = (FLOAT32)y[i];
665 }
666
667 for (i = 0; i < fac_len_prev; i += 8) {
668 iusace_find_nearest_neighbor(&x1[i], &y[i]);
669 }
670
671 for (i = 0; i < fac_len_prev; i++) {
672 x1[i] = (FLOAT32)y[i];
673 }
674
675 gain_prev = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len));
676 gain_next = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len));
677
678 for (i = 0; i < fac_len_prev; i++) {
679 x1[i] *= gain_prev;
680 }
681 for (i = 0; i < fac_len; i++) {
682 x2[i] *= gain_next;
683 }
684 for (i = 0; i<fac_len_prev>> 2; i++) {
685 k = i * lg / (fac_len_prev << 3);
686 x1[i] *= alfd_gains[k];
687 }
688 for (i = 0; i<fac_len>> 2; i++) {
689 k = i * lg / (fac_len << 3);
690 x2[i] *= alfd_gains[k];
691 }
692 iusace_tcx_mdct(x1, xn1, fac_len_prev, pstr_scratch);
693 iusace_tcx_mdct(x2, xn2, fac_len, pstr_scratch);
694
695 FLOAT32 coeff1 = (2.0f / (FLOAT32)fac_len_prev), coeff2 = (2.0f / (FLOAT32)fac_len);
696
697 for (i = 0; i < fac_len_prev; i++) {
698 xn1[i] = xn1[i] * coeff1;
699 }
700
701 for (i = 0; i < fac_len; i++) {
702 xn2[i] = xn2[i] * coeff2;
703 }
704
705 memset(xn1 + fac_len_prev, 0, fac_len_prev * sizeof(FLOAT32));
706 memset(xn2 + fac_len, 0, fac_len * sizeof(FLOAT32));
707
708 iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs);
709 iusace_synthesis_tool_float(lp_flt_coeffs, xn1, xn1, 2 * fac_len_prev, xn1 + fac_len_prev,
710 pstr_scratch->p_buf_synthesis_tool);
711
712 iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs);
713 iusace_synthesis_tool_float(lp_flt_coeffs, xn2, xn2, fac_len, xn2 + fac_len,
714 pstr_scratch->p_buf_synthesis_tool);
715
716 for (i = 0; i < fac_len_prev; i++) {
717 xn1[i] += facelp[i];
718 }
719
720 for (i = 0; i < frame_len + (fac_length << 1); i++) {
721 xn_buf[i] *= gain_tcx;
722 }
723
724 if (lpd_state->mode >= -1) {
725 for (i = 0; i < (2 * fac_len_prev); i++) {
726 xn_buf[i + fac_length - fac_len_prev] *= sine_window_prev[i];
727 }
728 for (i = 0; i < fac_length - fac_len_prev; i++) {
729 xn_buf[i] = 0.0f;
730 }
731 }
732 for (i = 0; i < (2 * fac_len); i++) {
733 xn_buf[i + frame_len + fac_length - fac_len] *= sine_window[(2 * fac_len) - 1 - i];
734 }
735 for (i = 0; i < fac_length - fac_len; i++) {
736 xn_buf[i + frame_len + fac_length + fac_len] = 0.0f;
737 }
738
739 if (lpd_state->mode != 0) {
740 for (i = 0; i < (2 * fac_length); i++) {
741 xn_buf[i] += lpd_state->tcx_quant[1 + 128 - fac_length + i];
742 }
743
744 mem_tcx_q = lpd_state->tcx_quant[128 - fac_length];
745 } else {
746 for (i = 0; i < fac_len_prev; i++) {
747 params[i - fac_len_prev] = y[i];
748 }
749
750 for (i = 0; i < (2 * fac_len_prev); i++) {
751 xn_buf[i + fac_length] += xn1[i];
752 }
753 mem_tcx_q = lpd_state->tcx_quant[128];
754 }
755
756 memcpy(lpd_state->tcx_quant, xn_buf + frame_len + fac_length - 128 - 1,
757 (1 + 256) * sizeof(FLOAT32));
758
759 for (i = 0; i < fac_len; i++) {
760 xn_buf[i + frame_len + (fac_length - fac_len)] += xn2[i];
761 }
762
763 if (lpd_state->mode > 0) {
764 iusace_apply_preemph(xn_buf, TILT_FAC, fac_length, &mem_tcx_q);
765
766 ptr_lp_flt_coeffs = lpd_state->lpc_coeffs_quant;
767
768 TTT = fac_length % LEN_SUBFR;
769 if (TTT != 0) {
770 memcpy(&(lpd_state->synth[ORDER + 128 - fac_length]), &xn_buf[0], TTT * sizeof(FLOAT32));
771 iusace_compute_lp_residual(ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length]),
772 &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length]), TTT);
773
774 ptr_lp_flt_coeffs += (ORDER + 1);
775 }
776
777 for (i_subfr = TTT; i_subfr < fac_length; i_subfr += LEN_SUBFR) {
778 memcpy(&(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), &xn_buf[i_subfr],
779 LEN_SUBFR * sizeof(FLOAT32));
780 iusace_compute_lp_residual(
781 ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]),
782 &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length + i_subfr]), LEN_SUBFR);
783 ptr_lp_flt_coeffs += (ORDER + 1);
784 }
785
786 ptr_lp_flt_coeffs = lpd_state->lpc_coeffs;
787 for (i_subfr = 0; i_subfr < fac_length; i_subfr += LEN_SUBFR) {
788 iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs);
789 iusace_compute_lp_residual(lp_flt_coeffs,
790 &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]),
791 &(lpd_state->wsynth[1 + 128 - fac_length + i_subfr]), LEN_SUBFR);
792 ptr_lp_flt_coeffs += (ORDER + 1);
793 }
794 tmp = lpd_state->wsynth[0 + 128 - fac_length];
795 iusace_apply_deemph(&(lpd_state->wsynth[1 + 128 - fac_length]), TILT_FAC, fac_length, &tmp);
796 }
797
798 k = ((frame_len / LEN_SUBFR) - 2) * (ORDER + 1);
799 memcpy(lpd_state->lpc_coeffs, lpc_coeffs + k, 2 * (ORDER + 1) * sizeof(FLOAT32));
800
801 memcpy(lpd_state->lpc_coeffs_quant, lpc_coeffs_quant + (2 * (ORDER + 1)),
802 (ORDER + 1) * sizeof(FLOAT32));
803 memcpy(lpd_state->lpc_coeffs_quant + (ORDER + 1), lpd_state->lpc_coeffs_quant,
804 (ORDER + 1) * sizeof(FLOAT32));
805
806 memcpy(synth - 128, &(lpd_state->synth[ORDER]), 128 * sizeof(FLOAT32));
807 lpd_state->tcx_fac = xn[frame_len - 1];
808
809 iusace_apply_preemph(xn, TILT_FAC, frame_len, &mem_tcx_q);
810 for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) {
811 memcpy(&synth[i_subfr], &xn[i_subfr], LEN_SUBFR * sizeof(FLOAT32));
812 iusace_compute_lp_residual(lpc_coeffs_quant + (2 * (ORDER + 1)), &synth[i_subfr],
813 &xn[i_subfr], LEN_SUBFR);
814 }
815 memcpy(lpd_state->synth, synth + frame_len - (ORDER + 128), (ORDER + 128) * sizeof(FLOAT32));
816
817 if (frame_len == len_subfrm) {
818 memcpy(x, lpd_state->acelp_exc + len_subfrm, len_subfrm * sizeof(FLOAT32));
819 memcpy(lpd_state->acelp_exc, x, len_subfrm * sizeof(FLOAT32));
820 memcpy(lpd_state->acelp_exc + len_subfrm, xn, len_subfrm * sizeof(FLOAT32));
821 } else {
822 memcpy(lpd_state->acelp_exc, xn + frame_len - (2 * len_subfrm),
823 2 * len_subfrm * sizeof(FLOAT32));
824 }
825
826 memcpy(wsynth - 128, &(lpd_state->wsynth[1]), 128 * sizeof(FLOAT32));
827
828 ptr_lp_flt_coeffs = lpc_coeffs;
829 for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) {
830 iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs);
831 iusace_compute_lp_residual(lp_flt_coeffs, &synth[i_subfr], &wsynth[i_subfr], LEN_SUBFR);
832 ptr_lp_flt_coeffs += (ORDER + 1);
833 }
834 tmp = wsynth[-1];
835 iusace_apply_deemph(wsynth, TILT_FAC, frame_len, &tmp);
836
837 memcpy(lpd_state->wsynth, wsynth + frame_len - (1 + 128), (1 + 128) * sizeof(FLOAT32));
838
839 lpd_state->mode = mode;
840
841 lpd_state->num_bits = 10 + target_bits;
842
843 return;
844 }
845