Coverage Report

Created: 2026-05-08 06:29

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/iusace_tcx_enc.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 <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
113
static VOID iusace_lpc_mdct(FLOAT32 *ptr_lpc_coeffs, FLOAT32 *mdct_gains, WORD32 length,
114
1.56M
                            iusace_scratch_mem *pstr_scratch) {
115
1.56M
  FLOAT32 *in_out = pstr_scratch->p_in_out_tcx;
116
1.56M
  WORD32 i;
117
118
28.1M
  for (i = 0; i < ORDER + 1; i++) {
119
26.5M
    in_out[2 * i] = (FLOAT32)(ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_cos[i]);
120
26.5M
    in_out[2 * i + 1] = (FLOAT32)(-ptr_lpc_coeffs[i] * iusace_lpc_pre_twid_sin[i]);
121
26.5M
  }
122
159M
  for (; i < length; i++) {
123
158M
    in_out[2 * i] = 0.f;
124
158M
    in_out[2 * i + 1] = 0.f;
125
158M
  }
126
127
1.56M
  iusace_complex_fft(in_out, length, pstr_scratch);
128
129
93.8M
  for (i = 0; i<length>> 1; i++) {
130
92.3M
    mdct_gains[i] = (FLOAT32)(
131
92.3M
        1.0f / sqrt(in_out[2 * i] * in_out[2 * i] + in_out[2 * i + 1] * in_out[2 * i + 1]));
132
92.3M
  }
133
134
1.56M
  return;
135
1.56M
}
136
137
0
UWORD32 iusace_rounded_sqrt(UWORD32 pos_num) {
138
0
  UWORD32 num = pos_num;
139
0
  UWORD32 value = 0;
140
0
  UWORD32 bit_set = 1 << 30;
141
142
0
  while (bit_set > num) {
143
0
    bit_set >>= 2;
144
0
  }
145
0
  while (bit_set) {
146
0
    if (num >= value + bit_set) {
147
0
      num -= value + bit_set;
148
0
      value += bit_set << 1;
149
0
    }
150
0
    value >>= 1;
151
0
    bit_set >>= 2;
152
0
  }
153
0
  num = value + 1;
154
0
  if (num * num - pos_num < pos_num - value * value) {
155
0
    return num;
156
0
  }
157
0
  return value;
158
0
}
159
160
static VOID iusace_noise_shaping(FLOAT32 *rr, WORD32 lg, WORD32 M, FLOAT32 *gain1,
161
781k
                                 FLOAT32 *gain2) {
162
781k
  WORD32 i, k;
163
781k
  FLOAT32 r, r_prev, g1, g2, a = 0, b = 0;
164
165
781k
  k = lg/M;
166
167
781k
  r_prev = 0;
168
317M
  for (i = 0; i < lg; i++) {
169
316M
    if ((i % k) == 0) {
170
46.1M
      g1 = gain1[i / k];
171
46.1M
      g2 = gain2[i / k];
172
46.1M
      a = 2.0f * g1 * g2 / (g1 + g2);
173
46.1M
      b = (g2 - g1) / (g1 + g2);
174
46.1M
    }
175
176
316M
    r = a * rr[i] + b * r_prev;
177
178
316M
    rr[i] = r;
179
316M
    r_prev = r;
180
316M
  }
181
182
781k
  return;
183
781k
}
184
185
781k
static VOID iusace_pre_shaping(FLOAT32 *rr, WORD32 lg, WORD32 M, FLOAT32 *gain1, FLOAT32 *gain2) {
186
781k
  WORD32 i, k;
187
781k
  FLOAT32 r, r_prev, g1, g2, a = 0, b = 0;
188
189
781k
  k = lg / M;
190
191
781k
  r_prev = 0;
192
317M
  for (i = 0; i < lg; i++) {
193
316M
    if ((i % k) == 0) {
194
46.1M
      g1 = gain1[i / k];
195
46.1M
      g2 = gain2[i / k];
196
197
46.1M
      a = (g1 + g2) / (2.0f * g1 * g2);
198
46.1M
      b = (g1 - g2) / (2.0f * g1 * g2);
199
46.1M
    }
200
201
316M
    r = a * rr[i] + b * r_prev;
202
203
316M
    r_prev = rr[i];
204
316M
    rr[i] = r;
205
316M
  }
206
207
781k
  return;
208
781k
}
209
210
781k
static VOID iusace_adapt_lo_freq_emph(FLOAT32 *signal, WORD32 length) {
211
781k
  WORD32 i, j, i_max;
212
781k
  FLOAT32 max_energy, factor, temp;
213
214
781k
  i_max = length >> 2;
215
216
781k
  max_energy = 0.01f;
217
10.6M
  for (i = 0; i < i_max; i += 8) {
218
9.89M
    temp = 0.01f;
219
89.0M
    for (j = i; j < i + 8; j++) {
220
79.1M
      temp += signal[j] * signal[j];
221
79.1M
    }
222
9.89M
    if (temp > max_energy) {
223
1.00M
      max_energy = temp;
224
1.00M
    }
225
9.89M
  }
226
227
781k
  factor = 10.0f;
228
10.6M
  for (i = 0; i < i_max; i += 8) {
229
9.89M
    temp = 0.01f;
230
89.0M
    for (j = i; j < i + 8; j++) {
231
79.1M
      temp += signal[j] * signal[j];
232
79.1M
    }
233
9.89M
    temp = (FLOAT32)sqrt(sqrt(max_energy / temp));
234
9.89M
    if (temp < factor) {
235
1.01M
      factor = temp;
236
1.01M
    }
237
89.0M
    for (j = i; j < i + 8; j++) {
238
79.1M
      signal[j] *= factor;
239
79.1M
    }
240
9.89M
  }
241
781k
  return;
242
781k
}
243
244
781k
static VOID iusace_adapt_lo_freq_deemph(FLOAT32 *signal, WORD32 length, FLOAT32 *gains) {
245
781k
  WORD32 i, j, i_max;
246
781k
  FLOAT32 max_energy, factor, energy, rm;
247
248
781k
  i_max = length >> 2;
249
250
781k
  max_energy = 0.01f;
251
10.6M
  for (i = 0; i < i_max; i += 8) {
252
9.89M
    energy = 0.01f;
253
89.0M
    for (j = i; j < i + 8; j++) {
254
79.1M
      energy += signal[j] * signal[j];
255
79.1M
    }
256
9.89M
    if (energy > max_energy) {
257
927k
      max_energy = energy;
258
927k
    }
259
9.89M
  }
260
261
781k
  factor = 0.1f;
262
10.6M
  for (i = 0; i < i_max; i += 8) {
263
9.89M
    energy = 0.01f;
264
89.0M
    for (j = i; j < i + 8; j++) {
265
79.1M
      energy += signal[j] * signal[j];
266
79.1M
    }
267
268
9.89M
    rm = (FLOAT32)sqrt(energy / max_energy);
269
9.89M
    if (rm > factor) {
270
954k
      factor = rm;
271
954k
    }
272
89.0M
    for (j = i; j < i + 8; j++) {
273
79.1M
      signal[j] *= factor;
274
79.1M
    }
275
9.89M
    gains[i / 8] = factor;
276
9.89M
  }
277
278
781k
  return;
279
781k
}
280
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
781k
                           WORD32 *params, WORD32 *n_param, WORD32 ch_idx, WORD32 k_idx) {
285
781k
  ia_usac_td_encoder_struct *st = usac_data->td_encoder[ch_idx];
286
781k
  iusace_scratch_mem *pstr_scratch = &usac_data->str_scratch;
287
781k
  FLOAT32 *weighted_sig = &pstr_scratch->p_wsig_buf[k_idx * st->len_subfrm];
288
781k
  FLOAT32 *wsynth = pstr_scratch->p_wsyn_tcx_buf;
289
781k
  FLOAT32 *synth = pstr_scratch->p_synth_tcx_buf;
290
781k
  WORD32 i, k, n, mode, i_subfr, lg, lext, index, target_bits;
291
781k
  FLOAT32 tmp, gain, fac_ns, energy, gain_tcx, nsfill_en_thres;
292
781k
  FLOAT32 *ptr_lp_flt_coeffs, lp_flt_coeffs[ORDER + 1];
293
781k
  const FLOAT32 *sine_window_prev, *sine_window;
294
781k
  FLOAT32 mem_tcx_q;
295
781k
  FLOAT32 *xn;
296
781k
  FLOAT32 *xn1 = pstr_scratch->p_xn1_tcx;
297
781k
  FLOAT32 *xn_buf = pstr_scratch->p_xn_buf_tcx;
298
781k
  FLOAT32 *x = pstr_scratch->p_x_tcx;
299
781k
  FLOAT32 *x_tmp = pstr_scratch->p_x_tmp_tcx;
300
781k
  FLOAT32 *en = pstr_scratch->p_en_tcx;
301
781k
  FLOAT32 sq_gain;
302
781k
  FLOAT32 gain_prev, gain_next;
303
781k
  FLOAT32 *alfd_gains = pstr_scratch->p_alfd_gains_tcx;
304
781k
  FLOAT32 *sq_enc = pstr_scratch->p_sq_enc_tcx;
305
781k
  WORD32 *sq_quant = pstr_scratch->p_sq_quant_tcx;
306
781k
  FLOAT32 sq_err_energy;
307
781k
  WORD32 max_k;
308
781k
  FLOAT32 *gain1 = pstr_scratch->p_gain1_tcx;
309
781k
  FLOAT32 *gain2 = pstr_scratch->p_gain2_tcx;
310
781k
  FLOAT32 *facelp = pstr_scratch->p_facelp_tcx;
311
781k
  FLOAT32 *xn2 = pstr_scratch->p_xn2_tcx;
312
781k
  FLOAT32 *fac_window = pstr_scratch->p_fac_window_tcx;
313
781k
  FLOAT32 *x1 = pstr_scratch->p_x1_tcx;
314
781k
  FLOAT32 *x2 = pstr_scratch->p_x2_tcx;
315
781k
  WORD32 *y = pstr_scratch->p_y_tcx;
316
317
781k
  WORD32 TTT;
318
781k
  FLOAT32 corr = 0;
319
781k
  WORD32 len_subfrm = st->len_subfrm;
320
781k
  WORD32 fac_length = len_subfrm >> 1;
321
781k
  WORD32 fac_len_prev, fac_len;
322
323
781k
  if (frame_len == 4 * st->len_subfrm) {
324
111k
    if (st->last_was_short) {
325
0
      fac_len_prev = (st->len_frame) / 16;
326
111k
    } else {
327
111k
      fac_len_prev = st->len_subfrm / 2;
328
111k
    }
329
111k
    if (st->next_is_short) {
330
0
      fac_len = (st->len_frame) / 16;
331
111k
    } else {
332
111k
      fac_len = st->len_subfrm / 2;
333
111k
    }
334
669k
  } else if (frame_len == 2 * st->len_subfrm) {
335
223k
    if (k_idx == 0 && st->last_was_short) {
336
0
      fac_len_prev = (st->len_frame) / 16;
337
223k
    } else {
338
223k
      fac_len_prev = st->len_subfrm / 2;
339
223k
    }
340
223k
    if (k_idx == 2 && st->next_is_short) {
341
0
      fac_len = (st->len_frame) / 16;
342
223k
    } else {
343
223k
      fac_len = st->len_subfrm / 2;
344
223k
    }
345
446k
  } else {
346
446k
    if (k_idx == 0 && st->last_was_short) {
347
0
      fac_len_prev = (st->len_frame) / 16;
348
446k
    } else {
349
446k
      fac_len_prev = st->len_subfrm / 2;
350
446k
    }
351
446k
    if (k_idx == 3 && st->next_is_short) {
352
0
      fac_len = (st->len_frame) / 16;
353
446k
    } else {
354
446k
      fac_len = st->len_subfrm / 2;
355
446k
    }
356
446k
  }
357
358
781k
  memset(xn_buf, 0, (128 + frame_len + 128) * sizeof(FLOAT32));
359
360
781k
  mode = frame_len / len_subfrm;
361
362
781k
  if (mode > 2) {
363
111k
    mode = 3;
364
111k
  }
365
366
781k
  if (lpd_state->mode == 0) {
367
285k
    params += fac_len_prev;
368
285k
  }
369
781k
  switch (fac_len_prev) {
370
0
    case 64:
371
0
      sine_window_prev = iusace_sin_window_128;
372
0
      break;
373
781k
    default:
374
781k
      sine_window_prev = iusace_sin_window_256;
375
781k
      break;
376
781k
  }
377
781k
  switch (fac_len) {
378
0
    case 64:
379
0
      sine_window = iusace_sin_window_128;
380
0
      break;
381
781k
    default:
382
781k
      sine_window = iusace_sin_window_256;
383
781k
      break;
384
781k
  }
385
386
781k
  lg = frame_len;
387
781k
  lext = fac_length;
388
781k
  xn = xn_buf + fac_length;
389
390
781k
  *n_param = lg;
391
392
781k
  target_bits = num_bits_per_supfrm - 10;
393
394
93.0M
  for (i = 0; i < fac_length; i++) {
395
92.3M
    xn_buf[i] = lpd_state->tcx_mem[i + 128 - fac_length];
396
92.3M
  }
397
398
781k
  memcpy(xn, speech, (frame_len + fac_length) * sizeof(FLOAT32));
399
400
781k
  tmp = xn[-1];
401
402
781k
  iusace_apply_deemph(xn, TILT_FAC, frame_len, &tmp);
403
404
781k
  memcpy(lpd_state->tcx_mem, &xn[frame_len - 128], 128 * sizeof(FLOAT32));
405
406
781k
  memcpy(&xn[frame_len], &speech[frame_len], lext * sizeof(FLOAT32));
407
781k
  iusace_apply_deemph(&xn[frame_len], TILT_FAC, lext, &tmp);
408
409
105M
  for (i = 0; i < ORDER + fac_len_prev; i++) {
410
104M
    xn1[i] = xn_buf[fac_length - ORDER + i];
411
104M
  }
412
105M
  for (i = 0; i < ORDER + fac_len; i++) {
413
104M
    xn2[i] = xn_buf[frame_len - ORDER + i];
414
104M
  }
415
416
781k
  if (lpd_state->mode >= -1) {
417
781k
    for (i = 0; i < fac_length - fac_len_prev; i++) {
418
0
      xn_buf[i] = 0.0f;
419
0
    }
420
185M
    for (i = fac_length - fac_len_prev; i < (fac_length + fac_len_prev); i++) {
421
184M
      xn_buf[i] *= sine_window_prev[i - fac_length + fac_len_prev];
422
184M
    }
423
185M
    for (i = 0; i < (2 * fac_len); i++) {
424
184M
      xn_buf[frame_len + fac_length - fac_len + i] *= sine_window[(2 * fac_len) - 1 - i];
425
184M
    }
426
781k
    for (i = 0; i < fac_length - fac_len; i++) {
427
0
      xn_buf[frame_len + fac_length + fac_len + i] = 0.0f;
428
0
    }
429
781k
  }
430
431
781k
  iusace_tcx_mdct_main(xn_buf, x, (2 * fac_length), frame_len - (2 * fac_length),
432
781k
                       (2 * fac_length), pstr_scratch);
433
434
781k
  iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs);
