Coverage Report

Created: 2026-06-25 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/decoder/ixheaacd_lpc.c
Line
Count
Source
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 <assert.h>
21
#include <float.h>
22
#include <stdlib.h>
23
#include <stdio.h>
24
#include <math.h>
25
#include <string.h>
26
27
#include "ixheaac_type_def.h"
28
#include "ixheaacd_bitbuffer.h"
29
#include "ixheaacd_interface.h"
30
#include "ixheaacd_defines.h"
31
#include "ixheaacd_aac_rom.h"
32
#include "ixheaacd_tns_usac.h"
33
#include "ixheaacd_cnst.h"
34
#include "ixheaacd_acelp_info.h"
35
36
#include "ixheaacd_sbrdecsettings.h"
37
#include "ixheaacd_info.h"
38
#include "ixheaacd_sbr_common.h"
39
#include "ixheaacd_drc_data_struct.h"
40
#include "ixheaacd_drc_dec.h"
41
#include "ixheaacd_sbrdecoder.h"
42
#include "ixheaacd_mps_polyphase.h"
43
#include "ixheaac_sbr_const.h"
44
45
#include "ixheaacd_pulsedata.h"
46
#include "ixheaacd_pns.h"
47
#include "ixheaacd_lt_predict.h"
48
#include "ixheaacd_ec_defines.h"
49
#include "ixheaacd_ec_struct_def.h"
50
#include "ixheaacd_main.h"
51
#include "ixheaacd_channelinfo.h"
52
#include "ixheaacd_ec.h"
53
#include "ixheaacd_arith_dec.h"
54
55
#include "ixheaacd_func_def.h"
56
#include "ixheaacd_windows.h"
57
#include "ixheaacd_acelp_com.h"
58
#include "ixheaac_constants.h"
59
#include "ixheaac_basic_ops32.h"
60
#include "ixheaac_basic_ops40.h"
61
62
#define LSF_GAP_F 50.0f
63
0
#define FREQ_MAX_F 6400.0f
64
#define FREQ_DIV_F 400.0f
65
66
extern const FLOAT32 ixheaacd_fir_lp_filt[1 + FILTER_DELAY];
67
68
const WORD32 ixheaacd_pow_10_i_by_128[128] = {
69
    16384,     17788,     19312,     20968,     22765,     24716,     26835,
70
    29135,     31632,     34343,     37287,     40483,     43953,     47720,
71
    51810,     56251,     61072,     66307,     71990,     78161,     84860,
72
    92134,     100030,    108604,    117913,    128019,    138992,    150905,
73
    163840,    177882,    193129,    209682,    227654,    247167,    268352,
74
    291353,    316325,    343438,    372874,    404834,    439532,    477205,
75
    518107,    562515,    610728,    663075,    719908,    781612,    848605,
76
    921340,    1000309,   1086046,   1179133,   1280197,   1389925,   1509057,
77
    1638400,   1778829,   1931294,   2096827,   2276549,   2471675,   2683525,
78
    2913532,   3163255,   3434381,   3728745,   4048340,   4395328,   4772057,
79
    5181075,   5625151,   6107289,   6630752,   7199081,   7816122,   8486051,
80
    9213400,   10003091,  10860467,  11791330,  12801978,  13899250,  15090570,
81
    16384000,  17788290,  19312945,  20968279,  22765494,  24716750,  26835250,
82
    29135329,  31632551,  34343813,  37287459,  40483409,  43953287,  47720573,
83
    51810757,  56251515,  61072895,  66307521,  71990813,  78161226,  84860513,
84
    92134002,  100030911, 108604672, 117913300, 128019781, 138992500, 150905703,
85
    163840000, 177882909, 193129453, 209682794, 227654941, 247167501, 268352504,
86
    291353298, 316325515, 343438130, 372874596, 404834095, 439532879, 477205734,
87
    518107571, 562515151};
88
89
VOID ixheaacd_lsf_weight_2st_flt(float *lsfq, float *w, WORD32 mode);
90
91
3.36M
static PLATFORM_INLINE WORD32 ixheaacd_mult32_m(WORD32 a, WORD32 b) {
92
3.36M
  WORD32 result;
93
3.36M
  WORD64 temp_result;
94
95
3.36M
  temp_result = (WORD64)a * (WORD64)b;
96
3.36M
  result = (WORD32)(temp_result >> 31);
97
98
3.36M
  return (result);
99
3.36M
}
100
101
void ixheaacd_reset_acelp_data_fix(ia_usac_data_struct *usac_data,
102
                                   ia_usac_lpd_decoder_handle st,
103
                                   WORD32 *ptr_overlap_buf,
104
48.8k
                                   WORD32 was_last_short, WORD32 tw_mdct) {
105
48.8k
  WORD32 i;
106
107
48.8k
  if (was_last_short == 1) {
108
7.21k
    st->mode_prev = -2;
109
41.6k
  } else {
110
41.6k
    st->mode_prev = -1;
111
41.6k
  }
112
113
390k
  for (i = 0; i < NUM_SUBFR_SUPERFRAME_BY2 - 1; i++) {
114
342k
    st->pitch_prev[i] = 64;
115
342k
    st->gain_prev[i] = 0;
116
342k
  }
117
118
48.8k
  st->bpf_active_prev = 0;
119
120
48.8k
  if (ptr_overlap_buf != NULL && !tw_mdct) {
121
17.3k
    const WORD32 *ptr_window_coeff;
122
17.3k
    WORD32 fac_length;
123
17.3k
    if (was_last_short) {
124
7.21k
      fac_length = (usac_data->ccfl) / 16;
125
10.1k
    } else {
126
10.1k
      fac_length = (usac_data->len_subfrm) / 2;
127
10.1k
    }
128
129
17.3k
    if (fac_length == 48) {
130
973
      ptr_window_coeff = ixheaacd_sine_win_96;
131
16.3k
    } else if (fac_length == 64) {
132
6.24k
      ptr_window_coeff = ixheaacd_sine_win_128;
133
10.1k
    } else if (fac_length == 96) {
134
1.78k
      ptr_window_coeff = ixheaacd_sine_win_192;
135
8.32k
    } else {
136
8.32k
      ptr_window_coeff = ixheaacd_sine_win_256;
137
8.32k
    }
138
139
3.38M
    for (i = 0; i < 2 * fac_length; i++) {
140
3.36M
      ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i] =
141
3.36M
          ixheaacd_mult32_m(
142
3.36M
              ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i],
143
3.36M
              ptr_window_coeff[2 * fac_length - 1 - i]);
144
3.36M
    }
