xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_tns_init.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 
21 #include <math.h>
22 #include <stdlib.h>
23 
24 #include "ixheaac_type_def.h"
25 #include "ixheaac_constants.h"
26 #include "ixheaace_aac_constants.h"
27 #include "ixheaac_error_standards.h"
28 #include "ixheaac_basic_ops32.h"
29 #include "ixheaac_basic_ops16.h"
30 #include "ixheaac_basic_ops40.h"
31 #include "ixheaac_basic_ops.h"
32 
33 #include "ixheaace_common_rom.h"
34 #include "ixheaace_psy_const.h"
35 #include "ixheaace_tns.h"
36 #include "ixheaace_tns_params.h"
37 #include "ixheaace_rom.h"
38 #include "ixheaace_bitbuffer.h"
39 #include "ixheaace_psy_configuration.h"
40 #include "ixheaace_tns_func.h"
41 #include "ixheaace_common_utils.h"
42 
ia_enhaacplus_enc_freq_to_band_with_rounding(WORD32 freq,WORD32 fs,WORD32 num_bands,const WORD32 * ptr_band_start_offset)43 static WORD32 ia_enhaacplus_enc_freq_to_band_with_rounding(WORD32 freq, WORD32 fs,
44                                                            WORD32 num_bands,
45                                                            const WORD32 *ptr_band_start_offset) {
46   WORD32 line_num, band;
47 
48   line_num = (freq * ptr_band_start_offset[num_bands] * 4 / fs + 1) / 2;
49 
50   /* freq > fs/2 */
51   if (line_num >= ptr_band_start_offset[num_bands]) {
52     return num_bands;
53   }
54 
55   /* find band the line number lies in */
56   /* bandStartOffset[] */
57   for (band = 0; band < num_bands; band++) {
58     if (ptr_band_start_offset[band + 1] > line_num) break;
59   }
60 
61   /* round to nearest band border */
62   if (line_num - ptr_band_start_offset[band] > ptr_band_start_offset[band + 1] - line_num) {
63     band++;
64   }
65 
66   return band;
67 }
68 
ia_enhaacplus_enc_calc_gauss_window(FLOAT32 * ptr_win,const WORD16 win_size,const WORD32 sampling_rate,const WORD16 block_type,const FLOAT32 time_resolution)69 static VOID ia_enhaacplus_enc_calc_gauss_window(FLOAT32 *ptr_win, const WORD16 win_size,
70                                                 const WORD32 sampling_rate,
71                                                 const WORD16 block_type,
72                                                 const FLOAT32 time_resolution) {
73   WORD16 i;
74 
75   FLOAT32 accu_gauss_exp;
76   accu_gauss_exp = (sampling_rate * time_resolution) * PI_BY_1000;
77 
78   if (block_type != SHORT_WINDOW) {
79     accu_gauss_exp = (FLOAT32)(accu_gauss_exp / FRAME_LEN_1024);
80   } else {
81     accu_gauss_exp = (FLOAT32)(accu_gauss_exp / FRAME_LEN_SHORT_128);
82   }
83 
84   accu_gauss_exp = -(accu_gauss_exp * 0.5f * accu_gauss_exp);
85 
86   for (i = 0; i < win_size; i++) {
87     ptr_win[i] = (FLOAT32)exp(accu_gauss_exp * (i + 0.5) * (i + 0.5));
88   }
89 }
90 
91 IA_ERRORCODE
ia_enhaacplus_enc_init_tns_configuration(WORD32 bit_rate,WORD32 sample_rate,WORD32 channels,ixheaace_temporal_noise_shaping_config * pstr_tns_config,ixheaace_psy_configuration_long * pstr_psy_config,WORD32 active,ixheaace_temporal_noise_shaping_tables * pstr_tns_tab,WORD32 frame_length,WORD32 aot)92 ia_enhaacplus_enc_init_tns_configuration(WORD32 bit_rate, WORD32 sample_rate, WORD32 channels,
93                                          ixheaace_temporal_noise_shaping_config *pstr_tns_config,
94                                          ixheaace_psy_configuration_long *pstr_psy_config,
95                                          WORD32 active,
96                                          ixheaace_temporal_noise_shaping_tables *pstr_tns_tab,
97                                          WORD32 frame_length, WORD32 aot)
98 
99 {
100   IA_ERRORCODE error;
101   pstr_tns_config->max_order = TEMPORAL_NOISE_SHAPING_MAX_ORDER;
102   pstr_tns_config->tns_start_freq = TEMPORAL_NOISE_SHAPING_START_FREQ;
103   pstr_tns_config->coef_res = TEMPORAL_NOISE_SHAPING_COEF_RES;
104 
105   error = ia_enhaacplus_enc_get_tns_param(&pstr_tns_config->conf_tab, bit_rate / channels,
106                                           channels, LONG_WINDOW, pstr_tns_tab->tns_info_tab,
107                                           sizeof(pstr_tns_tab->tns_info_tab));
108 
109   if (error != IA_NO_ERROR) {
110     return error;
111   }
112 
113   ia_enhaacplus_enc_calc_gauss_window(pstr_tns_config->acf_window_float,
114                                       (const WORD16)(pstr_tns_config->max_order + 1), sample_rate,
115                                       LONG_WINDOW, pstr_tns_config->conf_tab.tns_time_resolution
116 
117   );
118 
119   ia_enhaacplus_enc_get_tns_max_bands(
120       sample_rate, LONG_WINDOW, &pstr_tns_config->tns_max_sfb, pstr_tns_tab->tns_max_bands_table,
121       sizeof(pstr_tns_tab->tns_max_bands_table), aot, frame_length);
122 
123   pstr_tns_config->tns_active = 1;
124 
125   if (active == 0) {
126     pstr_tns_config->tns_active = 0;
127   }
128 
129   /*now calc band and line borders */
130   pstr_tns_config->tns_stop_band = MIN(pstr_psy_config->sfb_cnt, pstr_tns_config->tns_max_sfb);
131 
132   pstr_tns_config->tns_stop_line = pstr_psy_config->sfb_offsets[pstr_tns_config->tns_stop_band];
133 
134   pstr_tns_config->tns_start_band = ia_enhaacplus_enc_freq_to_band_with_rounding(
135       pstr_tns_config->tns_start_freq, sample_rate, pstr_psy_config->sfb_cnt,
136       pstr_psy_config->sfb_offsets);
137 
138   pstr_tns_config->tns_modify_begin_cb = ia_enhaacplus_enc_freq_to_band_with_rounding(
139       TEMPORAL_NOISE_SHAPING_MODIFY_BEGIN, sample_rate, pstr_psy_config->sfb_cnt,
140       pstr_psy_config->sfb_offsets);
141 
142   pstr_tns_config->tns_ratio_patch_lowest_cb = ia_enhaacplus_enc_freq_to_band_with_rounding(
143       RATIO_PATCH_LOWER_BORDER, sample_rate, pstr_psy_config->sfb_cnt,
144       pstr_psy_config->sfb_offsets);
145 
146   pstr_tns_config->tns_start_line = pstr_psy_config->sfb_offsets[pstr_tns_config->tns_start_band];
147 
148   pstr_tns_config->lpc_stop_band = ia_enhaacplus_enc_freq_to_band_with_rounding(
149       pstr_tns_config->conf_tab.lpc_stop_freq, sample_rate, pstr_psy_config->sfb_cnt,
150       pstr_psy_config->sfb_offsets);
151 
152   pstr_tns_config->lpc_stop_band =
153       MIN(pstr_tns_config->lpc_stop_band, pstr_psy_config->sfb_active);
154 
155   pstr_tns_config->lpc_stop_line = pstr_psy_config->sfb_offsets[pstr_tns_config->lpc_stop_band];
156   pstr_tns_config->lpc_start_band = ia_enhaacplus_enc_freq_to_band_with_rounding(
157       pstr_tns_config->conf_tab.lpc_start_freq, sample_rate, pstr_psy_config->sfb_cnt,
158       pstr_psy_config->sfb_offsets);
159 
160   pstr_tns_config->lpc_start_line = pstr_psy_config->sfb_offsets[pstr_tns_config->lpc_start_band];
161   pstr_tns_config->threshold = pstr_tns_config->conf_tab.thresh_on;
162 
163   return IA_NO_ERROR;
164 }
165 
ia_enhaacplus_enc_init_tns_configuration_short(WORD32 bit_rate,WORD32 sample_rate,WORD32 channels,ixheaace_temporal_noise_shaping_config * pstr_tns_config,ixheaace_psy_configuration_short * pstr_psy_config,WORD32 active,ixheaace_temporal_noise_shaping_tables * pstr_tns_tab,WORD32 frame_length,WORD32 aot)166 IA_ERRORCODE ia_enhaacplus_enc_init_tns_configuration_short(
167     WORD32 bit_rate, WORD32 sample_rate, WORD32 channels,
168     ixheaace_temporal_noise_shaping_config *pstr_tns_config,
169     ixheaace_psy_configuration_short *pstr_psy_config, WORD32 active,
170     ixheaace_temporal_noise_shaping_tables *pstr_tns_tab, WORD32 frame_length, WORD32 aot) {
171   IA_ERRORCODE error = IA_NO_ERROR;
172   pstr_tns_config->max_order = TEMPORAL_NOISE_SHAPING_MAX_ORDER_SHORT;
173   pstr_tns_config->tns_start_freq = TEMPORAL_NOISE_SHAPING_START_FREQ_SHORT;
174   pstr_tns_config->coef_res = TEMPORAL_NOISE_SHAPING_COEF_RES_SHORT;
175 
176   error = ia_enhaacplus_enc_get_tns_param(&pstr_tns_config->conf_tab, bit_rate / channels,
177                                           channels, SHORT_WINDOW, pstr_tns_tab->tns_info_tab,
178                                           sizeof(pstr_tns_tab->tns_info_tab));
179   if (error != IA_NO_ERROR) {
180     return error;
181   }
182   ia_enhaacplus_enc_calc_gauss_window(
183       pstr_tns_config->acf_window_float, (const WORD16)(pstr_tns_config->max_order + 1),
184       sample_rate, SHORT_WINDOW, pstr_tns_config->conf_tab.tns_time_resolution);
185 
186   ia_enhaacplus_enc_get_tns_max_bands(
187       sample_rate, SHORT_WINDOW, &pstr_tns_config->tns_max_sfb, pstr_tns_tab->tns_max_bands_table,
188       sizeof(pstr_tns_tab->tns_max_bands_table), aot, frame_length);
189 
190   pstr_tns_config->tns_active = 1;
191 
192   if (active == 0) {
193     pstr_tns_config->tns_active = 0;
194   }
195 
196   /*now calc band and line borders */
197 
198   pstr_tns_config->tns_stop_band = MIN(pstr_psy_config->sfb_cnt, pstr_tns_config->tns_max_sfb);
199 
200   pstr_tns_config->tns_stop_line = pstr_psy_config->sfb_offsets[pstr_tns_config->tns_stop_band];
201 
202   pstr_tns_config->tns_start_band = ia_enhaacplus_enc_freq_to_band_with_rounding(
203       pstr_tns_config->tns_start_freq, sample_rate, pstr_psy_config->sfb_cnt,
204       pstr_psy_config->sfb_offsets);
205 
206   pstr_tns_config->tns_modify_begin_cb = ia_enhaacplus_enc_freq_to_band_with_rounding(
207       TEMPORAL_NOISE_SHAPING_MODIFY_BEGIN, sample_rate, pstr_psy_config->sfb_cnt,
208       pstr_psy_config->sfb_offsets);
209 
210   pstr_tns_config->tns_ratio_patch_lowest_cb = ia_enhaacplus_enc_freq_to_band_with_rounding(
211       RATIO_PATCH_LOWER_BORDER, sample_rate, pstr_psy_config->sfb_cnt,
212       pstr_psy_config->sfb_offsets);
213 
214   pstr_tns_config->tns_start_line = pstr_psy_config->sfb_offsets[pstr_tns_config->tns_start_band];
215 
216   pstr_tns_config->lpc_stop_band = ia_enhaacplus_enc_freq_to_band_with_rounding(
217       pstr_tns_config->conf_tab.lpc_stop_freq, sample_rate, pstr_psy_config->sfb_cnt,
218       pstr_psy_config->sfb_offsets);
219 
220   pstr_tns_config->lpc_stop_band =
221       MIN(pstr_tns_config->lpc_stop_band, pstr_psy_config->sfb_active);
222 
223   pstr_tns_config->lpc_stop_line = pstr_psy_config->sfb_offsets[pstr_tns_config->lpc_stop_band];
224 
225   pstr_tns_config->lpc_start_band = ia_enhaacplus_enc_freq_to_band_with_rounding(
226       pstr_tns_config->conf_tab.lpc_start_freq, sample_rate, pstr_psy_config->sfb_cnt,
227       pstr_psy_config->sfb_offsets);
228 
229   pstr_tns_config->lpc_start_line = pstr_psy_config->sfb_offsets[pstr_tns_config->lpc_start_band];
230   pstr_tns_config->threshold = pstr_tns_config->conf_tab.thresh_on;
231 
232   return IA_NO_ERROR;
233 }
234 
235 const WORD32 ia_enhaacplus_enc_m_log2_table[INT_BITS] = {
236     0x00000000, 0x4ae00d00, 0x2934f080, 0x15c01a3f, 0x0b31fb80, 0x05aeb4e0, 0x02dcf2d0,
237     0x016fe50c, 0x00b84e23, 0x005c3e10, 0x002e24ca, 0x001713d6, 0x000b8a47, 0x0005c53b,
238     0x0002e2a3, 0x00017153, 0x0000b8aa, 0x00005c55, 0x00002e2b, 0x00001715, 0x00000b8b,
239     0x000005c5, 0x000002e3, 0x00000171, 0x000000b9, 0x0000005c, 0x0000002e, 0x00000017,
240     0x0000000c, 0x00000006, 0x00000003, 0x00000001};
241