• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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