435
781k
  iusace_lpc_mdct(lp_flt_coeffs, gain1, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1,
436
781k
                  pstr_scratch);
437
438
781k
  iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs);
439
781k
  iusace_lpc_mdct(lp_flt_coeffs, gain2, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME) << 1,
440
781k
                  pstr_scratch);
441
442
781k
  iusace_pre_shaping(x, lg, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME), gain1, gain2);
443
444
317M
  for (i = 0; i < lg; i++) {
445
316M
    x_tmp[i] = x[i];
446
316M
  }
447
448
781k
  iusace_adapt_lo_freq_emph(x, lg);
449
450
781k
  sq_gain = iusace_calc_sq_gain(x, target_bits, lg, pstr_scratch->p_sq_gain_en);
451
452
317M
  for (i = 0; i < lg; i++) {
453
316M
    sq_enc[i] = x[i] / sq_gain;
454
455
316M
    if (sq_enc[i] > 0.f)
456
156M
      sq_quant[i] = ((WORD32)(0.5f + sq_enc[i]));
457
159M
    else
458
159M
      sq_quant[i] = ((WORD32)(-0.5f + sq_enc[i]));
459
316M
  }
460
461
317M
  for (i = 0; i < lg; i++) {
462
316M
    params[i + 2] = sq_quant[i];
463
316M
    x[i] = (FLOAT32)sq_quant[i];
464
316M
  }
