• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <string.h>
21 #include "ixheaacd_type_def.h"
22 #include "ixheaacd_memory_standards.h"
23 #include "ixheaacd_mps_struct_def.h"
24 #include "ixheaacd_mps_res_rom.h"
25 #include "ixheaacd_mps_aac_struct.h"
26 #include "ixheaacd_constants.h"
27 #include "ixheaacd_basic_ops32.h"
28 #include "ixheaacd_basic_ops40.h"
29 #include "ixheaacd_bitbuffer.h"
30 #include "ixheaacd_common_rom.h"
31 #include "ixheaacd_sbrdecsettings.h"
32 #include "ixheaacd_sbr_scale.h"
33 #include "ixheaacd_env_extr_part.h"
34 #include "ixheaacd_sbr_rom.h"
35 #include "ixheaacd_hybrid.h"
36 #include "ixheaacd_ps_dec.h"
37 #include "ixheaacd_mps_polyphase.h"
38 #include "ixheaacd_config.h"
39 #include "ixheaacd_qmf_dec.h"
40 #include "ixheaacd_mps_dec.h"
41 #include "ixheaacd_mps_decor.h"
42 #include "ixheaacd_mps_hybfilter.h"
43 #include "ixheaacd_mps_mdct_2_qmf.h"
44 #include "ixheaacd_mps_get_index.h"
45 #include "ixheaacd_mps_macro_def.h"
46 #include "ixheaacd_mps_basic_op.h"
47 #include "ixheaacd_error_standards.h"
48 
ixheaacd_mdct_2_qmf(ia_heaac_mps_state_struct * pstr_mps_state)49 VOID ixheaacd_mdct_2_qmf(ia_heaac_mps_state_struct *pstr_mps_state) {
50   ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
51   WORD32 ch, rfpsf, qb;
52   WORD32 qmf_global_offset;
53   WORD32 time_slots = pstr_mps_state->time_slots;
54   WORD32 time_slots_x4 = (time_slots << 2);
55   WORD32 qmf_bands = pstr_mps_state->qmf_bands;
56   WORD32 *p_qmf_residual_real_post, *p_qmf_residual_imag_post;
57   VOID *scratch = pstr_mps_state->mps_scratch_mem_v;
58 
59   if (pstr_mps_state->up_mix_type != 2) {
60     WORD32 num_ch = pstr_mps_state->num_ott_boxes + pstr_mps_state->num_ttt_boxes;
61     WORD32 rfpsf_max = pstr_mps_state->residual_frames_per_spatial_frame;
62     WORD32 upd_qmf = pstr_mps_state->upd_qmf;
63 
64     WORD32 *qmf_residual_real_pre = p_array_struct->qmf_residual_real_pre;
65     WORD32 *qmf_residual_real_post = p_array_struct->qmf_residual_real_post;
66 
67     WORD32 *qmf_residual_imag_pre = p_array_struct->qmf_residual_imag_pre;
68     WORD32 *qmf_residual_imag_post = p_array_struct->qmf_residual_imag_post;
69 
70     WORD32 *p_res_mdct = p_array_struct->res_mdct;
71 
72     for (ch = 0; ch < num_ch; ch++) {
73       if (pstr_mps_state->bs_config.bs_residual_present[ch]) {
74         WORD32 *res_mdct = p_res_mdct;
75         qmf_global_offset = 0;
76 
77         p_qmf_residual_real_post = qmf_residual_real_post;
78         p_qmf_residual_imag_post = qmf_residual_imag_post;
79         for (qb = 0; qb < qmf_bands; qb++) {
80           memset(p_qmf_residual_real_post, 0, time_slots_x4);
81           memset(p_qmf_residual_imag_post, 0, time_slots_x4);
82 
83           p_qmf_residual_real_post += MAX_TIME_SLOTS;
84           p_qmf_residual_imag_post += MAX_TIME_SLOTS;
85         }
86 
87         for (rfpsf = 0; rfpsf < rfpsf_max; rfpsf++) {
88           ixheaacd_mdct2qmf_process(upd_qmf, res_mdct, qmf_residual_real_pre,
89                                     qmf_residual_real_post, qmf_residual_imag_pre,
90                                     qmf_residual_imag_post,
91                                     pstr_mps_state->res_block_type[ch][rfpsf], qmf_global_offset,
92                                     &(pstr_mps_state->ia_mps_dec_mps_table), scratch, time_slots);
93           qmf_global_offset += upd_qmf;
94           res_mdct += MDCTCOEFX2;
95         }
96       }
97 
98       qmf_residual_real_pre += QBXTS;
99       qmf_residual_imag_pre += QBXTS;
100 
101       qmf_residual_real_post += QBXTS;
102       qmf_residual_imag_post += QBXTS;
103 
104       p_res_mdct += RFX2XMDCTCOEF;
105     }
106   }
107 
108   if (pstr_mps_state->arbitrary_downmix == 2) {
109     WORD32 arbdmx_upd_qmf = pstr_mps_state->arbdmx_upd_qmf;
110     WORD32 offset = pstr_mps_state->num_ott_boxes + pstr_mps_state->num_ttt_boxes;
111     WORD32 in_ch = pstr_mps_state->num_input_channels;
112     WORD32 rfpsf_max = pstr_mps_state->arbdmx_frames_per_spatial_frame;
113 
114     WORD32 *qmf_residual_real_pre = p_array_struct->qmf_residual_real_pre + offset * QBXTS;
115     WORD32 *qmf_residual_imag_pre = p_array_struct->qmf_residual_imag_pre + offset * QBXTS;
116 
117     WORD32 *qmf_residual_real_post = p_array_struct->qmf_residual_real_post + offset * QBXTS;
118     WORD32 *qmf_residual_imag_post = p_array_struct->qmf_residual_imag_post + offset * QBXTS;
119 
120     WORD32 *p_res_mdct = p_array_struct->res_mdct + offset * RFX2XMDCTCOEF;
121 
122     for (ch = 0; ch < in_ch; ch++) {
123       WORD32 *res_mdct = p_res_mdct;
124       qmf_global_offset = 0;
125 
126       p_qmf_residual_real_post = qmf_residual_real_post;
127       p_qmf_residual_imag_post = qmf_residual_imag_post;
128       for (qb = 0; qb < qmf_bands; qb++) {
129         memset(p_qmf_residual_real_post, 0, time_slots_x4);
130         memset(p_qmf_residual_imag_post, 0, time_slots_x4);
131 
132         p_qmf_residual_real_post += MAX_TIME_SLOTS;
133         p_qmf_residual_imag_post += MAX_TIME_SLOTS;
134       }
135 
136       for (rfpsf = 0; rfpsf < rfpsf_max; rfpsf++) {
137         ixheaacd_mdct2qmf_process(
138             arbdmx_upd_qmf, res_mdct, qmf_residual_real_pre, qmf_residual_real_post,
139             qmf_residual_imag_pre, qmf_residual_imag_post,
140             pstr_mps_state->res_block_type[offset + ch][rfpsf], qmf_global_offset,
141             &(pstr_mps_state->ia_mps_dec_mps_table), scratch, time_slots);
142         qmf_global_offset += arbdmx_upd_qmf;
143         res_mdct += MDCTCOEFX2;
144       }
145 
146       qmf_residual_real_pre += QBXTS;
147       qmf_residual_imag_pre += QBXTS;
148 
149       qmf_residual_imag_post += QBXTS;
150       qmf_residual_real_post += QBXTS;
151 
152       p_res_mdct += RFX2XMDCTCOEF;
153     }
154   }
155   return;
156 }
157 
ixheaacd_hybrid_qmf_analysis(ia_heaac_mps_state_struct * pstr_mps_state)158 VOID ixheaacd_hybrid_qmf_analysis(ia_heaac_mps_state_struct *pstr_mps_state) {
159   WORD32 ch;
160   WORD32 in_ch = pstr_mps_state->num_input_channels;
161   WORD32 num_ott_boxes = pstr_mps_state->num_ott_boxes;
162   WORD32 num_ttt_boxes = pstr_mps_state->num_ttt_boxes;
163   WORD32 num_input_channels = in_ch;
164   WORD32 qmf_bands = pstr_mps_state->qmf_bands;
165   WORD32 time_slots = pstr_mps_state->time_slots;
166   WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
167   WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
168   SIZE_T *kernels = pstr_mps_state->kernels;
169   WORD32 *res_bands = pstr_mps_state->res_bands;
170   WORD32 *index = pstr_mps_state->index;
171 
172   ia_mps_dec_thyb_filter_state_struct *hyb_filter_state =
173       pstr_mps_state->mps_persistent_mem.hyb_filter_state;
174   ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
175 
176   ia_mps_dec_hybrid_tables_struct *hybrid_table_ptr =
177       pstr_mps_state->ia_mps_dec_mps_table.hybrid_table_ptr;
178 
179   WORD32 *p_buf_real = p_array_struct->buf_real;
180   WORD32 *p_buf_imag = p_array_struct->buf_imag;
181 
182   WORD32 *p_x_real = p_array_struct->x_real;
183   WORD32 *p_x_imag = p_array_struct->x_imag;
184 
185   for (ch = 0; ch < in_ch; ch++) {
186     ixheaacd_apply_ana_hyb_filt_bank_create_x(&hyb_filter_state[ch], p_buf_real, p_buf_imag,
187                                               qmf_bands, time_slots, p_x_real, p_x_imag,
188                                               hybrid_table_ptr);
189     pstr_mps_state->index[ch] = hybrid_bands;
190 
191     p_buf_real += TSXHB;
192     p_buf_imag += TSXHB;
193 
194     p_x_real += TSXHB;
195     p_x_imag += TSXHB;
196   }
197 
198   if ((pstr_mps_state->residual_coding) && (pstr_mps_state->up_mix_type != 2)) {
199     WORD32 *qmf_residual_real = p_array_struct->qmf_residual_real_pre;
200     WORD32 *qmf_residual_imag = p_array_struct->qmf_residual_imag_pre;
201 
202     WORD32 *p_dry_real = p_array_struct->w_dry_real;
203     WORD32 *p_dry_imag = p_array_struct->w_dry_imag;
204 
205     for (ch = 0; ch < num_ott_boxes; ch++) {
206       if (res_bands[ch] > 0) {
207         ixheaacd_apply_ana_hyb_filt_bank_merge_res_decor(
208             &hyb_filter_state[ch + num_input_channels], qmf_residual_real, qmf_residual_imag,
209             qmf_bands, time_slots, p_dry_real, p_dry_imag, hybrid_table_ptr);
210       }
211       qmf_residual_real += QBXTS;
212       qmf_residual_imag += QBXTS;
213 
214       p_dry_real += TSXHB;
215       p_dry_imag += TSXHB;
216     }
217 
218     for (ch = num_ott_boxes; ch < num_ott_boxes + num_ttt_boxes; ch++, in_ch++) {
219       if (res_bands[ch] > 0) {
220         ixheaacd_apply_ana_hyb_filt_bank_create_x_res(
221             &hyb_filter_state[ch + num_input_channels], qmf_residual_real, qmf_residual_imag,
222             qmf_bands, time_slots, p_x_real, p_x_imag, kernels, res_bands[ch], hybrid_bands,
223             num_parameter_bands, &index[in_ch], hybrid_table_ptr);
224       } else
225         index[in_ch] = 0;
226 
227       qmf_residual_real += QBXTS;
228       qmf_residual_imag += QBXTS;
229 
230       p_x_real += TSXHB;
231       p_x_imag += TSXHB;
232     }
233   }
234 
235   in_ch = num_input_channels + num_ttt_boxes;
236   if (pstr_mps_state->arbitrary_downmix == 2) {
237     WORD32 offset = num_ott_boxes + num_ttt_boxes;
238 
239     WORD32 *qmf_residual_real = p_array_struct->qmf_residual_real_pre + offset * QBXTS;
240     WORD32 *qmf_residual_imag = p_array_struct->qmf_residual_imag_pre + offset * QBXTS;
241 
242     p_x_real = p_array_struct->x_real + in_ch * TSXHB;
243     p_x_imag = p_array_struct->x_imag + in_ch * TSXHB;
244     for (ch = 0; ch < num_input_channels; ch++, in_ch++) {
245       ixheaacd_apply_ana_hyb_filt_bank_create_x_res(
246           &hyb_filter_state[offset + ch + num_input_channels], qmf_residual_real,
247           qmf_residual_imag, qmf_bands, time_slots, p_x_real, p_x_imag, kernels,
248           pstr_mps_state->arbdmx_residual_bands, hybrid_bands, num_parameter_bands, &index[in_ch],
249           hybrid_table_ptr);
250 
251       qmf_residual_real += QBXTS;
252       qmf_residual_imag += QBXTS;
253 
254       p_x_real += TSXHB;
255       p_x_imag += TSXHB;
256     }
257   }
258 }
259 
ixheaacd_merge_res_decor(ia_heaac_mps_state_struct * pstr_mps_state)260 VOID ixheaacd_merge_res_decor(ia_heaac_mps_state_struct *pstr_mps_state) {
261   WORD32 ts, qs, row, res;
262 
263   WORD32 temp_1;
264   SIZE_T *idx;
265 
266   ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
267   ia_mps_dec_auxilary_struct *p_aux_struct = pstr_mps_state->aux_struct;
268   WORD32 time_slots = pstr_mps_state->time_slots;
269   WORD32 hybrid_bands = pstr_mps_state->hybrid_bands;
270   WORD32 num_direct_signals = pstr_mps_state->num_direct_signals;
271   WORD32 num_w_channels = pstr_mps_state->num_w_channels;
272   WORD32 num_parameter_bands = pstr_mps_state->num_parameter_bands;
273   SIZE_T *kernels_ptr = pstr_mps_state->kernels;
274 
275   WORD32 *p_buf_real, *p_buf_imag, *p_buf_re, *p_buf_im;
276   WORD32 *buf_real_ch4, *buf_imag_ch4;
277   WORD32 *buf_real_ch3, *buf_imag_ch3;
278 
279   p_buf_real = p_array_struct->buffer_real + TSXHBX5;
280   p_buf_imag = p_array_struct->buffer_imag + TSXHBX5;
281 
282   for (ts = 0; ts < time_slots; ts++) {
283     p_buf_re = p_buf_real;
284     p_buf_im = p_buf_imag;
285 
286     buf_real_ch4 = p_buf_real - TSXHB;
287     buf_imag_ch4 = p_buf_imag - TSXHB;
288 
289     buf_real_ch3 = buf_real_ch4 - TSXHB;
290     buf_imag_ch3 = buf_imag_ch4 - TSXHB;
291 
292     for (qs = 0; qs < hybrid_bands; qs++) {
293       if ((kernels_ptr[qs] < ((UWORD32)(p_aux_struct->ttt_config[0][0].stop_band)) &&
294            p_aux_struct->ttt_config[0][0].use_ttt_decorr) ||
295           (kernels_ptr[qs] >= ((UWORD32)p_aux_struct->ttt_config[1][0].start_band) &&
296            p_aux_struct->ttt_config[1][0].use_ttt_decorr)) {
297         temp_1 = (WORD32)ONE_BY_SQRT_TWO_Q30;
298 
299         *p_buf_re = ixheaacd_mps_mult32_shr_30(*p_buf_re, temp_1);
300         *p_buf_re += (*buf_real_ch3 + *buf_real_ch4);
301 
302         *p_buf_im = ixheaacd_mps_mult32_shr_30(*p_buf_im, temp_1);
303         *p_buf_im += (*buf_imag_ch3 + *buf_imag_ch4);
304       }
305       p_buf_re++;
306       p_buf_im++;
307 
308       buf_real_ch4++;
309       buf_imag_ch4++;
310 
311       buf_real_ch3++;
312       buf_imag_ch3++;
313     }
314     p_buf_real += MAX_HYBRID_BANDS;
315     p_buf_imag += MAX_HYBRID_BANDS;
316   }
317 
318   if (pstr_mps_state->residual_coding) {
319     for (row = num_direct_signals; row < num_w_channels; row++) {
320       WORD32 resband;
321       res = ixheaacd_get_res_idx(pstr_mps_state, row);
322       resband = pstr_mps_state->res_bands[res];
323 
324       if (resband == 1 && (num_parameter_bands == 20 || num_parameter_bands == 28))
325         pstr_mps_state->index[res] = 3;
326       else {
327         idx = &kernels_ptr[0];
328         for (qs = 0; qs < hybrid_bands; qs++) {
329           if (*idx++ >= (SIZE_T)resband) {
330             pstr_mps_state->index[res] = qs;
331             qs = hybrid_bands;
332           }
333         }
334       }
335     }
336   }
337 }
338 
ixheaacd_create_w(ia_heaac_mps_state_struct * pstr_mps_state)339 VOID ixheaacd_create_w(ia_heaac_mps_state_struct *pstr_mps_state) {
340   WORD32 k;
341   ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
342   WORD32 num_direct_signals = pstr_mps_state->num_direct_signals;
343   WORD32 counter = num_direct_signals + pstr_mps_state->num_decor_signals;
344   WORD32 time_slots = pstr_mps_state->time_slots;
345   WORD32 offset = num_direct_signals * TSXHB;
346   WORD32 *p_buffer_real = p_array_struct->buf_real + offset;
347   WORD32 *p_buffer_imag = p_array_struct->buf_imag + offset;
348 
349   WORD32 *p_buf_real = p_array_struct->buffer_real + offset;
350   WORD32 *p_buf_imag = p_array_struct->buffer_imag + offset;
351 
352   for (k = num_direct_signals; k < counter; k++) {
353     ixheaacd_decorr_apply(pstr_mps_state, time_slots, p_buffer_real, p_buffer_imag, p_buf_real,
354                           p_buf_imag, k);
355 
356     p_buffer_real += TSXHB;
357     p_buffer_imag += TSXHB;
358 
359     p_buf_real += TSXHB;
360     p_buf_imag += TSXHB;
361   }
362   ixheaacd_merge_res_decor(pstr_mps_state);
363 }
364 
ixheaacd_update_buffers(ia_heaac_mps_state_struct * pstr_mps_state)365 VOID ixheaacd_update_buffers(ia_heaac_mps_state_struct *pstr_mps_state) {
366   ia_mps_dec_reuse_array_struct *p_array_struct = pstr_mps_state->array_struct;
367   WORD32 *temp_addr = p_array_struct->qmf_residual_real_post;
368   p_array_struct->qmf_residual_real_post = p_array_struct->qmf_residual_real_pre;
369   p_array_struct->qmf_residual_real_pre = temp_addr;
370 
371   temp_addr = p_array_struct->qmf_residual_imag_post;
372   p_array_struct->qmf_residual_imag_post = p_array_struct->qmf_residual_imag_pre;
373   p_array_struct->qmf_residual_imag_pre = temp_addr;
374 
375   p_array_struct->buffer_real = p_array_struct->qmf_residual_real_post;
376   p_array_struct->buffer_imag = p_array_struct->qmf_residual_imag_post;
377 
378   p_array_struct->m1_param = (ia_mps_dec_m1_param_struct *)p_array_struct->buffer_real;
379 }
380