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