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