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