/src/libxaac/encoder/iusace_psy_utils.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 <math.h> |
22 | | #include <string.h> |
23 | | |
24 | | #include "ixheaac_type_def.h" |
25 | | #include "ixheaace_adjust_threshold_data.h" |
26 | | #include "iusace_block_switch_const.h" |
27 | | #include "iusace_cnst.h" |
28 | | #include "iusace_bitbuffer.h" |
29 | | #include "ixheaace_mps_common_define.h" |
30 | | |
31 | | /* DRC */ |
32 | | #include "impd_drc_common_enc.h" |
33 | | #include "impd_drc_uni_drc.h" |
34 | | #include "impd_drc_tables.h" |
35 | | #include "impd_drc_api.h" |
36 | | #include "impd_drc_uni_drc_eq.h" |
37 | | #include "impd_drc_uni_drc_filter_bank.h" |
38 | | #include "impd_drc_gain_enc.h" |
39 | | #include "impd_drc_struct_def.h" |
40 | | |
41 | | #include "iusace_tns_usac.h" |
42 | | #include "iusace_psy_mod.h" |
43 | | #include "iusace_tns_usac.h" |
44 | | #include "iusace_config.h" |
45 | | #include "iusace_psy_utils.h" |
46 | | #include "iusace_fd_qc_util.h" |
47 | | #include "iusace_fd_qc_adjthr.h" |
48 | | #include "ixheaac_error_standards.h" |
49 | | #include "ixheaace_error_codes.h" |
50 | | |
51 | | extern ia_sfb_info_struct iusace_sfb_info_1024[12]; |
52 | | extern ia_sfb_info_struct iusace_sfb_info_768[12]; |
53 | | |
54 | | static const FLOAT32 iusace_bark_quiet_thr_val[] = { |
55 | | 15.0f, 10.0f, 7.0f, 2.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, |
56 | | 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 3.0f, 5.0f, 10.0f, 20.0f, 30.0f}; |
57 | | |
58 | | VOID iusace_calc_band_energy(const FLOAT64 *ptr_spec_coeffs, const WORD32 *band_offset, |
59 | 1.61M | const WORD32 num_bands, FLOAT32 *ptr_band_energy, WORD32 sfb_count) { |
60 | 1.61M | WORD32 i, j; |
61 | | |
62 | 1.61M | j = 0; |
63 | 1.61M | memset(ptr_band_energy, 0, sfb_count * sizeof(FLOAT32)); |
64 | 31.7M | for (i = 0; i < num_bands; i++) { |
65 | 440M | while (j < band_offset[i + 1]) { |
66 | 410M | ptr_band_energy[i] += (FLOAT32)(ptr_spec_coeffs[j] * ptr_spec_coeffs[j]); |
67 | 410M | j++; |
68 | 410M | } |
69 | 30.1M | } |
70 | 1.61M | return; |
71 | 1.61M | } |
72 | | |
73 | | VOID iusace_find_max_spreading(const WORD32 sfb_count, const FLOAT32 *ptr_mask_low_fac, |
74 | 2.78M | const FLOAT32 *ptr_mask_high_fac, FLOAT32 *ptr_spreaded_enegry) { |
75 | 2.78M | WORD32 i; |
76 | | |
77 | 53.8M | for (i = 1; i < sfb_count; i++) { |
78 | 51.0M | ptr_spreaded_enegry[i] = |
79 | 51.0M | MAX(ptr_spreaded_enegry[i], ptr_mask_high_fac[i] * ptr_spreaded_enegry[i - 1]); |
80 | 51.0M | } |
81 | | |
82 | 53.8M | for (i = sfb_count - 2; i >= 0; i--) { |
83 | 51.0M | ptr_spreaded_enegry[i] = |
84 | 51.0M | MAX(ptr_spreaded_enegry[i], ptr_mask_low_fac[i] * ptr_spreaded_enegry[i + 1]); |
85 | 51.0M | } |
86 | 2.78M | return; |
87 | 2.78M | } |
88 | | |
89 | | VOID iusace_pre_echo_control(FLOAT32 *ptr_thr_nm1, WORD32 sfb_count, FLOAT32 max_allowed_inc_fac, |
90 | 1.39M | FLOAT32 min_remaining_thr_fac, FLOAT32 *ptr_threshold) { |
91 | 1.39M | WORD32 i; |
92 | 1.39M | FLOAT32 thr1, thr2; |
93 | | |
94 | 28.3M | for (i = 0; i < sfb_count; i++) { |
95 | 26.9M | thr1 = max_allowed_inc_fac * (ptr_thr_nm1[i]); |
96 | 26.9M | thr2 = min_remaining_thr_fac * ptr_threshold[i]; |
97 | | |
98 | 26.9M | ptr_thr_nm1[i] = ptr_threshold[i]; |
99 | | |
100 | 26.9M | if (ptr_threshold[i] > thr1) { |
101 | 2.61M | ptr_threshold[i] = thr1; |
102 | 2.61M | } |
103 | 26.9M | if (thr2 > ptr_threshold[i]) { |
104 | 1.26M | ptr_threshold[i] = thr2; |
105 | 1.26M | } |
106 | 26.9M | } |
107 | 1.39M | return; |
108 | 1.39M | } |
109 | | |
110 | | static VOID iusace_sfb_init(WORD32 sample_rate, WORD32 block_type, WORD32 *ptr_sfb_offset, |
111 | 11.0k | WORD32 *ptr_sfb_count, WORD32 ccfl) { |
112 | 11.0k | const WORD16 *ptr_sfb_params = 0; |
113 | 11.0k | WORD32 start_offset, block_len = 0; |
114 | 11.0k | const ia_sfb_info_struct *pstr_sfb_info_tbls = &iusace_sfb_info_1024[0]; |
115 | 11.0k | WORD32 sampling_rate_mapped = iusace_map_sample_rate(sample_rate); |
116 | 11.0k | WORD16 prev_val = 0; |
117 | 11.0k | if (ccfl == LEN_SUPERFRAME_768) { |
118 | 2.76k | pstr_sfb_info_tbls = &iusace_sfb_info_768[0]; |
119 | 2.76k | } |
120 | | |
121 | | |
122 | 11.0k | if (block_type == ONLY_LONG_SEQUENCE) { |
123 | 5.53k | block_len = ccfl; |
124 | 5.53k | switch (sampling_rate_mapped) { |
125 | 440 | case 96000: |
126 | 440 | ptr_sfb_params = pstr_sfb_info_tbls[11].cb_offset_long; |
127 | 440 | break; |
128 | 64 | case 88200: |
129 | 64 | ptr_sfb_params = pstr_sfb_info_tbls[10].cb_offset_long; |
130 | 64 | break; |
131 | 52 | case 64000: |
132 | 52 | ptr_sfb_params = pstr_sfb_info_tbls[9].cb_offset_long; |
133 | 52 | break; |
134 | 155 | case 48000: |
135 | 155 | ptr_sfb_params = pstr_sfb_info_tbls[8].cb_offset_long; |
136 | 155 | break; |
137 | 242 | case 44100: |
138 | 242 | ptr_sfb_params = pstr_sfb_info_tbls[7].cb_offset_long; |
139 | 242 | break; |
140 | 726 | case 32000: |
141 | 726 | case 29400: |
142 | 726 | ptr_sfb_params = pstr_sfb_info_tbls[6].cb_offset_long; |
143 | 726 | break; |
144 | 1.16k | case 24000: |
145 | 1.16k | ptr_sfb_params = pstr_sfb_info_tbls[5].cb_offset_long; |
146 | 1.16k | break; |
147 | 479 | case 22050: |
148 | 479 | ptr_sfb_params = pstr_sfb_info_tbls[4].cb_offset_long; |
149 | 479 | break; |
150 | 813 | case 16000: |
151 | 813 | case 14700: |
152 | 813 | ptr_sfb_params = pstr_sfb_info_tbls[3].cb_offset_long; |
153 | 813 | break; |
154 | 705 | case 12000: |
155 | 705 | ptr_sfb_params = pstr_sfb_info_tbls[2].cb_offset_long; |
156 | 705 | break; |
157 | 214 | case 11025: |
158 | 214 | ptr_sfb_params = pstr_sfb_info_tbls[1].cb_offset_long; |
159 | 214 | break; |
160 | 482 | case 8000: |
161 | 482 | ptr_sfb_params = pstr_sfb_info_tbls[0].cb_offset_long; |
162 | 482 | break; |
163 | 0 | default: |
164 | 0 | ptr_sfb_params = pstr_sfb_info_tbls[8].cb_offset_long; |
165 | 0 | break; |
166 | 5.53k | } |
167 | 5.53k | } else { |
168 | 5.53k | block_len = ccfl >> 3; |
169 | 5.53k | switch (sampling_rate_mapped) { |
170 | 440 | case 96000: |
171 | 440 | ptr_sfb_params = pstr_sfb_info_tbls[11].cb_offset_short; |
172 | 440 | break; |
173 | 64 | case 88200: |
174 | 64 | ptr_sfb_params = pstr_sfb_info_tbls[10].cb_offset_short; |
175 | 64 | break; |
176 | 52 | case 64000: |
177 | 52 | ptr_sfb_params = pstr_sfb_info_tbls[9].cb_offset_short; |
178 | 52 | break; |
179 | 155 | case 48000: |
180 | 155 | ptr_sfb_params = pstr_sfb_info_tbls[8].cb_offset_short; |
181 | 155 | break; |
182 | 242 | case 44100: |
183 | 242 | ptr_sfb_params = pstr_sfb_info_tbls[7].cb_offset_short; |
184 | 242 | break; |
185 | 726 | case 32000: |
186 | 726 | case 29400: |
187 | 726 | ptr_sfb_params = pstr_sfb_info_tbls[6].cb_offset_short; |
188 | 726 | break; |
189 | 1.16k | case 24000: |
190 | 1.16k | ptr_sfb_params = pstr_sfb_info_tbls[5].cb_offset_short; |
191 | 1.16k | break; |
192 | 479 | case 22050: |
193 | 479 | ptr_sfb_params = pstr_sfb_info_tbls[4].cb_offset_short; |
194 | 479 | break; |
195 | 813 | case 16000: |
196 | 813 | case 14700: |
197 | 813 | ptr_sfb_params = pstr_sfb_info_tbls[3].cb_offset_short; |
198 | 813 | break; |
199 | 705 | case 12000: |
200 | 705 | ptr_sfb_params = pstr_sfb_info_tbls[2].cb_offset_short; |
201 | 705 | break; |
202 | 214 | case 11025: |
203 | 214 | ptr_sfb_params = pstr_sfb_info_tbls[1].cb_offset_short; |
204 | 214 | break; |
205 | 482 | case 8000: |
206 | 482 | ptr_sfb_params = pstr_sfb_info_tbls[0].cb_offset_short; |
207 | 482 | break; |
208 | 0 | default: |
209 | 0 | ptr_sfb_params = pstr_sfb_info_tbls[8].cb_offset_short; |
210 | 0 | break; |
211 | 5.53k | } |
212 | 5.53k | } |
213 | | |
214 | 11.0k | *ptr_sfb_count = 0; |
215 | 11.0k | start_offset = 0; |
216 | | |
217 | 323k | do { |
218 | 323k | ptr_sfb_offset[*ptr_sfb_count] = start_offset; |
219 | 323k | if (*ptr_sfb_count == 0) |
220 | 11.0k | prev_val = 0; |
221 | 312k | else |
222 | 312k | prev_val = ptr_sfb_params[*ptr_sfb_count - 1]; |
223 | 323k | start_offset += ptr_sfb_params[*ptr_sfb_count] - prev_val; |
224 | 323k | (*ptr_sfb_count)++; |
225 | 323k | } while (start_offset < block_len); |
226 | | |
227 | 11.0k | ptr_sfb_offset[*ptr_sfb_count] = start_offset; |
228 | | |
229 | 11.0k | return; |
230 | 11.0k | } |
231 | | |
232 | 646k | static FLOAT32 iusace_atan_approx(FLOAT32 val) { |
233 | 646k | if (val < (FLOAT32)1.0) { |
234 | 378k | return (val / ((FLOAT32)1.0f + (FLOAT32)0.280872f * val * val)); |
235 | 378k | } else { |
236 | 268k | return ((FLOAT32)1.57079633f - val / ((FLOAT32)0.280872f + val * val)); |
237 | 268k | } |
238 | 646k | } |
239 | | |
240 | | static FLOAT32 iusace_calc_bark_line_value(WORD32 num_lines, WORD32 fft_line, |
241 | 323k | WORD32 sample_rate) { |
242 | 323k | FLOAT32 center_freq, temp, b_value; |
243 | | |
244 | 323k | center_freq = (FLOAT32)fft_line * ((FLOAT32)sample_rate * (FLOAT32)0.5f) / (FLOAT32)num_lines; |
245 | 323k | temp = (FLOAT32)iusace_atan_approx((FLOAT32)1.3333333e-4f * center_freq); |
246 | 323k | b_value = (FLOAT32)13.3f * iusace_atan_approx((FLOAT32)0.00076f * center_freq) + |
247 | 323k | (FLOAT32)3.5f * temp * temp; |
248 | | |
249 | 323k | return (b_value); |
250 | 323k | } |
251 | | |
252 | | static VOID iusace_bark_values_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, WORD32 num_lines, |
253 | 11.0k | WORD32 sample_rate, FLOAT32 *ptr_b_value) { |
254 | 11.0k | WORD32 i; |
255 | 11.0k | FLOAT32 b_val0, b_val1; |
256 | 11.0k | b_val0 = 0.0f; |
257 | | |
258 | 334k | for (i = 0; i < sfb_count; i++) { |
259 | 323k | b_val1 = iusace_calc_bark_line_value(num_lines, ptr_sfb_offset[i + 1], sample_rate); |
260 | 323k | ptr_b_value[i] = (b_val0 + b_val1) * (FLOAT32)0.5f; |
261 | 323k | b_val0 = b_val1; |
262 | 323k | } |
263 | 11.0k | return; |
264 | 11.0k | } |
265 | | |
266 | | static VOID iusace_thr_quiet_init(WORD32 sfb_count, WORD32 *ptr_sfb_offset, FLOAT32 *ptr_bark_val, |
267 | 11.0k | FLOAT32 *ptr_thr_quiet) { |
268 | 11.0k | WORD32 i; |
269 | 11.0k | FLOAT32 bark_thr_quiet; |
270 | | |
271 | 334k | for (i = 0; i < sfb_count; i++) { |
272 | 323k | WORD32 b_val1, b_val2; |
273 | | |
274 | 323k | if (i > 0) { |
275 | 312k | b_val1 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i - 1]) >> 1; |
276 | 312k | } else { |
277 | 11.0k | b_val1 = (WORD32)(ptr_bark_val[i]) >> 1; |
278 | 11.0k | } |
279 | | |
280 | 323k | if (i < sfb_count - 1) { |
281 | 312k | b_val2 = (WORD32)(ptr_bark_val[i] + ptr_bark_val[i + 1]) >> 1; |
282 | 312k | } else { |
283 | 11.0k | b_val2 = (WORD32)(ptr_bark_val[i]); |
284 | 11.0k | } |
285 | 323k | b_val1 = MIN(b_val1, (WORD32)MAX_BARK_VALUE); |
286 | 323k | b_val2 = MIN(b_val2, (WORD32)MAX_BARK_VALUE); |
287 | 323k | bark_thr_quiet = MIN(iusace_bark_quiet_thr_val[b_val1], iusace_bark_quiet_thr_val[b_val2]); |
288 | | |
289 | 323k | ptr_thr_quiet[i] = (FLOAT32)pow(10.0f, (bark_thr_quiet - 20.0f) * (FLOAT32)0.1f) * 16887.8f * |
290 | 323k | (FLOAT32)(ptr_sfb_offset[i + 1] - ptr_sfb_offset[i]); |
291 | 323k | } |
292 | 11.0k | return; |
293 | 11.0k | } |
294 | | |
295 | | static VOID iusace_spreading_init(WORD32 sfb_count, FLOAT32 *ptr_bark_val, |
296 | | FLOAT32 *ptr_mask_low_fac, FLOAT32 *ptr_mask_high_fac, |
297 | | FLOAT32 *ptr_mask_low_fac_spr_energy, |
298 | | FLOAT32 *ptr_mask_high_fac_spr_energy, const WORD32 bit_rate, |
299 | 11.0k | WORD32 block_type) { |
300 | 11.0k | WORD32 i; |
301 | 11.0k | FLOAT32 mask_low_spr_energy, mask_high_spr_energy; |
302 | | |
303 | 11.0k | if (block_type != EIGHT_SHORT_SEQUENCE) { |
304 | 5.53k | mask_low_spr_energy = MASK_LOW_SP_ENERGY_L; |
305 | 5.53k | mask_high_spr_energy = (bit_rate > 22000) ? MASK_HIGH_SP_ENERGY_L : MASK_HIGH_SP_ENERGY_L_LBR; |
306 | 5.53k | } else { |
307 | 5.53k | mask_low_spr_energy = MASK_LOW_SP_ENERGY_S; |
308 | 5.53k | mask_high_spr_energy = MASK_HIGH_SP_ENERGY_S; |
309 | 5.53k | } |
310 | | |
311 | 334k | for (i = 0; i < sfb_count; i++) { |
312 | 323k | if (i > 0) { |
313 | 312k | FLOAT32 db_val; |
314 | 312k | FLOAT32 diff_val = (ptr_bark_val[i] - ptr_bark_val[i - 1]); |
315 | | |
316 | 312k | db_val = MASK_HIGH_FAC * diff_val; |
317 | 312k | ptr_mask_high_fac[i] = (FLOAT32)pow(10.0f, -db_val); |
318 | 312k | db_val = MASK_LOW_FAC * diff_val; |
319 | 312k | ptr_mask_low_fac[i - 1] = (FLOAT32)pow(10.0f, -db_val); |
320 | 312k | db_val = mask_high_spr_energy * diff_val; |
321 | 312k | ptr_mask_high_fac_spr_energy[i] = (FLOAT32)pow(10.0f, -db_val); |
322 | 312k | db_val = mask_low_spr_energy * diff_val; |
323 | 312k | ptr_mask_low_fac_spr_energy[i - 1] = (FLOAT32)pow(10.0f, -db_val); |
324 | 312k | } else { |
325 | 11.0k | ptr_mask_high_fac[i] = 0.0f; |
326 | 11.0k | ptr_mask_low_fac[sfb_count - 1] = 0.0f; |
327 | 11.0k | ptr_mask_high_fac_spr_energy[i] = 0.0f; |
328 | 11.0k | ptr_mask_low_fac_spr_energy[sfb_count - 1] = 0.0f; |
329 | 11.0k | } |
330 | 323k | } |
331 | 11.0k | return; |
332 | 11.0k | } |
333 | | |
334 | | static VOID iusace_min_snr_init(const WORD32 bit_rate, const WORD32 sample_rate, |
335 | | const WORD32 num_lines, const WORD32 *ptr_sfb_offset, |
336 | | const FLOAT32 *ptr_bark_value, const WORD32 sfb_active, |
337 | 11.0k | FLOAT32 *ptr_sfb_min_snr) { |
338 | 11.0k | WORD32 sfb; |
339 | 11.0k | FLOAT32 bark_fac; |
340 | 11.0k | FLOAT32 bark_width; |
341 | 11.0k | FLOAT32 pe_per_window, pe_part; |
342 | 11.0k | FLOAT32 snr; |
343 | 11.0k | FLOAT32 b_val0, b_val1; |
344 | | |
345 | 11.0k | if (sfb_active == 0) { |
346 | 0 | bark_fac = 1.0f; |
347 | 11.0k | } else { |
348 | 11.0k | bark_fac = (FLOAT32)1.0 / MIN(ptr_bark_value[sfb_active - 1] / MAX_BARK_VALUE, (FLOAT32)1.0); |
349 | 11.0k | } |
350 | | |
351 | 11.0k | pe_per_window = |
352 | 11.0k | iusace_bits_to_pe((FLOAT32)bit_rate / (FLOAT32)sample_rate * (FLOAT32)num_lines); |
353 | | |
354 | 11.0k | b_val0 = (FLOAT32)0.0f; |
355 | | |
356 | 324k | for (sfb = 0; sfb < sfb_active; sfb++) { |
357 | 313k | b_val1 = (FLOAT32)2.0 * ptr_bark_value[sfb] - b_val0; |
358 | 313k | bark_width = b_val1 - b_val0; |
359 | 313k | b_val0 = b_val1; |
360 | | |
361 | 313k | pe_part = pe_per_window * (FLOAT32)0.024f * bark_fac; |
362 | 313k | pe_part *= bark_width; |
363 | 313k | pe_part /= (FLOAT32)(ptr_sfb_offset[sfb + 1] - ptr_sfb_offset[sfb]); |
364 | 313k | snr = (FLOAT32)pow(2.0f, pe_part) - 1.5f; |
365 | 313k | snr = 1.0f / MAX(snr, 1.0f); |
366 | 313k | snr = MIN(snr, 0.8f); |
367 | 313k | snr = MAX(snr, 0.003f); |
368 | 313k | ptr_sfb_min_snr[sfb] = snr; |
369 | 313k | } |
370 | 11.0k | return; |
371 | 11.0k | } |
372 | | |
373 | | VOID iusace_psy_long_config_init(WORD32 bit_rate, WORD32 sample_rate, WORD32 band_width, |
374 | 5.53k | ia_psy_mod_long_config_struct *pstr_psy_config, WORD32 ccfl) { |
375 | 5.53k | WORD32 sfb; |
376 | 5.53k | FLOAT32 sfb_bark_val[MAX_NUM_GROUPED_SFB]; |
377 | | |
378 | 5.53k | iusace_sfb_init(sample_rate, ONLY_LONG_SEQUENCE, pstr_psy_config->sfb_offset, |
379 | 5.53k | &(pstr_psy_config->sfb_count), ccfl); |
380 | | |
381 | 5.53k | iusace_bark_values_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, |
382 | 5.53k | pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], sample_rate, |
383 | 5.53k | sfb_bark_val); |
384 | | |
385 | 5.53k | iusace_thr_quiet_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, sfb_bark_val, |
386 | 5.53k | pstr_psy_config->sfb_thr_quiet); |
387 | | |
388 | 5.53k | iusace_spreading_init( |
389 | 5.53k | pstr_psy_config->sfb_count, sfb_bark_val, pstr_psy_config->sfb_mask_low_fac, |
390 | 5.53k | pstr_psy_config->sfb_mask_high_fac, pstr_psy_config->sfb_mask_low_fac_spr_ener, |
391 | 5.53k | pstr_psy_config->sfb_mask_high_fac_spr_ener, bit_rate, ONLY_LONG_SEQUENCE); |
392 | | |
393 | 5.53k | pstr_psy_config->ratio = C_RATIO; |
394 | 5.53k | pstr_psy_config->max_allowed_inc_fac = 2.0f; |
395 | 5.53k | pstr_psy_config->min_remaining_thr_fac = 0.01f; |
396 | | |
397 | 5.53k | pstr_psy_config->clip_energy = (CLIP_ENERGY_VALUE_LONG * ccfl) / FRAME_LEN_LONG; |
398 | 5.53k | pstr_psy_config->low_pass_line = (WORD32)((2 * band_width * ccfl) / sample_rate); |
399 | | |
400 | 243k | for (sfb = 0; sfb < pstr_psy_config->sfb_count; sfb++) { |
401 | 238k | if (pstr_psy_config->sfb_offset[sfb] >= pstr_psy_config->low_pass_line) break; |
402 | 238k | } |
403 | 5.53k | pstr_psy_config->sfb_active = sfb; |
404 | | |
405 | 5.53k | iusace_min_snr_init(bit_rate, sample_rate, |
406 | 5.53k | pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], |
407 | 5.53k | pstr_psy_config->sfb_offset, sfb_bark_val, pstr_psy_config->sfb_active, |
408 | 5.53k | pstr_psy_config->sfb_min_snr); |
409 | | |
410 | 5.53k | return; |
411 | 5.53k | } |
412 | | |
413 | | VOID iusace_psy_short_config_init(WORD32 bit_rate, WORD32 sample_rate, WORD32 band_width, |
414 | 5.53k | ia_psy_mod_short_config_struct *pstr_psy_config, WORD32 ccfl) { |
415 | 5.53k | WORD32 sfb; |
416 | 5.53k | WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG; |
417 | 5.53k | FLOAT32 sfb_bark_val[MAX_NUM_GROUPED_SFB]; |
418 | | |
419 | 5.53k | iusace_sfb_init(sample_rate, EIGHT_SHORT_SEQUENCE, pstr_psy_config->sfb_offset, |
420 | 5.53k | &(pstr_psy_config->sfb_count), ccfl); |
421 | | |
422 | 5.53k | iusace_bark_values_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, |
423 | 5.53k | pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], sample_rate, |
424 | 5.53k | sfb_bark_val); |
425 | | |
426 | 5.53k | iusace_thr_quiet_init(pstr_psy_config->sfb_count, pstr_psy_config->sfb_offset, sfb_bark_val, |
427 | 5.53k | pstr_psy_config->sfb_thr_quiet); |
428 | | |
429 | 5.53k | iusace_spreading_init( |
430 | 5.53k | pstr_psy_config->sfb_count, sfb_bark_val, pstr_psy_config->sfb_mask_low_fac, |
431 | 5.53k | pstr_psy_config->sfb_mask_high_fac, pstr_psy_config->sfb_mask_low_fac_spr_ener, |
432 | 5.53k | pstr_psy_config->sfb_mask_high_fac_spr_ener, bit_rate, EIGHT_SHORT_SEQUENCE); |
433 | | |
434 | 5.53k | pstr_psy_config->ratio = C_RATIO; |
435 | 5.53k | pstr_psy_config->max_allowed_inc_fac = 2.0f; |
436 | 5.53k | pstr_psy_config->min_remaining_thr_fac = 0.01f; |
437 | | |
438 | 5.53k | pstr_psy_config->clip_energy = |
439 | 5.53k | (CLIP_ENERGY_VALUE_SHORT * frame_len_short) / FRAME_LEN_SHORT_128; |
440 | 5.53k | pstr_psy_config->low_pass_line = (WORD32)((2 * band_width * frame_len_short) / sample_rate); |
441 | | |
442 | 81.8k | for (sfb = 0; sfb < pstr_psy_config->sfb_count; sfb++) { |
443 | 77.4k | if (pstr_psy_config->sfb_offset[sfb] >= pstr_psy_config->low_pass_line) break; |
444 | 77.4k | } |
445 | 5.53k | pstr_psy_config->sfb_active = sfb; |
446 | | |
447 | 5.53k | iusace_min_snr_init(bit_rate, sample_rate, |
448 | 5.53k | pstr_psy_config->sfb_offset[pstr_psy_config->sfb_count], |
449 | 5.53k | pstr_psy_config->sfb_offset, sfb_bark_val, pstr_psy_config->sfb_active, |
450 | 5.53k | pstr_psy_config->sfb_min_snr); |
451 | | |
452 | 5.53k | return; |
453 | 5.53k | } |
454 | | |
455 | | IA_ERRORCODE iusace_sfb_params_init(WORD32 sample_rate, WORD32 frame_len, WORD32 *ptr_sfb_width, |
456 | 543k | WORD32 *num_sfb, WORD32 win_seq) { |
457 | 543k | WORD32 i, j, k; |
458 | 543k | ia_sfb_info_struct *ptr_sr_info = NULL; |
459 | 543k | WORD32 sampling_rate_mapped = 0; |
460 | | |
461 | 543k | if (frame_len == 1024) { |
462 | 365k | ptr_sr_info = &iusace_sfb_info_1024[0]; |
463 | 365k | } else { |
464 | 178k | ptr_sr_info = &iusace_sfb_info_768[0]; |
465 | 178k | } |
466 | | |
467 | 543k | if (sample_rate < 0) |
468 | 0 | { |
469 | 0 | return IA_EXHEAACE_INIT_FATAL_USAC_INVALID_CORE_SAMPLE_RATE; |
470 | 0 | } |
471 | | |
472 | 543k | sampling_rate_mapped = iusace_map_sample_rate(sample_rate); |
473 | | |
474 | 3.44M | while (ptr_sr_info->sample_rate != sampling_rate_mapped) { |
475 | 2.90M | if (ptr_sr_info->sample_rate == -1) { |
476 | 0 | return IA_EXHEAACE_INIT_FATAL_USAC_INVALID_CORE_SAMPLE_RATE; |
477 | 0 | } |
478 | 2.90M | ptr_sr_info++; |
479 | 2.90M | } |
480 | | |
481 | 543k | j = 0; |
482 | 24.0M | for (i = 0; i < ptr_sr_info->num_sfb_long; i++) { |
483 | 23.4M | k = ptr_sr_info->cb_offset_long[i]; |
484 | 23.4M | ptr_sr_info->sfb_width_long[i] = k - j; |
485 | 23.4M | j = k; |
486 | 23.4M | } |
487 | 543k | j = 0; |
488 | 8.12M | for (i = 0; i < ptr_sr_info->num_sfb_short; i++) { |
489 | 7.58M | k = ptr_sr_info->cb_offset_short[i]; |
490 | 7.58M | ptr_sr_info->sfb_width_short[i] = k - j; |
491 | 7.58M | j = k; |
492 | 7.58M | } |
493 | | |
494 | 543k | switch (win_seq) { |
495 | 140k | case EIGHT_SHORT_SEQUENCE: |
496 | 140k | memcpy(ptr_sfb_width, ptr_sr_info->sfb_width_short, (MAX_SFB_SHORT) * sizeof(WORD32)); |
497 | 140k | *num_sfb = ptr_sr_info->num_sfb_short; |
498 | 140k | break; |
499 | 313k | case ONLY_LONG_SEQUENCE: |
500 | 359k | case LONG_START_SEQUENCE: |
501 | 359k | case STOP_START_SEQUENCE: |
502 | 402k | case LONG_STOP_SEQUENCE: |
503 | 402k | default: |
504 | 402k | memcpy(ptr_sfb_width, ptr_sr_info->sfb_width_long, MAX_SFB_LONG * sizeof(WORD32)); |
505 | 402k | *num_sfb = ptr_sr_info->num_sfb_long; |
506 | 402k | break; |
507 | 543k | } |
508 | | |
509 | 543k | return IA_NO_ERROR; |
510 | 543k | } |