465
466
317M
  for (i = 0; i < lg; i++) {
467
316M
    en[i] = x[i] * x[i];
468
316M
  }
469
781k
  if (mode == 3) {
470
111k
    tmp = 0.9441f;
471
669k
  } else if (mode == 2) {
472
223k
    tmp = 0.8913f;
473
446k
  } else {
474
446k
    tmp = 0.7943f;
475
446k
  }
476
781k
  energy = 0.0f;
477
317M
  for (i = 0; i < lg; i++) {
478
316M
    if (en[i] > energy) {
479
39.3M
      energy = en[i];
480
39.3M
    }
481
316M
    en[i] = energy;
482
316M
    energy *= tmp;
483
316M
  }
484
781k
  energy = 0.0f;
485
317M
  for (i = lg - 1; i >= 0; i--) {
486
316M
    if (en[i] > energy) {
487
202M
      energy = en[i];
488
202M
    }
489
316M
    en[i] = energy;
490
316M
    energy *= tmp;
491
316M
  }
492
493
781k
  nsfill_en_thres = 0.707f;
494
495
781k
  tmp = 0.0625f;
496
781k
  k = 1;
497
317M
  for (i = 0; i < lg; i++) {
498
316M
    if (en[i] <= nsfill_en_thres) {
499
175M
      tmp += sq_enc[i] * sq_enc[i];
500
175M
      k++;
501
175M
    }
502
316M
  }
