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