145
6.85M
    for (i = 0; i < (usac_data->ccfl) / 2 - fac_length; i++) {
146
6.83M
      ptr_overlap_buf[(usac_data->ccfl) / 2 + fac_length + i] = 0;
147
6.83M
    }
148
149
17.3k
    if (ptr_overlap_buf != NULL) {
150
463k
      for (i = 0; i < (usac_data->len_subfrm) / 2 - fac_length; i++) {
151
446k
        st->exc_prev[i] = 0.0f;
152
446k
      }
153
3.40M
      for (i = 0; i < 2 * fac_length + 1; i++) {
154
3.38M
        st->exc_prev[(usac_data->len_subfrm) / 2 - fac_length + i] =
155
3.38M
            ptr_overlap_buf[i + usac_data->ccfl / 2 - fac_length - 1] /
156
3.38M
            (float)(16384);
157
3.38M
      }
158
17.3k
    } else {
159
0
      ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
160
0
    }
161
17.3k
  }
162
163
48.8k
  return;
164
48.8k
}
165
166
VOID ixheaacd_fix2flt_data(ia_usac_data_struct *usac_data,
167
17.3k
                           ia_usac_lpd_decoder_handle st, WORD32 k) {
168
17.3k
  WORD32 i;
169
17.3k
  WORD32 fac_length;
170
17.3k
  WORD32 window_sequence_last = usac_data->window_sequence_last[k];
171
17.3k
  WORD32 *p_ola_buffer = usac_data->overlap_data_ptr[k];
172
17.3k
  if (window_sequence_last == EIGHT_SHORT_SEQUENCE) {
173
7.21k
    fac_length = (usac_data->ccfl) / 16;
174
10.1k
  } else {
175
10.1k
    fac_length = (usac_data->len_subfrm) / 2;
176
10.1k
  }
177
178
17.3k
  ixheaacd_memset(st->lp_flt_coeff_a_prev, 2 * (ORDER + 1));
179
17.3k
  ixheaacd_memset(st->xcitation_prev, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
180
17.3k
  ixheaacd_memset(st->synth_prev, MAX_PITCH + SYNTH_DELAY_LMAX);
181
17.3k
  ixheaacd_memset(st->bpf_prev, FILTER_DELAY + LEN_SUBFR);
182
183
17.3k
  st->gain_threshold = 0.0f;
184
185
17.3k
  if (p_ola_buffer != NULL) {
186
463k
    for (i = 0; i < (usac_data->len_subfrm) / 2 - fac_length; i++) {
187
446k
      st->exc_prev[i] = 0;
188
446k
    }
189
3.40M
    for (i = 0; i < 2 * fac_length + 1; i++) {
190
3.38M
      st->exc_prev[(usac_data->len_subfrm) / 2 - fac_length + i] = (FLOAT32)(
191
3.38M
          p_ola_buffer[i + usac_data->ccfl / 2 - fac_length - 1] / 16384.0);
192
3.38M
    }
193
17.3k
  } else {
194
0
    ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
195
0
  }
196
197
17.3k
  return;
198
17.3k
}
199
200
void ixheaacd_init_acelp_data(ia_usac_data_struct *usac_data,
201
31.5k
                              ia_usac_lpd_decoder_handle st) {
202
31.5k
  ixheaacd_reset_acelp_data_fix(usac_data, st, NULL, 0, 0);
203
31.5k
}
204
205
4.94M
#define PI_BY_6400 (PI / 6400.0)
206
468k
#define SCALE1 (6400.0 / PI)
207
208
29.2k
void ixheaacd_lsp_2_lsf_conversion(float lsp[], float lsf[], WORD32 m) {
209
29.2k
  short i;
210
497k
  for (i = 0; i < m; i++) {
211
468k
    lsf[i] = (float)(acos(lsp[i]) * SCALE1);
212
468k
  }
213
29.2k
  return;
214
29.2k
}
215
216
static VOID ixheaacd_lsf_2_lsp_conversion_float(FLOAT32 lsf[], FLOAT32 lsp[],
217
309k
                                                WORD32 m) {
218
309k
  WORD32 i;
219
5.25M
  for (i = 0; i < m; i++)
220
4.94M
    lsp[i] = (FLOAT32)cos((double)lsf[i] * (double)PI_BY_6400);
221
222
309k
  return;
223
309k
}
224
225
static WORD32 ixheaacd_bass_post_filter(FLOAT32 *synth_sig, WORD32 *pitch, FLOAT32 *pitch_gain,
226
                                        FLOAT32 *synth_out, WORD32 len_fr, WORD32 len2,
227
104k
                                        FLOAT32 bpf_prev[], WORD32 ec_flag) {
228
104k
  WORD32 i, j, sf, num_subfr, pitch_lag, lg;
229
104k
  FLOAT32 x_energy, xy_corr, y_energy, norm_corr, energy, gain, tmp, alpha;
230
104k
  FLOAT32 noise_buf[FILTER_DELAY + (2 * LEN_SUBFR)], *noise_tmp1, *noise_tmp2,
231
104k
      *x, *y;
232
233
104k
  noise_tmp1 = noise_buf + FILTER_DELAY;
234
104k
  noise_tmp2 = noise_buf + FILTER_DELAY + LEN_SUBFR;
235
236
104k
  memcpy(synth_out, synth_sig - LEN_SUBFR, len_fr * sizeof(FLOAT32));
237
238
104k
  if (len_fr % 64)
239
0
    memset(synth_out + len_fr, 0, (LEN_SUBFR - len_fr % 64) * sizeof(FLOAT32));
240
241
104k
  sf = 0;
242
1.50M
  for (num_subfr = 0; num_subfr < len_fr; num_subfr += LEN_SUBFR, sf++) {
243
1.40M
    pitch_lag = pitch[sf];
244
1.40M
    gain = pitch_gain[sf];
245
1.40M
    if (((pitch_lag >> 1) + 96 - num_subfr) > MAX_PITCH) {
246
1
      if (ec_flag) {
247
0
        pitch_lag = (MAX_PITCH + num_subfr - 96) << 1;
248
1
      } else {
249
1
        return -1;
250
1
      }
251
1
    }
252
1.40M
    if (gain > 1.0f) gain = 1.0f;
253
1.40M
    if (gain < 0.0f) gain = 0.0f;
254
255
1.40M
    x = &synth_sig[num_subfr - 96];
256
1.40M
    y = &synth_sig[num_subfr - pitch_lag / 2 - 96];
257
258
1.40M
    x_energy = 0.01f;
259
1.40M
    xy_corr = 0.01f;
260
1.40M
    y_energy = 0.01f;
261
226M
    for (i = 0; i < LEN_SUBFR + 96; i++) {
262
224M
      x_energy += x[i] * x[i];
263
224M
      xy_corr += x[i] * y[i];
264
224M
      y_energy += y[i] * y[i];
265
224M
    }
266
267
1.40M
    norm_corr = xy_corr / (FLOAT32)sqrt(x_energy * y_energy);
268
269
1.40M
    if (norm_corr > 0.95f) pitch_lag >>= 1;
270
271
1.40M
    lg = len_fr + len2 - pitch_lag - num_subfr;
272
1.40M
    if (lg < 0) lg = 0;
273
1.40M
    if (lg > LEN_SUBFR) lg = LEN_SUBFR;
274
275
1.40M
    if (pitch_lag > MAX_PITCH) {
276
34
      if (ec_flag) {
277
0
        pitch_lag = MAX_PITCH;
278
34
      } else {
279
34
        return -1;
280
34
      }
281
34
    }
282
283
1.40M
    if (gain > 0) {
284
164k
      if (lg > 0) {
285
164k
        tmp = 0.01f;
286
10.6M
        for (i = 0; i < lg; i++) {
287
10.5M
          tmp += synth_sig[i + num_subfr] * synth_sig[i + num_subfr];
288
10.5M
        }
289
164k
        energy = 0.01f;
290
10.6M
        for (i = 0; i < lg; i++) {
291
10.5M
          energy += synth_sig[i + num_subfr + pitch_lag] *
292
10.5M
                    synth_sig[i + num_subfr + pitch_lag];
293
10.5M
        }
294
164k
        tmp = (FLOAT32)sqrt(tmp / energy);
295
164k
        if (tmp < gain) gain = tmp;
296
164k
      }
297
298
164k
      alpha = 0.5f * gain;
299
10.6M
      for (i = 0; i < lg; i++) {
300
10.5M
        noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
301
10.5M
                                 0.5f * synth_sig[i + num_subfr - pitch_lag] -
302
10.5M
                                 0.5f * synth_sig[i + num_subfr + pitch_lag]);
303
10.5M
      }
304
171k
      for (i = lg; i < LEN_SUBFR; i++) {
305
7.53k
        noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
306
7.53k
                                 synth_sig[i + num_subfr - pitch_lag]);
307
7.53k
      }
308
1.24M
    } else {
309
1.24M
      memset(noise_tmp2, 0, LEN_SUBFR * sizeof(FLOAT32));
310
1.24M
    }
311
312
1.40M
    memcpy(noise_buf, bpf_prev, (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
313
1.40M
    memcpy(bpf_prev, noise_buf + LEN_SUBFR,
314
1.40M
           (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
315
316
91.3M
    for (i = 0; i < LEN_SUBFR; i++) {
317
89.9M
      tmp = ixheaacd_fir_lp_filt[0] * noise_tmp1[i];
318
1.16G
      for (j = 1; j <= FILTER_DELAY; j++) {
319
1.07G
        tmp +=
320
1.07G
            ixheaacd_fir_lp_filt[j] * (noise_tmp1[i - j] + noise_tmp1[i + j]);
321
1.07G
      }
322
89.9M
      synth_out[i + num_subfr] -= tmp;
323
89.9M
    }
324
1.40M
  }
325
326
104k
  return 0;
327
104k
}
328
329
0
void ixheaacd_reorder_lsf(float *lsf, float min_dist, int n) {
330
0
  int i;
331
0
  float lsf_min;
332
333
0
  lsf_min = min_dist;
334
0
  for (i = 0; i < n; i++) {
335
0
    if (lsf[i] < lsf_min) lsf[i] = lsf_min;
336
337
0
    lsf_min = lsf[i] + min_dist;
338
0
  }
339
340
0
  lsf_min = FREQ_MAX_F - min_dist;
341
0
  for (i = n - 1; i >= 0; i--) {
342
0
    if (lsf[i] > lsf_min) lsf[i] = lsf_min;
343
344
0
    lsf_min = lsf[i] - min_dist;
345
0
  }
346
347
0
  return;
348
0
}
349
350
WORD32 ixheaacd_lpd_dec(ia_usac_data_struct *usac_data,
351
                        ia_usac_lpd_decoder_handle st,
352
                        ia_td_frame_data_struct *pstr_td_frame_data,
353
                        FLOAT32 fsynth[], WORD32 first_lpd_flag,
354
74.4k
                        WORD32 short_fac_flag, WORD32 bpf_control_info) {
355
74.4k
  FLOAT32 *synth_buf = usac_data->synth_buf;
356
74.4k
  FLOAT32 *xcitation_buff = usac_data->exc_buf;
357
74.4k
  FLOAT32 lsp_curr[ORDER];
358
74.4k
  FLOAT32 lsf_curr[ORDER];
359
74.4k
  FLOAT32 *lp_flt_coff_a = usac_data->lp_flt_coff;
360
74.4k
  FLOAT32 *synth, *xcitation_curr;
361
74.4k
  WORD32 *pitch = usac_data->pitch;
362
74.4k
  FLOAT32 *pitch_gain = usac_data->pitch_gain;
363
74.4k
  FLOAT32 lsf_flt[(2 * NUM_FRAMES + 1) * ORDER];
364
365
74.4k
  WORD32 i, k, tp, mode;
366
74.4k
  WORD32 *mod;
367
74.4k
  FLOAT32 gain, stability_factor = 0.0f;
368
74.4k
  FLOAT32 tmp, synth_corr, synth_energy;
369
370
74.4k
  WORD32 len_fr;
371
74.4k
  WORD32 len_subfrm;
372
74.4k
  WORD32 num_subfr;
373
74.4k
  WORD32 num_subfr_in_superfr;
374
74.4k
  WORD32 num_subfr_by2;
375
74.4k
  WORD32 synth_delay;
376
74.4k
  WORD32 num_samples = 0;
377
378
74.4k
  WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
379
380
74.4k
  WORD32 subfr_len = 0, n_subfr = 0;
381
74.4k
  WORD32 err = 0;
382
74.4k
  WORD32 ch = usac_data->present_chan;
383
384
74.4k
  len_fr = usac_data->ccfl;
385
74.4k
  len_subfrm = usac_data->len_subfrm;
386
74.4k
  num_subfr = usac_data->num_subfrm;
387
74.4k
  num_subfr_in_superfr = NUM_FRAMES * num_subfr;
388
74.4k
  num_subfr_by2 = (num_subfr_in_superfr / 2) - 1;
389
74.4k
  synth_delay = num_subfr_by2 * LEN_SUBFR;
390
391
74.4k
  synth = synth_buf + MAX_PITCH + synth_delay;
392
74.4k
  ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
393
74.4k
  ixheaacd_memset(synth, SYNTH_DELAY_LMAX + LEN_SUPERFRAME - synth_delay);
394
395
74.4k
  xcitation_curr = xcitation_buff + MAX_PITCH + INTER_LP_FIL_ORDER + 1;
396
74.4k
  ixheaacd_mem_cpy(st->xcitation_prev, xcitation_buff,
397
74.4k
                   MAX_PITCH + INTER_LP_FIL_ORDER + 1);
398
74.4k
  memset(xcitation_curr, 0, sizeof(FLOAT32) * (LEN_SUPERFRAME + 1));
399
400
74.4k
  mod = pstr_td_frame_data->mod;
401
74.4k
  if (usac_data->frame_ok == 1) {
402
74.4k
    usac_data->num_lost_lpd_frames[usac_data->present_chan] = 0;
403
74.4k
  }
404
405
74.4k
  if (usac_data->ec_flag && usac_data->frame_ok == 0) {
406
0
    ixheaacd_usac_lpc_ec(usac_data->lsp_coeff, usac_data->lpc4_lsf, usac_data->lsf_adaptive_mean,
407
0
                         first_lpd_flag);
408
0
  }
409
543k
  for (i = 0; i < num_subfr_by2; i++) {
410
469k
    pitch[i] = st->pitch_prev[i];
411
469k
    pitch_gain[i] = st->gain_prev[i];
412
469k
  }
413
1.16M
  for (i = 0; i < num_subfr_in_superfr; i++) {
414
1.08M
    pitch[i + num_subfr_by2] = 64;
415
1.08M
    pitch_gain[i + num_subfr_by2] = 0.0f;
416
1.08M
  }
417
418
74.4k
  if (usac_data->frame_ok) {
419
74.4k
    if (!first_lpd_flag) {
420
29.2k
      ixheaacd_lsp_2_lsf_conversion(st->lspold, lsf_flt, ORDER);
421
29.2k
    }
422
423
74.4k
    ixheaacd_alg_vec_dequant(pstr_td_frame_data, first_lpd_flag, lsf_flt, pstr_td_frame_data->mod,
424
74.4k
                             usac_data->ec_flag);
425
74.4k
  }
426
74.4k
  if (usac_data->ec_flag && !(usac_data->frame_ok)) {
427
0
    for (i = 0; i < 5; i++) {
428
0
      memcpy(&lsf_flt[i * ORDER], &usac_data->lsp_coeff[i], ORDER * sizeof(lsf_flt[0]));
429
0
    }
430
0
  }
431
74.4k
  if (first_lpd_flag) {
432
45.2k
    ixheaacd_mem_cpy(&lsf_flt[0], st->lsf_prev, ORDER);
433
45.2k
    ixheaacd_lsf_2_lsp_conversion_float(st->lsf_prev, st->lspold, ORDER);
434
45.2k
  }
435
436
74.4k
  if ((first_lpd_flag && mod[0] == 0) || (first_lpd_flag && mod[1] == 0) ||
437
45.1k
      ((first_lpd_flag && mod[2] == 0 && len_subfrm != LEN_FRAME))) {
438
30.6k
    FLOAT32 lp_flt_coeff_a[9 * (ORDER + 1)];
439
30.6k
    FLOAT32 tmp_buf[3 * LEN_FRAME + ORDER];
440
30.6k
    FLOAT32 tmp_res_buf[3 * LEN_FRAME];
441
30.6k
    FLOAT32 *tmp = &(tmp_buf[LEN_FRAME]);
442
30.6k
    FLOAT32 *ptr_tmp = &(tmp_res_buf[LEN_FRAME]);
443
30.6k
    WORD32 tmp_start;
444
30.6k
    FLOAT32 mem = 0;
445
30.6k
    WORD32 gain;
446
30.6k
    WORD32 length;
447
448
30.6k
    ixheaacd_interpolation_lsp_params(st->lspold, st->lspold, lp_flt_coeff_a,
449
30.6k
                                      8);
450
451
30.6k
    memcpy(st->lp_flt_coeff_a_prev, lp_flt_coeff_a,
452
30.6k
           (ORDER + 1) * sizeof(FLOAT32));
453
30.6k
    memcpy(st->lp_flt_coeff_a_prev + ORDER + 1, lp_flt_coeff_a,
454
30.6k
           (ORDER + 1) * sizeof(FLOAT32));
455
456
30.6k
    if (mod[0] == 0) {
457
18.9k
      WORD32 fac_length;
458
18.9k
      if (short_fac_flag) {
459
4.14k
        fac_length = (len_subfrm * NUM_FRAMES) / 16;
460
14.7k
      } else {
461
14.7k
        fac_length = len_subfrm / 2;
462
14.7k
      }
463
464
18.9k
      if (usac_data->frame_ok == 0) {
465
0
        memset(&pstr_td_frame_data->fac_data[0], 0, sizeof(pstr_td_frame_data->fac_data));
466
0
      }
467
18.9k
      gain = ixheaacd_pow_10_i_by_128[pstr_td_frame_data->fac_data[0]];
468
469
18.9k
      memcpy(ptr_scratch, &pstr_td_frame_data->fac_data[0],
470
18.9k
             129 * sizeof(WORD32));
471
472
1.01M
      for (i = 0; i < fac_length / 2; i++) {
473
1.00M
        pstr_td_frame_data->fac_data[i] = ptr_scratch[2 * i + 1] << 16;
474
1.00M
        pstr_td_frame_data->fac_data[fac_length / 2 + i] =
475
1.00M
            ptr_scratch[fac_length - 2 * i] << 16;
476
1.00M
      }
477
478
18.9k
      if (usac_data->ec_flag == 0) {
479
18.9k
        if (fac_length & (fac_length - 1)) {
480
5.07k
          if ((fac_length != 48) && (fac_length != 96) && (fac_length != 192) &&
481
0
              (fac_length != 384) && (fac_length != 768)) {
482
0
            return -1;
483
0
          }
484
5.07k
        }
485
18.9k
      }
486
487
18.9k
      ixheaacd_fwd_alias_cancel_tool(usac_data, pstr_td_frame_data, fac_length, lp_flt_coeff_a,
488
18.9k
                                     gain);
489
490
18.9k
      memset(&usac_data->overlap_data_ptr[usac_data->present_chan][(len_fr / 2)], 0,
491
18.9k
             fac_length * sizeof(WORD32));
492
18.9k
    }
493
494
14.4M
    for (i = 0; i < 2 * len_subfrm; i++)
495
14.3M
      st->fd_synth[ORDER + i] = (FLOAT32)(
496
14.3M
          (FLOAT32)usac_data->overlap_data_ptr[usac_data->present_chan][i] /
497
14.3M
          16384.0);
498
30.6k
    num_samples = min(2 * len_subfrm, MAX_PITCH + synth_delay);
499
500
30.6k
    ixheaacd_mem_cpy(st->fd_synth + ORDER, synth - 2 * len_subfrm,
501
30.6k
                     2 * len_subfrm);
502
503
30.6k
    ixheaacd_preemphsis_tool_float(st->fd_synth + ORDER, PREEMPH_FILT_FAC,
504
30.6k
                                   2 * len_subfrm, mem);
505
506
30.6k
    ixheaacd_memset(tmp, ORDER);
507
30.6k
    ixheaacd_mem_cpy(st->fd_synth + ORDER, tmp + ORDER, 2 * len_subfrm);
508
30.6k
    tmp_start = 0;
509
510
30.6k
    ixheaacd_memset(ptr_tmp - len_subfrm, 3 * len_subfrm);
511
30.6k
    memset(st->fd_synth, 0, ORDER * sizeof(WORD32));
512
30.6k
    length = (2 * len_subfrm - tmp_start) / LEN_SUBFR;
513
514
30.6k
    ixheaacd_residual_tool_float1(lp_flt_coeff_a,
515
30.6k
                                  &st->fd_synth[ORDER + tmp_start],
516
30.6k
                                  &ptr_tmp[tmp_start], LEN_SUBFR, length);
517
518
30.6k
    if (mod[0] != 0 && (len_subfrm == LEN_FRAME || mod[1] != 0)) {
519
7.76k
      num_samples = min(len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
520
22.9k
    } else {
521
22.9k
      num_samples = min(2 * len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
522
22.9k
    }
523
30.6k
    ixheaacd_mem_cpy(ptr_tmp + 2 * len_subfrm - num_samples,
524
30.6k
                     xcitation_curr - num_samples, num_samples);
525
30.6k
  }
526
527
74.4k
  k = 0;
528
529
338k
  while (k < 4) {
530
263k
    if (usac_data->ec_flag && usac_data->frame_ok == 0) {
531
0
      if (mod[k] != 0 && usac_data->frame_ok == 0 &&
532
0
          usac_data->str_error_concealment[ch].prev_frame_ok[0] == 0 && k == 0) {
533
0
        memcpy(st->lspold, usac_data->lspold_ec, sizeof(st->lspold));
534
0
      }
535
0
      usac_data->num_lost_lpd_frames[usac_data->present_chan]++;
536
0
    }
537
538
263k
    mode = mod[k];
539
263k
    if ((st->mode_prev == 0) && (mode > 0) &&
540
60.4k
        (k != 0 || st->bpf_active_prev == 1)) {
541
36.6k
      i = (k * num_subfr) + num_subfr_by2;
542
36.6k
      pitch[i + 1] = pitch[i] = pitch[i - 1];
543
36.6k
      pitch_gain[i + 1] = pitch_gain[i] = pitch_gain[i - 1];
544
36.6k
    }
545
263k
    if (usac_data->frame_ok == 0) {
546
0
      memcpy(lsf_curr, &lsf_flt[(k + 1) * ORDER], ORDER * sizeof(FLOAT32));
547
263k
    } else {
548
263k
      if ((mode == 0) || (mode == 1))
549
230k
        memcpy(lsf_curr, &lsf_flt[(k + 1) * ORDER], ORDER * sizeof(FLOAT32));
550
33.2k
      else if (mode == 2)
551
32.8k
        memcpy(lsf_curr, &lsf_flt[(k + 2) * ORDER], ORDER * sizeof(FLOAT32));
552
344
      else
553
344
        memcpy(lsf_curr, &lsf_flt[(k + 4) * ORDER], ORDER * sizeof(FLOAT32));
554
263k
    }
555
556
263k
    ixheaacd_lsf_2_lsp_conversion_float(lsf_curr, lsp_curr, ORDER);
557
263k
    if (usac_data->frame_ok) {
558
263k
      tmp = 0.0f;
559
4.48M
      for (i = 0; i < ORDER; i++) {
560
4.22M
        tmp += (lsf_curr[i] - st->lsf_prev[i]) * (lsf_curr[i] - st->lsf_prev[i]);
561
4.22M
      }
562
263k
      stability_factor = (FLOAT32)(1.25f - (tmp / 400000.0f));
563
263k
      if (stability_factor > 1.0f) {
564
57.6k
        stability_factor = 1.0f;
565
57.6k
      }
566
263k
      if (stability_factor < 0.0f) {
567
132k
        stability_factor = 0.0f;
568
132k
      }
569
263k
      if (usac_data->ec_flag) {
570
0
        usac_data->stability_factor_old = stability_factor;
571
0
      }
572
263k
    }
573
263k
    if (usac_data->ec_flag && !(usac_data->frame_ok)) {
574
0
      stability_factor = usac_data->stability_factor_old;
575
0
    }
576
263k
    if (usac_data->frame_ok == 0) {
577
0
      mode = st->mode_prev;
578
0
    }
579
263k
    if ((usac_data->frame_ok == 1 && mode == 0) ||
580
150k
        (usac_data->frame_ok == 0 && (st->mode_prev == 0 || st->mode_prev == 1))) {
581
150k
      ixheaacd_interpolation_lsp_params(st->lspold, lsp_curr, lp_flt_coff_a, num_subfr);
582
583
150k
      if (usac_data->frame_ok == 1 || (usac_data->frame_ok == 0 && st->mode_prev == 0)) {
584
150k
        ixheaacd_acelp_alias_cnx(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
585
150k
                                 stability_factor, st);
586
150k
      }
587
588
150k
      if (usac_data->frame_ok == 0 && st->mode_prev == 1) {
589
0
        ixheaacd_usac_tcx_ec(usac_data, st, lsp_curr, k, lp_flt_coff_a);
590
0
      }
591
592
150k
      if ((st->mode_prev != 0) && bpf_control_info) {
593
24.4k
        i = (k * num_subfr) + num_subfr_by2;
594
24.4k
        pitch[i - 1] = pitch[i];
595
24.4k
        pitch_gain[i - 1] = pitch_gain[i];
596
24.4k
        if (st->mode_prev != -2) {
597
23.3k
          pitch[i - 2] = pitch[i];
598
23.3k
          pitch_gain[i - 2] = pitch_gain[i];
599
23.3k
        }
600
24.4k
      }
601
150k
      k++;
602
150k
    } else {
603
113k
      if (mode == 1) {
604
79.8k
        subfr_len = len_subfrm;
605
79.8k
        n_subfr = num_subfr;
606
79.8k
      } else if (mode == 2) {
607
32.8k
        subfr_len = len_subfrm << 1;
608
32.8k
        n_subfr = num_subfr_in_superfr / 2;
609
32.8k
      } else if (mode == 3) {
610
344
        subfr_len = len_subfrm << 2;
611
344
        n_subfr = num_subfr_in_superfr;
612
344
      } else {
613
0
        if (usac_data->frame_ok == 0) {
614
0
          mode = 3;
615
0
          subfr_len = len_subfrm << 2;
616
0
          n_subfr = num_subfr_in_superfr;
617
0
        }
618
0
      }
619
620
113k
      ixheaacd_lpc_coef_gen(st->lspold, lsp_curr, lp_flt_coff_a, n_subfr,
621
113k
                            ORDER);
622
623
113k
      err = ixheaacd_tcx_mdct(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
624
113k
                              subfr_len, st);
625
113k
      if (err) return err;
626
113k
      if (usac_data->frame_ok == 1 && k == 2) {
627
32.6k
        memcpy(usac_data->lp_flt_coff_a_ec, &lp_flt_coff_a[k * (ORDER + 1)],
628
32.6k
               sizeof(usac_data->lp_flt_coff_a_ec));
629
32.6k
      }
630
113k
      k += (1 << (mode - 1));
631
113k
    }
632
633
263k
    st->mode_prev = mode;
634
263k
    if (usac_data->frame_ok == 0) {
635
0
      memcpy(usac_data->lspold_ec, st->lspold, sizeof(st->lspold));
636
0
    }
637
263k
    ixheaacd_mem_cpy(lsp_curr, st->lspold, ORDER);
638
263k
    ixheaacd_mem_cpy(lsf_curr, st->lsf_prev, ORDER);
639
263k
  }
640
641
74.4k
  ixheaacd_mem_cpy(xcitation_buff + len_fr, st->xcitation_prev,
642
74.4k
                   MAX_PITCH + INTER_LP_FIL_ORDER + 1);
643
644
74.4k
  ixheaacd_mem_cpy(synth_buf + len_fr, st->synth_prev, MAX_PITCH + synth_delay);
645
646
74.4k
  if (!bpf_control_info) {
647
50.2k
    if (mod[0] != 0 && st->bpf_active_prev) {
648
35.8k
      for (i = 2; i < num_subfr_in_superfr; i++)
649
33.2k
        pitch_gain[num_subfr_by2 + i] = 0.0;
650
47.6k
    } else {
651
734k
      for (i = 0; i < num_subfr_in_superfr; i++)
652
687k
        pitch_gain[num_subfr_by2 + i] = 0.0;
653
47.6k
    }
654
50.2k
  }
655
74.4k
  st->bpf_active_prev = bpf_control_info;
656
657
543k
  for (i = 0; i < num_subfr_by2; i++) {
658
469k
    st->pitch_prev[i] = pitch[num_subfr_in_superfr + i];
659
469k
    st->gain_prev[i] = pitch_gain[num_subfr_in_superfr + i];
660
469k
  }
661
662
74.4k
  synth = synth_buf + MAX_PITCH;
663
664
1.16M
  for (i = 0; i < num_subfr_in_superfr; i++) {
665
1.08M
    tp = pitch[i];
666
1.08M
    gain = pitch_gain[i];
667
1.08M
    if (gain > 0.0f) {
668
254k
      synth_corr = 0.0f, synth_energy = 1e-6f;
669
254k
      if ((((i * LEN_SUBFR) + LEN_SUBFR) > LEN_SUPERFRAME) ||
670
254k
          ((((i * LEN_SUBFR) + LEN_SUBFR) - tp) > LEN_SUPERFRAME)) {
671
0
        if (usac_data->ec_flag) {
672
0
          tp = LEN_SUPERFRAME - LEN_SUBFR - (i * LEN_SUBFR);
673
0
        } else
674
0
          return -1;
675
0
      }
676
16.5M
      for (k = 0; k < LEN_SUBFR; k++) {
677
16.3M
        synth_corr +=
678
16.3M
            synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
679
16.3M
        synth_energy +=
680
16.3M
            synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
681
16.3M
      }
682
254k
      pitch_gain[i] = synth_corr / synth_energy;
683
254k
    }
684
1.08M
  }
685
686
74.4k
  if (mod[3] == 0) {
687
48.7k
    err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr, synth_delay,
688
48.7k
                                    st->bpf_prev, usac_data->ec_flag);
689
48.7k
  } else {
690
25.7k
    err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr,
691
25.7k
                                    synth_delay - (len_subfrm / 2), st->bpf_prev,
692
25.7k
                                    usac_data->ec_flag);
693
25.7k
  }
694
74.4k
  if (err) return err;
695
74.4k
  if (usac_data->ec_flag && usac_data->frame_ok) {
696
0
    memcpy(usac_data->lpc4_lsf, pstr_td_frame_data->lpc4_lsf, sizeof(usac_data->lpc4_lsf));
697
0
    memcpy(usac_data->str_error_concealment[ch].lsf4, usac_data->lpc4_lsf,
698
0
           sizeof(usac_data->lpc4_lsf));
699
0
    memcpy(usac_data->lsf_adaptive_mean, pstr_td_frame_data->lsf_adaptive_mean_cand,
700
0
           sizeof(usac_data->lsf_adaptive_mean));
701
0
  }
702
74.4k
  return err;
703
74.4k
}
704
705
VOID ixheaacd_lpd_dec_update(ia_usac_lpd_decoder_handle tddec,
706
15.3k
                             ia_usac_data_struct *usac_data, WORD32 i_ch) {
707
15.3k
  WORD32 i, k;
708
709
15.3k
  WORD32 *ptr_overlap = &usac_data->overlap_data_ptr[i_ch][0];
710
15.3k
  WORD32 len_fr, lpd_sbf_len, lpd_delay, num_subfr_by2, synth_delay, fac_length;
711
712
15.3k
  if (usac_data->tw_mdct[0])
713
0
    ptr_overlap = &usac_data->overlap_data_ptr[i_ch][usac_data->ccfl / 2];
714
715
15.3k
  len_fr = usac_data->ccfl;
716
15.3k
  lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
717
15.3k
  lpd_delay = lpd_sbf_len * LEN_SUBFR;
718
15.3k
  num_subfr_by2 = lpd_sbf_len - 1;
719
15.3k
  synth_delay = num_subfr_by2 * LEN_SUBFR;
720
15.3k
  fac_length = (usac_data->len_subfrm) / 2;
721
722
7.59M
  for (i = 0; i < LEN_SUBFR + synth_delay; i++)
723
7.57M
    ptr_overlap[i] = (WORD32)(
724
7.57M
        (FLOAT32)tddec->synth_prev[MAX_PITCH - (LEN_SUBFR) + i] * 16384.0);
725
726
15.3k
  ptr_overlap += LEN_SUBFR + synth_delay - fac_length;
727
728
3.80M
  for (k = 0; k < 2 * fac_length; k++)
729
3.78M
    ptr_overlap[k] = (WORD32)((FLOAT32)tddec->exc_prev[k + 1] * 16384.0);
730
731
15.3k
  ptr_overlap = &usac_data->overlap_data_ptr[i_ch][lpd_delay + fac_length];
732
733
5.69M
  for (i = 0; i < len_fr - lpd_delay - fac_length; i++) ptr_overlap[i] = 0;
734
735
15.3k
  usac_data->window_shape[i_ch] = WIN_SEL_0;
736
15.3k
  usac_data->window_sequence_last[i_ch] = EIGHT_SHORT_SEQUENCE;
737
15.3k
  usac_data->td_frame_prev[i_ch] = 1;
738
739
15.3k
  if (tddec->mode_prev == 0) {
740
10.6k
    memmove(usac_data->lpc_prev[i_ch], &tddec->lp_flt_coeff_a_prev[ORDER + 1],
741
10.6k
            (ORDER + 1) * sizeof(FLOAT32));
742
10.6k
    memmove(usac_data->acelp_in[i_ch], tddec->exc_prev,
743
10.6k
            (1 + (2 * FAC_LENGTH)) * sizeof(FLOAT32));
744
10.6k
  }
745
746
15.3k
  return;
747
15.3k
}
748
749
WORD32 ixheaacd_lpd_bpf_fix(ia_usac_data_struct *usac_data,
750
                            WORD32 is_short_flag, FLOAT32 out_buffer[],
751
29.9k
                            ia_usac_lpd_decoder_handle st) {
752
29.9k
  WORD32 i, tp, k;
753
29.9k
  float synth_buf[MAX_PITCH + SYNTH_DELAY_LMAX + LEN_SUPERFRAME];
754
29.9k
  float signal_out[LEN_SUPERFRAME];
755
29.9k
  float *synth, synth_corr, synth_energy;
756
29.9k
  WORD32 pitch[NUM_SUBFR_SUPERFRAME_BY2 + 3];
757
29.9k
  float pitch_gain[NUM_SUBFR_SUPERFRAME_BY2 + 3];
758
29.9k
  WORD32 len_fr, lpd_sbf_len, num_subfr_by2, synth_delay;
759
29.9k
  WORD32 err = 0;
760
761
29.9k
  len_fr = usac_data->ccfl;
762
29.9k
  lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
763
29.9k
  num_subfr_by2 = lpd_sbf_len - 1;
764
29.9k
  synth_delay = num_subfr_by2 * LEN_SUBFR;
765
766
29.9k
  ixheaacd_memset(synth_buf, MAX_PITCH + synth_delay + len_fr);
767
29.9k
  ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
768
29.9k
  ixheaacd_mem_cpy(out_buffer, synth_buf + MAX_PITCH - (LEN_SUBFR),
769
29.9k
                   synth_delay + len_fr + (LEN_SUBFR));
770
771
228k
  for (i = 0; i < num_subfr_by2; i++) {
772
198k
    pitch[i] = st->pitch_prev[i];
773
198k
    pitch_gain[i] = st->gain_prev[i];
774
198k
  }
775
149k
  for (i = num_subfr_by2; i < lpd_sbf_len + 3; i++) {
776
119k
    pitch[i] = 64;
777
119k
    pitch_gain[i] = 0.0f;
778
119k
  }
779
29.9k
  if (st->mode_prev == 0) {
780
20.6k
    pitch[num_subfr_by2] = pitch[num_subfr_by2 - 1];
781
20.6k
    pitch_gain[num_subfr_by2] = pitch_gain[num_subfr_by2 - 1];
782
20.6k
    if (!is_short_flag) {
783
12.1k
      pitch[num_subfr_by2 + 1] = pitch[num_subfr_by2];
784
12.1k
      pitch_gain[num_subfr_by2 + 1] = pitch_gain[num_subfr_by2];
785
12.1k
    }
786
20.6k
  }
787
788
29.9k
  synth = synth_buf + MAX_PITCH;
789
790
288k
  for (i = 0; i < num_subfr_by2 + 2; i++) {
791
258k
    tp = pitch[i];
792
258k
    if ((i * LEN_SUBFR + MAX_PITCH) < tp) {
793
7
      if (usac_data->ec_flag == 0)
794
7
        return -1;
795
0
      else {
796
0
        tp = MAX_PITCH - (i * LEN_SUBFR);
797
0
      }
798
258k
    } else if (((i * LEN_SUBFR + MAX_PITCH - tp) >= 1883) ||
799
258k
               (((i * LEN_SUBFR) + LEN_SUBFR) > LEN_SUPERFRAME) ||
800
258k
               ((((i * LEN_SUBFR) + LEN_SUBFR) - tp) > LEN_SUPERFRAME)) {
801
0
      if (usac_data->ec_flag == 0)
802
0
        return -1;
803
0
      else {
804
0
        tp = (i * LEN_SUBFR + MAX_PITCH - 1882);
805
0
      }
806
0
    }
807
808
258k
    if (pitch_gain[i] > 0.0f) {
809
25.6k
      synth_corr = 0.0f, synth_energy = 1e-6f;
810
1.66M
      for (k = 0; k < LEN_SUBFR; k++) {
811
1.64M
        synth_corr +=
812
1.64M
            synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
813
1.64M
        synth_energy +=
814
1.64M
            synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
815
1.64M
      }
816
25.6k
      pitch_gain[i] = synth_corr / synth_energy;
817
25.6k
    }
818
258k
  }
819
820
29.9k
  err = ixheaacd_bass_post_filter(
821
29.9k
      synth, pitch, pitch_gain, signal_out, (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR,
822
29.9k
      len_fr - (lpd_sbf_len + 4) * LEN_SUBFR, st->bpf_prev, usac_data->ec_flag);
823
29.9k
  if (err != 0) return err;
824
825
29.8k
  ixheaacd_mem_cpy(signal_out, out_buffer,
826
29.8k
                   (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR);
827
29.8k
  return err;
828
29.9k
}