503
504
781k
  iusace_adapt_lo_freq_deemph(x, lg, alfd_gains);
505
506
781k
  energy = 1e-6f;
507
317M
  for (i = 0; i < lg; i++) {
508
316M
    corr += x_tmp[i] * x[i];
509
316M
    energy += x[i] * x[i];
510
316M
  }
511
781k
  gain_tcx = (corr / energy);
512
513
781k
  if (gain_tcx == 0.0f) {
514
25.1k
    gain_tcx = sq_gain;
515
25.1k
  }
516
517
781k
  energy = 0.0001f;
518
317M
  for (i = 0; i < lg; i++) {
519
316M
    tmp = x_tmp[i] - gain_tcx * x[i];
520
316M
    energy += tmp * tmp;
521
316M
  }
522
523
781k
  tmp = (FLOAT32)sqrt((energy * (2.0f / (FLOAT32)lg)) / (FLOAT32)lg);
524
525
317M
  for (i = 0; i < frame_len; i++) {
526
316M
    wsynth[i] = weighted_sig[i] + tmp;
527
316M
  }
528
529
781k
  energy = 0.01f;
530
317M
  for (i = 0; i < lg; i++) {
531
316M
    energy += x[i] * x[i];
532
316M
  }
533
534
781k
  tmp = (FLOAT32)(2.0f * sqrt(energy) / (FLOAT32)lg);
