xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_fwd_alias_cnx.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 <string.h>
22*15dc779aSAndroid Build Coastguard Worker #include <math.h>
23*15dc779aSAndroid Build Coastguard Worker 
24*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_type_def.h"
25*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_bitbuffer.h"
26*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_interface.h"
27*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_tns_usac.h"
28*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_cnst.h"
29*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_info.h"
30*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_td_mdct.h"
31*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecsettings.h"
32*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_info.h"
33*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbr_common.h"
34*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_data_struct.h"
35*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_drc_dec.h"
36*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_sbrdecoder.h"
37*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_mps_polyphase.h"
38*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_sbr_const.h"
39*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_defines.h"
40*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_ec_struct_def.h"
41*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_main.h"
42*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_arith_dec.h"
43*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_windows.h"
44*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_constants.h"
45*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops32.h"
46*15dc779aSAndroid Build Coastguard Worker #include "ixheaac_basic_ops40.h"
47*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_func_def.h"
48*15dc779aSAndroid Build Coastguard Worker #include "ixheaacd_acelp_com.h"
49*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_mult32_m(WORD32 a,WORD32 b)50*15dc779aSAndroid Build Coastguard Worker static PLATFORM_INLINE WORD32 ixheaacd_mult32_m(WORD32 a, WORD32 b) {
51*15dc779aSAndroid Build Coastguard Worker   WORD32 result;
52*15dc779aSAndroid Build Coastguard Worker   WORD64 temp_result;
53*15dc779aSAndroid Build Coastguard Worker 
54*15dc779aSAndroid Build Coastguard Worker   temp_result = (WORD64)a * (WORD64)b;
55*15dc779aSAndroid Build Coastguard Worker   result = (WORD32)(temp_result >> 31);
56*15dc779aSAndroid Build Coastguard Worker 
57*15dc779aSAndroid Build Coastguard Worker   return (result);
58*15dc779aSAndroid Build Coastguard Worker }
59*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_weighted_synthesis_filter(WORD32 * a,WORD32 * ap)60*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_weighted_synthesis_filter(WORD32 *a, WORD32 *ap) {
61*15dc779aSAndroid Build Coastguard Worker   WORD32 f;
62*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
63*15dc779aSAndroid Build Coastguard Worker   ap[0] = a[0];
64*15dc779aSAndroid Build Coastguard Worker   f = IGAMMA1;
65*15dc779aSAndroid Build Coastguard Worker   for (i = 1; i <= ORDER; i++) {
66*15dc779aSAndroid Build Coastguard Worker     ap[i] = ixheaacd_mult32_m(f, a[i]);
67*15dc779aSAndroid Build Coastguard Worker     f = ixheaacd_mult32_m(f, IGAMMA1);
68*15dc779aSAndroid Build Coastguard Worker   }
69*15dc779aSAndroid Build Coastguard Worker   return;
70*15dc779aSAndroid Build Coastguard Worker }
71*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_synthesis_tool(WORD32 a[],WORD32 x[],WORD32 l,WORD32 qshift,WORD32 * preshift)72*15dc779aSAndroid Build Coastguard Worker static VOID ixheaacd_synthesis_tool(WORD32 a[], WORD32 x[], WORD32 l,
73*15dc779aSAndroid Build Coastguard Worker                                     WORD32 qshift, WORD32 *preshift) {
74*15dc779aSAndroid Build Coastguard Worker   WORD32 s;
75*15dc779aSAndroid Build Coastguard Worker   WORD32 i, j;
76*15dc779aSAndroid Build Coastguard Worker 
77*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < l; i++) {
78*15dc779aSAndroid Build Coastguard Worker     s = x[i];
79*15dc779aSAndroid Build Coastguard Worker     for (j = 1; j <= ORDER; j += 4) {
80*15dc779aSAndroid Build Coastguard Worker       s = ixheaac_sub32_sat(
81*15dc779aSAndroid Build Coastguard Worker           s, ixheaac_mul32_sh(a[j], x[i - j], (WORD8)(qshift)));
82*15dc779aSAndroid Build Coastguard Worker       s = ixheaac_sub32_sat(
83*15dc779aSAndroid Build Coastguard Worker           s, ixheaac_mul32_sh(a[j + 1], x[i - (j + 1)], (WORD8)(qshift)));
84*15dc779aSAndroid Build Coastguard Worker       s = ixheaac_sub32_sat(
85*15dc779aSAndroid Build Coastguard Worker           s, ixheaac_mul32_sh(a[j + 2], x[i - (j + 2)], (WORD8)(qshift)));
86*15dc779aSAndroid Build Coastguard Worker       s = ixheaac_sub32_sat(
87*15dc779aSAndroid Build Coastguard Worker           s, ixheaac_mul32_sh(a[j + 3], x[i - (j + 3)], (WORD8)(qshift)));
88*15dc779aSAndroid Build Coastguard Worker     }
89*15dc779aSAndroid Build Coastguard Worker     x[i] = s;
90*15dc779aSAndroid Build Coastguard Worker   }
91*15dc779aSAndroid Build Coastguard Worker 
92*15dc779aSAndroid Build Coastguard Worker   (*preshift)++;
93*15dc779aSAndroid Build Coastguard Worker   return;
94*15dc779aSAndroid Build Coastguard Worker }
95*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_fwd_alias_cancel_tool(ia_usac_data_struct * usac_data,ia_td_frame_data_struct * pstr_td_frame_data,WORD32 fac_length,FLOAT32 * lp_filt_coeff,WORD32 gain)96*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_fwd_alias_cancel_tool(
97*15dc779aSAndroid Build Coastguard Worker     ia_usac_data_struct *usac_data, ia_td_frame_data_struct *pstr_td_frame_data,
98*15dc779aSAndroid Build Coastguard Worker     WORD32 fac_length, FLOAT32 *lp_filt_coeff, WORD32 gain) {
99*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
100*15dc779aSAndroid Build Coastguard Worker   FLOAT32 lp_filt_coeff_a[ORDER + 1];
101*15dc779aSAndroid Build Coastguard Worker   WORD32 qshift = 0;
102*15dc779aSAndroid Build Coastguard Worker 
103*15dc779aSAndroid Build Coastguard Worker   WORD32 *x_in = pstr_td_frame_data->fac_data;
104*15dc779aSAndroid Build Coastguard Worker   WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
105*15dc779aSAndroid Build Coastguard Worker   WORD32 *fac_signal = &usac_data->x_ac_dec[16];
106*15dc779aSAndroid Build Coastguard Worker   FLOAT32 fac_signal_flt[128 + 16];
107*15dc779aSAndroid Build Coastguard Worker   FLOAT32 *ptr_fac_signal_flt = &fac_signal_flt[16];
108*15dc779aSAndroid Build Coastguard Worker   WORD32 *ptr_overlap_buf =
109*15dc779aSAndroid Build Coastguard Worker       &(usac_data->overlap_data_ptr[usac_data->present_chan]
110*15dc779aSAndroid Build Coastguard Worker                                    [(usac_data->ccfl / 2) - fac_length]);
111*15dc779aSAndroid Build Coastguard Worker 
112*15dc779aSAndroid Build Coastguard Worker   memset(fac_signal - 16, 0, ORDER * sizeof(WORD32));
113*15dc779aSAndroid Build Coastguard Worker 
114*15dc779aSAndroid Build Coastguard Worker   ixheaacd_acelp_mdct(x_in, fac_signal, &qshift, fac_length, ptr_scratch);
115*15dc779aSAndroid Build Coastguard Worker 
116*15dc779aSAndroid Build Coastguard Worker   ixheaacd_lpc_coeff_wt_apply(lp_filt_coeff, lp_filt_coeff_a);
117*15dc779aSAndroid Build Coastguard Worker 
118*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < fac_length; i++)
119*15dc779aSAndroid Build Coastguard Worker     ptr_fac_signal_flt[i] =
120*15dc779aSAndroid Build Coastguard Worker         (FLOAT32)((FLOAT32)fac_signal[i] / (1 << (16 - qshift)));
121*15dc779aSAndroid Build Coastguard Worker 
122*15dc779aSAndroid Build Coastguard Worker   memset(ptr_fac_signal_flt - 16, 0, 16 * sizeof(FLOAT32));
123*15dc779aSAndroid Build Coastguard Worker 
124*15dc779aSAndroid Build Coastguard Worker   ixheaacd_synthesis_tool_float1(lp_filt_coeff_a, ptr_fac_signal_flt,
125*15dc779aSAndroid Build Coastguard Worker                                  fac_length);
126*15dc779aSAndroid Build Coastguard Worker 
127*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < fac_length; i++)
128*15dc779aSAndroid Build Coastguard Worker     fac_signal[i] = (WORD32)(ptr_fac_signal_flt[i] * (1 << (16 - qshift)));
129*15dc779aSAndroid Build Coastguard Worker 
130*15dc779aSAndroid Build Coastguard Worker   for (i = 0; i < fac_length; i++)
131*15dc779aSAndroid Build Coastguard Worker     ptr_overlap_buf[i] = ixheaac_add32_sat(
132*15dc779aSAndroid Build Coastguard Worker         ptr_overlap_buf[i],
133*15dc779aSAndroid Build Coastguard Worker         (WORD32)ixheaac_mul32_sh(fac_signal[i], gain, (WORD8)(16 - qshift)));
134*15dc779aSAndroid Build Coastguard Worker 
135*15dc779aSAndroid Build Coastguard Worker   return;
136*15dc779aSAndroid Build Coastguard Worker }
137*15dc779aSAndroid Build Coastguard Worker 
ixheaacd_fr_alias_cnx_fix(WORD32 * x_in,WORD32 len,WORD32 fac_length,WORD32 * lp_filt_coeff,WORD32 * izir,WORD32 * fac_data_out,WORD8 * qshift1,WORD8 qshift2,WORD8 qshift3,WORD32 * preshift,WORD32 * ptr_scratch)138*15dc779aSAndroid Build Coastguard Worker VOID ixheaacd_fr_alias_cnx_fix(WORD32 *x_in, WORD32 len, WORD32 fac_length,
139*15dc779aSAndroid Build Coastguard Worker                                  WORD32 *lp_filt_coeff, WORD32 *izir,
140*15dc779aSAndroid Build Coastguard Worker                                  WORD32 *fac_data_out, WORD8 *qshift1,
141*15dc779aSAndroid Build Coastguard Worker                                  WORD8 qshift2, WORD8 qshift3, WORD32 *preshift,
142*15dc779aSAndroid Build Coastguard Worker                                  WORD32 *ptr_scratch) {
143*15dc779aSAndroid Build Coastguard Worker   WORD32 i;
144*15dc779aSAndroid Build Coastguard Worker   const WORD32 *sine_window;
145*15dc779aSAndroid Build Coastguard Worker   WORD32 fac_window[2 * FAC_LENGTH];
146*15dc779aSAndroid Build Coastguard Worker   WORD32 lp_filt_coeff_a[ORDER + 1];
147*15dc779aSAndroid Build Coastguard Worker 
148*15dc779aSAndroid Build Coastguard Worker   if (fac_length == 48) {
149*15dc779aSAndroid Build Coastguard Worker     sine_window = ixheaacd_sine_win_96;
150*15dc779aSAndroid Build Coastguard Worker   } else if (fac_length == 64) {
151*15dc779aSAndroid Build Coastguard Worker     sine_window = ixheaacd_sine_win_128;
152*15dc779aSAndroid Build Coastguard Worker   } else if (fac_length == 96) {
153*15dc779aSAndroid Build Coastguard Worker     sine_window = ixheaacd_sine_win_192;
154*15dc779aSAndroid Build Coastguard Worker   } else {
155*15dc779aSAndroid Build Coastguard Worker     sine_window = ixheaacd_sine_win_256;
156*15dc779aSAndroid Build Coastguard Worker   }
157*15dc779aSAndroid Build Coastguard Worker 
158*15dc779aSAndroid Build Coastguard Worker   if (lp_filt_coeff != NULL && fac_data_out != NULL) {
159*15dc779aSAndroid Build Coastguard Worker     memset(fac_data_out - 16, 0, ORDER * sizeof(WORD32));
160*15dc779aSAndroid Build Coastguard Worker     ixheaacd_acelp_mdct(x_in, fac_data_out, preshift, fac_length,
161*15dc779aSAndroid Build Coastguard Worker                               ptr_scratch);
162*15dc779aSAndroid Build Coastguard Worker 
163*15dc779aSAndroid Build Coastguard Worker     ixheaacd_weighted_synthesis_filter(lp_filt_coeff, lp_filt_coeff_a);
164*15dc779aSAndroid Build Coastguard Worker 
165*15dc779aSAndroid Build Coastguard Worker     memset(fac_data_out + fac_length, 0, fac_length * sizeof(WORD32));
166*15dc779aSAndroid Build Coastguard Worker 
167*15dc779aSAndroid Build Coastguard Worker     ixheaacd_synthesis_tool(lp_filt_coeff_a, fac_data_out, 2 * fac_length,
168*15dc779aSAndroid Build Coastguard Worker                             qshift2, preshift);
169*15dc779aSAndroid Build Coastguard Worker 
170*15dc779aSAndroid Build Coastguard Worker     if (izir != NULL) {
171*15dc779aSAndroid Build Coastguard Worker       for (i = 0; i < fac_length; i++) {
172*15dc779aSAndroid Build Coastguard Worker         fac_window[i] = ixheaacd_mult32_m(
173*15dc779aSAndroid Build Coastguard Worker             sine_window[i], sine_window[(2 * fac_length) - 1 - i]);
174*15dc779aSAndroid Build Coastguard Worker         fac_window[fac_length + i] =
175*15dc779aSAndroid Build Coastguard Worker             2147483647 - ixheaacd_mult32_m(sine_window[fac_length + i],
176*15dc779aSAndroid Build Coastguard Worker                                            sine_window[fac_length + i]);
177*15dc779aSAndroid Build Coastguard Worker       }
178*15dc779aSAndroid Build Coastguard Worker       for (i = 0; i < fac_length; i++) {
179*15dc779aSAndroid Build Coastguard Worker         WORD32 temp1;
180*15dc779aSAndroid Build Coastguard Worker         WORD32 temp2;
181*15dc779aSAndroid Build Coastguard Worker 
182*15dc779aSAndroid Build Coastguard Worker         temp1 = ixheaac_mul32_sh(
183*15dc779aSAndroid Build Coastguard Worker             izir[1 + (len / 2) + i], fac_window[fac_length + i],
184*15dc779aSAndroid Build Coastguard Worker             (char)((qshift3 - *qshift1 + 31 + (WORD8)(*preshift))));
185*15dc779aSAndroid Build Coastguard Worker 
186*15dc779aSAndroid Build Coastguard Worker         temp2 = ixheaac_mul32_sh(
187*15dc779aSAndroid Build Coastguard Worker             izir[1 + (len / 2) - 1 - i], fac_window[fac_length - 1 - i],
188*15dc779aSAndroid Build Coastguard Worker             (char)((qshift3 - *qshift1 + 31 + (WORD8)(*preshift))));
189*15dc779aSAndroid Build Coastguard Worker 
190*15dc779aSAndroid Build Coastguard Worker         fac_data_out[i] =
191*15dc779aSAndroid Build Coastguard Worker             ixheaac_add32_sat3((fac_data_out[i] / 2), temp1, temp2);
192*15dc779aSAndroid Build Coastguard Worker 
193*15dc779aSAndroid Build Coastguard Worker         fac_data_out[fac_length + i] = (fac_data_out[fac_length + i] / 2);
194*15dc779aSAndroid Build Coastguard Worker       }
195*15dc779aSAndroid Build Coastguard Worker     }
196*15dc779aSAndroid Build Coastguard Worker   }
197*15dc779aSAndroid Build Coastguard Worker 
198*15dc779aSAndroid Build Coastguard Worker   return;
199*15dc779aSAndroid Build Coastguard Worker }
200