xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_mps_res_pns_js_thumb.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 "ixheaac_type_def.h"
21 #include "ixheaac_constants.h"
22 #include "ixheaacd_cnst.h"
23 #include "ixheaac_basic_ops32.h"
24 #include "ixheaac_basic_ops16.h"
25 #include "ixheaacd_bitbuffer.h"
26 #include "ixheaacd_mps_aac_struct.h"
27 #include "ixheaacd_mps_res_rom.h"
28 #include "ixheaacd_mps_res_channelinfo.h"
29 #include "ixheaacd_mps_res_tns.h"
30 
ixheaacd_res_get_maximum_tns_bands(ia_mps_dec_residual_ics_info_struct * p_ics_info,ia_mps_dec_residual_aac_tables_struct * aac_tables_ptr,WORD32 * win_len)31 static PLATFORM_INLINE WORD16 ixheaacd_res_get_maximum_tns_bands(
32     ia_mps_dec_residual_ics_info_struct *p_ics_info,
33     ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr, WORD32 *win_len) {
34   WORD32 i = 0;
35   *win_len = 1;
36 
37   if (p_ics_info->window_sequence == EIGHT_SHORT_SEQUENCE) {
38     *win_len = 8;
39     i = 1;
40   }
41 
42   return aac_tables_ptr->res_block_tables_ptr
43       ->tns_max_bands_tbl[p_ics_info->sampling_rate_index][i];
44 }
45 
ixheaacd_res_tns_decode_coeffs_32x16(const ia_mps_dec_residual_filter_struct * filter,WORD16 * a,ia_mps_dec_residual_aac_tables_struct * aac_tables_ptr)46 VOID ixheaacd_res_tns_decode_coeffs_32x16(const ia_mps_dec_residual_filter_struct *filter,
47                                           WORD16 *a,
48                                           ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr) {
49   WORD tmp;
50   WORD16 *aptr = a;
51   WORD16 *tns_coeff_ptr;
52   WORD8 offset = 4;
53   WORD8 *p_coeff = (WORD8 *)&filter->coeff[0];
54   WORD32 tmp1;
55 
56   tmp = filter->resolution;
57   tns_coeff_ptr = aac_tables_ptr->res_block_tables_ptr->tns_coeff3_16;
58   if (tmp) {
59     tns_coeff_ptr = aac_tables_ptr->res_block_tables_ptr->tns_coeff4_16;
60     offset = offset << 1;
61   }
62   tmp1 = filter->order;
63   do {
64     WORD8 temp = *p_coeff++;
65     *aptr++ = tns_coeff_ptr[temp + offset];
66     tmp1--;
67   } while (tmp1 != 0);
68 }
69 
ixheaacd_res_ctns_apply(ia_mps_dec_residual_channel_info_struct * p_aac_decoder_channel_info,WORD16 max_sfb,ia_mps_dec_residual_aac_tables_struct * aac_tables_ptr)70 VOID ixheaacd_res_ctns_apply(ia_mps_dec_residual_channel_info_struct *p_aac_decoder_channel_info,
71                              WORD16 max_sfb,
72                              ia_mps_dec_residual_aac_tables_struct *aac_tables_ptr) {
73   WORD i;
74   WORD16 scale_lpc;
75 
76   ia_mps_dec_residual_tns_data *p_tns_data = &p_aac_decoder_channel_info->tns_data;
77   WORD32 *p_spectrum = p_aac_decoder_channel_info->p_spectral_coefficient;
78 
79   WORD window, index, start, stop, size, scale_spec;
80   ia_mps_dec_residual_ics_info_struct *p_ics_info = &p_aac_decoder_channel_info->ics_info;
81   WORD win_len, tns_max_bands;
82   WORD16 maximum_bins_short = ixheaac_shr16_dir_sat(p_ics_info->frame_length, 3);
83 
84   WORD32 coeff_parc[MAX_ORDER + 1];
85   WORD32 lpc[MAX_ORDER + 1];
86 
87   const WORD16 *scale_factor_bands_tbl;
88 
89   if (!p_tns_data->tns_data_present) return;
90 
91   tns_max_bands = ixheaacd_res_get_maximum_tns_bands(p_ics_info, aac_tables_ptr, &win_len);
92 
93   scale_factor_bands_tbl =
94       ixheaacd_res_get_sfb_offsets(&p_aac_decoder_channel_info->ics_info, aac_tables_ptr);
95 
96   for (window = 0; window < win_len; window++) {
97     WORD ind_len = p_tns_data->number_of_filters[window];
98 
99     for (index = 0; index < ind_len; index++) {
100       ia_mps_dec_residual_filter_struct *filter = &p_tns_data->filter[window][index];
101 
102       if (filter->order <= 0 || filter->order > MAX_ORDER_LONG) continue;
103 
104       ixheaacd_res_tns_decode_coeffs_32x16(filter, (WORD16 *)coeff_parc, aac_tables_ptr);
105 
106       start = ixheaac_min32(ixheaac_min32(filter->start_band, tns_max_bands), max_sfb);
107 
108       start = scale_factor_bands_tbl[start];
109 
110       stop = ixheaac_min32(ixheaac_min32(filter->stop_band, tns_max_bands), max_sfb);
111 
112       stop = scale_factor_bands_tbl[stop];
113 
114       size = (stop - start);
115       if (size <= 0) continue;
116 
117       ixheaacd_res_tns_parcor_2_lpc_32x16((WORD16 *)coeff_parc, (WORD16 *)lpc, &scale_lpc,
118                                           filter->order);
119       {
120         WORD32 *p_tmp = p_spectrum + (window * maximum_bins_short) + start;
121         scale_spec = ixheaacd_res_calc_max_spectral_line(p_tmp, size);
122       }
123 
124       scale_spec = ((scale_spec - 4) - scale_lpc);
125 
126       if (scale_spec > 0) {
127         WORD shift;
128 
129         scale_spec = ixheaac_min32(scale_spec, 31);
130 
131         if (filter->direction == -1)
132           shift = stop - 1;
133         else
134           shift = start;
135 
136         ixheaacd_res_tns_ar_filter_fixed_32x16(&p_spectrum[(window * maximum_bins_short) + shift],
137                                                size, filter->direction, (WORD16 *)lpc,
138                                                filter->order, (WORD32)scale_lpc, scale_spec);
139       } else {
140         WORD shift;
141         WORD32 *p_tmp = p_spectrum + (window * maximum_bins_short) + start;
142 
143         scale_spec = -scale_spec;
144         scale_spec = ixheaac_min32(scale_spec, 31);
145 
146         for (i = size; i != 0; i--) {
147           *p_tmp = (*p_tmp >> scale_spec);
148           p_tmp++;
149         }
150 
151         if (filter->direction == -1)
152           shift = stop - 1;
153         else
154           shift = start;
155 
156         {
157           WORD32 shift_val = scale_lpc;
158 
159           ixheaacd_res_tns_ar_filter_fixed_32x16(
160               &p_spectrum[(window * maximum_bins_short) + shift], size, filter->direction,
161               (WORD16 *)lpc, filter->order, shift_val, 0);
162         }
163         {
164           p_tmp = p_spectrum + (window * maximum_bins_short) + start;
165           i = size;
166           do {
167             *p_tmp = (*p_tmp << scale_spec);
168             p_tmp++;
169             i--;
170           } while (i != 0);
171         }
172       }
173     }
174   }
175 }
176