535
781k
  gain = gain_tcx * tmp;
536
537
781k
  index = (WORD32)floor(0.5f + (28.0f * (FLOAT32)log10(gain)));
538
781k
  if (index < 0) {
539
214k
    index = 0;
540
214k
  }
541
781k
  if (index > 127) {
542
14.4k
    index = 127;
543
14.4k
  }
544
781k
  params[1] = index;
545
546
781k
  gain_tcx = (FLOAT32)pow(10.0f, ((FLOAT32)index) / 28.0f) / tmp;
547
781k
  st->gain_tcx = gain_tcx;
548
549
781k
  sq_err_energy = 0.f;
550
781k
  n = 0;
551
20.5M
  for (k = lg / 2; k < lg;) {
552
19.7M
    tmp = 0.f;
553
554
19.7M
    max_k = MIN(lg, k + 8);
555
178M
    for (i = k; i < max_k; i++) {
556
158M
      tmp += (FLOAT32)sq_quant[i] * sq_quant[i];
557
158M
    }
558
19.7M
    if (tmp == 0.f) {
559
13.6M
      tmp = 0.f;
560
123M
      for (i = k; i < max_k; i++) {
561
109M
        tmp += sq_enc[i] * sq_enc[i];
562
109M
      }
563
564
13.6M
      sq_err_energy += (FLOAT32)log10((tmp / (FLOAT64)8) + 0.000000001);
565
13.6M
      n += 1;
566
13.6M
    }
567
19.7M
    k = max_k;
568
19.7M
  }
569
781k
  if (n > 0) {
570
764k
    fac_ns = (FLOAT32)pow(10., sq_err_energy / (FLOAT64)(2 * n));
571
764k
  } else {
572
16.3k
    fac_ns = 0.f;
573
16.3k
  }
574
575
781k
  tmp = 8.0f - (16.0f * fac_ns);
576
577
781k
  index = (WORD32)floor(tmp + 0.5);
578
781k
  if (index < 0) {
579
0
    index = 0;
580
0
  }
581
781k
  if (index > 7) {
582
157k
    index = 7;
583
157k
  }
584
585
781k
  params[0] = index;
586
587
781k
  iusace_noise_shaping(x, lg, ((FDNS_RESOLUTION * len_subfrm) / LEN_FRAME), gain1, gain2);
588
589
781k
  iusace_tcx_imdct(x, xn_buf, (2 * fac_length), frame_len - (2 * fac_length), (2 * fac_length),
590
781k
                   pstr_scratch);
591
501M
  for (i = 0; i < frame_len + (2 * fac_length); i++) {
592
501M
    xn_buf[i] = xn_buf[i] * (2.0f / lg);
593
501M
  }
594
595
93.0M
  for (i = 0; i < fac_len_prev; i++) {
596
92.3M
    fac_window[i] = sine_window_prev[i] * sine_window_prev[(2 * fac_len_prev) - 1 - i];
597
92.3M
    fac_window[fac_len_prev + i] =
598
92.3M
        1.0f - (sine_window_prev[fac_len_prev + i] * sine_window_prev[fac_len_prev + i]);
599
92.3M
  }
600
601
93.0M
  for (i = 0; i < fac_len_prev; i++) {
602
92.3M
    xn1[ORDER + i] -= sq_gain * xn_buf[fac_length + i] * sine_window_prev[fac_len_prev + i];
603
92.3M
  }
604
93.0M
  for (i = 0; i < fac_len; i++) {
605
92.3M
    xn2[ORDER + i] -= sq_gain * xn_buf[i + frame_len] * sine_window[(2 * fac_len) - 1 - i];
606
92.3M
  }
607
608
13.2M
  for (i = 0; i < ORDER; i++) {
609
12.4M
    xn1[i] -= lpd_state->tcx_quant[1 + 128 - ORDER + i];
610
12.4M
    xn2[i] -= sq_gain * xn_buf[frame_len - ORDER + i];
611
12.4M
  }
