/src/libxaac/decoder/ixheaacd_freq_sca.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * * |
3 | | * Copyright (C) 2018 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 | | #include <string.h> |
24 | | #include "ixheaacd_sbr_common.h" |
25 | | #include "ixheaac_type_def.h" |
26 | | |
27 | | #include "ixheaac_constants.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 "ixheaac_basic_op.h" |
34 | | #include "ixheaacd_intrinsics.h" |
35 | | #include "ixheaacd_common_rom.h" |
36 | | #include "ixheaacd_basic_funcs.h" |
37 | | #include "ixheaacd_bitbuffer.h" |
38 | | #include "ixheaacd_sbrdecsettings.h" |
39 | | #include "ixheaacd_sbr_scale.h" |
40 | | #include "ixheaacd_lpp_tran.h" |
41 | | #include "ixheaacd_env_extr_part.h" |
42 | | #include "ixheaacd_sbr_rom.h" |
43 | | #include "ixheaacd_hybrid.h" |
44 | | #include "ixheaacd_ps_dec.h" |
45 | | #include "ixheaacd_env_extr.h" |
46 | | |
47 | | #include "ixheaac_sbr_const.h" |
48 | | #include "ixheaacd_env_extr.h" |
49 | | #include "ixheaacd_freq_sca.h" |
50 | | #include "ixheaacd_intrinsics.h" |
51 | | |
52 | | const WORD32 ixheaacd_samp_rate_table[12] = {92017, 75132, 55426, 46009, |
53 | | 37566, 27713, 23004, 18783, |
54 | | 13856, 11502, 9391, 16428320}; |
55 | | |
56 | | const WORD32 ixheaacd_v_offset_40[16] = { |
57 | | 3 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, |
58 | | 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 2 + 1, 1 + 1, 0}; |
59 | | |
60 | 612k | static WORD32 ixheaacd_int_div(WORD32 num, WORD32 den) { |
61 | 612k | if (den != 0) { |
62 | 612k | WORD32 result = 0; |
63 | 612k | WORD32 temp = 0; |
64 | 1.40M | while (den <= num) { |
65 | 789k | temp = 0; |
66 | 1.66M | while (num >= (den << (temp + 1))) { |
67 | 871k | temp++; |
68 | 871k | } |
69 | 789k | result = result + (1 << temp); |
70 | 789k | num = num - (den * (1 << temp)); |
71 | 789k | } |
72 | 612k | return result; |
73 | 612k | } else { |
74 | 0 | return 0; |
75 | 0 | } |
76 | 612k | } |
77 | | |
78 | 199k | VOID ixheaacd_aac_shellsort(WORD16 *in, WORD32 n) { |
79 | 199k | WORD32 i, j; |
80 | 199k | WORD32 inc; |
81 | 199k | WORD32 v, w; |
82 | | |
83 | 199k | inc = 1; |
84 | | |
85 | 450k | do { |
86 | 450k | inc = (((inc << 1) + inc) + 1); |
87 | 450k | } while (inc <= n); |
88 | | |
89 | 450k | do { |
90 | 450k | inc = (ixheaacd_int_div(inc, 3)); |
91 | 3.29M | for (i = inc; i < n; i++) { |
92 | 2.84M | v = in[i]; |
93 | 2.84M | j = i; |
94 | | |
95 | 3.29M | while ((w = in[(j - inc)]) > v) { |
96 | 515k | in[j] = w; |
97 | 515k | j = (j - inc); |
98 | | |
99 | 515k | if (j < inc) break; |
100 | 515k | } |
101 | 2.84M | in[j] = v; |
102 | 2.84M | } |
103 | | |
104 | 450k | } while (inc > 1); |
105 | 199k | } |
106 | | |
107 | | WORD32 |
108 | | ixheaacd_calc_start_band(WORD32 fs_mapped, const WORD32 start_freq, |
109 | 63.3k | FLOAT32 upsamp_fac) { |
110 | 63.3k | WORD32 k0_min; |
111 | | |
112 | 63.3k | if (upsamp_fac == 4) { |
113 | 2.01k | if (fs_mapped < 32000) { |
114 | 1.52k | k0_min = (WORD32)(((FLOAT32)(3000 * 2 * 32) / fs_mapped) + 0.5); |
115 | 1.52k | } else { |
116 | 487 | if (fs_mapped < 64000) { |
117 | 487 | k0_min = (WORD32)(((FLOAT32)(4000 * 2 * 32) / fs_mapped) + 0.5); |
118 | 487 | } else { |
119 | 0 | k0_min = (WORD32)(((FLOAT32)(5000 * 2 * 32) / fs_mapped) + 0.5); |
120 | 0 | } |
121 | 487 | } |
122 | 61.3k | } else { |
123 | 61.3k | if (fs_mapped < 32000) { |
124 | 27.0k | k0_min = (WORD32)(((FLOAT32)(3000 * 2 * 64) / fs_mapped) + 0.5); |
125 | 34.3k | } else { |
126 | 34.3k | if (fs_mapped < 64000) { |
127 | 22.8k | k0_min = (WORD32)(((FLOAT32)(4000 * 2 * 64) / fs_mapped) + 0.5); |
128 | 22.8k | } else { |
129 | 11.5k | k0_min = (WORD32)(((FLOAT32)(5000 * 2 * 64) / fs_mapped) + 0.5); |
130 | 11.5k | } |
131 | 34.3k | } |
132 | 61.3k | } |
133 | | |
134 | 63.3k | switch (fs_mapped) { |
135 | 25.5k | case 16000: { |
136 | 25.5k | WORD32 v_offset[] = {-8, -7, -6, -5, -4, -3, -2, -1, |
137 | 25.5k | 0, 1, 2, 3, 4, 5, 6, 7}; |
138 | 25.5k | return (k0_min + v_offset[start_freq]); |
139 | 0 | } break; |
140 | 1.95k | case 22050: { |
141 | 1.95k | WORD32 v_offset[] = {-5, -4, -3, -2, -1, 0, 1, 2, |
142 | 1.95k | 3, 4, 5, 6, 7, 9, 11, 13}; |
143 | 1.95k | return (k0_min + v_offset[start_freq]); |
144 | 0 | } break; |
145 | 1.03k | case 24000: { |
146 | 1.03k | WORD32 v_offset[] = {-5, -3, -2, -1, 0, 1, 2, 3, |
147 | 1.03k | 4, 5, 6, 7, 9, 11, 13, 16}; |
148 | 1.03k | return (k0_min + v_offset[start_freq]); |
149 | 0 | } break; |
150 | 15.9k | case 32000: { |
151 | 15.9k | WORD32 v_offset[] = {-6, -4, -2, -1, 0, 1, 2, 3, |
152 | 15.9k | 4, 5, 6, 7, 9, 11, 13, 16}; |
153 | 15.9k | return (k0_min + v_offset[start_freq]); |
154 | 0 | } break; |
155 | 819 | case 40000: { |
156 | 819 | WORD32 v_offset[] = {-1, 0, 1, 2, 3, 4, 5, 6, |
157 | 819 | 7, 8, 9, 11, 13, 15, 17, 19}; |
158 | 819 | return (k0_min + v_offset[start_freq]); |
159 | 0 | } break; |
160 | 436 | case 44100: |
161 | 6.48k | case 48000: |
162 | 16.2k | case 64000: { |
163 | 16.2k | WORD32 v_offset[] = {-4, -2, -1, 0, 1, 2, 3, 4, |
164 | 16.2k | 5, 6, 7, 9, 11, 13, 16, 20}; |
165 | 16.2k | return (k0_min + v_offset[start_freq]); |
166 | 6.48k | } break; |
167 | 457 | case 88200: |
168 | 1.80k | case 96000: { |
169 | 1.80k | WORD32 v_offset[] = {-2, -1, 0, 1, 2, 3, 4, 5, |
170 | 1.80k | 6, 7, 9, 11, 13, 16, 20, 24}; |
171 | 1.80k | return (k0_min + v_offset[start_freq]); |
172 | 457 | } break; |
173 | | |
174 | 0 | default: { |
175 | 0 | WORD32 v_offset[] = {0, 1, 2, 3, 4, 5, 6, 7, |
176 | 0 | 9, 11, 13, 16, 20, 24, 28, 33}; |
177 | 0 | return (k0_min + v_offset[start_freq]); |
178 | 457 | } |
179 | 63.3k | } |
180 | 63.3k | } |
181 | | |
182 | | WORD32 |
183 | 54.7k | ixheaacd_calc_stop_band(WORD32 fs, const WORD32 stop_freq, FLOAT32 upsamp_fac) { |
184 | 54.7k | WORD32 result, i; |
185 | 54.7k | WORD16 arr_stop_freq[14]; |
186 | 54.7k | WORD32 k1_min; |
187 | 54.7k | WORD16 arr_diff_stop_freq[13]; |
188 | | |
189 | 54.7k | if (upsamp_fac == 4) { |
190 | 903 | fs = fs / 2; |
191 | 903 | if (fs < 32000) { |
192 | 556 | k1_min = (WORD32)(((FLOAT32)(6000 * 2 * 32) / fs) + 0.5); |
193 | 556 | } else { |
194 | 347 | if (fs < 64000) { |
195 | 347 | k1_min = (WORD32)(((FLOAT32)(8000 * 2 * 32) / fs) + 0.5); |
196 | 347 | } else { |
197 | 0 | k1_min = (WORD32)(((FLOAT32)(10000 * 2 * 32) / fs) + 0.5); |
198 | 0 | } |
199 | 347 | } |
200 | 53.8k | } else { |
201 | 53.8k | if (fs < 32000) { |
202 | 22.6k | k1_min = (WORD32)(((FLOAT32)(6000 * 2 * 64) / fs) + 0.5); |
203 | 31.2k | } else { |
204 | 31.2k | if (fs < 64000) { |
205 | 26.3k | k1_min = (WORD32)(((FLOAT32)(8000 * 2 * 64) / fs) + 0.5); |
206 | 26.3k | } else { |
207 | 4.83k | k1_min = (WORD32)(((FLOAT32)(10000 * 2 * 64) / fs) + 0.5); |
208 | 4.83k | } |
209 | 31.2k | } |
210 | 53.8k | } |
211 | | |
212 | | /*Calculate stop frequency vector*/ |
213 | 821k | for (i = 0; i <= 13; i++) { |
214 | 766k | arr_stop_freq[i] = (WORD32)(k1_min * pow(64.0 / k1_min, i / 13.0) + 0.5); |
215 | 766k | } |
216 | | |
217 | | /*Ensure increasing bandwidth */ |
218 | 766k | for (i = 0; i <= 12; i++) { |
219 | 711k | arr_diff_stop_freq[i] = arr_stop_freq[i + 1] - arr_stop_freq[i]; |
220 | 711k | } |
221 | | |
222 | 54.7k | ixheaacd_aac_shellsort(&arr_diff_stop_freq[0], |
223 | 54.7k | 13); /*Sort bandwidth changes */ |
224 | | |
225 | 54.7k | result = k1_min; |
226 | 298k | for (i = 0; i < stop_freq; i++) { |
227 | 244k | result = ixheaac_add32_sat(result, arr_diff_stop_freq[i]); |
228 | 244k | } |
229 | | |
230 | 54.7k | return (result); |
231 | 54.7k | } |
232 | | IA_ERRORCODE ixheaacd_calc_k0_k2_bands(const WORD32 samp_freq, |
233 | | const WORD32 start_freq, |
234 | | const WORD32 stop_freq, |
235 | | FLOAT32 upsamp_fac, WORD16 *ptr_k0, |
236 | 63.3k | WORD16 *ptr_k2) { |
237 | 63.3k | IA_ERRORCODE err_code = IA_NO_ERROR; |
238 | | |
239 | 63.3k | WORD32 fs_mapped = 0; |
240 | 63.3k | WORD32 fs = samp_freq; |
241 | | |
242 | 63.3k | if (upsamp_fac == 4) { |
243 | 2.01k | fs = fs / 2; |
244 | 2.01k | } |
245 | | |
246 | 63.3k | if (fs >= 0 && fs < 18783) { |
247 | 25.5k | fs_mapped = 16000; |
248 | 37.8k | } else if (fs >= 18783 && fs < 23004) { |
249 | 1.95k | fs_mapped = 22050; |
250 | 35.8k | } else if (fs >= 23004 && fs < 27713) { |
251 | 1.03k | fs_mapped = 24000; |
252 | 34.8k | } else if (fs >= 27713 && fs < 35777) { |
253 | 15.9k | fs_mapped = 32000; |
254 | 18.8k | } else if (fs >= 35777 && fs < 42000) { |
255 | 819 | fs_mapped = 40000; |
256 | 18.0k | } else if (fs >= 42000 && fs < 46009) { |
257 | 436 | fs_mapped = 44100; |
258 | 17.5k | } else if (fs >= 46009 && fs < 55426) { |
259 | 6.04k | fs_mapped = 48000; |
260 | 11.5k | } else if (fs >= 55426 && fs < 75132) { |
261 | 9.73k | fs_mapped = 64000; |
262 | 9.73k | } else if (fs >= 75132 && fs < 92017) { |
263 | 457 | fs_mapped = 88200; |
264 | 1.34k | } else if (fs >= 92017) { |
265 | 1.34k | fs_mapped = 96000; |
266 | 1.34k | } else { |
267 | 0 | return -1; |
268 | 0 | } |
269 | | |
270 | | /* Update start_freq struct */ |
271 | 63.3k | *ptr_k0 = ixheaacd_calc_start_band(fs_mapped, start_freq, upsamp_fac); |
272 | | |
273 | | /*Update stop_freq struct */ |
274 | 63.3k | if (stop_freq < 14) { |
275 | 54.7k | *ptr_k2 = ixheaacd_calc_stop_band(samp_freq, stop_freq, upsamp_fac); |
276 | 54.7k | } else if (stop_freq == 14) { |
277 | 5.95k | *ptr_k2 = 2 * (*ptr_k0); |
278 | 5.95k | } else { |
279 | 2.65k | *ptr_k2 = 3 * (*ptr_k0); |
280 | 2.65k | } |
281 | | |
282 | | /* limit to Nyqvist */ |
283 | 63.3k | if (*ptr_k2 > 64) { |
284 | 18.1k | *ptr_k2 = 64; |
285 | 18.1k | } |
286 | 63.3k | return err_code; |
287 | 63.3k | } |
288 | | |
289 | | IA_ERRORCODE ixheaacd_calc_master_frq_bnd_tbl( |
290 | | ia_freq_band_data_struct *pstr_freq_band_data, |
291 | | ia_sbr_header_data_struct *ptr_header_data, |
292 | 63.3k | ixheaacd_misc_tables *pstr_common_tables) { |
293 | 63.3k | WORD32 k; |
294 | 63.3k | WORD32 fs = ptr_header_data->out_sampling_freq; |
295 | 63.3k | WORD16 bands; |
296 | 63.3k | WORD16 k0 = 0, k2 = 0, k1; |
297 | 63.3k | WORD32 k2_achived; |
298 | 63.3k | WORD32 k2_diff; |
299 | 63.3k | WORD32 incr; |
300 | 63.3k | WORD32 dk; |
301 | 63.3k | WORD16 vec_dk[MAX_OCTAVE + MAX_SECOND_REGION]; |
302 | 63.3k | WORD16 *vec_dk0 = &vec_dk[0]; |
303 | 63.3k | WORD16 *vec_dk1 = &vec_dk[MAX_OCTAVE]; |
304 | 63.3k | WORD16 upsamp_fac = ptr_header_data->upsamp_fac; |
305 | 63.3k | WORD16 *f_master_tbl = pstr_freq_band_data->f_master_tbl; |
306 | 63.3k | WORD16 num_mf_bands; |
307 | 63.3k | IA_ERRORCODE err_code = IA_NO_ERROR; |
308 | | |
309 | 63.3k | k1 = 0; |
310 | 63.3k | incr = 0; |
311 | 63.3k | dk = 0; |
312 | | |
313 | 63.3k | err_code = ixheaacd_calc_k0_k2_bands(fs, ptr_header_data->start_freq, |
314 | 63.3k | ptr_header_data->stop_freq, upsamp_fac, |
315 | 63.3k | &k0, &k2); |
316 | 63.3k | if (err_code) return err_code; |
317 | | |
318 | 63.3k | if (k2 > NO_SYNTHESIS_CHANNELS) { |
319 | 0 | k2 = NO_SYNTHESIS_CHANNELS; |
320 | 0 | } |
321 | 63.3k | if (upsamp_fac == 4) { |
322 | 2.01k | if ((sub_d(k2, k0) > MAX_FREQ_COEFFS) || (k2 <= k0)) { |
323 | 5 | return -1; |
324 | 5 | } |
325 | 2.01k | if ((2 * fs == 44100) && (sub_d(k2, k0) > MAX_FREQ_COEFFS)) { |
326 | 0 | return -1; |
327 | 0 | } |
328 | 2.01k | if ((2 * fs >= 48000) && (sub_d(k2, k0) > MAX_FREQ_COEFFS)) { |
329 | 0 | return -1; |
330 | 0 | } |
331 | 61.3k | } else { |
332 | 61.3k | if ((sub_d(k2, k0) > MAX_FREQ_COEFFS_SBR) || (k2 <= k0)) { |
333 | 52 | return -1; |
334 | 52 | } |
335 | 61.2k | if ((fs == 44100) && (sub_d(k2, k0) > MAX_FREQ_COEFFS_FS44100)) { |
336 | 10 | return -1; |
337 | 10 | } |
338 | 61.2k | if ((fs >= 48000) && (sub_d(k2, k0) > MAX_FREQ_COEFFS_FS48000)) { |
339 | 24 | return -1; |
340 | 24 | } |
341 | 61.2k | } |
342 | | |
343 | 63.2k | if (ptr_header_data->freq_scale == 0) { |
344 | 9.45k | WORD16 num_bands; |
345 | 9.45k | if (ptr_header_data->alter_scale == 0) { |
346 | 8.33k | dk = 1; |
347 | 8.33k | num_bands = (WORD16)(k2 - k0); |
348 | 8.33k | num_bands = num_bands - (num_bands & 0x1); |
349 | 8.33k | } else { |
350 | 1.12k | dk = 2; |
351 | 1.12k | num_bands = (WORD16)((k2 - k0) + 2) >> 2; |
352 | 1.12k | num_bands = num_bands << 1; |
353 | 1.12k | } |
354 | 9.45k | if (num_bands < 1) { |
355 | 2 | return -1; |
356 | 2 | } |
357 | 9.45k | k2_achived = k0 + (num_bands << (dk - 1)); |
358 | | |
359 | 9.45k | k2_diff = k2 - k2_achived; |
360 | | |
361 | 263k | for (k = 0; k < num_bands; k++) { |
362 | 254k | vec_dk[k] = dk; |
363 | 254k | } |
364 | | |
365 | 9.45k | if (k2_diff < 0) { |
366 | 920 | incr = 1; |
367 | 920 | k = 0; |
368 | 920 | } |
369 | 9.45k | if (k2_diff > 0) { |
370 | 4.14k | incr = -1; |
371 | 4.14k | k = sub_d(num_bands, 1); |
372 | 4.14k | } |
373 | 15.3k | while (k2_diff != 0) { |
374 | 5.90k | vec_dk[k] = vec_dk[k] - incr; |
375 | 5.90k | k = (WORD16)(k + incr); |
376 | 5.90k | k2_diff = k2_diff + incr; |
377 | 5.90k | } |
378 | 9.45k | f_master_tbl[0] = k0; |
379 | 263k | for (k = 1; k <= num_bands; k++) |
380 | 254k | f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk[k - 1]; |
381 | 9.45k | num_mf_bands = num_bands; |
382 | 53.8k | } else { |
383 | 53.8k | WORD32 num_bands0; |
384 | 53.8k | WORD32 num_bands1; |
385 | | |
386 | 53.8k | switch (ptr_header_data->freq_scale) { |
387 | 3.71k | case 1: |
388 | 3.71k | bands = 12; |
389 | 3.71k | break; |
390 | 46.6k | case 2: |
391 | 46.6k | bands = 10; |
392 | 46.6k | break; |
393 | 3.39k | case 3: |
394 | 3.39k | bands = 8; |
395 | 3.39k | break; |
396 | 0 | default: |
397 | 0 | bands = 8; |
398 | 53.8k | }; |
399 | | |
400 | 53.8k | if ((upsamp_fac == 4) && (k0 < bands)) { |
401 | 1.66k | bands = ((WORD32)(k0 - (k0 & 1))); |
402 | 1.66k | } |
403 | | |
404 | 53.8k | if ((WORD32)(10000 * k2) > (WORD32)(22449 * k0)) { |
405 | 42.5k | k1 = k0 << 1; |
406 | | |
407 | 42.5k | num_bands0 = bands; |
408 | | |
409 | 42.5k | num_bands1 = pstr_common_tables->log_dual_is_table[k2] - |
410 | 42.5k | pstr_common_tables->log_dual_is_table[k1]; |
411 | 42.5k | num_bands1 = bands * num_bands1; |
412 | | |
413 | 42.5k | if (ptr_header_data->alter_scale) { |
414 | 36.3k | num_bands1 = (WORD32)(((WORD64)num_bands1 * (0x6276)) >> 15); |
415 | 36.3k | } |
416 | 42.5k | num_bands1 = num_bands1 + 0x1000; |
417 | | |
418 | 42.5k | num_bands1 = num_bands1 >> 13; |
419 | 42.5k | num_bands1 = num_bands1 << 1; |
420 | | |
421 | 42.5k | if (num_bands0 < 1) { |
422 | 1 | return -1; |
423 | 1 | } |
424 | | |
425 | 42.5k | if (num_bands1 < 1) { |
426 | 2 | return -1; |
427 | 2 | } |
428 | | |
429 | 42.5k | ixheaacd_calc_bands(vec_dk0, k0, k1, (WORD16)num_bands0); |
430 | | |
431 | 42.5k | ixheaacd_aac_shellsort(vec_dk0, num_bands0); |
432 | | |
433 | 42.5k | f_master_tbl[0] = k0; |
434 | | |
435 | 457k | for (k = 1; k <= num_bands0; k++) |
436 | 414k | f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk0[k - 1]; |
437 | | |
438 | 42.5k | ixheaacd_calc_bands(vec_dk1, k1, k2, (WORD16)num_bands1); |
439 | 42.5k | ixheaacd_aac_shellsort(vec_dk1, num_bands1); |
440 | | |
441 | 42.5k | if (vec_dk1[0] < vec_dk0[num_bands0 - 1]) { |
442 | 2.51k | WORD16 change = vec_dk0[num_bands0 - 1] - vec_dk1[0]; |
443 | 2.51k | WORD16 temp = vec_dk1[num_bands1 - 1] - vec_dk1[0]; |
444 | 2.51k | temp = temp >> 1; |
445 | 2.51k | if (change > temp) { |
446 | 395 | change = temp; |
447 | 395 | } |
448 | 2.51k | vec_dk1[0] = vec_dk1[0] + change; |
449 | 2.51k | vec_dk1[num_bands1 - 1] = vec_dk1[num_bands1 - 1] - change; |
450 | 2.51k | ixheaacd_aac_shellsort(vec_dk1, num_bands1); |
451 | 2.51k | } |
452 | | |
453 | 42.5k | f_master_tbl[num_bands0] = k1; |
454 | 340k | for (k = 1; k <= num_bands1; k++) |
455 | 297k | f_master_tbl[num_bands0 + k] = |
456 | 297k | f_master_tbl[num_bands0 + k - 1] + vec_dk1[k - 1]; |
457 | 42.5k | num_mf_bands = add_d(num_bands0, num_bands1); |
458 | 42.5k | } else { |
459 | 11.2k | k1 = k2; |
460 | | |
461 | 11.2k | num_bands0 = pstr_common_tables->log_dual_is_table[k1] - |
462 | 11.2k | pstr_common_tables->log_dual_is_table[k0]; |
463 | | |
464 | 11.2k | num_bands0 = bands * num_bands0; |
465 | | |
466 | 11.2k | num_bands0 = num_bands0 + 0x1000; |
467 | | |
468 | 11.2k | num_bands0 = num_bands0 >> 13; |
469 | 11.2k | num_bands0 = num_bands0 << 1; |
470 | | |
471 | 11.2k | if (num_bands0 < 1) { |
472 | 7 | return -1; |
473 | 7 | } |
474 | 11.2k | ixheaacd_calc_bands(vec_dk0, k0, k1, (WORD16)num_bands0); |
475 | 11.2k | ixheaacd_aac_shellsort(vec_dk0, num_bands0); |
476 | | |
477 | 11.2k | if (vec_dk0[0] == 0) { |
478 | 27 | return -1; |
479 | 27 | } |
480 | | |
481 | 11.1k | f_master_tbl[0] = k0; |
482 | 95.5k | for (k = 1; k <= num_bands0; k++) |
483 | 84.3k | f_master_tbl[k] = f_master_tbl[k - 1] + vec_dk0[k - 1]; |
484 | | |
485 | 11.1k | num_mf_bands = num_bands0; |
486 | 11.1k | } |
487 | 53.8k | } |
488 | 63.2k | if (num_mf_bands < 1) { |
489 | 0 | return -1; |
490 | 0 | } |
491 | 63.2k | pstr_freq_band_data->num_mf_bands = num_mf_bands; |
492 | | |
493 | 63.2k | if (upsamp_fac == 4) { |
494 | 20.7k | for (k = 1; k < num_mf_bands; k++) { |
495 | 18.7k | if (!(f_master_tbl[k] - f_master_tbl[k - 1] <= k0 - 2)) { |
496 | 14 | return -1; |
497 | 14 | } |
498 | 18.7k | } |
499 | 2.00k | } |
500 | | |
501 | 63.2k | return 0; |
502 | 63.2k | } |
503 | | |
504 | | static WORD16 ixheaacd_calc_freq_ratio(WORD16 k_start, WORD16 k_stop, |
505 | 96.3k | WORD16 num_bands) { |
506 | 96.3k | WORD32 bandfactor; |
507 | 96.3k | WORD32 step; |
508 | 96.3k | WORD32 direction; |
509 | 96.3k | WORD32 start; |
510 | 96.3k | WORD32 stop; |
511 | 96.3k | WORD32 temp; |
512 | 96.3k | WORD32 j, i; |
513 | | |
514 | 96.3k | bandfactor = 0x3f000000L; |
515 | 96.3k | step = 0x20000000L; |
516 | 96.3k | direction = 1; |
517 | 96.3k | start = ixheaac_shl32(ixheaac_deposit16l_in32(k_start), INT_BITS - 8); |
518 | 96.3k | stop = ixheaac_shl32(ixheaac_deposit16l_in32(k_stop), INT_BITS - 8); |
519 | | |
520 | 96.3k | i = 0; |
521 | | |
522 | 4.40M | do { |
523 | 4.40M | i = i + 1; |
524 | 4.40M | temp = stop; |
525 | | |
526 | 40.7M | for (j = 0; j < num_bands; j++) |
527 | 36.3M | temp = ixheaac_mult16x16in32_shl(ixheaac_extract16h(temp), |
528 | 36.3M | ixheaac_extract16h(bandfactor)); |
529 | | |
530 | 4.40M | if (temp < start) { |
531 | 2.64M | if (direction == 0) step = ixheaac_shr32(step, 1); |
532 | 2.64M | direction = 1; |
533 | 2.64M | bandfactor = ixheaac_add32_sat(bandfactor, step); |
534 | 2.64M | } else { |
535 | 1.75M | if (direction == 1) step = ixheaac_shr32(step, 1); |
536 | 1.75M | direction = 0; |
537 | 1.75M | bandfactor = ixheaac_sub32_sat(bandfactor, step); |
538 | 1.75M | } |
539 | | |
540 | 4.40M | if (i > 100) { |
541 | 0 | step = 0; |
542 | 0 | } |
543 | 4.40M | } while (step > 0); |
544 | | |
545 | 96.3k | return ixheaac_extract16h(bandfactor); |
546 | 96.3k | } |
547 | | |
548 | | VOID ixheaacd_calc_bands(WORD16 *diff, WORD16 start, WORD16 stop, |
549 | 96.3k | WORD16 num_bands) { |
550 | 96.3k | WORD32 i; |
551 | 96.3k | WORD32 previous; |
552 | 96.3k | WORD32 current; |
553 | 96.3k | WORD32 temp, exact; |
554 | 96.3k | WORD16 bandfactor = ixheaacd_calc_freq_ratio(start, stop, num_bands); |
555 | | |
556 | 96.3k | previous = stop; |
557 | 96.3k | exact = ixheaac_shl32_sat(ixheaac_deposit16l_in32(stop), INT_BITS - 8); |
558 | | |
559 | 893k | for (i = num_bands - 1; i >= 0; i--) { |
560 | 797k | exact = ixheaac_mult16x16in32(ixheaac_extract16h(exact), bandfactor); |
561 | | |
562 | 797k | temp = ixheaac_add32_sat(exact, 0x00400000); |
563 | 797k | exact = exact << 1; |
564 | | |
565 | 797k | current = ixheaac_extract16l(ixheaac_shr32(temp, (INT_BITS - 9))); |
566 | | |
567 | 797k | diff[i] = sub_d(previous, current); |
568 | 797k | previous = current; |
569 | 797k | } |
570 | 96.3k | } |
571 | | |
572 | | static VOID ixheaacd_derive_hi_lo_freq_bnd_tbls( |
573 | | ia_freq_band_data_struct *pstr_freq_band_data, |
574 | 63.1k | ia_sbr_header_data_struct *ptr_header_data) { |
575 | 63.1k | WORD16 k; |
576 | 63.1k | WORD16 xover_band = ptr_header_data->xover_band; |
577 | 63.1k | WORD16 *f_master_tbl = pstr_freq_band_data->f_master_tbl + xover_band; |
578 | 63.1k | WORD16 *f_low_tbl = pstr_freq_band_data->freq_band_table[LOW]; |
579 | 63.1k | WORD16 *f_high_tbl = pstr_freq_band_data->freq_band_table[HIGH]; |
580 | 63.1k | WORD16 num_mf_bands = pstr_freq_band_data->num_mf_bands; |
581 | 63.1k | WORD16 num_lf_bands, num_hf_bands; |
582 | 63.1k | num_hf_bands = num_mf_bands - xover_band; |
583 | 63.1k | k = 0; |
584 | 63.1k | *f_low_tbl = *f_high_tbl = *f_master_tbl; |
585 | 63.1k | f_low_tbl++; |
586 | 63.1k | f_high_tbl++; |
587 | 63.1k | f_master_tbl++; |
588 | 63.1k | k++; |
589 | 63.1k | if ((num_hf_bands & 1)) { |
590 | 20.1k | *f_low_tbl = *f_high_tbl = *f_master_tbl; |
591 | 20.1k | f_high_tbl++; |
592 | 20.1k | f_master_tbl++; |
593 | 20.1k | f_low_tbl++; |
594 | 20.1k | k++; |
595 | 20.1k | } |
596 | 485k | for (; k <= num_hf_bands; k++) { |
597 | 422k | *f_high_tbl = *f_master_tbl; |
598 | 422k | f_high_tbl++; |
599 | 422k | f_master_tbl++; |
600 | 422k | k++; |
601 | | |
602 | 422k | *f_low_tbl = *f_high_tbl = *f_master_tbl; |
603 | 422k | f_high_tbl++; |
604 | 422k | f_master_tbl++; |
605 | 422k | f_low_tbl++; |
606 | 422k | } |
607 | 63.1k | num_lf_bands = ((num_hf_bands + 1) >> 1); |
608 | | |
609 | 63.1k | pstr_freq_band_data->num_sf_bands[LOW] = num_lf_bands; |
610 | 63.1k | pstr_freq_band_data->num_sf_bands[HIGH] = num_hf_bands; |
611 | 63.1k | } |
612 | | |
613 | | WORD32 ixheaacd_derive_noise_freq_bnd_tbl( |
614 | | ia_sbr_header_data_struct *ptr_header_data, |
615 | | ixheaacd_misc_tables *pstr_common_tables, |
616 | 62.8k | ia_freq_band_data_struct *pstr_freq_band_data) { |
617 | 62.8k | WORD16 k2, kx; |
618 | 62.8k | WORD32 temp; |
619 | 62.8k | WORD32 num_lf_bands = pstr_freq_band_data->num_sf_bands[LOW]; |
620 | 62.8k | WORD32 num_hf_bands = pstr_freq_band_data->num_sf_bands[HIGH]; |
621 | 62.8k | k2 = pstr_freq_band_data->freq_band_table[HIGH][num_hf_bands]; |
622 | 62.8k | kx = pstr_freq_band_data->freq_band_table[HIGH][0]; |
623 | | |
624 | 62.8k | if (ptr_header_data->noise_bands == 0) { |
625 | 5.82k | temp = 1; |
626 | 57.0k | } else { |
627 | 57.0k | temp = pstr_common_tables->log_dual_is_table[k2] - |
628 | 57.0k | pstr_common_tables->log_dual_is_table[kx]; |
629 | 57.0k | temp = temp * ptr_header_data->noise_bands; |
630 | 57.0k | temp = temp + 0x800; |
631 | 57.0k | temp = temp >> 12; |
632 | 57.0k | if (temp == 0) { |
633 | 3.51k | temp = 1; |
634 | 3.51k | } |
635 | 57.0k | } |
636 | 62.8k | if (temp > MAX_NOISE_COEFFS) { |
637 | 13 | return -1; |
638 | 13 | } |
639 | 62.8k | pstr_freq_band_data->num_nf_bands = temp; |
640 | 62.8k | pstr_freq_band_data->num_if_bands = pstr_freq_band_data->num_nf_bands; |
641 | 62.8k | { |
642 | 62.8k | WORD16 i_k, k; |
643 | 62.8k | WORD16 num, den; |
644 | 62.8k | WORD16 *f_noise_tbl = pstr_freq_band_data->freq_band_tbl_noise; |
645 | 62.8k | WORD16 *f_low_tbl = pstr_freq_band_data->freq_band_table[LOW]; |
646 | 62.8k | WORD32 num_nf_bands = pstr_freq_band_data->num_nf_bands; |
647 | | |
648 | 62.8k | num = num_lf_bands; |
649 | 62.8k | den = num_nf_bands; |
650 | | |
651 | 62.8k | k = 0; |
652 | 62.8k | *f_noise_tbl = f_low_tbl[0]; |
653 | 62.8k | f_noise_tbl++; |
654 | 62.8k | k++; |
655 | 62.8k | i_k = 0; |
656 | | |
657 | 224k | for (; k <= num_nf_bands; k++) { |
658 | 162k | i_k = i_k + (WORD16)ixheaacd_int_div(num, den); |
659 | 162k | *f_noise_tbl = f_low_tbl[i_k]; |
660 | 162k | num = num_lf_bands - i_k; |
661 | 162k | den = den - 1; |
662 | 162k | f_noise_tbl++; |
663 | 162k | } |
664 | 62.8k | } |
665 | 62.8k | return 0; |
666 | 62.8k | } |
667 | | |
668 | | WORD32 ixheaacd_calc_frq_bnd_tbls(ia_sbr_header_data_struct *ptr_header_data, |
669 | 63.3k | ixheaacd_misc_tables *pstr_common_tables) { |
670 | 63.3k | WORD32 err; |
671 | 63.3k | WORD16 num_lf_bands, lsb, usb; |
672 | 63.3k | ia_freq_band_data_struct *pstr_freq_band_data = |
673 | 63.3k | ptr_header_data->pstr_freq_band_data; |
674 | | |
675 | 63.3k | err = ixheaacd_calc_master_frq_bnd_tbl(pstr_freq_band_data, ptr_header_data, |
676 | 63.3k | pstr_common_tables); |
677 | | |
678 | 63.3k | if (err || |
679 | 63.3k | (ptr_header_data->xover_band > pstr_freq_band_data->num_mf_bands)) { |
680 | 236 | return -1; |
681 | 236 | } |
682 | | |
683 | 63.1k | ixheaacd_derive_hi_lo_freq_bnd_tbls(pstr_freq_band_data, ptr_header_data); |
684 | | |
685 | 63.1k | num_lf_bands = pstr_freq_band_data->num_sf_bands[LOW]; |
686 | | |
687 | 63.1k | if ((num_lf_bands <= 0) || |
688 | 63.1k | (num_lf_bands > ixheaac_shr16(MAX_FREQ_COEFFS, 1))) { |
689 | 37 | return -1; |
690 | 37 | } |
691 | | |
692 | 63.0k | lsb = pstr_freq_band_data->freq_band_table[LOW][0]; |
693 | 63.0k | usb = pstr_freq_band_data->freq_band_table[LOW][num_lf_bands]; |
694 | | |
695 | 63.0k | pstr_freq_band_data->sub_band_start = lsb; |
696 | | |
697 | 63.0k | ptr_header_data->status = 1; |
698 | | |
699 | 63.0k | if ((lsb > ((ptr_header_data->sbr_ratio_idx == SBR_UPSAMPLE_IDX_4_1) ? 16 : 32)) || |
700 | 63.0k | (lsb >= usb)) { |
701 | 253 | return -1; |
702 | 253 | } |
703 | | |
704 | 62.8k | if (ixheaacd_derive_noise_freq_bnd_tbl(ptr_header_data, pstr_common_tables, |
705 | 62.8k | pstr_freq_band_data)) { |
706 | 13 | return -1; |
707 | 13 | } |
708 | | |
709 | 62.8k | pstr_freq_band_data->sub_band_start = lsb; |
710 | 62.8k | pstr_freq_band_data->sub_band_end = usb; |
711 | | |
712 | 62.8k | return 0; |
713 | 62.8k | } |