Coverage Report

Created: 2026-09-03 07:06

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