612
613
93.0M
  for (i = 0; i < fac_len_prev; i++) {
614
92.3M
    facelp[i] = lpd_state->tcx_quant[1 + 128 + i] * fac_window[fac_len_prev + i] +
615
92.3M
                lpd_state->tcx_quant[1 + 128 - 1 - i] * fac_window[fac_len_prev - 1 - i];
616
92.3M
  }
617
618
781k
  energy = 0.0f;
619
93.0M
  for (i = 0; i < fac_len_prev; i++) energy += xn1[ORDER + i] * xn1[ORDER + i];
620
781k
  energy *= 2.0f;
621
781k
  tmp = 0.0f;
622
93.0M
  for (i = 0; i < fac_len_prev; i++) tmp += facelp[i] * facelp[i];
623
781k
  if (tmp > energy)
624
166k
    gain = (FLOAT32)sqrt(energy / tmp);
625
614k
  else
626
614k
    gain = 1.0f;
627
628
93.0M
  for (i = 0; i < fac_len_prev; i++) {
629
92.3M
    xn1[ORDER + i] -= gain * facelp[i];
630
92.3M
  }
631
632
781k
  iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs);
633
781k
  iusace_compute_lp_residual(lp_flt_coeffs, xn1 + ORDER, x1, fac_len_prev);
634
635
781k
  iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs);
636
781k
  iusace_compute_lp_residual(lp_flt_coeffs, xn2 + ORDER, x2, fac_len);
637
638
781k
  iusace_tcx_mdct(x1, x1, fac_len_prev, pstr_scratch);
639
781k
  iusace_tcx_mdct(x2, x2, fac_len, pstr_scratch);
640
641
781k
  gain_prev = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len));
642
781k
  gain_next = (FLOAT32)(sq_gain * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len));
643
644
93.0M
  for (i = 0; i < fac_len_prev; i++) {
645
92.3M
    x1[i] /= gain_prev;
646
92.3M
  }
647
93.0M
  for (i = 0; i < fac_len; i++) {
648
92.3M
    x2[i] /= gain_next;
649
92.3M
  }
650
23.8M
  for (i = 0; i < fac_len_prev / 4; i++) {
651
23.0M
    k = i * lg / (8 * fac_len_prev);
652
23.0M
    x1[i] /= alfd_gains[k];
653
23.0M
  }
654
23.8M
  for (i = 0; i < fac_len / 4; i++) {
655
23.0M
    k = i * lg / (8 * fac_len);
656
23.0M
    x2[i] /= alfd_gains[k];
657
23.0M
  }
658
659
12.3M
  for (i = 0; i < fac_len; i += 8) {
660
11.5M
    iusace_find_nearest_neighbor(&x2[i], &y[i]);
661
11.5M
  }
662
93.0M
  for (i = 0; i < fac_len; i++) {
663
92.3M
    lpd_state->avq_params[i] = y[i];
664
92.3M
    x2[i] = (FLOAT32)y[i];
665
92.3M
  }
666
667
12.3M
  for (i = 0; i < fac_len_prev; i += 8) {
668
11.5M
    iusace_find_nearest_neighbor(&x1[i], &y[i]);
669
11.5M
  }
670
671
93.0M
  for (i = 0; i < fac_len_prev; i++) {
672
92.3M
    x1[i] = (FLOAT32)y[i];
673
92.3M
  }
674
675
781k
  gain_prev = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len_prev) / (FLOAT32)frame_len));
676
781k
  gain_next = (FLOAT32)(gain_tcx * 0.5f * sqrt(((FLOAT32)fac_len) / (FLOAT32)frame_len));
677
678
93.0M
  for (i = 0; i < fac_len_prev; i++) {
679
92.3M
    x1[i] *= gain_prev;
680
92.3M
  }
681
93.0M
  for (i = 0; i < fac_len; i++) {
682
92.3M
    x2[i] *= gain_next;
683
92.3M
  }
684
23.8M
  for (i = 0; i<fac_len_prev>> 2; i++) {
685
23.0M
    k = i * lg / (fac_len_prev << 3);
686
23.0M
    x1[i] *= alfd_gains[k];
687
23.0M
  }
688
23.8M
  for (i = 0; i<fac_len>> 2; i++) {
689
23.0M
    k = i * lg / (fac_len << 3);
690
23.0M
    x2[i] *= alfd_gains[k];
691
23.0M
  }
692
781k
  iusace_tcx_mdct(x1, xn1, fac_len_prev, pstr_scratch);
693
781k
  iusace_tcx_mdct(x2, xn2, fac_len, pstr_scratch);
694
695
781k
  FLOAT32 coeff1 = (2.0f / (FLOAT32)fac_len_prev), coeff2 = (2.0f / (FLOAT32)fac_len);
