/src/libxaac/encoder/ixheaace_mps_frame_windowing.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * * |
3 | | * Copyright (C) 2023 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 | | |
21 | | #include <stdlib.h> |
22 | | #include <string.h> |
23 | | #include "ixheaac_type_def.h" |
24 | | #include "ixheaac_error_standards.h" |
25 | | #include "ixheaace_error_codes.h" |
26 | | #include "ixheaace_mps_common_fix.h" |
27 | | #include "ixheaace_mps_defines.h" |
28 | | |
29 | | #include "ixheaace_mps_common_define.h" |
30 | | #include "ixheaace_mps_bitstream.h" |
31 | | #include "ixheaace_mps_frame_windowing.h" |
32 | | |
33 | | static IA_ERRORCODE ixheaace_mps_212_frame_window_list_limit( |
34 | | ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 lower_limit, |
35 | 0 | const WORD32 upper_limit) { |
36 | 0 | IA_ERRORCODE error = IA_NO_ERROR; |
37 | 0 | WORD32 list_cnt = 0; |
38 | 0 | for (list_cnt = 0; list_cnt < pstr_frame_win_list->win_list_cnt; list_cnt++) { |
39 | 0 | if (pstr_frame_win_list->dat[list_cnt].slot < lower_limit || |
40 | 0 | pstr_frame_win_list->dat[list_cnt].slot > upper_limit) { |
41 | 0 | if (list_cnt == MAX_NUM_PARAMS - 1) { |
42 | 0 | pstr_frame_win_list->dat[list_cnt].hold = IXHEAACE_MPS_FRAME_WINDOWING_INTP; |
43 | 0 | pstr_frame_win_list->dat[list_cnt].slot = -1; |
44 | 0 | } else { |
45 | 0 | WORD32 param = 0; |
46 | 0 | for (param = list_cnt; param < MAX_NUM_PARAMS - 1; param++) { |
47 | 0 | pstr_frame_win_list->dat[param] = pstr_frame_win_list->dat[param + 1]; |
48 | 0 | } |
49 | 0 | } |
50 | |
|
51 | 0 | pstr_frame_win_list->win_list_cnt--; |
52 | 0 | --list_cnt; |
53 | 0 | } |
54 | 0 | } |
55 | 0 | return error; |
56 | 0 | } |
57 | | |
58 | | static IA_ERRORCODE ixheaace_mps_212_frame_window_list_add( |
59 | | ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 slot, |
60 | 103k | const WORD32 hold) { |
61 | 103k | IA_ERRORCODE error = IA_NO_ERROR; |
62 | | |
63 | 103k | if (pstr_frame_win_list->win_list_cnt >= MAX_NUM_PARAMS) { |
64 | 0 | return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR; |
65 | 103k | } else if (pstr_frame_win_list->win_list_cnt > 0 && |
66 | 103k | pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].slot - slot > 0) { |
67 | 0 | return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR; |
68 | 103k | } else { |
69 | 103k | pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt].hold = hold; |
70 | 103k | pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt].slot = slot; |
71 | 103k | pstr_frame_win_list->win_list_cnt++; |
72 | 103k | } |
73 | 103k | return error; |
74 | 103k | } |
75 | | |
76 | | IA_ERRORCODE |
77 | | ixheaace_mps_212_frame_window_init( |
78 | | ixheaace_mps_pstr_frame_win pstr_frame_win, |
79 | 1.53k | const ixheaace_mps_pstr_frame_win_config pstr_frame_win_config) { |
80 | 1.53k | IA_ERRORCODE error = IA_NO_ERROR; |
81 | 1.53k | WORD32 slot; |
82 | 1.53k | WORD32 time_slots = pstr_frame_win_config->num_time_slots_max; |
83 | 1.53k | pstr_frame_win->frame_keep_flag = pstr_frame_win_config->frame_keep_flag; |
84 | 1.53k | pstr_frame_win->num_time_slots_max = pstr_frame_win_config->num_time_slots_max; |
85 | 1.53k | pstr_frame_win->start_slope = 0; |
86 | 1.53k | pstr_frame_win->start_rect = time_slots >> 1; |
87 | 1.53k | pstr_frame_win->stop_slope = ((3 * time_slots) >> 1) - 1; |
88 | 1.53k | pstr_frame_win->stop_rect = time_slots; |
89 | 26.9k | for (slot = 0; slot<time_slots>> 1; slot++) { |
90 | 25.4k | pstr_frame_win->p_tapper_sync_flt[slot] = (FLOAT32)slot / time_slots; |
91 | 25.4k | } |
92 | 1.53k | pstr_frame_win->p_tapper_sync_flt[time_slots >> 1] = 1.0f; |
93 | 1.53k | pstr_frame_win->taper_syn_len = time_slots >> 1; |
94 | 1.53k | pstr_frame_win->taper_ana_len = pstr_frame_win->start_rect - pstr_frame_win->start_slope; |
95 | 26.9k | for (slot = 0; slot < pstr_frame_win->taper_ana_len; slot++) { |
96 | 25.4k | pstr_frame_win->p_taper_ana_flt[slot] = 1.0f; |
97 | 25.4k | } |
98 | | |
99 | 1.53k | return error; |
100 | 1.53k | } |
101 | | |
102 | | IA_ERRORCODE ixheaace_mps_212_frame_window_get_window( |
103 | | ixheaace_mps_pstr_frame_win pstr_frame_win, WORD32 tr_pos[MAX_NUM_PARAMS], |
104 | | const WORD32 time_slots, ixheaace_mps_framing_info *const pstr_framing_info, |
105 | | FLOAT32 *ptr_window_ana[MAX_NUM_PARAMS], |
106 | 103k | ixheaace_mps_pstr_frame_win_list const pstr_frame_win_list, const WORD32 avoid_keep) { |
107 | 103k | IA_ERRORCODE error = IA_NO_ERROR; |
108 | 103k | WORD32 win_cnt = 0; |
109 | 103k | WORD32 w, ps; |
110 | 103k | WORD32 idx; |
111 | 103k | WORD32 param; |
112 | 103k | WORD32 start_slope = pstr_frame_win->start_slope; |
113 | 103k | WORD32 start_rect = pstr_frame_win->start_rect; |
114 | 103k | WORD32 stop_slope = pstr_frame_win->stop_slope; |
115 | 103k | WORD32 stop_rect = pstr_frame_win->stop_rect; |
116 | 103k | WORD32 taper_ana_len = pstr_frame_win->taper_ana_len; |
117 | 103k | FLOAT32 apply_right_window_gain[MAX_NUM_PARAMS]; |
118 | 103k | FLOAT32 *p_taper_ana = pstr_frame_win->p_taper_ana_flt; |
119 | | |
120 | 103k | if ((time_slots > pstr_frame_win->num_time_slots_max) || (time_slots < 0)) { |
121 | 0 | return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG; |
122 | 0 | } |
123 | | |
124 | 103k | pstr_frame_win_list->win_list_cnt = 0; |
125 | 830k | for (param = 0; param < MAX_NUM_PARAMS; param++) { |
126 | 727k | pstr_frame_win_list->dat[param].slot = -1; |
127 | 727k | pstr_frame_win_list->dat[param].hold = IXHEAACE_MPS_FRAME_WINDOWING_INTP; |
128 | 727k | } |
129 | 103k | memset(apply_right_window_gain, 0, sizeof(apply_right_window_gain)); |
130 | 103k | if (tr_pos[0] <= 0) { |
131 | 103k | win_cnt = 0; |
132 | 103k | error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, time_slots - 1, |
133 | 103k | IXHEAACE_MPS_FRAME_WINDOWING_INTP); |
134 | 103k | if (error) { |
135 | 0 | return error; |
136 | 0 | } |
137 | 103k | for (idx = 0; idx < start_slope; idx++) { |
138 | 0 | ptr_window_ana[win_cnt][idx] = 0.0f; |
139 | 0 | } |
140 | 1.72M | for (idx = 0; idx < taper_ana_len; idx++) { |
141 | 1.62M | ptr_window_ana[win_cnt][start_slope + idx] = p_taper_ana[idx]; |
142 | 1.62M | } |
143 | | |
144 | 1.74M | for (idx = 0; idx < time_slots - start_rect; idx++) { |
145 | 1.64M | ptr_window_ana[win_cnt][start_rect + idx] = 1.0f; |
146 | 1.64M | } |
147 | | |
148 | 103k | apply_right_window_gain[win_cnt] = 1.0f; |
149 | 103k | win_cnt++; |
150 | 103k | } else { |
151 | 0 | WORD32 p_l = tr_pos[0]; |
152 | 0 | win_cnt = 0; |
153 | 0 | error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, p_l - 1, |
154 | 0 | IXHEAACE_MPS_FRAME_WINDOWING_HOLD); |
155 | 0 | if (error) { |
156 | 0 | return error; |
157 | 0 | } |
158 | 0 | error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, p_l, |
159 | 0 | IXHEAACE_MPS_FRAME_WINDOWING_INTP); |
160 | 0 | if (error) { |
161 | 0 | return error; |
162 | 0 | } |
163 | | |
164 | 0 | error = ixheaace_mps_212_frame_window_list_limit(pstr_frame_win_list, 0, time_slots - 1); |
165 | 0 | if (error) { |
166 | 0 | return error; |
167 | 0 | } |
168 | | |
169 | 0 | error = ixheaace_mps_212_frame_window_list_add(pstr_frame_win_list, time_slots - 1, |
170 | 0 | IXHEAACE_MPS_FRAME_WINDOWING_HOLD); |
171 | 0 | if (error) { |
172 | 0 | return error; |
173 | 0 | } |
174 | | |
175 | 0 | if (pstr_frame_win_list->win_list_cnt > MAX_NUM_PARAMS) { |
176 | 0 | return IA_EXHEAACE_CONFIG_NONFATAL_MPS_INVALID_CONFIG; |
177 | 0 | } |
178 | 0 | for (ps = 0; ps < pstr_frame_win_list->win_list_cnt - 1; ps++) { |
179 | 0 | if (IXHEAACE_MPS_FRAME_WINDOWING_HOLD != pstr_frame_win_list->dat[ps].hold) { |
180 | 0 | WORD32 start = pstr_frame_win_list->dat[ps].slot; |
181 | 0 | WORD32 stop = pstr_frame_win_list->dat[ps + 1].slot; |
182 | |
|
183 | 0 | for (idx = 0; idx < start; idx++) { |
184 | 0 | ptr_window_ana[win_cnt][idx] = 0.0f; |
185 | 0 | } |
186 | 0 | for (idx = 0; idx < stop - start + 1; idx++) { |
187 | 0 | ptr_window_ana[win_cnt][start + idx] = 1.0f; |
188 | 0 | } |
189 | 0 | for (idx = 0; idx < time_slots - stop - 1; idx++) { |
190 | 0 | ptr_window_ana[win_cnt][stop + 1 + idx] = 0.0f; |
191 | 0 | } |
192 | |
|
193 | 0 | apply_right_window_gain[win_cnt] = ptr_window_ana[win_cnt][time_slots - 1]; |
194 | 0 | win_cnt++; |
195 | 0 | } |
196 | 0 | } |
197 | |
|
198 | 0 | if (pstr_frame_win_list->win_list_cnt - 1 < 0 || |
199 | 0 | pstr_frame_win_list->win_list_cnt - 1 >= MAX_NUM_PARAMS) { |
200 | 0 | return IA_EXHEAACE_CONFIG_NONFATAL_MPS_PARAM_ERROR; |
201 | 0 | } else if (pstr_frame_win_list->win_list_cnt > 0) { |
202 | 0 | if (pstr_frame_win_list->win_list_cnt - 1 == MAX_NUM_PARAMS - 1) { |
203 | 0 | pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].slot = -1; |
204 | 0 | pstr_frame_win_list->dat[pstr_frame_win_list->win_list_cnt - 1].hold = |
205 | 0 | IXHEAACE_MPS_FRAME_WINDOWING_INTP; |
206 | 0 | } else { |
207 | 0 | for (param = pstr_frame_win_list->win_list_cnt - 1; param < MAX_NUM_PARAMS - 1; param++) { |
208 | 0 | pstr_frame_win_list->dat[param] = pstr_frame_win_list->dat[param + 1]; |
209 | 0 | } |
210 | 0 | } |
211 | 0 | pstr_frame_win_list->win_list_cnt--; |
212 | 0 | } |
213 | 0 | if (error) { |
214 | 0 | return error; |
215 | 0 | } |
216 | 0 | } |
217 | | |
218 | 207k | for (w = 0; w < win_cnt; w++) { |
219 | 103k | if (apply_right_window_gain[w] <= 0) { |
220 | 0 | for (idx = 0; idx < time_slots; idx++) { |
221 | 0 | ptr_window_ana[w][time_slots + idx] = 0.0f; |
222 | 0 | } |
223 | 103k | } else { |
224 | 103k | if (tr_pos[1] < 0) { |
225 | 207k | for (idx = 0; idx < stop_rect - time_slots + 1; idx++) { |
226 | 103k | ptr_window_ana[w][time_slots + idx] = 1.0f; |
227 | 103k | } |
228 | 1.72M | for (idx = 0; idx < taper_ana_len; idx++) { |
229 | 1.62M | ptr_window_ana[w][stop_rect + idx] = p_taper_ana[taper_ana_len - 1 - idx]; |
230 | 1.62M | } |
231 | 1.74M | for (idx = 0; idx < 2 * time_slots - stop_slope - 1; idx++) { |
232 | 1.64M | ptr_window_ana[w][stop_slope + 1 + idx] = 0.0f; |
233 | 1.64M | } |
234 | 103k | } else { |
235 | 0 | WORD32 p_r = tr_pos[1]; |
236 | 0 | for (idx = 0; idx < p_r - time_slots; idx++) { |
237 | 0 | ptr_window_ana[w][time_slots + idx] = 1.0f; |
238 | 0 | } |
239 | 0 | for (idx = 0; idx < 2 * time_slots - p_r; idx++) { |
240 | 0 | ptr_window_ana[w][p_r + idx] = 0.0f; |
241 | 0 | } |
242 | 0 | } |
243 | 103k | if (apply_right_window_gain[w] < 1.0f) { |
244 | 0 | WORD32 slot; |
245 | 0 | for (slot = 0; slot < time_slots; slot++) { |
246 | 0 | ptr_window_ana[w][time_slots + slot] = |
247 | 0 | ptr_window_ana[w][time_slots + slot] * apply_right_window_gain[w]; |
248 | 0 | } |
249 | 0 | } |
250 | 103k | } |
251 | 103k | } |
252 | 103k | if (pstr_frame_win->frame_keep_flag == 1) { |
253 | 3.37M | for (idx = 0; idx < time_slots; idx++) { |
254 | 3.26M | ptr_window_ana[0][2 * time_slots + idx] = ptr_window_ana[0][time_slots + idx]; |
255 | 3.26M | ptr_window_ana[0][time_slots + idx] = ptr_window_ana[0][idx]; |
256 | 3.26M | } |
257 | 103k | if (avoid_keep == 0) { |
258 | 1.82M | for (idx = 0; idx < time_slots; idx++) { |
259 | 1.76M | ptr_window_ana[0][idx] = 1.0f; |
260 | 1.76M | } |
261 | 55.5k | } else { |
262 | 1.54M | for (idx = 0; idx < time_slots; idx++) { |
263 | 1.50M | ptr_window_ana[0][idx] = 0.0f; |
264 | 1.50M | } |
265 | 48.3k | } |
266 | 103k | } |
267 | 103k | pstr_framing_info->num_param_sets = pstr_frame_win_list->win_list_cnt; |
268 | 103k | pstr_framing_info->bs_framing_type = 1; |
269 | 207k | for (ps = 0; ps < pstr_framing_info->num_param_sets; ps++) { |
270 | 103k | pstr_framing_info->bs_param_slots[ps] = pstr_frame_win_list->dat[ps].slot; |
271 | 103k | } |
272 | 103k | if ((pstr_framing_info->num_param_sets == 1) && |
273 | 103k | (pstr_framing_info->bs_param_slots[0] == time_slots - 1)) { |
274 | 103k | pstr_framing_info->bs_framing_type = 0; |
275 | 103k | } |
276 | 103k | return error; |
277 | 103k | } |
278 | | |
279 | | VOID ixheaace_mps_212_analysis_windowing( |
280 | | const WORD32 num_time_slots, const WORD32 start_time_slot, FLOAT32 *ptr_window_ana, |
281 | | ixheaace_cmplx_str pp_cmplx_data_in[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS], |
282 | | ixheaace_cmplx_str pp_cmplx_data_out[MAX_ANA_TIME_SLOT][MAX_QMF_BANDS], |
283 | 207k | const WORD32 num_hybrid_bands) { |
284 | 207k | WORD32 band, slot; |
285 | 207k | FLOAT32 win; |
286 | | |
287 | 13.5M | for (slot = start_time_slot; slot < num_time_slots; slot++) { |
288 | 13.3M | win = ptr_window_ana[slot]; |
289 | 13.3M | if (win != 1.0f) { |
290 | 0 | for (band = 0; band < num_hybrid_bands; band++) { |
291 | 0 | pp_cmplx_data_out[slot][band].re = win * pp_cmplx_data_in[slot][band].re; |
292 | 0 | pp_cmplx_data_out[slot][band].im = win * pp_cmplx_data_in[slot][band].im; |
293 | 0 | } |
294 | 13.3M | } else { |
295 | 865M | for (band = 0; band < num_hybrid_bands; band++) { |
296 | 852M | pp_cmplx_data_out[slot][band].re = pp_cmplx_data_in[slot][band].re; |
297 | 852M | pp_cmplx_data_out[slot][band].im = pp_cmplx_data_in[slot][band].im; |
298 | 852M | } |
299 | 13.3M | } |
300 | 13.3M | } |
301 | 207k | } |