/src/libxaac/encoder/ixheaace_psy_configuration.c
Line | Count | Source |
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 <stdlib.h> |
22 | | #include <math.h> |
23 | | |
24 | | #include "ixheaac_type_def.h" |
25 | | #include "ixheaac_constants.h" |
26 | | #include "impd_drc_common_enc.h" |
27 | | #include "impd_drc_uni_drc.h" |
28 | | #include "impd_drc_tables.h" |
29 | | #include "impd_drc_api.h" |
30 | | #include "ixheaace_api.h" |
31 | | #include "ixheaace_aac_constants.h" |
32 | | #include "ixheaac_basic_ops32.h" |
33 | | #include "ixheaac_basic_ops16.h" |
34 | | #include "ixheaac_basic_ops40.h" |
35 | | #include "ixheaac_basic_ops.h" |
36 | | #include "ixheaac_error_standards.h" |
37 | | #include "ixheaace_error_codes.h" |
38 | | #include "ixheaace_psy_const.h" |
39 | | #include "ixheaace_tns.h" |
40 | | #include "ixheaace_tns_params.h" |
41 | | #include "ixheaace_rom.h" |
42 | | #include "ixheaace_common_rom.h" |
43 | | #include "ixheaace_bitbuffer.h" |
44 | | #include "ixheaace_psy_configuration.h" |
45 | | |
46 | | #include "ixheaace_adjust_threshold_data.h" |
47 | | #include "ixheaace_tns_params.h" |
48 | | #include "ixheaace_dynamic_bits.h" |
49 | | #include "ixheaace_qc_data.h" |
50 | | #include "ixheaace_block_switch.h" |
51 | | #include "ixheaace_psy_data.h" |
52 | | #include "ixheaace_interface.h" |
53 | | #include "ixheaace_adjust_threshold.h" |
54 | | #include "ixheaace_common_utils.h" |
55 | | |
56 | | static IA_ERRORCODE ia_enhaacplus_enc_init_sfb_table(ixheaace_psycho_tables *pstr_psycho_tab, |
57 | | WORD32 sample_rate, WORD32 aot, |
58 | | WORD32 block_type, WORD32 *ptr_sfb_offset, |
59 | 9.84k | WORD32 *sfb_cnt, WORD32 long_frame_len) { |
60 | 9.84k | const UWORD8 *ptr_sfb_param = NULL; |
61 | 9.84k | UWORD32 i; |
62 | 9.84k | WORD32 spec_start_offset, spec_lines = 0; |
63 | | |
64 | | /* sfb_info_tab[] */ |
65 | 53.4k | for (i = 0; i < sizeof(pstr_psycho_tab->sfb_info_tab) / sizeof(ixheaace_sfb_info_tab); i++) { |
66 | 53.4k | if (pstr_psycho_tab->sfb_info_tab[i].sample_rate == sample_rate) { |
67 | 9.84k | switch (block_type) { |
68 | 6.01k | case LONG_WINDOW: |
69 | 6.01k | case START_WINDOW: |
70 | 6.01k | case STOP_WINDOW: |
71 | 6.01k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { |
72 | 3.83k | if (long_frame_len == FRAME_LEN_960) { |
73 | 1.24k | ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long_960; |
74 | 2.58k | } else { |
75 | 2.58k | ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long; |
76 | 2.58k | } |
77 | 3.83k | spec_lines = long_frame_len; |
78 | 3.83k | break; |
79 | 3.83k | } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) { |
80 | 2.17k | if (long_frame_len == FRAME_LEN_480) |
81 | 1.04k | ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long_480_ld; |
82 | 1.13k | else |
83 | 1.13k | ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_long_512_ld; |
84 | 2.17k | spec_lines = long_frame_len; |
85 | 2.17k | break; |
86 | 2.17k | } |
87 | | |
88 | 3.83k | case SHORT_WINDOW: |
89 | 3.83k | if (long_frame_len == FRAME_LEN_SHORT_120) { |
90 | 1.24k | ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_short_120; |
91 | 2.58k | } else { |
92 | 2.58k | ptr_sfb_param = pstr_psycho_tab->sfb_info_tab[i].param_short; |
93 | 2.58k | } |
94 | 3.83k | spec_lines = long_frame_len; |
95 | 3.83k | break; |
96 | 9.84k | } |
97 | 9.84k | break; |
98 | 9.84k | } |
99 | 53.4k | } |
100 | | |
101 | 9.84k | if (ptr_sfb_param == NULL) { |
102 | 0 | return IA_EXHEAACE_INIT_FATAL_SCALE_FACTOR_BAND_NOT_SUPPORTED; |
103 | 0 | } |
104 | | |
105 | 9.84k | *sfb_cnt = 0; |
106 | 9.84k | spec_start_offset = 0; |
107 | | |
108 | 294k | do { |
109 | 294k | ptr_sfb_offset[*sfb_cnt] = spec_start_offset; |
110 | | |
111 | 294k | spec_start_offset += ptr_sfb_param[*sfb_cnt]; |
112 | | |
113 | 294k | (*sfb_cnt)++; |
114 | 294k | } while (spec_start_offset < spec_lines); |
115 | | |
116 | 9.84k | if (spec_start_offset != spec_lines) { |
117 | 0 | return IA_EXHEAACE_INIT_FATAL_SFB_TABLE_INIT_FAILED; |
118 | 0 | } |
119 | | |
120 | 9.84k | ptr_sfb_offset[*sfb_cnt] = spec_start_offset; |
121 | | |
122 | 9.84k | return IA_NO_ERROR; |
123 | 9.84k | } |
124 | | |
125 | 732k | FLOAT32 iaace_atan_approx(FLOAT32 val) { |
126 | 732k | if (val < (FLOAT32)1.0f) { |
127 | 492k | return (val / ((FLOAT32)1.0f + (FLOAT32)0.280872f * val * val)); |
128 | 492k | } else { |
129 | 239k | return ((FLOAT32)1.57079633f - val / ((FLOAT32)0.280872f + val * val)); |
130 | 239k | } |
131 | 732k | } |
132 | | |
133 | 294k | static FLOAT32 iaace_calc_bark_line_value(WORD32 num_lines, WORD32 fft_line, WORD32 sample_rate) { |
134 | 294k | FLOAT32 center_freq, temp, b_value; |
135 | 294k | center_freq = (FLOAT32)fft_line * ((FLOAT32)sample_rate * (FLOAT32)0.5f) / (FLOAT32)num_lines; |
136 | 294k | temp = (FLOAT32)iaace_atan_approx((FLOAT32)1.3333333e-4f * center_freq); |
137 | 294k | b_value = (FLOAT32)13.3f * iaace_atan_approx((FLOAT32)0.00076f * center_freq) + |
138 | 294k | (FLOAT32)3.5f * temp * temp; |
139 | 294k | return (b_value); |
140 | 294k | } |
141 | | |
142 | | static VOID iaace_thr_quiet_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, FLOAT32 *ptr_bark_val, |
143 | | FLOAT32 *ptr_thr_quiet, const FLOAT32 *ptr_bark_quiet_thr_val, |
144 | 9.84k | WORD32 aot) { |
145 | 9.84k | WORD32 i; |
146 | 9.84k | FLOAT32 bark_thr_quiet; |
147 | | |
148 | 304k | for (i = 0; i < sfb_count; i++) { |
149 | 294k | if (aot == AOT_AAC_ELD) { |
150 | 48.6k | ptr_thr_quiet[i] = (FLOAT32)(ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]) * 42; |
151 | 246k | } else { |
152 | 246k | WORD32 b_val1, b_val2; |
153 | | |
154 | 246k | if (i > 0) { |
155 | 237k | b_val1 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i - 1]) >> 1; |
156 | 237k | } else { |
157 | 8.24k | b_val1 = (WORD32)(ptr_bark_val[i]) >> 1; |
158 | 8.24k | } |
159 | | |
160 | 246k | if (i < sfb_count - 1) { |
161 | 237k | b_val2 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i + 1]) >> 1; |
162 | 237k | } else { |
163 | 8.24k | b_val2 = (WORD32)(ptr_bark_val[i]); |
164 | 8.24k | } |
165 | 246k | b_val1 = MIN(b_val1, (WORD32)MAX_BARK_VALUE); |
166 | 246k | b_val2 = MIN(b_val2, (WORD32)MAX_BARK_VALUE); |
167 | 246k | bark_thr_quiet = MIN(ptr_bark_quiet_thr_val[b_val1], ptr_bark_quiet_thr_val[b_val2]); |
168 | | |
169 | 246k | ptr_thr_quiet[i] = (FLOAT32)db_lin_scale(bark_thr_quiet - 20.0f) * 16887.8f * |
170 | 246k | (FLOAT32)(ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]); |
171 | 246k | } |
172 | 294k | } |
173 | 9.84k | } |
174 | | |
175 | | static VOID iaace_spreading_init(WORD32 sfb_count, FLOAT32 *ptr_bark_val, |
176 | | FLOAT32 *ptr_mask_low_fac, FLOAT32 *ptr_mask_high_fac, |
177 | | FLOAT32 *ptr_mask_low_fac_spr_energy, |
178 | | FLOAT32 *ptr_mask_high_fac_spr_energy, const WORD32 bit_rate, |
179 | 9.84k | WORD32 block_type) { |
180 | 9.84k | WORD32 i; |
181 | 9.84k | FLOAT32 mask_low_spr_energy, mask_high_spr_energy; |
182 | | |
183 | 9.84k | if (block_type != SHORT_WINDOW) { |
184 | 6.01k | mask_low_spr_energy = MASK_LOW_SP_ENERGY_L; |
185 | 6.01k | mask_high_spr_energy = (bit_rate > MASK_HIGH_SP_BITRATE_THRESH) ? MASK_HIGH_SP_ENERGY_L |
186 | 6.01k | : MASK_HIGH_SP_ENERGY_L_LBR; |
187 | 6.01k | } else { |
188 | 3.83k | mask_low_spr_energy = MASK_LOW_SP_ENERGY_S; |
189 | 3.83k | mask_high_spr_energy = MASK_HIGH_SP_ENERGY_S; |
190 | 3.83k | } |
191 | | |
192 | 304k | for (i = 0; i < sfb_count; i++) { |
193 | 294k | if (i > 0) { |
194 | 285k | FLOAT32 db_val; |
195 | 285k | FLOAT32 diff_val = (ptr_bark_val[i] - ptr_bark_val[i - 1]); |
196 | | |
197 | 285k | db_val = MASK_HIGH_FAC * diff_val; |
198 | 285k | ptr_mask_high_fac[i] = (FLOAT32)pow(10.0f, -db_val); |
199 | 285k | db_val = MASK_LOW_FAC * diff_val; |
200 | 285k | ptr_mask_low_fac[i - 1] = (FLOAT32)pow(10.0f, -db_val); |
201 | 285k | db_val = mask_high_spr_energy * diff_val; |
202 | 285k | ptr_mask_high_fac_spr_energy[i] = (FLOAT32)pow(10.0f, -db_val); |
203 | 285k | db_val = mask_low_spr_energy * diff_val; |
204 | 285k | ptr_mask_low_fac_spr_energy[i - 1] = (FLOAT32)pow(10.0f, -db_val); |
205 | 285k | } else { |
206 | 9.84k | ptr_mask_high_fac[i] = 0.0f; |
207 | 9.84k | ptr_mask_low_fac[sfb_count - 1] = 0.0f; |
208 | 9.84k | ptr_mask_high_fac_spr_energy[i] = 0.0f; |
209 | 9.84k | ptr_mask_low_fac_spr_energy[sfb_count - 1] = 0.0f; |
210 | 9.84k | } |
211 | 294k | } |
212 | 9.84k | return; |
213 | 9.84k | } |
214 | | |
215 | | static VOID iaace_bark_values_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, WORD32 num_lines, |
216 | 9.84k | WORD32 sample_rate, FLOAT32 *ptr_b_value, WORD32 aot) { |
217 | 9.84k | WORD32 i; |
218 | 9.84k | FLOAT32 b_val0, b_val1; |
219 | 9.84k | b_val0 = 0.0f; |
220 | | |
221 | 304k | for (i = 0; i < sfb_count; i++) { |
222 | 294k | b_val1 = iaace_calc_bark_line_value(num_lines, ptr_sfb_offset[i + 1], sample_rate); |
223 | 294k | ptr_b_value[i] = (b_val0 + b_val1) * (FLOAT32)0.5f; |
224 | 294k | if (aot == AOT_AAC_ELD) { |
225 | 48.6k | if (ptr_b_value[i] > MAX_BARK_VALUE) { |
226 | 0 | ptr_b_value[i] = MAX_BARK_VALUE; |
227 | 0 | } |
228 | 48.6k | } |
229 | | |
230 | 294k | b_val0 = b_val1; |
231 | 294k | } |
232 | 9.84k | } |
233 | | |
234 | 9.84k | static FLOAT32 iaace_bits_to_pe(const FLOAT32 bits) { return (bits * 1.18f); } |
235 | | static VOID iaace_min_snr_init(const WORD32 bit_rate, const WORD32 sample_rate, |
236 | | const WORD32 num_lines, const WORD32 *ptr_sfb_offset, |
237 | | const FLOAT32 *ptr_bark_value, const WORD32 sfb_active, |
238 | 9.84k | FLOAT32 *ptr_sfb_min_snr) { |
239 | 9.84k | WORD32 sfb; |
240 | 9.84k | FLOAT32 bark_fac; |
241 | 9.84k | FLOAT32 bark_width; |
242 | 9.84k | FLOAT32 pe_per_window, pe_part; |
243 | 9.84k | FLOAT32 snr; |
244 | 9.84k | FLOAT32 b_val0, b_val1; |
245 | | |
246 | 9.84k | bark_fac = (FLOAT32)1.0 / MIN(ptr_bark_value[sfb_active - 1] / MAX_BARK_VALUE, (FLOAT32)1.0); |
247 | 9.84k | pe_per_window = iaace_bits_to_pe((FLOAT32)bit_rate / (FLOAT32)sample_rate * (FLOAT32)num_lines); |
248 | 9.84k | b_val0 = (FLOAT32)0.0f; |
249 | | |
250 | 241k | for (sfb = 0; sfb < sfb_active; sfb++) { |
251 | 231k | b_val1 = (FLOAT32)2.0 * ptr_bark_value[sfb] - b_val0; |
252 | 231k | bark_width = b_val1 - b_val0; |
253 | 231k | b_val0 = b_val1; |
254 | | |
255 | 231k | pe_part = pe_per_window * (FLOAT32)0.024f * bark_fac; |
256 | 231k | pe_part *= bark_width; |
257 | 231k | pe_part /= (FLOAT32)(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
258 | 231k | snr = (FLOAT32)pow(2.0f, pe_part) - 1.5f; |
259 | 231k | snr = 1.0f / MAX(snr, 1.0f); |
260 | 231k | snr = MIN(snr, 0.8f); |
261 | 231k | snr = MAX(snr, 0.003f); |
262 | 231k | ptr_sfb_min_snr[sfb] = snr; |
263 | 231k | } |
264 | 9.84k | } |
265 | | |
266 | | IA_ERRORCODE ia_enhaacplus_enc_init_psy_configuration( |
267 | | WORD32 bit_rate, WORD32 sample_rate, WORD32 bandwidth, WORD32 aot, |
268 | | ixheaace_psy_configuration_long *pstr_psy_conf, ixheaace_aac_tables *pstr_aac_tables, |
269 | 6.01k | WORD32 long_frame_len) { |
270 | 6.01k | WORD32 sfb; |
271 | 6.01k | FLOAT32 sfb_bark_val[MAXIMUM_SCALE_FACTOR_BAND_LONG]; |
272 | 6.01k | IA_ERRORCODE error; |
273 | 6.01k | error = ia_enhaacplus_enc_init_sfb_table(pstr_aac_tables->pstr_psycho_tab, sample_rate, aot, |
274 | 6.01k | LONG_WINDOW, pstr_psy_conf->sfb_offsets, |
275 | 6.01k | &(pstr_psy_conf->sfb_cnt), long_frame_len); |
276 | 6.01k | if (error != IA_NO_ERROR) { |
277 | 0 | return error; |
278 | 0 | } |
279 | | |
280 | | /* calculate bark values for each pb */ |
281 | 6.01k | iaace_bark_values_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets, |
282 | 6.01k | pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt], sample_rate, |
283 | 6.01k | sfb_bark_val, aot); |
284 | | |
285 | | /*init thresholds in quiet */ |
286 | | |
287 | 6.01k | iaace_thr_quiet_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets, sfb_bark_val, |
288 | 6.01k | pstr_psy_conf->sfb_threshold_quiet, |
289 | 6.01k | pstr_aac_tables->pstr_psycho_tab->ixheaace_bark_quiet_thr_val, aot); |
290 | | |
291 | | /* calculate spreading function */ |
292 | | |
293 | 6.01k | iaace_spreading_init(pstr_psy_conf->sfb_cnt, sfb_bark_val, pstr_psy_conf->sfb_mask_low_factor, |
294 | 6.01k | pstr_psy_conf->sfb_mask_high_factor, |
295 | 6.01k | pstr_psy_conf->sfb_mask_low_factor_spread_nrg, |
296 | 6.01k | pstr_psy_conf->sfb_mask_high_factor_spread_nrg, bit_rate, LONG_WINDOW); |
297 | | |
298 | | /* |
299 | | init ratio |
300 | | */ |
301 | | |
302 | 6.01k | pstr_psy_conf->min_remaining_threshold_factor = MIN_THRESH_FAC; |
303 | | |
304 | 6.01k | pstr_psy_conf->clip_energy = CLIP_ENERGY_VALUE_LONG; |
305 | 6.01k | if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) { |
306 | 3.83k | pstr_psy_conf->ratio_float = C_RATIO; |
307 | 3.83k | } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) { |
308 | 2.17k | if (aot == AOT_AAC_ELD) { |
309 | 1.59k | pstr_psy_conf->ratio_float = C_RATIO; |
310 | 1.59k | } else { |
311 | 581 | pstr_psy_conf->ratio_float = SNR_FLOAT; |
312 | 581 | } |
313 | 2.17k | } |
314 | | |
315 | 6.01k | pstr_psy_conf->lowpass_line = (WORD32)((2 * bandwidth * long_frame_len) / sample_rate); |
316 | | |
317 | | /* pstr_psy_conf->pstr_sfb_offset[] */ |
318 | 194k | for (sfb = 0; sfb < pstr_psy_conf->sfb_cnt; sfb++) { |
319 | 194k | if (pstr_psy_conf->sfb_offsets[sfb] >= pstr_psy_conf->lowpass_line) break; |
320 | 194k | } |
321 | 6.01k | pstr_psy_conf->sfb_active = sfb; |
322 | | |
323 | | /* |
324 | | calculate minSnr |
325 | | */ |
326 | 6.01k | iaace_min_snr_init(bit_rate, sample_rate, pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt], |
327 | 6.01k | pstr_psy_conf->sfb_offsets, sfb_bark_val, pstr_psy_conf->sfb_active, |
328 | 6.01k | pstr_psy_conf->sfb_min_snr); |
329 | | |
330 | 6.01k | return IA_NO_ERROR; |
331 | 6.01k | } |
332 | | |
333 | | IA_ERRORCODE ia_enhaacplus_enc_init_psy_configuration_short( |
334 | | WORD32 bit_rate, WORD32 sample_rate, WORD32 bandwidth, WORD32 aot, |
335 | | ixheaace_psy_configuration_short *pstr_psy_conf, ixheaace_aac_tables *pstr_aac_tables, |
336 | 3.83k | WORD32 long_frame_len) { |
337 | 3.83k | WORD32 sfb; |
338 | 3.83k | FLOAT32 sfb_bark_val[MAXIMUM_SCALE_FACTOR_BAND_SHORT] = {0}; |
339 | 3.83k | IA_ERRORCODE error; |
340 | | /* |
341 | | init sfb table |
342 | | */ |
343 | 3.83k | error = ia_enhaacplus_enc_init_sfb_table(pstr_aac_tables->pstr_psycho_tab, sample_rate, aot, |
344 | 3.83k | SHORT_WINDOW, pstr_psy_conf->sfb_offsets, |
345 | 3.83k | &(pstr_psy_conf->sfb_cnt), long_frame_len); |
346 | | |
347 | 3.83k | if (error != IA_NO_ERROR) { |
348 | 0 | return error; |
349 | 0 | } |
350 | | |
351 | 3.83k | iaace_bark_values_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets, |
352 | 3.83k | pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt], sample_rate, |
353 | 3.83k | sfb_bark_val, aot); |
354 | | |
355 | 3.83k | iaace_thr_quiet_init(pstr_psy_conf->sfb_cnt, pstr_psy_conf->sfb_offsets, sfb_bark_val, |
356 | 3.83k | pstr_psy_conf->sfb_threshold_quiet, |
357 | 3.83k | pstr_aac_tables->pstr_psycho_tab->ixheaace_bark_quiet_thr_val, aot); |
358 | | |
359 | | /* |
360 | | calculate spreading function |
361 | | */ |
362 | 3.83k | iaace_spreading_init(pstr_psy_conf->sfb_cnt, sfb_bark_val, pstr_psy_conf->sfb_mask_low_factor, |
363 | 3.83k | pstr_psy_conf->sfb_mask_high_factor, |
364 | 3.83k | pstr_psy_conf->sfb_mask_low_factor_spread_nrg, |
365 | 3.83k | pstr_psy_conf->sfb_mask_high_factor_spread_nrg, bit_rate, SHORT_WINDOW); |
366 | | |
367 | | /* |
368 | | init ratio |
369 | | */ |
370 | | |
371 | 3.83k | pstr_psy_conf->min_remaining_threshold_factor = 0.01f; |
372 | | |
373 | 3.83k | pstr_psy_conf->clip_energy = CLIP_ENERGY_VALUE_LONG / (TRANS_FAC * TRANS_FAC); |
374 | 3.83k | switch (aot) { |
375 | 1.34k | case AOT_AAC_LC: |
376 | 3.52k | case AOT_SBR: |
377 | 3.83k | case AOT_PS: |
378 | 3.83k | pstr_psy_conf->ratio_float = C_RATIO; |
379 | 3.83k | break; |
380 | | |
381 | 0 | case AOT_AAC_LD: |
382 | 0 | case AOT_AAC_ELD: |
383 | 0 | pstr_psy_conf->ratio_float = SNR_FLOAT; |
384 | 0 | break; |
385 | 3.83k | } |
386 | | |
387 | 3.83k | pstr_psy_conf->lowpass_line = (WORD32)((2 * bandwidth * long_frame_len) / sample_rate); |
388 | 46.7k | for (sfb = 0; sfb < pstr_psy_conf->sfb_cnt; sfb++) { |
389 | 45.9k | if (pstr_psy_conf->sfb_offsets[sfb] >= pstr_psy_conf->lowpass_line) break; |
390 | 45.9k | } |
391 | 3.83k | pstr_psy_conf->sfb_active = sfb; |
392 | | |
393 | 3.83k | iaace_min_snr_init(bit_rate, sample_rate, pstr_psy_conf->sfb_offsets[pstr_psy_conf->sfb_cnt], |
394 | 3.83k | pstr_psy_conf->sfb_offsets, sfb_bark_val, pstr_psy_conf->sfb_active, |
395 | 3.83k | pstr_psy_conf->sfb_min_snr); |
396 | | |
397 | 3.83k | return IA_NO_ERROR; |
398 | 3.83k | } |
399 | | |
400 | | WORD32 ia_enhaacplus_enc_power2(WORD32 power, WORD q_power, WORD *q_result, |
401 | | const WORD32 *power_of_2_table_neg, |
402 | 0 | const WORD32 *power_of_2_table_pos) { |
403 | 0 | WORD32 int_part, frac_part; |
404 | 0 | WORD32 result; |
405 | 0 | WORD16 sign = 0; |
406 | |
|
407 | 0 | if (power < 0) { |
408 | 0 | sign = 1; |
409 | 0 | power = ixheaac_negate32(power); |
410 | 0 | } |
411 | |
|
412 | 0 | if (q_power < 32) |
413 | 0 | int_part = ixheaac_shr32(power, q_power); |
414 | 0 | else |
415 | 0 | int_part = 0; |
416 | |
|
417 | 0 | if (q_power < 39) { |
418 | 0 | power = ixheaac_shr32_dir(power, q_power - 8); |
419 | 0 | frac_part = power & 0xFF; |
420 | 0 | } else |
421 | 0 | frac_part = 0; |
422 | |
|
423 | 0 | if (!sign) { |
424 | 0 | result = power_of_2_table_pos[frac_part]; |
425 | 0 | *q_result = Q_POWER2_TABLE - int_part; |
426 | 0 | } else { |
427 | 0 | result = power_of_2_table_neg[frac_part]; |
428 | 0 | *q_result = Q_POWER2_TABLE + int_part; |
429 | 0 | } |
430 | |
|
431 | 0 | return (result); |
432 | 0 | } |