696
697
93.0M
  for (i = 0; i < fac_len_prev; i++) {
698
92.3M
    xn1[i] = xn1[i] * coeff1;
699
92.3M
  }
700
701
93.0M
  for (i = 0; i < fac_len; i++) {
702
92.3M
    xn2[i] = xn2[i] * coeff2;
703
92.3M
  }
704
705
781k
  memset(xn1 + fac_len_prev, 0, fac_len_prev * sizeof(FLOAT32));
706
781k
  memset(xn2 + fac_len, 0, fac_len * sizeof(FLOAT32));
707
708
781k
  iusace_get_weighted_lpc(lpc_coeffs_quant + (ORDER + 1), lp_flt_coeffs);
709
781k
  iusace_synthesis_tool_float(lp_flt_coeffs, xn1, xn1, 2 * fac_len_prev, xn1 + fac_len_prev,
710
781k
                              pstr_scratch->p_buf_synthesis_tool);
711
712
781k
  iusace_get_weighted_lpc(lpc_coeffs_quant + (2 * (ORDER + 1)), lp_flt_coeffs);
713
781k
  iusace_synthesis_tool_float(lp_flt_coeffs, xn2, xn2, fac_len, xn2 + fac_len,
714
781k
                              pstr_scratch->p_buf_synthesis_tool);
715
716
93.0M
  for (i = 0; i < fac_len_prev; i++) {
717
92.3M
    xn1[i] += facelp[i];
718
92.3M
  }
719
720
501M
  for (i = 0; i < frame_len + (fac_length << 1); i++) {
721
501M
    xn_buf[i] *= gain_tcx;
722
501M
  }
723
724
781k
  if (lpd_state->mode >= -1) {
725
185M
    for (i = 0; i < (2 * fac_len_prev); i++) {
726
184M
      xn_buf[i + fac_length - fac_len_prev] *= sine_window_prev[i];
727
184M
    }
728
781k
    for (i = 0; i < fac_length - fac_len_prev; i++) {
729
0
      xn_buf[i] = 0.0f;
730
0
    }
731
781k
  }
732
185M
  for (i = 0; i < (2 * fac_len); i++) {
733
184M
    xn_buf[i + frame_len + fac_length - fac_len] *= sine_window[(2 * fac_len) - 1 - i];
734
184M
  }
735
781k
  for (i = 0; i < fac_length - fac_len; i++) {
736
0
    xn_buf[i + frame_len + fac_length + fac_len] = 0.0f;
737
0
  }
738
739
781k
  if (lpd_state->mode != 0) {
740
118M
    for (i = 0; i < (2 * fac_length); i++) {
741
118M
      xn_buf[i] += lpd_state->tcx_quant[1 + 128 - fac_length + i];
742
118M
    }
743
744
495k
    mem_tcx_q = lpd_state->tcx_quant[128 - fac_length];
745
495k
  } else {
746
33.4M
    for (i = 0; i < fac_len_prev; i++) {
747
33.1M
      params[i - fac_len_prev] = y[i];
748
33.1M
    }
749
750
66.6M
    for (i = 0; i < (2 * fac_len_prev); i++) {
751
66.3M
      xn_buf[i + fac_length] += xn1[i];
752
66.3M
    }
753
285k
    mem_tcx_q = lpd_state->tcx_quant[128];
754
285k
  }
755
756
781k
  memcpy(lpd_state->tcx_quant, xn_buf + frame_len + fac_length - 128 - 1,
757
781k
         (1 + 256) * sizeof(FLOAT32));
758
759
93.0M
  for (i = 0; i < fac_len; i++) {
760
92.3M
    xn_buf[i + frame_len + (fac_length - fac_len)] += xn2[i];
761
92.3M
  }
762
763
781k
  if (lpd_state->mode > 0) {
764
485k
    iusace_apply_preemph(xn_buf, TILT_FAC, fac_length, &mem_tcx_q);
765
766
485k
    ptr_lp_flt_coeffs = lpd_state->lpc_coeffs_quant;
767
768
485k
    TTT = fac_length % LEN_SUBFR;
769
485k
    if (TTT != 0) {
770
133k
      memcpy(&(lpd_state->synth[ORDER + 128 - fac_length]), &xn_buf[0], TTT * sizeof(FLOAT32));
771
133k
      iusace_compute_lp_residual(ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length]),
772
133k
                                 &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length]), TTT);
773
774
133k
      ptr_lp_flt_coeffs += (ORDER + 1);
775
133k
    }
776
777
1.32M
    for (i_subfr = TTT; i_subfr < fac_length; i_subfr += LEN_SUBFR) {
778
838k
      memcpy(&(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]), &xn_buf[i_subfr],
779
838k
             LEN_SUBFR * sizeof(FLOAT32));
