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 <stdlib.h>
21*15dc779aSAndroid Build Coastguard Worker #include <math.h>
22*15dc779aSAndroid Build Coastguard Worker
23*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
24*15dc779aSAndroid Build Coastguard Worker
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_interface.h"
27*15dc779aSAndroid Build Coastguard Worker
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_tns_usac.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_cnst.h"
30*15dc779aSAndroid Build Coastguard Worker
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_info.h"
32*15dc779aSAndroid Build Coastguard Worker
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_td_mdct.h"
34*15dc779aSAndroid Build Coastguard Worker
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_info.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_data_struct.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_dec.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecoder.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_polyphase.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_sbr_const.h"
43*15dc779aSAndroid Build Coastguard Worker
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_main.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_arith_dec.h"
48*15dc779aSAndroid Build Coastguard Worker
49*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_func_def.h"
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
54*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_512[4][512];
55*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_384[4][384];
56*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_256[4][256];
57*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_192[4][192];
58*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_128[4][128];
59*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_96[4][96];
60*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_64[4][64];
61*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_48[4][48];
62*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_32[4][32];
63*15dc779aSAndroid Build Coastguard Worker extern const WORD32 ixheaacd_pre_post_twid_cos_sin_24[4][24];
64*15dc779aSAndroid Build Coastguard Worker
ixheaacd_mul_sub64_sat_32(WORD32 a,WORD32 b,WORD32 c,WORD32 d)65*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaacd_mul_sub64_sat_32(WORD32 a, WORD32 b,
66*15dc779aSAndroid Build Coastguard Worker WORD32 c, WORD32 d) {
67*15dc779aSAndroid Build Coastguard Worker WORD64 diff;
68*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result1;
69*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result2;
70*15dc779aSAndroid Build Coastguard Worker
71*15dc779aSAndroid Build Coastguard Worker temp_result1 = (WORD64)a * (WORD64)c;
72*15dc779aSAndroid Build Coastguard Worker temp_result2 = (WORD64)b * (WORD64)d;
73*15dc779aSAndroid Build Coastguard Worker
74*15dc779aSAndroid Build Coastguard Worker diff = (temp_result1 - temp_result2) >> 32;
75*15dc779aSAndroid Build Coastguard Worker
76*15dc779aSAndroid Build Coastguard Worker if (diff >= 2147483647)
77*15dc779aSAndroid Build Coastguard Worker diff = 2147483647;
78*15dc779aSAndroid Build Coastguard Worker else if (diff <= -2147483647 - 1)
79*15dc779aSAndroid Build Coastguard Worker diff = -2147483647 - 1;
80*15dc779aSAndroid Build Coastguard Worker
81*15dc779aSAndroid Build Coastguard Worker return ((WORD32)diff);
82*15dc779aSAndroid Build Coastguard Worker }
83*15dc779aSAndroid Build Coastguard Worker
ixheaacd_mul_add64_sat_32(WORD32 a,WORD32 b,WORD32 c,WORD32 d)84*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaacd_mul_add64_sat_32(WORD32 a, WORD32 b,
85*15dc779aSAndroid Build Coastguard Worker WORD32 c, WORD32 d) {
86*15dc779aSAndroid Build Coastguard Worker WORD64 sum;
87*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result1;
88*15dc779aSAndroid Build Coastguard Worker WORD64 temp_result2;
89*15dc779aSAndroid Build Coastguard Worker
90*15dc779aSAndroid Build Coastguard Worker temp_result1 = (WORD64)a * (WORD64)c;
91*15dc779aSAndroid Build Coastguard Worker temp_result2 = (WORD64)b * (WORD64)d;
92*15dc779aSAndroid Build Coastguard Worker
93*15dc779aSAndroid Build Coastguard Worker sum = (temp_result1 + temp_result2) >> 32;
94*15dc779aSAndroid Build Coastguard Worker
95*15dc779aSAndroid Build Coastguard Worker if (sum >= 2147483647)
96*15dc779aSAndroid Build Coastguard Worker sum = 2147483647;
97*15dc779aSAndroid Build Coastguard Worker else if (sum <= -2147483647 - 1)
98*15dc779aSAndroid Build Coastguard Worker sum = -2147483647 - 1;
99*15dc779aSAndroid Build Coastguard Worker
100*15dc779aSAndroid Build Coastguard Worker return ((WORD32)sum);
101*15dc779aSAndroid Build Coastguard Worker }
102*15dc779aSAndroid Build Coastguard Worker
ixheaacd_pre_twid(WORD32 * in,WORD32 * r_ptr,WORD32 * i_ptr,WORD32 nlength,const WORD32 * ptr_pre_cos_sin)103*15dc779aSAndroid Build Coastguard Worker static void ixheaacd_pre_twid(WORD32 *in, WORD32 *r_ptr, WORD32 *i_ptr,
104*15dc779aSAndroid Build Coastguard Worker WORD32 nlength, const WORD32 *ptr_pre_cos_sin) {
105*15dc779aSAndroid Build Coastguard Worker WORD32 i;
106*15dc779aSAndroid Build Coastguard Worker
107*15dc779aSAndroid Build Coastguard Worker const WORD32 *cos_ptr = &ptr_pre_cos_sin[0];
108*15dc779aSAndroid Build Coastguard Worker const WORD32 *sin_ptr = &ptr_pre_cos_sin[nlength];
109*15dc779aSAndroid Build Coastguard Worker
110*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < nlength; i += 4) {
111*15dc779aSAndroid Build Coastguard Worker *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i], in[nlength + i], cos_ptr[i],
112*15dc779aSAndroid Build Coastguard Worker sin_ptr[i]);
113*15dc779aSAndroid Build Coastguard Worker *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i], in[nlength + i], sin_ptr[i],
114*15dc779aSAndroid Build Coastguard Worker cos_ptr[i]);
115*15dc779aSAndroid Build Coastguard Worker
116*15dc779aSAndroid Build Coastguard Worker *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i + 1], in[nlength + i + 1],
117*15dc779aSAndroid Build Coastguard Worker cos_ptr[i + 1], sin_ptr[i + 1]);
118*15dc779aSAndroid Build Coastguard Worker *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i + 1], in[nlength + i + 1],
119*15dc779aSAndroid Build Coastguard Worker sin_ptr[i + 1], cos_ptr[i + 1]);
120*15dc779aSAndroid Build Coastguard Worker
121*15dc779aSAndroid Build Coastguard Worker *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i + 2], in[nlength + i + 2],
122*15dc779aSAndroid Build Coastguard Worker cos_ptr[i + 2], sin_ptr[i + 2]);
123*15dc779aSAndroid Build Coastguard Worker *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i + 2], in[nlength + i + 2],
124*15dc779aSAndroid Build Coastguard Worker sin_ptr[i + 2], cos_ptr[i + 2]);
125*15dc779aSAndroid Build Coastguard Worker
126*15dc779aSAndroid Build Coastguard Worker *r_ptr++ = ixheaacd_mul_sub64_sat_32(in[i + 3], in[nlength + i + 3],
127*15dc779aSAndroid Build Coastguard Worker cos_ptr[i + 3], sin_ptr[i + 3]);
128*15dc779aSAndroid Build Coastguard Worker *i_ptr++ = ixheaacd_mul_add64_sat_32(in[i + 3], in[nlength + i + 3],
129*15dc779aSAndroid Build Coastguard Worker sin_ptr[i + 3], cos_ptr[i + 3]);
130*15dc779aSAndroid Build Coastguard Worker }
131*15dc779aSAndroid Build Coastguard Worker }
132*15dc779aSAndroid Build Coastguard Worker
ixheaacd_post_twid(WORD32 * data_re,WORD32 * data_im,WORD32 * out,WORD32 nlength,const WORD32 * ptr_post_cos_sin)133*15dc779aSAndroid Build Coastguard Worker static void ixheaacd_post_twid(WORD32 *data_re, WORD32 *data_im, WORD32 *out,
134*15dc779aSAndroid Build Coastguard Worker WORD32 nlength, const WORD32 *ptr_post_cos_sin) {
135*15dc779aSAndroid Build Coastguard Worker WORD32 i;
136*15dc779aSAndroid Build Coastguard Worker
137*15dc779aSAndroid Build Coastguard Worker const WORD32 *cos_ptr = &ptr_post_cos_sin[nlength * 2];
138*15dc779aSAndroid Build Coastguard Worker const WORD32 *sin_ptr = &ptr_post_cos_sin[nlength * 3];
139*15dc779aSAndroid Build Coastguard Worker
140*15dc779aSAndroid Build Coastguard Worker WORD32 *out_ptr = &out[2 * nlength - 1];
141*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < nlength; i += 4) {
142*15dc779aSAndroid Build Coastguard Worker out[0] = ixheaacd_mul_sub64_sat_32(data_re[i], data_im[i], cos_ptr[i],
143*15dc779aSAndroid Build Coastguard Worker sin_ptr[i]);
144*15dc779aSAndroid Build Coastguard Worker out_ptr[0] = -ixheaacd_mul_add64_sat_32(data_re[i], data_im[i], sin_ptr[i],
145*15dc779aSAndroid Build Coastguard Worker cos_ptr[i]);
146*15dc779aSAndroid Build Coastguard Worker
147*15dc779aSAndroid Build Coastguard Worker out[2] = ixheaacd_mul_sub64_sat_32(data_re[i + 1], data_im[i + 1],
148*15dc779aSAndroid Build Coastguard Worker cos_ptr[i + 1], sin_ptr[i + 1]);
149*15dc779aSAndroid Build Coastguard Worker out_ptr[-2] = -ixheaacd_mul_add64_sat_32(data_re[i + 1], data_im[i + 1],
150*15dc779aSAndroid Build Coastguard Worker sin_ptr[i + 1], cos_ptr[i + 1]);
151*15dc779aSAndroid Build Coastguard Worker
152*15dc779aSAndroid Build Coastguard Worker out[4] = ixheaacd_mul_sub64_sat_32(data_re[i + 2], data_im[i + 2],
153*15dc779aSAndroid Build Coastguard Worker cos_ptr[i + 2], sin_ptr[i + 2]);
154*15dc779aSAndroid Build Coastguard Worker out_ptr[-4] = -ixheaacd_mul_add64_sat_32(data_re[i + 2], data_im[i + 2],
155*15dc779aSAndroid Build Coastguard Worker sin_ptr[i + 2], cos_ptr[i + 2]);
156*15dc779aSAndroid Build Coastguard Worker
157*15dc779aSAndroid Build Coastguard Worker out[6] = ixheaacd_mul_sub64_sat_32(data_re[i + 3], data_im[i + 3],
158*15dc779aSAndroid Build Coastguard Worker cos_ptr[i + 3], sin_ptr[i + 3]);
159*15dc779aSAndroid Build Coastguard Worker out_ptr[-6] = -ixheaacd_mul_add64_sat_32(data_re[i + 3], data_im[i + 3],
160*15dc779aSAndroid Build Coastguard Worker sin_ptr[i + 3], cos_ptr[i + 3]);
161*15dc779aSAndroid Build Coastguard Worker out += 8;
162*15dc779aSAndroid Build Coastguard Worker out_ptr -= 8;
163*15dc779aSAndroid Build Coastguard Worker }
164*15dc779aSAndroid Build Coastguard Worker }
165*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_mdct(WORD32 * ptr_in,WORD32 * ptr_out,WORD32 * preshift,WORD32 length,WORD32 * ptr_scratch)166*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_acelp_mdct(WORD32 *ptr_in, WORD32 *ptr_out, WORD32 *preshift, WORD32 length,
167*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_scratch) {
168*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_data_r = ptr_scratch;
169*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_data_i = ptr_scratch + 512;
170*15dc779aSAndroid Build Coastguard Worker const WORD32 *ptr_pre_post_twid;
171*15dc779aSAndroid Build Coastguard Worker
172*15dc779aSAndroid Build Coastguard Worker switch (length) {
173*15dc779aSAndroid Build Coastguard Worker case 1024:
174*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_512[0][0];
175*15dc779aSAndroid Build Coastguard Worker break;
176*15dc779aSAndroid Build Coastguard Worker case 768:
177*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_384[0][0];
178*15dc779aSAndroid Build Coastguard Worker break;
179*15dc779aSAndroid Build Coastguard Worker case 512:
180*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_256[0][0];
181*15dc779aSAndroid Build Coastguard Worker break;
182*15dc779aSAndroid Build Coastguard Worker case 384:
183*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_192[0][0];
184*15dc779aSAndroid Build Coastguard Worker break;
185*15dc779aSAndroid Build Coastguard Worker case 256:
186*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_128[0][0];
187*15dc779aSAndroid Build Coastguard Worker break;
188*15dc779aSAndroid Build Coastguard Worker case 192:
189*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_96[0][0];
190*15dc779aSAndroid Build Coastguard Worker break;
191*15dc779aSAndroid Build Coastguard Worker case 128:
192*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_64[0][0];
193*15dc779aSAndroid Build Coastguard Worker break;
194*15dc779aSAndroid Build Coastguard Worker case 96:
195*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_48[0][0];
196*15dc779aSAndroid Build Coastguard Worker break;
197*15dc779aSAndroid Build Coastguard Worker case 64:
198*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_32[0][0];
199*15dc779aSAndroid Build Coastguard Worker break;
200*15dc779aSAndroid Build Coastguard Worker case 48:
201*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_24[0][0];
202*15dc779aSAndroid Build Coastguard Worker break;
203*15dc779aSAndroid Build Coastguard Worker default:
204*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid = &ixheaacd_pre_post_twid_cos_sin_24[0][0];
205*15dc779aSAndroid Build Coastguard Worker break;
206*15dc779aSAndroid Build Coastguard Worker }
207*15dc779aSAndroid Build Coastguard Worker
208*15dc779aSAndroid Build Coastguard Worker ixheaacd_pre_twid(ptr_in, ptr_data_r, ptr_data_i, length / 2,
209*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid);
210*15dc779aSAndroid Build Coastguard Worker
211*15dc779aSAndroid Build Coastguard Worker ixheaacd_complex_fft(ptr_data_r, ptr_data_i, length / 2, -1, preshift);
212*15dc779aSAndroid Build Coastguard Worker *preshift += 1;
213*15dc779aSAndroid Build Coastguard Worker
214*15dc779aSAndroid Build Coastguard Worker ixheaacd_post_twid(ptr_data_r, ptr_data_i, ptr_out, length / 2,
215*15dc779aSAndroid Build Coastguard Worker ptr_pre_post_twid);
216*15dc779aSAndroid Build Coastguard Worker *preshift += 1;
217*15dc779aSAndroid Build Coastguard Worker return;
218*15dc779aSAndroid Build Coastguard Worker }
219*15dc779aSAndroid Build Coastguard Worker
ixheaacd_acelp_mdct_main(ia_usac_data_struct * usac_data,WORD32 * in,WORD32 * out,WORD32 l,WORD32 m,WORD32 * preshift)220*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_acelp_mdct_main(ia_usac_data_struct *usac_data, WORD32 *in, WORD32 *out, WORD32 l,
221*15dc779aSAndroid Build Coastguard Worker WORD32 m, WORD32 *preshift) {
222*15dc779aSAndroid Build Coastguard Worker WORD32 i;
223*15dc779aSAndroid Build Coastguard Worker WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
224*15dc779aSAndroid Build Coastguard Worker WORD32 *output_buffer = &usac_data->x_ac_dec[0];
225*15dc779aSAndroid Build Coastguard Worker
226*15dc779aSAndroid Build Coastguard Worker ixheaacd_acelp_mdct(in, output_buffer, preshift, l + m, ptr_scratch);
227*15dc779aSAndroid Build Coastguard Worker
228*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < m / 2; i++) {
229*15dc779aSAndroid Build Coastguard Worker out[l + m / 2 - 1 - i] = -output_buffer[m / 2 + l / 2 + i];
230*15dc779aSAndroid Build Coastguard Worker }
231*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < l / 2; i++) {
232*15dc779aSAndroid Build Coastguard Worker out[i] = output_buffer[m + l / 2 + i];
233*15dc779aSAndroid Build Coastguard Worker out[l - 1 - i] = -output_buffer[m + l / 2 + i];
234*15dc779aSAndroid Build Coastguard Worker }
235*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < m / 2; i++) {
236*15dc779aSAndroid Build Coastguard Worker out[l + m / 2 + i] = -output_buffer[m / 2 + l / 2 - 1 - i];
237*15dc779aSAndroid Build Coastguard Worker }
238*15dc779aSAndroid Build Coastguard Worker for (i = 0; i < l / 2; i++) {
239*15dc779aSAndroid Build Coastguard Worker out[l + m + i] = -output_buffer[l / 2 - 1 - i];
240*15dc779aSAndroid Build Coastguard Worker out[2 * l + m - 1 - i] = -output_buffer[l / 2 - 1 - i];
241*15dc779aSAndroid Build Coastguard Worker }
242*15dc779aSAndroid Build Coastguard Worker return;
243*15dc779aSAndroid Build Coastguard Worker }
244