xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_mps_poly_filt.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 "ixheaac_type_def.h"
22*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
23*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_interface.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_common_rom.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_scale.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_env_extr_part.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_rom.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_hybrid.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ps_dec.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_config.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_qmf_dec.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_polyphase.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_struct_def.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_res_rom.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_aac_struct.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_dec.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_function_selector.h"
40*15dc779aSAndroid Build Coastguard Worker 
41*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32
42*15dc779aSAndroid Build Coastguard Worker     ixheaacd_mps_polyphase_filter_coeff[10 * MAX_NUM_QMF_BANDS_SAC / 2];
43*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_mps_post_twid[30];
44*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_mps_pre_twid[64];
45*15dc779aSAndroid Build Coastguard Worker 
46*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_ldmps_polyphase_filter_coeff[1280];
47*15dc779aSAndroid Build Coastguard Worker 
48*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_ldmps_pre_twid[32];
49*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_mps_post_re_32[64];
50*15dc779aSAndroid Build Coastguard Worker extern const FLOAT32 ixheaacd_mps_post_im_32[64];
51*15dc779aSAndroid Build Coastguard Worker 
52*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synt_init(FLOAT32 state[POLY_PHASE_SYNTH_SIZE])53*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synt_init(FLOAT32 state[POLY_PHASE_SYNTH_SIZE]) {
54*15dc779aSAndroid Build Coastguard Worker   memset(state, 0, sizeof(FLOAT32) * POLY_PHASE_SYNTH_SIZE);
55*15dc779aSAndroid Build Coastguard Worker }
56*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synt_post_fft_twiddle_dec(WORD32 resolution,FLOAT32 * fin_re,FLOAT32 * fin_im,const FLOAT32 * table_re,const FLOAT32 * table_im,FLOAT32 * state)57*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synt_post_fft_twiddle_dec(WORD32 resolution, FLOAT32 *fin_re,
58*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *fin_im,
59*15dc779aSAndroid Build Coastguard Worker   const FLOAT32 *table_re,
60*15dc779aSAndroid Build Coastguard Worker   const FLOAT32 *table_im,
61*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *state) {
62*15dc779aSAndroid Build Coastguard Worker   WORD32 l;
63*15dc779aSAndroid Build Coastguard Worker   for (l = 0; l < 2 * resolution; l++) {
64*15dc779aSAndroid Build Coastguard Worker     state[2 * resolution - l - 1] =
65*15dc779aSAndroid Build Coastguard Worker       ((fin_re[l] * table_re[l]) + (fin_im[l] * table_im[l]));
66*15dc779aSAndroid Build Coastguard Worker   }
67*15dc779aSAndroid Build Coastguard Worker }
68*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synt_out_calc_dec(WORD32 resolution,FLOAT32 * out,FLOAT32 * state,const FLOAT32 * filter_coeff)69*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synt_out_calc_dec(WORD32 resolution, FLOAT32 *out,
70*15dc779aSAndroid Build Coastguard Worker                                     FLOAT32 *state,
71*15dc779aSAndroid Build Coastguard Worker                                     const FLOAT32 *filter_coeff) {
72*15dc779aSAndroid Build Coastguard Worker   WORD32 l, k;
73*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *out1, *out2, *state1, *state2;
74*15dc779aSAndroid Build Coastguard Worker   out1 = out;
75*15dc779aSAndroid Build Coastguard Worker   out2 = out + resolution;
76*15dc779aSAndroid Build Coastguard Worker   state1 = state;
77*15dc779aSAndroid Build Coastguard Worker   state2 = state + (3 * resolution);
78*15dc779aSAndroid Build Coastguard Worker 
79*15dc779aSAndroid Build Coastguard Worker   for (k = 0; k < 5; k++) {
80*15dc779aSAndroid Build Coastguard Worker     for (l = 0; l < resolution; l++) {
81*15dc779aSAndroid Build Coastguard Worker       *out1++ = (*state1++) * (*filter_coeff++);
82*15dc779aSAndroid Build Coastguard Worker       *out2++ = (*state2++) * (*filter_coeff++);
83*15dc779aSAndroid Build Coastguard Worker     }
84*15dc779aSAndroid Build Coastguard Worker     out1 += resolution;
85*15dc779aSAndroid Build Coastguard Worker     out2 += resolution;
86*15dc779aSAndroid Build Coastguard Worker     state1 += (3 * resolution);
87*15dc779aSAndroid Build Coastguard Worker     state2 += (3 * resolution);
88*15dc779aSAndroid Build Coastguard Worker   }
89*15dc779aSAndroid Build Coastguard Worker }
90*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synt_out_calc_dec_ldmps(WORD32 resolution,FLOAT32 * out,FLOAT32 * state,const FLOAT32 * filter_coeff)91*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synt_out_calc_dec_ldmps(WORD32 resolution, FLOAT32 *out,
92*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *state, const FLOAT32 *filter_coeff) {
93*15dc779aSAndroid Build Coastguard Worker   WORD32 l, k;
94*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *out1, *out2, *state1, *state2;
95*15dc779aSAndroid Build Coastguard Worker   const FLOAT32 *filter1, *filter2;
96*15dc779aSAndroid Build Coastguard Worker   filter1 = filter_coeff;
97*15dc779aSAndroid Build Coastguard Worker   filter2 = filter_coeff + resolution;
98*15dc779aSAndroid Build Coastguard Worker   out1 = out;
99*15dc779aSAndroid Build Coastguard Worker   out2 = out + resolution;
100*15dc779aSAndroid Build Coastguard Worker   state1 = state;
101*15dc779aSAndroid Build Coastguard Worker   state2 = state + (3 * resolution);
102*15dc779aSAndroid Build Coastguard Worker 
103*15dc779aSAndroid Build Coastguard Worker   for (k = 0; k < 5; k++) {
104*15dc779aSAndroid Build Coastguard Worker     for (l = 0; l < resolution; l++) {
105*15dc779aSAndroid Build Coastguard Worker       *out1++ = (*state1++) * (*filter1++);
106*15dc779aSAndroid Build Coastguard Worker       *out2++ = (*state2++) * (*filter2++);
107*15dc779aSAndroid Build Coastguard Worker     }
108*15dc779aSAndroid Build Coastguard Worker     filter1 += resolution;
109*15dc779aSAndroid Build Coastguard Worker     filter2 += resolution;
110*15dc779aSAndroid Build Coastguard Worker     out1 += resolution;
111*15dc779aSAndroid Build Coastguard Worker     out2 += resolution;
112*15dc779aSAndroid Build Coastguard Worker     state1 += (3 * resolution);
113*15dc779aSAndroid Build Coastguard Worker     state2 += (3 * resolution);
114*15dc779aSAndroid Build Coastguard Worker   }
115*15dc779aSAndroid Build Coastguard Worker }
116*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synt_out_calc_dec_ldmps_32(WORD32 resolution,FLOAT32 * out,FLOAT32 * state,const FLOAT32 * filter_coeff)117*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synt_out_calc_dec_ldmps_32(WORD32 resolution, FLOAT32 *out,
118*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *state, const FLOAT32 *filter_coeff) {
119*15dc779aSAndroid Build Coastguard Worker   WORD32 l, k;
120*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *out1, *out2, *state1, *state2;
121*15dc779aSAndroid Build Coastguard Worker   const FLOAT32 *filter1, *filter2;
122*15dc779aSAndroid Build Coastguard Worker   filter1 = filter_coeff;
123*15dc779aSAndroid Build Coastguard Worker   filter2 = filter_coeff + 2 * resolution;
124*15dc779aSAndroid Build Coastguard Worker   out1 = out;
125*15dc779aSAndroid Build Coastguard Worker   out2 = out + resolution;
126*15dc779aSAndroid Build Coastguard Worker   state1 = state;
127*15dc779aSAndroid Build Coastguard Worker   state2 = state + (3 * resolution);
128*15dc779aSAndroid Build Coastguard Worker 
129*15dc779aSAndroid Build Coastguard Worker   for (k = 0; k < 5; k++) {
130*15dc779aSAndroid Build Coastguard Worker     for (l = 0; l < resolution; l++) {
131*15dc779aSAndroid Build Coastguard Worker       *out1++ = ((*state1++) * (filter1[2*l] + filter1[2*l+1])/2);
132*15dc779aSAndroid Build Coastguard Worker       *out2++ = ((*state2++) *  (filter2[2 * l] + filter2[2 * l + 1])/2);
133*15dc779aSAndroid Build Coastguard Worker     }
134*15dc779aSAndroid Build Coastguard Worker     filter1 += 4 * resolution;
135*15dc779aSAndroid Build Coastguard Worker     filter2 += 4 * resolution;
136*15dc779aSAndroid Build Coastguard Worker     out1 += resolution;
137*15dc779aSAndroid Build Coastguard Worker     out2 += resolution;
138*15dc779aSAndroid Build Coastguard Worker     state1 += (3 * resolution);
139*15dc779aSAndroid Build Coastguard Worker     state2 += (3 * resolution);
140*15dc779aSAndroid Build Coastguard Worker   }
141*15dc779aSAndroid Build Coastguard Worker }
142*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synth_pre_twidle(FLOAT32 * out_re,FLOAT32 * out_im,FLOAT32 * c_in,WORD32 len)143*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synth_pre_twidle(FLOAT32 *out_re, FLOAT32 *out_im,
144*15dc779aSAndroid Build Coastguard Worker                                    FLOAT32 *c_in, WORD32 len) {
145*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
146*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *c_s = c_in;
147*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_re_s = out_re;
148*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_im_s = out_im;
149*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *c_e = c_in + (len << 1) - 1;
150*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_im_e = out_im + len - 1;
151*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_re_e = out_re + len - 1;
152*15dc779aSAndroid Build Coastguard Worker   const FLOAT32 *prtw = ixheaacd_mps_pre_twid;
153*15dc779aSAndroid Build Coastguard Worker 
154*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < len; i += 4) {
155*15dc779aSAndroid Build Coastguard Worker     *p_re_s = ((*c_s++) * (*prtw));
156*15dc779aSAndroid Build Coastguard Worker     p_re_s++;
157*15dc779aSAndroid Build Coastguard Worker     *p_im_s = -((*c_s--) * (*prtw));
158*15dc779aSAndroid Build Coastguard Worker     p_im_s++;
159*15dc779aSAndroid Build Coastguard Worker     *p_im_s = ((*c_e--) * (*prtw));
160*15dc779aSAndroid Build Coastguard Worker     p_im_s--;
161*15dc779aSAndroid Build Coastguard Worker     *p_re_s = ((*c_e++) * (*prtw++));
162*15dc779aSAndroid Build Coastguard Worker     p_re_s--;
163*15dc779aSAndroid Build Coastguard Worker     *p_im_s += ((*c_e--) * (*prtw));
164*15dc779aSAndroid Build Coastguard Worker     p_im_s++;
165*15dc779aSAndroid Build Coastguard Worker     *p_re_s += ((*c_e--) * (*prtw));
166*15dc779aSAndroid Build Coastguard Worker     p_re_s++;
167*15dc779aSAndroid Build Coastguard Worker     *p_re_s -= ((*c_s++) * (*prtw));
168*15dc779aSAndroid Build Coastguard Worker     p_re_s++;
169*15dc779aSAndroid Build Coastguard Worker     *p_im_s += ((*c_s++) * (*prtw++));
170*15dc779aSAndroid Build Coastguard Worker     p_im_s++;
171*15dc779aSAndroid Build Coastguard Worker     *p_im_e = ((*c_e--) * (*prtw));
172*15dc779aSAndroid Build Coastguard Worker     p_im_e--;
173*15dc779aSAndroid Build Coastguard Worker     *p_re_e = -((*c_e++) * (*prtw));
174*15dc779aSAndroid Build Coastguard Worker     p_re_e--;
175*15dc779aSAndroid Build Coastguard Worker     *p_re_e = ((*c_s++) * (*prtw));
176*15dc779aSAndroid Build Coastguard Worker     p_re_e++;
177*15dc779aSAndroid Build Coastguard Worker     *p_im_e = ((*c_s--) * (*prtw++));
178*15dc779aSAndroid Build Coastguard Worker     p_im_e++;
179*15dc779aSAndroid Build Coastguard Worker     *p_re_e += ((*c_s++) * (*prtw));
180*15dc779aSAndroid Build Coastguard Worker     p_re_e--;
181*15dc779aSAndroid Build Coastguard Worker     *p_im_e += ((*c_s++) * (*prtw));
182*15dc779aSAndroid Build Coastguard Worker     p_im_e--;
183*15dc779aSAndroid Build Coastguard Worker     *p_im_e -= ((*c_e--) * (*prtw));
184*15dc779aSAndroid Build Coastguard Worker     p_im_e--;
185*15dc779aSAndroid Build Coastguard Worker     *p_re_e += ((*c_e--) * (*prtw++));
186*15dc779aSAndroid Build Coastguard Worker     p_re_e--;
187*15dc779aSAndroid Build Coastguard Worker   }
188*15dc779aSAndroid Build Coastguard Worker }
189*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synth_post_twidle(FLOAT32 * state,FLOAT32 * out_re,FLOAT32 * out_im,WORD32 len)190*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synth_post_twidle(FLOAT32 *state, FLOAT32 *out_re,
191*15dc779aSAndroid Build Coastguard Worker                                     FLOAT32 *out_im, WORD32 len) {
192*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
193*15dc779aSAndroid Build Coastguard Worker   {
194*15dc779aSAndroid Build Coastguard Worker     FLOAT32 x_0, x_1, x_2, x_3;
195*15dc779aSAndroid Build Coastguard Worker     FLOAT32 *p_re_e, *p_im_e;
196*15dc779aSAndroid Build Coastguard Worker     const FLOAT32 *potw = ixheaacd_mps_post_twid;
197*15dc779aSAndroid Build Coastguard Worker     FLOAT32 *p_re_s = out_re;
198*15dc779aSAndroid Build Coastguard Worker     FLOAT32 *p_im_s = out_im;
199*15dc779aSAndroid Build Coastguard Worker 
200*15dc779aSAndroid Build Coastguard Worker     p_re_e = p_re_s + (len - 2);
201*15dc779aSAndroid Build Coastguard Worker     p_im_e = p_im_s + (len - 2);
202*15dc779aSAndroid Build Coastguard Worker     x_0 = *p_re_e;
203*15dc779aSAndroid Build Coastguard Worker     x_1 = *(p_re_e + 1);
204*15dc779aSAndroid Build Coastguard Worker     x_2 = *p_im_e;
205*15dc779aSAndroid Build Coastguard Worker     x_3 = *(p_im_e + 1);
206*15dc779aSAndroid Build Coastguard Worker 
207*15dc779aSAndroid Build Coastguard Worker     *(p_re_e + 1) = -*(p_re_s + 1);
208*15dc779aSAndroid Build Coastguard Worker     *(p_im_e + 1) = -*p_im_s;
209*15dc779aSAndroid Build Coastguard Worker     *p_im_s = *(p_im_s + 1);
210*15dc779aSAndroid Build Coastguard Worker 
211*15dc779aSAndroid Build Coastguard Worker     for (i = 5; i < len; i += 4) {
212*15dc779aSAndroid Build Coastguard Worker       FLOAT32 twdr = *potw++;
213*15dc779aSAndroid Build Coastguard Worker       FLOAT32 twdi = *potw++;
214*15dc779aSAndroid Build Coastguard Worker       FLOAT32 tmp;
215*15dc779aSAndroid Build Coastguard Worker 
216*15dc779aSAndroid Build Coastguard Worker       *p_re_e = (x_0 * twdi);
217*15dc779aSAndroid Build Coastguard Worker       *p_re_e += (x_1 * twdr);
218*15dc779aSAndroid Build Coastguard Worker       p_re_e--;
219*15dc779aSAndroid Build Coastguard Worker       p_re_s++;
220*15dc779aSAndroid Build Coastguard Worker       *p_re_s = (x_0 * twdr);
221*15dc779aSAndroid Build Coastguard Worker       *p_re_s -= (x_1 * twdi);
222*15dc779aSAndroid Build Coastguard Worker       p_re_s++;
223*15dc779aSAndroid Build Coastguard Worker       x_1 = *p_re_e--;
224*15dc779aSAndroid Build Coastguard Worker       x_0 = *p_re_e++;
225*15dc779aSAndroid Build Coastguard Worker       *p_re_e = (*p_re_s++ * twdi);
226*15dc779aSAndroid Build Coastguard Worker       *p_re_e += -(*p_re_s * twdr);
227*15dc779aSAndroid Build Coastguard Worker       p_re_e--;
228*15dc779aSAndroid Build Coastguard Worker       tmp = (*p_re_s-- * twdi);
229*15dc779aSAndroid Build Coastguard Worker       *p_re_s = tmp + (*p_re_s * twdr);
230*15dc779aSAndroid Build Coastguard Worker 
231*15dc779aSAndroid Build Coastguard Worker       *p_im_e = -(x_2 * twdr);
232*15dc779aSAndroid Build Coastguard Worker       *p_im_e += (x_3 * twdi);
233*15dc779aSAndroid Build Coastguard Worker       p_im_e--;
234*15dc779aSAndroid Build Coastguard Worker       p_im_s++;
235*15dc779aSAndroid Build Coastguard Worker       *p_im_s = -(x_2 * twdi);
236*15dc779aSAndroid Build Coastguard Worker       *p_im_s -= (x_3 * twdr);
237*15dc779aSAndroid Build Coastguard Worker       p_im_s++;
238*15dc779aSAndroid Build Coastguard Worker       x_3 = *p_im_e--;
239*15dc779aSAndroid Build Coastguard Worker       x_2 = *p_im_e++;
240*15dc779aSAndroid Build Coastguard Worker       *p_im_e = -(*p_im_s++ * twdr);
241*15dc779aSAndroid Build Coastguard Worker       *p_im_e -= (*p_im_s * twdi);
242*15dc779aSAndroid Build Coastguard Worker       p_im_e--;
243*15dc779aSAndroid Build Coastguard Worker       tmp = (*p_im_s-- * twdr);
244*15dc779aSAndroid Build Coastguard Worker       *p_im_s = tmp - (*p_im_s * twdi);
245*15dc779aSAndroid Build Coastguard Worker     }
246*15dc779aSAndroid Build Coastguard Worker 
247*15dc779aSAndroid Build Coastguard Worker     *p_re_e = 0.7071067f * (x_1 + x_0);
248*15dc779aSAndroid Build Coastguard Worker     *p_im_e = 0.7071067f * (x_3 - x_2);
249*15dc779aSAndroid Build Coastguard Worker     *(p_re_s + 1) = -0.7071067f * (x_1 - x_0);
250*15dc779aSAndroid Build Coastguard Worker     *(p_im_s + 1) = -0.7071067f * (x_3 + x_2);
251*15dc779aSAndroid Build Coastguard Worker   }
252*15dc779aSAndroid Build Coastguard Worker 
253*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < len; i++) {
254*15dc779aSAndroid Build Coastguard Worker     state[i] = out_im[i] - out_re[i];
255*15dc779aSAndroid Build Coastguard Worker     state[len + i] = out_im[len - i - 1] + out_re[len - i - 1];
256*15dc779aSAndroid Build Coastguard Worker     state[len - i - 1] = out_im[len - i - 1] - out_re[len - i - 1];
257*15dc779aSAndroid Build Coastguard Worker     state[2 * len - i - 1] = out_im[i] + out_re[i];
258*15dc779aSAndroid Build Coastguard Worker   }
259*15dc779aSAndroid Build Coastguard Worker }
260*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synt_pre_twiddle_dec(FLOAT32 * ptr_in,const FLOAT32 * table,FLOAT32 * fin_re,FLOAT32 * fin_im,WORD32 resolution)261*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synt_pre_twiddle_dec(FLOAT32 *ptr_in, const FLOAT32 *table,
262*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *fin_re, FLOAT32 *fin_im,
263*15dc779aSAndroid Build Coastguard Worker   WORD32 resolution) {
264*15dc779aSAndroid Build Coastguard Worker   WORD32 k;
265*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *c_s = ptr_in;
266*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_re_s = fin_re;
267*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_im_s = fin_im;
268*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *c_e = ptr_in + (resolution << 1) - 1;
269*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_im_e = fin_im + resolution - 1;
270*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *p_re_e = fin_re + resolution - 1;
271*15dc779aSAndroid Build Coastguard Worker 
272*15dc779aSAndroid Build Coastguard Worker   for (k = 0; k < resolution; k += 2) {
273*15dc779aSAndroid Build Coastguard Worker     *p_re_s = (*c_s++) * (*table);
274*15dc779aSAndroid Build Coastguard Worker     *p_im_s = (*c_s) * (*table);
275*15dc779aSAndroid Build Coastguard Worker 
276*15dc779aSAndroid Build Coastguard Worker     *p_re_e = (*c_e--) * (*table);
277*15dc779aSAndroid Build Coastguard Worker     *p_im_e = -(*c_e) * (*table++);
278*15dc779aSAndroid Build Coastguard Worker 
279*15dc779aSAndroid Build Coastguard Worker     *p_re_s += (*c_s--) * (*table);
280*15dc779aSAndroid Build Coastguard Worker     *p_im_s += -(*c_s++) * (*table);
281*15dc779aSAndroid Build Coastguard Worker     p_re_s++;
282*15dc779aSAndroid Build Coastguard Worker     p_im_s++;
283*15dc779aSAndroid Build Coastguard Worker     c_s++;
284*15dc779aSAndroid Build Coastguard Worker 
285*15dc779aSAndroid Build Coastguard Worker     *p_re_e += (*c_e++) * (*table);
286*15dc779aSAndroid Build Coastguard Worker     *p_im_e += (*c_e--) * (*table++);
287*15dc779aSAndroid Build Coastguard Worker     p_re_e--;
288*15dc779aSAndroid Build Coastguard Worker     p_im_e--;
289*15dc779aSAndroid Build Coastguard Worker     c_e--;
290*15dc779aSAndroid Build Coastguard Worker   }
291*15dc779aSAndroid Build Coastguard Worker }
292*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mps_synt_calc(ia_mps_dec_state_struct * self)293*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_mps_synt_calc(ia_mps_dec_state_struct *self) {
294*15dc779aSAndroid Build Coastguard Worker   WORD32 k, l, ts, ch;
295*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *state, *tmp_state, *out;
296*15dc779aSAndroid Build Coastguard Worker   const FLOAT32 *filt_coeff;
297*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *tmp_buf = self->tmp_buf;
298*15dc779aSAndroid Build Coastguard Worker   FLOAT32 fin_re[64] = {0};
299*15dc779aSAndroid Build Coastguard Worker   FLOAT32 fin_im[64] = {0};
300*15dc779aSAndroid Build Coastguard Worker 
301*15dc779aSAndroid Build Coastguard Worker   WORD32 resolution = self->resolution;
302*15dc779aSAndroid Build Coastguard Worker   WORD32 m_resolution = resolution >> 1;
303*15dc779aSAndroid Build Coastguard Worker   const FLOAT32 *ixheaacd_mps_post_re, *ixheaacd_mps_post_im;
304*15dc779aSAndroid Build Coastguard Worker   VOID(*ixheaacd_mps_synt_out_calc_pointer)
305*15dc779aSAndroid Build Coastguard Worker   (WORD32 resolution, FLOAT32 *out, FLOAT32 *state, const FLOAT32 *filter_coeff);
306*15dc779aSAndroid Build Coastguard Worker 
307*15dc779aSAndroid Build Coastguard Worker   if (self->ldmps_config.ldmps_present_flag)
308*15dc779aSAndroid Build Coastguard Worker   {
309*15dc779aSAndroid Build Coastguard Worker     ixheaacd_mps_synt_out_calc_pointer = &ixheaacd_mps_synt_out_calc_dec_ldmps;
310*15dc779aSAndroid Build Coastguard Worker     filt_coeff = ixheaacd_ldmps_polyphase_filter_coeff;
311*15dc779aSAndroid Build Coastguard Worker   }
312*15dc779aSAndroid Build Coastguard Worker   else
313*15dc779aSAndroid Build Coastguard Worker   {
314*15dc779aSAndroid Build Coastguard Worker     ixheaacd_mps_synt_out_calc_pointer = ixheaacd_mps_synt_out_calc;
315*15dc779aSAndroid Build Coastguard Worker     filt_coeff = ixheaacd_mps_polyphase_filter_coeff;
316*15dc779aSAndroid Build Coastguard Worker   }
317*15dc779aSAndroid Build Coastguard Worker   if (self->qmf_band_count == 32)
318*15dc779aSAndroid Build Coastguard Worker   {
319*15dc779aSAndroid Build Coastguard Worker     for (ch = 0; ch < self->out_ch_count; ch++) {
320*15dc779aSAndroid Build Coastguard Worker       tmp_state = self->qmf_filt_state[ch];
321*15dc779aSAndroid Build Coastguard Worker       state = &tmp_buf[self->time_slots * 2 * resolution];
322*15dc779aSAndroid Build Coastguard Worker       memcpy(state, tmp_state, sizeof(FLOAT32) * 18 * resolution);
323*15dc779aSAndroid Build Coastguard Worker       out = &tmp_buf[74 * MAX_NUM_QMF_BANDS_SAC];
324*15dc779aSAndroid Build Coastguard Worker 
325*15dc779aSAndroid Build Coastguard Worker       ixheaacd_mps_post_re = ixheaacd_mps_post_re_32;
326*15dc779aSAndroid Build Coastguard Worker       ixheaacd_mps_post_im = ixheaacd_mps_post_im_32;
327*15dc779aSAndroid Build Coastguard Worker 
328*15dc779aSAndroid Build Coastguard Worker       for (ts = 0; ts < self->time_slots; ts++) {
329*15dc779aSAndroid Build Coastguard Worker 
330*15dc779aSAndroid Build Coastguard Worker         state -= (2 * resolution);
331*15dc779aSAndroid Build Coastguard Worker 
332*15dc779aSAndroid Build Coastguard Worker         ixheaacd_mps_synt_pre_twiddle_dec(&self->qmf_out_dir[ch][ts][0].re,
333*15dc779aSAndroid Build Coastguard Worker             ixheaacd_ldmps_pre_twid, fin_re, fin_im, resolution);
334*15dc779aSAndroid Build Coastguard Worker 
335*15dc779aSAndroid Build Coastguard Worker         for (k = resolution; k < 2 * resolution; k++)
336*15dc779aSAndroid Build Coastguard Worker         {
337*15dc779aSAndroid Build Coastguard Worker           fin_re[k] = 0;
338*15dc779aSAndroid Build Coastguard Worker           fin_im[k] = 0;
339*15dc779aSAndroid Build Coastguard Worker         }
340*15dc779aSAndroid Build Coastguard Worker 
341*15dc779aSAndroid Build Coastguard Worker         ixheaacd_mps_complex_fft(fin_re, fin_im, 2 * resolution);
342*15dc779aSAndroid Build Coastguard Worker 
343*15dc779aSAndroid Build Coastguard Worker         ixheaacd_mps_synt_post_fft_twiddle_dec(resolution, fin_re, fin_im,
344*15dc779aSAndroid Build Coastguard Worker                                               ixheaacd_mps_post_re,
345*15dc779aSAndroid Build Coastguard Worker                                               ixheaacd_mps_post_im, state);
346*15dc779aSAndroid Build Coastguard Worker 
347*15dc779aSAndroid Build Coastguard Worker         ixheaacd_mps_synt_out_calc_dec_ldmps_32(resolution, out, state, filt_coeff);
348*15dc779aSAndroid Build Coastguard Worker 
349*15dc779aSAndroid Build Coastguard Worker         for (k = 0; k < resolution; k++) {
350*15dc779aSAndroid Build Coastguard Worker           FLOAT32 acc = out[k];
351*15dc779aSAndroid Build Coastguard Worker           for (l = 1; l < 10; l++) {
352*15dc779aSAndroid Build Coastguard Worker             acc += out[resolution * l + k];
353*15dc779aSAndroid Build Coastguard Worker           }
354*15dc779aSAndroid Build Coastguard Worker           self->output_buffer[ch][self->qmf_band_count * ts + k] = acc;
355*15dc779aSAndroid Build Coastguard Worker         }
356*15dc779aSAndroid Build Coastguard Worker       }
357*15dc779aSAndroid Build Coastguard Worker       memcpy(tmp_state, state, sizeof(FLOAT32) * 18 * resolution);
358*15dc779aSAndroid Build Coastguard Worker     }
359*15dc779aSAndroid Build Coastguard Worker   }
360*15dc779aSAndroid Build Coastguard Worker   else
361*15dc779aSAndroid Build Coastguard Worker   {
362*15dc779aSAndroid Build Coastguard Worker     for (ch = 0; ch < self->out_ch_count; ch++) {
363*15dc779aSAndroid Build Coastguard Worker       tmp_state = self->qmf_filt_state[ch];
364*15dc779aSAndroid Build Coastguard Worker       state = &tmp_buf[self->time_slots * 2 * resolution];
365*15dc779aSAndroid Build Coastguard Worker       memcpy(state, tmp_state, sizeof(FLOAT32) * 18 * resolution);
366*15dc779aSAndroid Build Coastguard Worker       out = &tmp_buf[74 * MAX_NUM_QMF_BANDS_SAC];
367*15dc779aSAndroid Build Coastguard Worker 
368*15dc779aSAndroid Build Coastguard Worker       for (ts = 0; ts < self->time_slots; ts++) {
369*15dc779aSAndroid Build Coastguard Worker 
370*15dc779aSAndroid Build Coastguard Worker         state -= (2 * resolution);
371*15dc779aSAndroid Build Coastguard Worker 
372*15dc779aSAndroid Build Coastguard Worker         ixheaacd_mps_synth_pre_twidle(
373*15dc779aSAndroid Build Coastguard Worker           fin_re, fin_im, &self->qmf_out_dir[ch][ts][0].re, resolution);
374*15dc779aSAndroid Build Coastguard Worker 
375*15dc779aSAndroid Build Coastguard Worker         ixheaacd_mps_synth_calc_fft(fin_re, fin_im, m_resolution);
376*15dc779aSAndroid Build Coastguard Worker 
377*15dc779aSAndroid Build Coastguard Worker         ixheaacd_mps_synth_post_twidle(state, fin_re, fin_im, resolution);
378*15dc779aSAndroid Build Coastguard Worker         (*ixheaacd_mps_synt_out_calc_pointer)(resolution, out, state, filt_coeff);
379*15dc779aSAndroid Build Coastguard Worker 
380*15dc779aSAndroid Build Coastguard Worker         for (k = 0; k < resolution; k++) {
381*15dc779aSAndroid Build Coastguard Worker           FLOAT32 acc = out[k];
382*15dc779aSAndroid Build Coastguard Worker           for (l = 1; l < 10; l++) {
383*15dc779aSAndroid Build Coastguard Worker             acc += out[resolution * l + k];
384*15dc779aSAndroid Build Coastguard Worker           }
385*15dc779aSAndroid Build Coastguard Worker           self->output_buffer[ch][self->qmf_band_count * ts + k] = acc;
386*15dc779aSAndroid Build Coastguard Worker         }
387*15dc779aSAndroid Build Coastguard Worker       }
388*15dc779aSAndroid Build Coastguard Worker       memcpy(tmp_state, state, sizeof(FLOAT32) * 18 * resolution);
389*15dc779aSAndroid Build Coastguard Worker     }
390*15dc779aSAndroid Build Coastguard Worker   }
391*15dc779aSAndroid Build Coastguard Worker }
392