780
838k
      iusace_compute_lp_residual(
781
838k
          ptr_lp_flt_coeffs, &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]),
782
838k
          &(lpd_state->acelp_exc[(2 * len_subfrm) - fac_length + i_subfr]), LEN_SUBFR);
783
838k
      ptr_lp_flt_coeffs += (ORDER + 1);
784
838k
    }
785
786
485k
    ptr_lp_flt_coeffs = lpd_state->lpc_coeffs;
787
1.45M
    for (i_subfr = 0; i_subfr < fac_length; i_subfr += LEN_SUBFR) {
788
971k
      iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs);
789
971k
      iusace_compute_lp_residual(lp_flt_coeffs,
790
971k
                                 &(lpd_state->synth[ORDER + 128 - fac_length + i_subfr]),
791
971k
                                 &(lpd_state->wsynth[1 + 128 - fac_length + i_subfr]), LEN_SUBFR);
792
971k
      ptr_lp_flt_coeffs += (ORDER + 1);
793
971k
    }
794
485k
    tmp = lpd_state->wsynth[0 + 128 - fac_length];
795
485k
    iusace_apply_deemph(&(lpd_state->wsynth[1 + 128 - fac_length]), TILT_FAC, fac_length, &tmp);
796
485k
  }
797
798
781k
  k = ((frame_len / LEN_SUBFR) - 2) * (ORDER + 1);
799
781k
  memcpy(lpd_state->lpc_coeffs, lpc_coeffs + k, 2 * (ORDER + 1) * sizeof(FLOAT32));
800
801
781k
  memcpy(lpd_state->lpc_coeffs_quant, lpc_coeffs_quant + (2 * (ORDER + 1)),
802
781k
         (ORDER + 1) * sizeof(FLOAT32));
803
781k
  memcpy(lpd_state->lpc_coeffs_quant + (ORDER + 1), lpd_state->lpc_coeffs_quant,
804
781k
         (ORDER + 1) * sizeof(FLOAT32));
805
806
781k
  memcpy(synth - 128, &(lpd_state->synth[ORDER]), 128 * sizeof(FLOAT32));
807
781k
  lpd_state->tcx_fac = xn[frame_len - 1];
808
809
781k
  iusace_apply_preemph(xn, TILT_FAC, frame_len, &mem_tcx_q);
810
5.72M
  for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) {
811
4.94M
    memcpy(&synth[i_subfr], &xn[i_subfr], LEN_SUBFR * sizeof(FLOAT32));
812
4.94M
    iusace_compute_lp_residual(lpc_coeffs_quant + (2 * (ORDER + 1)), &synth[i_subfr],
813
4.94M
                               &xn[i_subfr], LEN_SUBFR);
814
4.94M
  }
815
781k
  memcpy(lpd_state->synth, synth + frame_len - (ORDER + 128), (ORDER + 128) * sizeof(FLOAT32));
816
817
781k
  if (frame_len == len_subfrm) {
818
446k
    memcpy(x, lpd_state->acelp_exc + len_subfrm, len_subfrm * sizeof(FLOAT32));
819
446k
    memcpy(lpd_state->acelp_exc, x, len_subfrm * sizeof(FLOAT32));
820
446k
    memcpy(lpd_state->acelp_exc + len_subfrm, xn, len_subfrm * sizeof(FLOAT32));
821
446k
  } else {
822
334k
    memcpy(lpd_state->acelp_exc, xn + frame_len - (2 * len_subfrm),
823
334k
           2 * len_subfrm * sizeof(FLOAT32));
824
334k
  }
825
826
781k
  memcpy(wsynth - 128, &(lpd_state->wsynth[1]), 128 * sizeof(FLOAT32));
827
828
781k
  ptr_lp_flt_coeffs = lpc_coeffs;
829
5.72M
  for (i_subfr = 0; i_subfr < frame_len; i_subfr += LEN_SUBFR) {
830
4.94M
    iusace_get_weighted_lpc(ptr_lp_flt_coeffs, lp_flt_coeffs);
831
4.94M
    iusace_compute_lp_residual(lp_flt_coeffs, &synth[i_subfr], &wsynth[i_subfr], LEN_SUBFR);
832
4.94M
    ptr_lp_flt_coeffs += (ORDER + 1);
833
4.94M
  }
834
781k
  tmp = wsynth[-1];
835
781k
  iusace_apply_deemph(wsynth, TILT_FAC, frame_len, &tmp);
836
837
781k
  memcpy(lpd_state->wsynth, wsynth + frame_len - (1 + 128), (1 + 128) * sizeof(FLOAT32));
838
839
781k
  lpd_state->mode = mode;
840
841
781k
  lpd_state->num_bits = 10 + target_bits;
842
843
781k
  return;
844
781k
}