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