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