xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_pns_js_thumb.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "ixheaacd_sbr_common.h"
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaac_basic_ops32.h"
27 #include "ixheaac_basic_ops16.h"
28 #include "ixheaac_basic_ops40.h"
29 #include "ixheaac_basic_ops.h"
30 
31 #include "ixheaacd_bitbuffer.h"
32 
33 #include "ixheaacd_error_codes.h"
34 #include "ixheaacd_defines.h"
35 #include "ixheaacd_aac_rom.h"
36 #include "ixheaacd_common_rom.h"
37 #include "ixheaacd_basic_funcs.h"
38 #include "ixheaacd_aac_imdct.h"
39 #include "ixheaac_basic_op.h"
40 #include "ixheaacd_intrinsics.h"
41 
42 #include "ixheaacd_pulsedata.h"
43 
44 #include "ixheaacd_pns.h"
45 #include "ixheaacd_drc_data_struct.h"
46 
47 #include "ixheaacd_lt_predict.h"
48 #include "ixheaacd_cnst.h"
49 #include "ixheaacd_ec_defines.h"
50 #include "ixheaacd_ec_struct_def.h"
51 #include "ixheaacd_channelinfo.h"
52 #include "ixheaacd_drc_dec.h"
53 #include "ixheaacd_sbrdecoder.h"
54 #include "ixheaacd_block.h"
55 
56 #include "ixheaacd_channel.h"
57 
58 #include "ixheaacd_audioobjtypes.h"
59 #include "ixheaacd_latmdemux.h"
60 #include "ixheaacd_aacdec.h"
61 #include "ixheaacd_tns.h"
62 #include "ixheaacd_function_selector.h"
63 
ixheaacd_is_correlation(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info,WORD16 pns_band)64 static PLATFORM_INLINE WORD16 ixheaacd_is_correlation(
65     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info, WORD16 pns_band) {
66   ia_pns_correlation_info_struct *ptr_corr_info =
67       ptr_aac_dec_channel_info->pstr_pns_corr_info;
68 
69   return ((ptr_corr_info->correlated[(pns_band >> PNS_BAND_FLAGS_SHIFT)] >>
70            (pns_band & PNS_BAND_FLAGS_MASK)) &
71           1);
72 }
73 
ixheaacd_gen_rand_vec(WORD32 scale,WORD shift,WORD32 * ptr_spec_coef,WORD32 sfb_width,WORD32 * seed)74 VOID ixheaacd_gen_rand_vec(WORD32 scale, WORD shift, WORD32 *ptr_spec_coef,
75                            WORD32 sfb_width, WORD32 *seed) {
76   WORD nrg_scale;
77   WORD32 nrg = 0;
78   WORD32 *spec = ptr_spec_coef;
79   WORD32 sfb;
80 
81   for (sfb = 0; sfb <= sfb_width; sfb++) {
82     *seed = (WORD32)(((WORD64)1664525 * (WORD64)(*seed)) + (WORD64)1013904223);
83 
84     *spec = (*seed >> 3);
85 
86     nrg = ixheaac_add32_sat(nrg, ixheaac_mult32_shl_sat(*spec, *spec));
87 
88     spec++;
89   }
90 
91   nrg_scale = ixheaac_norm32(nrg);
92 
93   if (nrg_scale > 0) {
94     nrg_scale &= ~1;
95     nrg = ixheaac_shl32_sat(nrg, nrg_scale);
96     shift = shift - (nrg_scale >> 1);
97   }
98 
99   nrg = ixheaacd_sqrt(nrg);
100   scale = ixheaac_div32_pos_normb(scale, nrg);
101 
102   spec = ptr_spec_coef;
103 
104   if (shift < -31) {
105     shift = -31;
106   }
107   for (sfb = 0; sfb <= sfb_width; sfb++) {
108     *spec = ixheaac_shr32_dir_sat_limit(ixheaac_mult32_shl_sat(*spec, scale),
109                                          shift);
110     spec++;
111   }
112 }
113 
ixheaacd_pns_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info[],WORD32 channel,ia_aac_dec_tables_struct * ptr_aac_tables)114 VOID ixheaacd_pns_process(
115     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info[], WORD32 channel,
116     ia_aac_dec_tables_struct *ptr_aac_tables) {
117   ia_pns_info_struct *ptr_pns_info =
118       &ptr_aac_dec_channel_info[channel]->str_pns_info;
119   ia_ics_info_struct *ptr_ics_info =
120       &ptr_aac_dec_channel_info[channel]->str_ics_info;
121   WORD16 maximum_bins_short = ptr_ics_info->frame_length >> 3;
122   WORD32 *ptr_scale_mant_tab =
123       ptr_aac_tables->pstr_block_tables->scale_mant_tab;
124 
125   if (ptr_pns_info->pns_active) {
126     const WORD16 *swb_offset =
127         ptr_aac_tables->str_aac_sfb_info[ptr_ics_info->window_sequence]
128             .sfb_index;
129 
130     WORD num_win_group, grp_len, sfb;
131     WORD32 *spec = &ptr_aac_dec_channel_info[channel]->ptr_spec_coeff[0];
132 
133     for (num_win_group = 0; num_win_group < ptr_ics_info->num_window_groups;
134          num_win_group++) {
135       grp_len = ptr_ics_info->window_group_length[num_win_group];
136 
137       for (grp_len = 0;
138            grp_len < ptr_ics_info->window_group_length[num_win_group];
139            grp_len++) {
140         for (sfb = 0; sfb < ptr_ics_info->max_sfb; sfb++) {
141           WORD16 pns_band = ((num_win_group << 4) + sfb);
142 
143           if (ptr_aac_dec_channel_info[channel]
144                   ->str_pns_info.pns_used[pns_band]) {
145             WORD32 scale_mant;
146             WORD32 scale_exp;
147             WORD32 sfb_width = swb_offset[sfb + 1] - swb_offset[sfb] - 1;
148             WORD32 *ptr_spec = &spec[swb_offset[sfb]];
149 
150             scale_mant = ptr_scale_mant_tab[ptr_aac_dec_channel_info[channel]
151                                                 ->ptr_scale_factor[pns_band] &
152                                             PNS_SCALE_MANT_TAB_MASK];
153             scale_exp = add_d(sub_d(31, (ptr_aac_dec_channel_info[channel]
154                                              ->ptr_scale_factor[pns_band] >>
155                                          PNS_SCALEFACTOR_SCALING)),
156                               PNS_SCALE_MANT_TAB_SCALING);
157 
158             if (ixheaacd_is_correlation(ptr_aac_dec_channel_info[LEFT],
159                                         pns_band)) {
160               if (channel == 0) {
161                 ptr_aac_dec_channel_info[LEFT]
162                     ->pstr_pns_corr_info->random_vector[pns_band] =
163                     ptr_aac_dec_channel_info[LEFT]
164                         ->pstr_pns_rand_vec_data->current_seed;
165 
166                 ixheaacd_gen_rand_vec(
167                     scale_mant, scale_exp, ptr_spec, sfb_width,
168                     &(ptr_aac_dec_channel_info[LEFT]
169                           ->pstr_pns_rand_vec_data->current_seed));
170               }
171 
172               else {
173                 ixheaacd_gen_rand_vec(
174                     scale_mant, scale_exp, ptr_spec, sfb_width,
175                     &(ptr_aac_dec_channel_info[LEFT]
176                           ->pstr_pns_corr_info->random_vector[pns_band]));
177               }
178 
179             }
180 
181             else {
182               ixheaacd_gen_rand_vec(
183                   scale_mant, scale_exp, ptr_spec, sfb_width,
184                   &(ptr_aac_dec_channel_info[LEFT]
185                         ->pstr_pns_rand_vec_data->current_seed));
186             }
187           }
188         }
189 
190         if (maximum_bins_short == 120)
191           spec += maximum_bins_short;
192         else
193           spec += 128;
194       }
195     }
196   }
197 
198   if (channel == 0) {
199     ptr_aac_dec_channel_info[0]->pstr_pns_rand_vec_data->pns_frame_number++;
200   }
201 }
202 
ixheaacd_tns_decode_coef(const ia_filter_info_struct * filter,WORD16 * parcor_coef,ia_aac_dec_tables_struct * ptr_aac_tables)203 VOID ixheaacd_tns_decode_coef(const ia_filter_info_struct *filter,
204                               WORD16 *parcor_coef,
205                               ia_aac_dec_tables_struct *ptr_aac_tables) {
206   WORD order, resolution;
207   WORD16 *ptr_par_coef = parcor_coef;
208   WORD16 *tns_coeff_ptr;
209   WORD8 ixheaacd_drc_offset = 4;
210   WORD8 *ptr_coef = (WORD8 *)filter->coef;
211 
212   resolution = filter->resolution;
213   tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3_16;
214 
215   if (resolution) {
216     tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4_16;
217     ixheaacd_drc_offset = ixheaacd_drc_offset << 1;
218   }
219 
220   for (order = 0; order < filter->order; order++) {
221     WORD8 temp = *ptr_coef++;
222     *ptr_par_coef++ = tns_coeff_ptr[temp + ixheaacd_drc_offset];
223   }
224 }
225 
ixheaacd_tns_decode_coef_ld(const ia_filter_info_struct * filter,WORD32 * parcor_coef,ia_aac_dec_tables_struct * ptr_aac_tables)226 VOID ixheaacd_tns_decode_coef_ld(const ia_filter_info_struct *filter,
227                                  WORD32 *parcor_coef,
228                                  ia_aac_dec_tables_struct *ptr_aac_tables) {
229   WORD order, resolution;
230   WORD32 *ptr_par_coef = parcor_coef;
231   WORD32 *tns_coeff_ptr;
232   WORD8 offset = 4;
233   WORD8 *ptr_coef = (WORD8 *)filter->coef;
234 
235   resolution = filter->resolution;
236   tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff3;
237 
238   if (resolution) {
239     tns_coeff_ptr = ptr_aac_tables->pstr_block_tables->tns_coeff4;
240     offset = offset << 1;
241   }
242 
243   for (order = 0; order < filter->order; order++) {
244     WORD8 temp = *ptr_coef++;
245     *ptr_par_coef++ = tns_coeff_ptr[temp + offset];
246   }
247 }
248 
ixheaacd_aac_tns_process(ia_aac_dec_channel_info_struct * ptr_aac_dec_channel_info,WORD32 num_ch,ia_aac_dec_tables_struct * ptr_aac_tables,WORD32 object_type,WORD32 ar_flag,WORD32 * predicted_spectrum)249 VOID ixheaacd_aac_tns_process(
250     ia_aac_dec_channel_info_struct *ptr_aac_dec_channel_info, WORD32 num_ch,
251     ia_aac_dec_tables_struct *ptr_aac_tables, WORD32 object_type,
252     WORD32 ar_flag, WORD32 *predicted_spectrum) {
253   WORD i;
254   WORD16 scale_lpc;
255 
256   ia_tns_info_aac_struct *ptr_tns_info =
257       &ptr_aac_dec_channel_info->str_tns_info;
258   WORD32 *spec = ptr_aac_dec_channel_info->ptr_spec_coeff;
259   WORD32 *scratch_buf = ptr_aac_dec_channel_info->scratch_buf_ptr;
260 
261   WORD win, filt, start, stop, size, scale_spec;
262   ia_ics_info_struct *ptr_ics_info = &ptr_aac_dec_channel_info->str_ics_info;
263   WORD num_window, tns_max_bands, win_seq;
264   WORD16 maximum_bins_short = ptr_ics_info->frame_length >> 3;
265   WORD position;
266 
267   WORD32 parcor_coef[MAX_ORDER + 1];
268   WORD16 parcor_coef_16[MAX_ORDER + 1];
269 
270   WORD32 lpc_coef[MAX_ORDER + 1];
271   WORD16 lpc_coef_16[MAX_ORDER + 1];
272 
273   const WORD16 *ptr_sfb_table;
274 
275   WORD16 max_bin_long = ptr_ics_info->frame_length;
276 
277   win_seq = ptr_ics_info->window_sequence == 0
278                 ? 0
279                 : (ptr_ics_info->window_sequence % 2 == 0);
280 
281   if (ar_flag)
282     spec = ptr_aac_dec_channel_info->ptr_spec_coeff;
283   else {
284     spec = predicted_spectrum;
285   }
286 
287   if (object_type == AOT_ER_AAC_ELD || object_type == AOT_ER_AAC_LD ||
288       object_type == AOT_AAC_LTP) {
289     if (512 == ptr_ics_info->frame_length) {
290       tns_max_bands =
291           ptr_aac_tables->pstr_block_tables
292               ->tns_max_bands_tbl_ld[ptr_ics_info->sampling_rate_index];
293       win_seq = 1;
294       num_window = win_seq;
295     } else if (480 == ptr_ics_info->frame_length) {
296       tns_max_bands =
297           ptr_aac_tables->pstr_block_tables
298               ->tns_max_bands_tbl_480[ptr_ics_info->sampling_rate_index];
299       win_seq = 1;
300       num_window = win_seq;
301     } else {
302       tns_max_bands =
303           ptr_aac_tables->pstr_block_tables
304               ->tns_max_bands_tbl[ptr_ics_info->sampling_rate_index][win_seq];
305 
306       num_window = win_seq ? 8 : 1;
307     }
308   } else {
309     tns_max_bands =
310         ptr_aac_tables->pstr_block_tables
311             ->tns_max_bands_tbl[ptr_ics_info->sampling_rate_index][win_seq];
312 
313     num_window = win_seq ? 8 : 1;
314   }
315 
316   ptr_sfb_table =
317       ptr_aac_tables->str_aac_sfb_info[ptr_ics_info->window_sequence].sfb_index;
318 
319   for (win = 0; win < num_window; win++) {
320     WORD n_filt = ptr_tns_info->n_filt[win];
321 
322     for (filt = 0; filt < n_filt; filt++) {
323       ia_filter_info_struct *filter = &ptr_tns_info->str_filter[win][filt];
324 
325       if (filter->order <= 0) {
326         continue;
327       }
328 
329       if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
330           (num_ch > 2)) {
331         ixheaacd_tns_decode_coefficients(filter, parcor_coef, ptr_aac_tables);
332 
333       } else {
334         ixheaacd_tns_decode_coef(filter, parcor_coef_16, ptr_aac_tables);
335       }
336 
337       start = ixheaac_min32(ixheaac_min32(filter->start_band, tns_max_bands),
338                              ptr_ics_info->max_sfb);
339 
340       start = ptr_sfb_table[start];
341 
342       stop = ixheaac_min32(ixheaac_min32(filter->stop_band, tns_max_bands),
343                             ptr_ics_info->max_sfb);
344 
345       stop = ptr_sfb_table[stop];
346 
347       size = (stop - start);
348 
349       if (size <= 0) {
350         continue;
351       }
352       if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
353           (num_ch > 2)) {
354         ixheaacd_tns_parcor_to_lpc(parcor_coef, lpc_coef, &scale_lpc,
355                                    filter->order);
356 
357       } else {
358         (*ixheaacd_tns_parcor_lpc_convert)(parcor_coef_16, lpc_coef_16,
359                                            &scale_lpc, filter->order);
360       }
361 
362       {
363         WORD32 *ptr_tmp;
364 
365         if (maximum_bins_short == 120)
366           ptr_tmp = spec + (win * maximum_bins_short) + start;
367         else
368           ptr_tmp = spec + (win << 7) + start;
369 
370         scale_spec = (*ixheaacd_calc_max_spectral_line)(ptr_tmp, size);
371       }
372 
373       if (filter->direction == -1) {
374         position = stop - 1;
375 
376         if (maximum_bins_short == 120) {
377           if (((win * maximum_bins_short) + position) < filter->order) continue;
378         } else {
379           if (((win << 7) + position) < filter->order) continue;
380         }
381 
382       } else {
383         position = start;
384         if (maximum_bins_short == 120) {
385           if ((((win * maximum_bins_short) + position) + filter->order) > max_bin_long)
386             continue;
387         } else {
388           if ((((win << 7) + position) + filter->order) > MAX_BINS_LONG) continue;
389         }
390       }
391 
392       if ((num_ch <= 2) &&
393           ((object_type != AOT_ER_AAC_LD) && (object_type != AOT_AAC_LTP)))
394         scale_spec = ((scale_spec - 4) - scale_lpc);
395       else {
396         if (scale_spec > 17)
397           scale_spec = ((scale_spec - 6) - scale_lpc);
398         else if (scale_spec > 11)
399           scale_spec = ((scale_spec - 5) - scale_lpc);
400         else
401           scale_spec = ((scale_spec - 4) - scale_lpc);
402       }
403 
404       if (scale_spec > 0) {
405         scale_spec = ixheaac_min32(scale_spec, 31);
406 
407         if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
408             (num_ch > 2)) {
409           if (ar_flag)
410           {
411             if (maximum_bins_short == 120) {
412               (*ixheaacd_tns_ar_filter_fixed)(&spec[(win * maximum_bins_short) + position],
413                                               size, filter->direction,
414                                               (WORD32 *)lpc_coef, filter->order,
415                                               (WORD32)scale_lpc, scale_spec);
416             } else {
417               (*ixheaacd_tns_ar_filter_fixed)(&spec[(win << 7) + position], size,
418                                               filter->direction,
419                                               (WORD32 *)lpc_coef, filter->order,
420                                               (WORD32)scale_lpc, scale_spec);
421             }
422           } else {
423             if (maximum_bins_short == 120) {
424               ixheaacd_tns_ma_filter_fixed_ld(&spec[(win * maximum_bins_short) + position],
425                                               size, filter->direction, lpc_coef,
426                                               filter->order, scale_lpc);
427             } else {
428               ixheaacd_tns_ma_filter_fixed_ld(&spec[(win << 7) + position], size,
429                                               filter->direction, lpc_coef,
430                                               filter->order, scale_lpc);
431             }
432           }
433         } else {
434           if (object_type == AOT_ER_AAC_ELD) scale_spec = scale_spec - 1;
435           if (maximum_bins_short == 120) {
436             (*ixheaacd_tns_ar_filter)(&spec[(win * maximum_bins_short) + position], size,
437                                       filter->direction, lpc_coef_16,
438                                       filter->order, (WORD32)scale_lpc,
439                                       scale_spec, scratch_buf);
440           } else {
441             (*ixheaacd_tns_ar_filter)(&spec[(win << 7) + position], size,
442                                       filter->direction, lpc_coef_16,
443                                       filter->order, (WORD32)scale_lpc,
444                                       scale_spec, scratch_buf);
445           }
446         }
447       }
448 
449       else {
450         WORD32 *ptr_tmp;
451 
452         if (maximum_bins_short == 120)
453           ptr_tmp = spec + (win * maximum_bins_short) + start;
454         else
455           ptr_tmp = spec + (win >> 7) + start;
456 
457         scale_spec = -scale_spec;
458         scale_spec = ixheaac_min32(scale_spec, 31);
459 
460         for (i = size; i != 0; i--) {
461           *ptr_tmp = (*ptr_tmp >> scale_spec);
462           ptr_tmp++;
463         }
464 
465         if ((object_type == AOT_ER_AAC_LD) || (object_type == AOT_AAC_LTP) ||
466             num_ch > 2) {
467           if (ar_flag) {
468             if (maximum_bins_short == 120) {
469               (*ixheaacd_tns_ar_filter_fixed)(
470                   &spec[(win * maximum_bins_short) + position], size, filter->direction,
471                   (WORD32 *)lpc_coef, filter->order, scale_lpc, 0);
472             } else {
473               (*ixheaacd_tns_ar_filter_fixed)(
474                   &spec[(win << 7) + position], size, filter->direction,
475                   (WORD32 *)lpc_coef, filter->order, scale_lpc, 0);
476             }
477           } else {
478             if (maximum_bins_short == 120) {
479               ixheaacd_tns_ma_filter_fixed_ld(&spec[(win * maximum_bins_short) + position],
480                                               size, filter->direction, lpc_coef,
481                                               filter->order, scale_lpc);
482             } else {
483               ixheaacd_tns_ma_filter_fixed_ld(&spec[(win << 7) + position], size,
484                                               filter->direction, lpc_coef,
485                                               filter->order, scale_lpc);
486             }
487           }
488         } else {
489           if (object_type == AOT_ER_AAC_ELD) {
490             scale_lpc = scale_lpc - 1;
491           }
492 
493           if (maximum_bins_short == 120) {
494             (*ixheaacd_tns_ar_filter)(&spec[(win * maximum_bins_short) + position], size,
495                                       filter->direction, lpc_coef_16,
496                                       filter->order, scale_lpc, 0, scratch_buf);
497           } else {
498             (*ixheaacd_tns_ar_filter)(&spec[(win << 7) + position], size,
499                                       filter->direction, lpc_coef_16,
500                                       filter->order, scale_lpc, 0, scratch_buf);
501           }
502         }
503 
504         if (maximum_bins_short == 120)
505           ptr_tmp = spec + (win * maximum_bins_short) + start;
506         else
507           ptr_tmp = spec + (win << 7) + start;
508 
509         for (i = size; i != 0; i--) {
510           *ptr_tmp = (*ptr_tmp << scale_spec);
511           ptr_tmp++;
512         }
513       }
514     }
515   }
516 }