1/******************************************************************************
2 *                                                                            *
3 * Copyright (C) 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*/
20#include <float.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <math.h>
24#include <string.h>
25
26#include "ixheaacd_cnst.h"
27#include <ixheaacd_type_def.h>
28#include "ixheaacd_bitbuffer.h"
29#include "ixheaacd_acelp_com.h"
30
31#include <ixheaacd_type_def.h>
32#include "ixheaacd_bitbuffer.h"
33#include "ixheaacd_interface.h"
34
35#include "ixheaacd_tns_usac.h"
36#include "ixheaacd_cnst.h"
37
38#include "ixheaacd_acelp_info.h"
39
40#include "ixheaacd_td_mdct.h"
41
42#include "ixheaacd_sbrdecsettings.h"
43#include "ixheaacd_info.h"
44#include "ixheaacd_sbr_common.h"
45#include "ixheaacd_drc_data_struct.h"
46#include "ixheaacd_drc_dec.h"
47#include "ixheaacd_sbrdecoder.h"
48#include "ixheaacd_mps_polyphase.h"
49#include "ixheaacd_sbr_const.h"
50
51#include "ixheaacd_constants.h"
52#include <ixheaacd_basic_ops32.h>
53#include <ixheaacd_basic_ops40.h>
54#include "ixheaacd_main.h"
55#include "ixheaacd_arith_dec.h"
56
57#define FREQ_MAX 6400.0f
58
59#define ABS(A) ((A) < 0 ? (-A) : (A))
60
61static VOID ixheaacd_compute_coeff_poly_f(FLOAT32 lsp[], FLOAT32 *f1,
62                                          FLOAT32 *f2) {
63  FLOAT32 b1, b2;
64  FLOAT32 *ptr_lsp;
65  WORD32 i, j;
66
67  ptr_lsp = lsp;
68  f1[0] = f2[0] = 1.0f;
69
70  for (i = 1; i <= ORDER_BY_2; i++) {
71    b1 = -2.0f * (*ptr_lsp++);
72    b2 = -2.0f * (*ptr_lsp++);
73    f1[i] = (b1 * f1[i - 1]) + (2.0f * f1[i - 2]);
74    f2[i] = (b2 * f2[i - 1]) + (2.0f * f2[i - 2]);
75    for (j = i - 1; j > 0; j--) {
76      f1[j] += (b1 * f1[j - 1]) + f1[j - 2];
77      f2[j] += (b2 * f2[j - 1]) + f2[j - 2];
78    }
79  }
80
81  return;
82}
83VOID ixheaacd_lsp_to_lp_conversion(FLOAT32 *lsp, FLOAT32 *lp_flt_coff_a) {
84  WORD32 i;
85  FLOAT32 *ppoly_f1, *ppoly_f2;
86  FLOAT32 *plp_flt_coff_a_bott, *plp_flt_coff_a_top;
87  FLOAT32 poly1[ORDER_BY_2 + 2], poly2[ORDER_BY_2 + 2];
88
89  poly1[0] = 0.0f;
90  poly2[0] = 0.0f;
91
92  ixheaacd_compute_coeff_poly_f(lsp, &poly1[1], &poly2[1]);
93
94  ppoly_f1 = poly1 + ORDER_BY_2 + 1;
95  ppoly_f2 = poly2 + ORDER_BY_2 + 1;
96
97  for (i = 0; i < ORDER_BY_2; i++) {
98    ppoly_f1[0] += ppoly_f1[-1];
99    ppoly_f2[0] -= ppoly_f2[-1];
100    ppoly_f1--;
101    ppoly_f2--;
102  }
103
104  plp_flt_coff_a_bott = lp_flt_coff_a;
105  *plp_flt_coff_a_bott++ = 1.0f;
106  plp_flt_coff_a_top = lp_flt_coff_a + ORDER;
107  ppoly_f1 = poly1 + 2;
108  ppoly_f2 = poly2 + 2;
109  for (i = 0; i < ORDER_BY_2; i++) {
110    *plp_flt_coff_a_bott++ = 0.5f * (*ppoly_f1 + *ppoly_f2);
111    *plp_flt_coff_a_top-- = 0.5f * (*ppoly_f1++ - *ppoly_f2++);
112  }
113
114  return;
115}
116
117VOID ixheaacd_lpc_to_td(float *coeff, WORD32 order, float *gains, WORD32 lg) {
118  FLOAT32 data_r[LEN_SUPERFRAME * 2];
119  FLOAT32 data_i[LEN_SUPERFRAME * 2];
120  FLOAT64 avg_fac;
121  WORD32 idata_r[LEN_SUPERFRAME * 2];
122  WORD32 idata_i[LEN_SUPERFRAME * 2];
123  WORD8 qshift;
124  WORD32 preshift = 0;
125  WORD32 itemp;
126  FLOAT32 ftemp = 0;
127  FLOAT32 tmp, qfac;
128  WORD32 i, size_n;
129
130  size_n = 2 * lg;
131  avg_fac = PI / (FLOAT32)(size_n);
132
133  for (i = 0; i < order + 1; i++) {
134    tmp = (FLOAT32)(((FLOAT32)i) * avg_fac);
135    data_r[i] = (FLOAT32)(coeff[i] * cos(tmp));
136    data_i[i] = (FLOAT32)(-coeff[i] * sin(tmp));
137  }
138  for (; i < size_n; i++) {
139    data_r[i] = 0.f;
140    data_i[i] = 0.f;
141  }
142
143  for (i = 0; i < size_n; i++) {
144    if (ABS(data_r[i]) > ftemp) ftemp = ABS(data_r[i]);
145    if (ABS(data_i[i]) > ftemp) ftemp = ABS(data_i[i]);
146  }
147
148  itemp = (WORD32)ftemp;
149  qshift = ixheaacd_norm32(itemp);
150
151  for (i = 0; i < size_n; i++) {
152    idata_r[i] = (WORD32)(data_r[i] * ((WORD64)1 << qshift));
153    idata_i[i] = (WORD32)(data_i[i] * ((WORD64)1 << qshift));
154  }
155
156  ixheaacd_complex_fft(idata_r, idata_i, size_n, -1, &preshift);
157
158  qfac = 1.0f / ((FLOAT32)((WORD64)1 << (qshift - preshift)));
159
160  for (i = 0; i < size_n; i++) {
161    data_r[i] = (FLOAT32)((FLOAT32)idata_r[i] * qfac);
162    data_i[i] = (FLOAT32)((FLOAT32)idata_i[i] * qfac);
163  }
164
165  for (i = 0; i < size_n / 2; i++) {
166    gains[i] =
167        (FLOAT32)(1.0f / sqrt(data_r[i] * data_r[i] + data_i[i] * data_i[i]));
168  }
169
170  return;
171}
172
173VOID ixheaacd_noise_shaping(FLOAT32 r[], WORD32 lg, WORD32 M, FLOAT32 g1[],
174                            FLOAT32 g2[]) {
175  WORD32 i, k;
176  FLOAT32 rr_prev, a = 0, b = 0;
177  FLOAT32 rr[1024];
178
179  k = lg / M;
180
181  rr_prev = 0;
182
183  memcpy(&rr, r, lg * sizeof(FLOAT32));
184
185  for (i = 0; i < lg; i++) {
186    if ((i % k) == 0) {
187      a = 2.0f * g1[i / k] * g2[i / k] / (g1[i / k] + g2[i / k]);
188      b = (g2[i / k] - g1[i / k]) / (g1[i / k] + g2[i / k]);
189    }
190
191    rr[i] = a * rr[i] + b * rr_prev;
192    rr_prev = rr[i];
193  }
194
195  for (i = 0; i < lg / 2; i++) {
196    r[i] = rr[2 * i];
197    r[lg / 2 + i] = rr[lg - 2 * i - 1];
198  }
199  return;
200}
201
202VOID ixheaacd_lpc_coef_gen(FLOAT32 lsf_old[], FLOAT32 lsf_new[], FLOAT32 a[],
203                           WORD32 nb_subfr, WORD32 m) {
204  FLOAT32 lsf[ORDER], *ptr_a;
205  FLOAT32 inc, fnew, fold;
206  WORD32 i;
207
208  ptr_a = a;
209
210  inc = 1.0f / (FLOAT32)nb_subfr;
211  fnew = 0.5f - (0.5f * inc);
212  fold = 1.0f - fnew;
213
214  for (i = 0; i < m; i++) {
215    lsf[i] = (lsf_old[i] * fold) + (lsf_new[i] * fnew);
216  }
217  ixheaacd_lsp_to_lp_conversion(lsf, ptr_a);
218  ptr_a += (m + 1);
219  ixheaacd_lsp_to_lp_conversion(lsf_old, ptr_a);
220  ptr_a += (m + 1);
221  ixheaacd_lsp_to_lp_conversion(lsf_new, ptr_a);
222  ptr_a += (m + 1);
223
224  return;
225}
226
227VOID ixheaacd_interpolation_lsp_params(FLOAT32 lsp_old[], FLOAT32 lsp_new[],
228                                       FLOAT32 lp_flt_coff_a[],
229                                       WORD32 nb_subfr) {
230  FLOAT32 lsp[ORDER];
231  FLOAT32 factor;
232  WORD32 i, k;
233  FLOAT32 x_plus_y, x_minus_y;
234
235  factor = 1.0f / (FLOAT32)nb_subfr;
236
237  x_plus_y = 0.5f * factor;
238
239  for (k = 0; k < nb_subfr; k++) {
240    x_minus_y = 1.0f - x_plus_y;
241    for (i = 0; i < ORDER; i++) {
242      lsp[i] = (lsp_old[i] * x_minus_y) + (lsp_new[i] * x_plus_y);
243    }
244    x_plus_y += factor;
245
246    ixheaacd_lsp_to_lp_conversion(lsp, lp_flt_coff_a);
247
248    lp_flt_coff_a += (ORDER + 1);
249  }
250
251  ixheaacd_lsp_to_lp_conversion(lsp_new, lp_flt_coff_a);
252
253  return;
254}
255