Coverage Report

Created: 2024-06-21 06:45

/src/libxaac/decoder/ixheaacd_env_dec.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
#include <string.h>
21
#include <math.h>
22
#include "ixheaacd_sbr_common.h"
23
#include "ixheaac_type_def.h"
24
#include "ixheaac_error_standards.h"
25
#include "ixheaac_constants.h"
26
#include "ixheaac_basic_ops32.h"
27
#include "ixheaac_basic_ops16.h"
28
#include "ixheaac_basic_ops40.h"
29
#include "ixheaac_basic_ops.h"
30
#include "ixheaac_basic_op.h"
31
#include "ixheaacd_intrinsics.h"
32
#include "ixheaacd_bitbuffer.h"
33
#include "ixheaacd_sbrdecsettings.h"
34
#include "ixheaacd_sbr_scale.h"
35
#include "ixheaacd_lpp_tran.h"
36
#include "ixheaacd_env_extr_part.h"
37
#include "ixheaacd_sbr_rom.h"
38
#include "ixheaacd_hybrid.h"
39
#include "ixheaacd_ps_dec.h"
40
#include "ixheaacd_env_extr.h"
41
#include "ixheaacd_common_rom.h"
42
#include "ixheaacd_env_dec.h"
43
#include "ixheaac_sbr_const.h"
44
#include "ixheaacd_basic_funcs.h"
45
#include "ixheaacd_audioobjtypes.h"
46
47
5.49M
#define add16_m(a, b) ((a) + (b))
48
984k
#define sub16_m(a, b) ((a) - (b))
49
50
#define mult16x16_16(a, b) ixheaac_mult16((a), (b))
51
52
static VOID ixheaacd_dequant_esbr_env_data(FLOAT32 *ptr_env_sf,
53
                                           WORD32 num_env_sf,
54
                                           WORD32 num_noise_fac, WORD32 amp_res,
55
163k
                                           FLOAT32 *ptr_noise_floor) {
56
163k
  WORD32 i;
57
163k
  const FLOAT32 array[2] = {0.5f, 1.0f};
58
163k
  FLOAT32 a_flt = array[amp_res];
59
60
1.98M
  for (i = 0; i < num_env_sf; i++) {
61
1.81M
    ptr_env_sf[i] = (FLOAT32)(pow(2, ptr_env_sf[i] * a_flt) * 64);
62
1.81M
  }
63
64
608k
  for (i = 0; i < num_noise_fac; i++) {
65
445k
    FLOAT32 temp = ptr_noise_floor[i];
66
67
445k
    temp = NOISE_FLOOR_OFFSET - temp;
68
445k
    temp = (FLOAT32)pow(2.0f, temp);
69
70
445k
    ptr_noise_floor[i] = temp;
71
445k
  }
72
163k
}
73
74
static VOID ixheaacd_dequant_pvc_env_data(WORD32 num_noise_fac,
75
73.5k
                                          FLOAT32 *ptr_noise_floor) {
76
73.5k
  WORD32 i;
77
78
349k
  for (i = 0; i < num_noise_fac; i++) {
79
275k
    FLOAT32 temp = ptr_noise_floor[i];
80
81
275k
    temp = NOISE_FLOOR_OFFSET - temp;
82
275k
    temp = (FLOAT32)pow(2.0f, temp);
83
84
275k
    ptr_noise_floor[i] = temp;
85
275k
  }
86
73.5k
}
87
88
VOID ixheaacd_map_res_energy(WORD16 curr_val, WORD16 *prev_data,
89
                             WORD32 ixheaacd_drc_offset, WORD32 index,
90
1.96M
                             WORD32 res) {
91
1.96M
  if (res == LOW) {
92
1.24M
    if (ixheaacd_drc_offset >= 0) {
93
1.24M
      if (index < ixheaacd_drc_offset) {
94
27.9k
        prev_data[index] = curr_val;
95
1.22M
      } else {
96
1.22M
        WORD32 index_2;
97
1.22M
        index_2 = ((index + index) - ixheaacd_drc_offset);
98
1.22M
        prev_data[index_2] = curr_val;
99
1.22M
        prev_data[index_2 + 1] = curr_val;
100
1.22M
      }
101
1.24M
    } else {
102
0
      ixheaacd_drc_offset = -(ixheaacd_drc_offset);
103
104
0
      if (index < ixheaacd_drc_offset) {
105
0
        WORD32 index_3;
106
0
        index_3 = ((index + index) + index);
107
0
        prev_data[index_3] = curr_val;
108
0
        prev_data[index_3 + 1] = curr_val;
109
0
        prev_data[index_3 + 2] = curr_val;
110
0
      } else {
111
0
        WORD32 index_2;
112
0
        index_2 = ((index + index) + ixheaacd_drc_offset);
113
0
        prev_data[index_2] = curr_val;
114
0
        prev_data[index_2 + 1] = curr_val;
115
0
      }
116
0
    }
117
1.24M
  } else {
118
721k
    prev_data[index] = curr_val;
119
721k
  }
120
1.96M
}
121
122
VOID ixheaacd_process_del_cod_env_data(
123
    ia_sbr_header_data_struct *ptr_header_data,
124
    ia_sbr_frame_info_data_struct *ptr_sbr_data,
125
249k
    ia_sbr_prev_frame_data_struct *ptr_prev_data) {
126
249k
  WORD32 i, dtdf_dir, num_sf_bands, band, freq_res;
127
249k
  WORD16 temp_val;
128
249k
  WORD16 *ptr_prev_env_sf = ptr_prev_data->sfb_nrg_prev;
129
249k
  WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;
130
131
249k
  FLOAT32 *ptr_env_sf_float = ptr_sbr_data->flt_env_sf_arr;
132
133
249k
  WORD32 ixheaacd_drc_offset;
134
249k
  band = 0;
135
136
249k
  ixheaacd_drc_offset =
137
249k
      ((ptr_header_data->pstr_freq_band_data->num_sf_bands[LOW] << 1) -
138
249k
       ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH]);
139
140
654k
  for (i = 0; i < ptr_sbr_data->str_frame_info_details.num_env; i++) {
141
404k
    dtdf_dir = ptr_sbr_data->del_cod_dir_arr[i];
142
404k
    freq_res = ptr_sbr_data->str_frame_info_details.freq_res[i];
143
144
404k
    num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands[freq_res];
145
146
404k
    if (dtdf_dir == DTDF_DIR_FREQ) {
147
231k
      ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf, ixheaacd_drc_offset,
148
231k
                              0, freq_res);
149
231k
      ptr_env_sf++;
150
151
231k
      ptr_env_sf_float++;
152
153
1.96M
      for (band = 1; band < num_sf_bands; band++) {
154
1.73M
        *ptr_env_sf = *ptr_env_sf + *(ptr_env_sf - 1);
155
1.73M
        ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf,
156
1.73M
                                ixheaacd_drc_offset, band, freq_res);
157
158
1.73M
        *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
159
1.73M
        ptr_env_sf_float++;
160
161
1.73M
        ptr_env_sf++;
162
1.73M
      }
163
164
231k
    } else {
165
173k
      if (freq_res == LOW) {
166
63.6k
        if (ixheaacd_drc_offset < 0) {
167
0
          WORD32 tar, index_3;
168
0
          ixheaacd_drc_offset = -ixheaacd_drc_offset;
169
0
          tar = ixheaac_min32(ixheaacd_drc_offset, band);
170
171
0
          for (band = 0; band < tar; band++) {
172
0
            index_3 = ((band + band) + band);
173
0
            temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);
174
175
0
            ptr_prev_env_sf[index_3] = temp_val;
176
0
            ptr_prev_env_sf[index_3 + 1] = temp_val;
177
0
            ptr_prev_env_sf[index_3 + 2] = temp_val;
178
0
            *ptr_env_sf++ = temp_val;
179
180
0
            *ptr_env_sf_float = (FLOAT32)temp_val;
181
0
            ptr_env_sf_float++;
182
0
          }
183
184
0
          for (; band < num_sf_bands; band++) {
185
0
            index_3 = (band << 1) + ixheaacd_drc_offset;
186
0
            temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);
187
0
            ptr_prev_env_sf[index_3] = temp_val;
188
0
            ptr_prev_env_sf[index_3 + 1] = temp_val;
189
0
            *ptr_env_sf++ = temp_val;
190
0
            *ptr_env_sf_float = (FLOAT32)temp_val;
191
0
            ptr_env_sf_float++;
192
0
          }
193
63.6k
        } else {
194
63.6k
          WORD32 tar, index_2;
195
63.6k
          WORD16 *ptr2 = ptr_prev_env_sf;
196
63.6k
          tar = ixheaac_min32(ixheaacd_drc_offset, band);
197
69.1k
          for (band = 0; band < tar; band++) {
198
5.53k
            *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
199
5.53k
            *ptr2 = *ptr_env_sf;
200
201
5.53k
            *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
202
5.53k
            ptr_env_sf_float++;
203
204
5.53k
            ptr2++;
205
5.53k
            ptr_env_sf++;
206
5.53k
          }
207
208
418k
          for (; band < num_sf_bands; band++) {
209
354k
            index_2 = (band < ixheaacd_drc_offset)
210
354k
                          ? band
211
354k
                          : ((band << 1) - ixheaacd_drc_offset);
212
354k
            temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_2]);
213
354k
            ptr_prev_env_sf[index_2] = temp_val;
214
354k
            ptr_prev_env_sf[index_2 + 1] = temp_val;
215
354k
            *ptr_env_sf++ = temp_val;
216
217
354k
            *ptr_env_sf_float = (FLOAT32)temp_val;
218
354k
            ptr_env_sf_float++;
219
354k
          }
220
63.6k
        }
221
222
109k
      } else {
223
109k
        WORD16 *ptr2 = ptr_prev_env_sf;
224
1.23M
        for (band = num_sf_bands - 1; band >= 0; band--) {
225
1.12M
          *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
226
1.12M
          *ptr2 = *ptr_env_sf;
227
1.12M
          *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
228
1.12M
          ptr_env_sf_float++;
229
1.12M
          ptr2++;
230
1.12M
          ptr_env_sf++;
231
1.12M
        }
232
109k
        band = num_sf_bands;
233
109k
      }
234
173k
    }
235
404k
  }
236
249k
}
237
238
static PLATFORM_INLINE WORD32
239
ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
240
                                 ia_sbr_frame_info_data_struct *ptr_sbr_data,
241
                                 ia_sbr_prev_frame_data_struct *ptr_prev_data,
242
6.09k
                                 ixheaacd_misc_tables *pstr_common_tables) {
243
6.09k
  WORD32 i, num_env_sf;
244
6.09k
  ia_frame_info_struct *p_frame_info = &ptr_sbr_data->str_frame_info_details;
245
6.09k
  WORD16 *num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands;
246
6.09k
  WORD32 start_pos_est;
247
6.09k
  WORD32 ref_len, new_len, shift;
248
6.09k
  WORD16 delta_exp;
249
250
6.09k
  start_pos_est =
251
6.09k
      (ptr_prev_data->end_position - ptr_header_data->num_time_slots);
252
253
6.09k
  ref_len = (p_frame_info->border_vec[1] - p_frame_info->border_vec[0]);
254
255
6.09k
  new_len = (p_frame_info->border_vec[1] - start_pos_est);
256
257
6.09k
  if (new_len <= 0) {
258
995
    new_len = ref_len;
259
995
    start_pos_est = p_frame_info->border_vec[0];
260
995
  }
261
262
6.09k
  delta_exp = pstr_common_tables->log_dual_is_table[ref_len];
263
6.09k
  delta_exp -= pstr_common_tables->log_dual_is_table[new_len];
264
265
6.09k
  shift = (SHORT_BITS - ENV_EXP_FRACT - 3 - ptr_sbr_data->amp_res);
266
6.09k
  delta_exp = ixheaac_shr16(delta_exp, (WORD16)shift);
267
6.09k
  p_frame_info->border_vec[0] = start_pos_est;
268
6.09k
  p_frame_info->noise_border_vec[0] = start_pos_est;
269
270
6.09k
  if (start_pos_est < 0) return -1;
271
272
6.09k
  if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
273
5.46k
    num_env_sf =
274
5.46k
        ((p_frame_info->freq_res[0]) ? num_sf_bands[HIGH] : num_sf_bands[LOW]);
275
276
48.5k
    for (i = 0; i < num_env_sf; i++) {
277
43.0k
      ptr_sbr_data->int_env_sf_arr[i] =
278
43.0k
          add16_m(ptr_sbr_data->int_env_sf_arr[i], delta_exp);
279
43.0k
      ptr_sbr_data->flt_env_sf_arr[i] =
280
43.0k
          (FLOAT32)(ptr_sbr_data->int_env_sf_arr[i]);
281
43.0k
    }
282
5.46k
  }
283
284
6.09k
  return 0;
285
6.09k
}
286
287
WORD16 ixheaacd_check_env_data(ia_sbr_header_data_struct *ptr_header_data,
288
                               ia_sbr_frame_info_data_struct *ptr_sbr_data,
289
25.5k
                               ia_sbr_prev_frame_data_struct *ptr_prev_data) {
290
25.5k
  WORD16 *ptr_evn_sf = ptr_sbr_data->int_env_sf_arr;
291
25.5k
  FLOAT32 *ptr_evn_sf_float = ptr_sbr_data->flt_env_sf_arr;
292
25.5k
  WORD16 *ptr_prev_evn_sf = ptr_prev_data->sfb_nrg_prev;
293
25.5k
  WORD32 i;
294
25.5k
  FLAG error_code = 0;
295
25.5k
  WORD16 sbr_max_env_sf;
296
25.5k
  WORD32 amp_res = ptr_sbr_data->amp_res;
297
298
25.5k
  sbr_max_env_sf = (SBR_ENV_SF_MAX_VAL_1_5 >> amp_res);
299
300
496k
  for (i = 0; i < ptr_sbr_data->num_env_sfac; i++) {
301
471k
    if (ptr_evn_sf[i] > sbr_max_env_sf) {
302
64.8k
      error_code = 1;
303
64.8k
    }
304
471k
    if (ptr_evn_sf[i] < 0) {
305
73.3k
      ptr_evn_sf[i] = 0;
306
73.3k
      ptr_evn_sf_float[i] = 0;
307
73.3k
    }
308
471k
  }
309
310
326k
  for (i = 0; i < ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
311
301k
       i++) {
312
301k
    if (ptr_prev_evn_sf[i] < 0) {
313
46.4k
      ptr_prev_evn_sf[i] = 0;
314
254k
    } else {
315
254k
      if (ptr_prev_evn_sf[i] > sbr_max_env_sf)
316
44.7k
        ptr_prev_evn_sf[i] = sbr_max_env_sf;
317
254k
    }
318
301k
  }
319
25.5k
  return (WORD16)(error_code);
320
25.5k
}
321
322
VOID ixheaacd_dequant_env_data(ia_sbr_frame_info_data_struct *ptr_sbr_data,
323
58.0k
                               WORD32 amp_res) {
324
58.0k
  WORD32 i;
325
58.0k
  WORD32 num_env_sf = ptr_sbr_data->num_env_sfac;
326
58.0k
  WORD32 mantissa;
327
58.0k
  WORD32 amp_res_1;
328
58.0k
  WORD32 exponent;
329
58.0k
  WORD32 exp_add = (7 + NRG_EXP_OFFSET);
330
58.0k
  WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;
331
58.0k
  const WORD32 mant_arr[2] = {0x4000, 0x5a80};
332
333
58.0k
  amp_res_1 = (1 - amp_res);
334
335
823k
  for (i = num_env_sf - 1; i >= 0; i--) {
336
765k
    exponent = *ptr_env_sf;
337
765k
    mantissa = mant_arr[(exponent & amp_res_1)];
338
765k
    exponent = (exponent >> amp_res_1);
339
765k
    exponent = (exponent + exp_add);
340
765k
    *ptr_env_sf++ = (WORD16)(mantissa | (exponent & MASK_FOR_EXP));
341
765k
  }
342
58.0k
}
343
344
static PLATFORM_INLINE VOID
345
ixheaacd_limit_noise_floor_fac(ia_sbr_header_data_struct *ptr_header_data,
346
319k
                               ia_sbr_frame_info_data_struct *ptr_sbr_data) {
347
319k
  WORD32 i, tot_nf_bands;
348
319k
  WORD32 value;
349
319k
  WORD32 num_nf_bands;
350
319k
  WORD16 *ptr_noise_floor;
351
319k
  FLOAT32 *ptr_noise_floor_flt;
352
353
319k
  num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
354
355
319k
  tot_nf_bands =
356
319k
      ptr_sbr_data->str_frame_info_details.num_noise_env * num_nf_bands;
357
358
319k
  ptr_noise_floor = ptr_sbr_data->int_noise_floor;
359
360
319k
  ptr_noise_floor_flt = &ptr_sbr_data->flt_noise_floor[0];
361
362
1.24M
  for (i = tot_nf_bands - 1; i >= 0; i--) {
363
927k
    value = *ptr_noise_floor;
364
927k
    if (value > MAX_NOISE_FLOOR_FAC_VAL) {
365
28.3k
      *ptr_noise_floor = MAX_NOISE_FLOOR_FAC_VAL;
366
28.3k
      *ptr_noise_floor_flt = MAX_NOISE_FLOOR_FAC_VAL;
367
898k
    } else {
368
898k
      if (value < MIN_NOISE_FLOOR_FAC_VAL) {
369
44.8k
        *ptr_noise_floor = MIN_NOISE_FLOOR_FAC_VAL;
370
44.8k
        *ptr_noise_floor_flt = MIN_NOISE_FLOOR_FAC_VAL;
371
44.8k
      }
372
898k
    }
373
927k
    ptr_noise_floor++;
374
927k
    ptr_noise_floor_flt++;
375
927k
  }
376
319k
}
377
378
419k
VOID ixheaacd_add_arr(WORD16 *ptr1, WORD16 *ptr2, WORD32 num) {
379
419k
  WORD32 i;
380
1.08M
  for (i = num - 1; i >= 0; i--) {
381
661k
    *ptr2 = (*ptr2 + *ptr1);
382
661k
    ptr2++;
383
661k
    ptr1++;
384
661k
  }
385
419k
}
386
387
419k
VOID ixheaacd_add_farr(FLOAT32 *ptr1, FLOAT32 *ptr2, WORD32 num) {
388
419k
  WORD32 i;
389
1.08M
  for (i = num - 1; i >= 0; i--) {
390
661k
    *ptr2 = (*ptr2 + *ptr1);
391
661k
    ptr2++;
392
661k
    ptr1++;
393
661k
  }
394
419k
}
395
396
IA_ERRORCODE ixheaacd_calc_noise_floor(
397
    ia_sbr_header_data_struct *ptr_header_data,
398
    ia_sbr_frame_info_data_struct *ptr_sbr_data,
399
    ia_sbr_prev_frame_data_struct *ptr_prev_data,
400
319k
    WORD32 audio_object_type) {
401
319k
  WORD32 i;
402
319k
  WORD32 num_nf_bands;
403
319k
  WORD32 num_noise_env;
404
319k
  WORD32 ixheaacd_drc_offset;
405
319k
  WORD16 *ptr_noise_floor = ptr_sbr_data->int_noise_floor;
406
407
319k
  WORD16 *ptr_prev_noise_floor = ptr_prev_data->prev_noise_level;
408
319k
  WORD16 *ptr1, *ptr2;
409
319k
  FLOAT32 *f_ptr1, *f_ptr2;
410
319k
  WORD32 num;
411
319k
  FLOAT32 *ptr_noise_floor_float = ptr_sbr_data->flt_noise_floor;
412
413
319k
  num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
414
319k
  num_noise_env = ptr_sbr_data->str_frame_info_details.num_noise_env;
415
416
319k
  if (ptr_sbr_data->del_cod_dir_noise_arr[0] == DTDF_DIR_FREQ) {
417
216k
    ptr1 = ptr_noise_floor++;
418
216k
    ptr2 = ptr_noise_floor;
419
216k
    num = num_nf_bands - 1;
420
216k
    f_ptr1 = &ptr_noise_floor_float[0];
421
216k
    f_ptr2 = &ptr_noise_floor_float[1];
422
216k
  } else {
423
102k
    ptr1 = ptr_prev_noise_floor;
424
102k
    ptr2 = ptr_sbr_data->int_noise_floor;
425
102k
    f_ptr1 = &ptr_sbr_data->prev_noise_level[0];
426
102k
    f_ptr2 = &ptr_noise_floor_float[0];
427
102k
    num = num_nf_bands;
428
102k
  }
429
430
319k
  ixheaacd_add_arr(ptr1, ptr2, num);
431
319k
  ixheaacd_add_farr(f_ptr1, f_ptr2, num);
432
433
319k
  if (num_noise_env > 1) {
434
100k
    if (ptr_sbr_data->del_cod_dir_noise_arr[1] == DTDF_DIR_FREQ) {
435
55.3k
      ptr1 = &ptr_sbr_data->int_noise_floor[num_nf_bands];
436
55.3k
      ptr2 = &ptr_sbr_data->int_noise_floor[(num_nf_bands + 1)];
437
55.3k
      f_ptr1 = &ptr_sbr_data->flt_noise_floor[num_nf_bands];
438
55.3k
      f_ptr2 = &ptr_sbr_data->flt_noise_floor[(num_nf_bands + 1)];
439
55.3k
      num = num_nf_bands - 1;
440
55.3k
    } else {
441
44.9k
      ptr1 = &ptr_sbr_data->int_noise_floor[0];
442
44.9k
      ptr2 = &ptr_sbr_data->int_noise_floor[num_nf_bands];
443
44.9k
      f_ptr1 = &ptr_sbr_data->flt_noise_floor[0];
444
44.9k
      f_ptr2 = &ptr_sbr_data->flt_noise_floor[num_nf_bands];
445
44.9k
      num = num_nf_bands;
446
44.9k
    }
447
100k
    ixheaacd_add_arr(ptr1, ptr2, num);
448
100k
    ixheaacd_add_farr(f_ptr1, f_ptr2, num);
449
100k
  }
450
451
319k
  ixheaacd_limit_noise_floor_fac(ptr_header_data, ptr_sbr_data);
452
453
319k
  ixheaacd_drc_offset = num_nf_bands * (num_noise_env - 1);
454
319k
  if (ixheaacd_drc_offset < 0 || ixheaacd_drc_offset >= MAX_NUM_NOISE_VALUES)
455
22
    return IA_FATAL_ERROR;
456
318k
  ptr1 = &ptr_sbr_data->int_noise_floor[ixheaacd_drc_offset];
457
318k
  ptr2 = ptr_prev_noise_floor;
458
459
318k
  memcpy(ptr2, ptr1, sizeof(WORD16) * (num_nf_bands));
460
318k
  if (!ptr_header_data->usac_flag) {
461
203k
    for (i = 0; i < num_nf_bands; i++) {
462
130k
      ptr_sbr_data->prev_noise_level[i] = ptr_prev_noise_floor[i];
463
130k
    }
464
72.6k
  }
465
318k
  if (audio_object_type != AOT_ER_AAC_ELD && ptr_header_data->enh_sbr) {
466
262k
    WORD32 noise_floor_exp, tot_nf_bands;
467
468
262k
    tot_nf_bands = (num_nf_bands * num_noise_env);
469
262k
    ptr_noise_floor = &ptr_sbr_data->int_noise_floor[0];
470
471
1.05M
    for (i = 0; i < tot_nf_bands; i++) {
472
789k
      noise_floor_exp =
473
789k
          (NOISE_FLOOR_OFFSET_INT + 1 + NOISE_EXP_OFFSET - *ptr_noise_floor);
474
475
789k
      *ptr_noise_floor_float++ = *ptr_noise_floor;
476
789k
      *ptr_noise_floor++ = (WORD16)(0x4000 + (noise_floor_exp & MASK_FOR_EXP));
477
789k
    }
478
262k
  } else {
479
56.0k
    if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
480
50.9k
      WORD32 noise_floor_exp, tot_nf_bands;
481
482
50.9k
      tot_nf_bands = (num_nf_bands * num_noise_env);
483
50.9k
      ptr_noise_floor = &ptr_sbr_data->int_noise_floor[0];
484
485
175k
      for (i = 0; i < tot_nf_bands; i++) {
486
124k
        noise_floor_exp =
487
124k
            (NOISE_FLOOR_OFFSET_INT + 1 + NOISE_EXP_OFFSET - *ptr_noise_floor);
488
124k
        *ptr_noise_floor_float++ = *ptr_noise_floor;
489
124k
        *ptr_noise_floor++ = (WORD16)(0x4000 + (noise_floor_exp & MASK_FOR_EXP));
490
124k
      }
491
50.9k
    }
492
56.0k
  }
493
318k
  return IA_NO_ERROR;
494
319k
}
495
496
IA_ERRORCODE ixheaacd_dec_sbrdata_for_pvc(
497
    ia_sbr_header_data_struct *ptr_header_data,
498
    ia_sbr_frame_info_data_struct *ptr_sbr_data,
499
    ia_sbr_prev_frame_data_struct *ptr_prev_data,
500
76.8k
    WORD32 audio_object_type) {
501
76.8k
  WORD32 err = 0;
502
76.8k
  err = ixheaacd_calc_noise_floor(ptr_header_data, ptr_sbr_data, ptr_prev_data,
503
76.8k
                                  audio_object_type);
504
76.8k
  if (err) return err;
505
506
76.8k
  if (!ptr_sbr_data->coupling_mode) {
507
73.5k
    ptr_sbr_data->num_noise_sfac =
508
73.5k
        ptr_header_data->pstr_freq_band_data->num_nf_bands *
509
73.5k
        ptr_sbr_data->str_frame_info_details.num_noise_env;
510
73.5k
    ixheaacd_dequant_pvc_env_data(ptr_sbr_data->num_noise_sfac,
511
73.5k
                                  ptr_sbr_data->flt_noise_floor);
512
73.5k
  }
513
76.8k
  return IA_NO_ERROR;
514
76.8k
}
515
516
VOID ixheaacd_sbr_env_dequant_coup_fix(
517
    ia_sbr_header_data_struct *ptr_header_data,
518
    ia_sbr_frame_info_data_struct *ptr_data_left,
519
    ia_sbr_frame_info_data_struct *ptr_data_right,
520
17.7k
    ixheaacd_misc_tables *pstr_common_tables) {
521
17.7k
  WORD32 i;
522
17.7k
  WORD32 num_env_sf = ptr_data_left->num_env_sfac;
523
17.7k
  WORD16 temp_left_mant, temp_right_mant, temp_right_plus1_mant, new_left_mant,
524
17.7k
      new_right_mant;
525
17.7k
  WORD16 temp_left_exp, temp_right_exp, temp_rightplus1_exp, new_left_exp,
526
17.7k
      new_right_exp;
527
17.7k
  WORD32 i_end;
528
17.7k
  WORD16 *r_data = ptr_data_right->int_env_sf_arr;
529
17.7k
  WORD16 *l_data = ptr_data_left->int_env_sf_arr;
530
531
466k
  for (i = 0; i < num_env_sf; i++) {
532
448k
    temp_right_mant = (WORD16)(*r_data & MASK_M);
533
448k
    temp_right_exp = (WORD16)(*r_data & MASK_FOR_EXP);
534
535
448k
    temp_right_exp = sub16_m(temp_right_exp, add16_m(18, NRG_EXP_OFFSET));
536
448k
    temp_left_mant = (WORD16)(*l_data & MASK_M);
537
448k
    temp_left_exp = (WORD16)(*l_data & MASK_FOR_EXP);
538
539
448k
    temp_left_exp = sub16_m(temp_left_exp, NRG_EXP_OFFSET);
540
541
448k
    ixheaacd_fix_mant_exp_add(temp_right_mant, temp_right_exp, 0x4000, 1,
542
448k
                              &temp_right_plus1_mant, &temp_rightplus1_exp);
543
544
448k
    new_right_exp = ixheaacd_fix_mant_div(temp_left_mant, temp_right_plus1_mant,
545
448k
                                          &new_right_mant, pstr_common_tables);
546
547
448k
    new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;
548
549
448k
    new_left_mant = ixheaac_mult16_shl(temp_right_mant, new_right_mant);
550
551
448k
    new_left_exp = add16_m(temp_right_exp, new_right_exp);
552
553
448k
    *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
554
448k
                         ((new_right_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
555
448k
    *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
556
448k
                         ((new_left_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
557
448k
  }
558
559
17.7k
  i_end = ptr_header_data->pstr_freq_band_data->num_nf_bands *
560
17.7k
          ptr_data_left->str_frame_info_details.num_noise_env;
561
17.7k
  r_data = ptr_data_right->int_noise_floor;
562
17.7k
  l_data = ptr_data_left->int_noise_floor;
563
564
61.9k
  for (i = i_end - 1; i >= 0; i--) {
565
44.1k
    temp_left_exp =
566
44.1k
        sub16_m((WORD16)(*l_data & (WORD16)MASK_FOR_EXP), NOISE_EXP_OFFSET);
567
44.1k
    temp_right_exp = sub16_m(*r_data, 12);
568
569
44.1k
    ixheaacd_fix_mant_exp_add(0x4000, ixheaac_add16(1, temp_right_exp), 0x4000,
570
44.1k
                              1, &temp_right_plus1_mant, &temp_rightplus1_exp);
571
572
44.1k
    new_right_exp = ixheaacd_fix_mant_div(0x4000, temp_right_plus1_mant,
573
44.1k
                                          &new_right_mant, pstr_common_tables);
574
575
44.1k
    new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;
576
577
44.1k
    new_left_mant = new_right_mant;
578
44.1k
    new_left_exp = add16_m(new_right_exp, temp_right_exp);
579
44.1k
    *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
580
44.1k
                         ((new_right_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
581
44.1k
    *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
582
44.1k
                         ((new_left_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
583
44.1k
  }
584
17.7k
}
585
586
VOID ixheaacd_sbr_env_dequant_coup(
587
    ia_sbr_frame_info_data_struct *ptr_data_ch_0,
588
17.7k
    ia_sbr_frame_info_data_struct *ptr_data_ch_1) {
589
17.7k
  FLOAT32 *ptr_env_sf_left = ptr_data_ch_0->flt_env_sf_arr;
590
17.7k
  FLOAT32 *ptr_env_sf_right = ptr_data_ch_1->flt_env_sf_arr;
591
17.7k
  FLOAT32 *ptr_noise_floor_left = ptr_data_ch_0->flt_noise_floor;
592
17.7k
  FLOAT32 *ptr_noise_floor_right = ptr_data_ch_1->flt_noise_floor;
593
17.7k
  WORD32 num_env_sf = ptr_data_ch_0->num_env_sfac;
594
17.7k
  WORD32 num_noise_fac = ptr_data_ch_0->num_noise_sfac;
595
17.7k
  WORD32 amp_res = ptr_data_ch_0->amp_res;
596
597
17.7k
  WORD32 i;
598
17.7k
  FLOAT32 temp_l, temp_r;
599
17.7k
  const FLOAT32 pan_offset[2] = {24.0f, 12.0f};
600
17.7k
  const FLOAT32 a_arr[2] = {0.5f, 1.0f};
601
602
17.7k
  FLOAT32 a = a_arr[amp_res];
603
604
466k
  for (i = 0; i < num_env_sf; i++) {
605
448k
    temp_l = ptr_env_sf_left[i];
606
448k
    temp_r = ptr_env_sf_right[i];
607
608
448k
    ptr_env_sf_left[i] =
609
448k
        (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
610
448k
                        (1 + pow(2, (pan_offset[amp_res] - temp_r) * a))));
611
448k
    ptr_env_sf_right[i] =
612
448k
        (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
613
448k
                        (1 + pow(2, (temp_r - pan_offset[amp_res]) * a))));
614
448k
  }
615
616
61.9k
  for (i = 0; i < num_noise_fac; i++) {
617
44.1k
    temp_l = ptr_noise_floor_left[i];
618
44.1k
    temp_r = ptr_noise_floor_right[i];
619
620
44.1k
    ptr_noise_floor_left[i] =
621
44.1k
        (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
622
44.1k
                  (1 + pow(2, pan_offset[1] - temp_r)));
623
44.1k
    ptr_noise_floor_right[i] =
624
44.1k
        (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
625
44.1k
                  (1 + pow(2, temp_r - pan_offset[1])));
626
44.1k
  }
627
17.7k
}
628
IA_ERRORCODE ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
629
                                  ia_sbr_header_data_struct *ptr_header_data_ch_1,
630
                                  ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
631
                                  ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
632
                                  ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
633
                                  ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
634
                                  ixheaacd_misc_tables *ptr_common_tables, WORD32 ldmps_present,
635
179k
                                  WORD32 audio_object_type, WORD32 ec_flag) {
636
179k
  FLAG error_code;
637
179k
  WORD32 err = 0;
638
179k
  WORD16 temp_sfb_nrg_prev[MAX_FREQ_COEFFS];
639
179k
  WORD32 usac_flag = ptr_header_data_ch_0->usac_flag |
640
179k
                     ptr_header_data_ch_0->enh_sbr;
641
642
179k
  if (ec_flag) {
643
0
    memcpy(temp_sfb_nrg_prev, ptr_prev_data_ch_0->sfb_nrg_prev, MAX_FREQ_COEFFS * sizeof(WORD16));
644
0
  }
645
646
179k
  err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0, ptr_prev_data_ch_0,
647
179k
                              ptr_prev_data_ch_1, ptr_common_tables, audio_object_type, ec_flag);
648
649
179k
  if (err) return err;
650
651
179k
  err = ixheaacd_calc_noise_floor(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
652
179k
                                  ptr_prev_data_ch_0, audio_object_type);
653
179k
  if (err) return err;
654
179k
  if ((!ptr_sbr_data_ch_0->coupling_mode &&
655
179k
     ((usac_flag) && (audio_object_type != AOT_ER_AAC_ELD))) || ldmps_present) {
656
138k
    ptr_sbr_data_ch_0->num_noise_sfac =
657
138k
        ptr_header_data_ch_0->pstr_freq_band_data->num_nf_bands *
658
138k
        ptr_sbr_data_ch_0->str_frame_info_details.num_noise_env;
659
660
138k
    ixheaacd_dequant_esbr_env_data(
661
138k
        ptr_sbr_data_ch_0->flt_env_sf_arr, ptr_sbr_data_ch_0->num_env_sfac,
662
138k
        ptr_sbr_data_ch_0->num_noise_sfac, ptr_sbr_data_ch_0->amp_res,
663
138k
        ptr_sbr_data_ch_0->flt_noise_floor);
664
138k
  }
665
666
179k
  if (ptr_sbr_data_ch_1 != NULL) {
667
62.5k
    error_code = ptr_header_data_ch_0->err_flag;
668
62.5k
    err =
669
62.5k
        ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1, ptr_prev_data_ch_1,
670
62.5k
                              ptr_prev_data_ch_0, ptr_common_tables, audio_object_type, ec_flag);
671
672
62.5k
    if (err) return err;
673
674
62.5k
    err = ixheaacd_calc_noise_floor(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
675
62.5k
                                    ptr_prev_data_ch_1, audio_object_type);
676
677
62.5k
    if (err) return err;
678
679
62.5k
    if (!ptr_sbr_data_ch_1->coupling_mode &&
680
62.5k
        ((usac_flag) && (audio_object_type != AOT_ER_AAC_ELD))) {
681
24.8k
      ptr_sbr_data_ch_1->num_noise_sfac =
682
24.8k
          ptr_header_data_ch_1->pstr_freq_band_data->num_nf_bands *
683
24.8k
          ptr_sbr_data_ch_1->str_frame_info_details.num_noise_env;
684
685
24.8k
      ixheaacd_dequant_esbr_env_data(
686
24.8k
          ptr_sbr_data_ch_1->flt_env_sf_arr, ptr_sbr_data_ch_1->num_env_sfac,
687
24.8k
          ptr_sbr_data_ch_1->num_noise_sfac, ptr_sbr_data_ch_1->amp_res,
688
24.8k
          ptr_sbr_data_ch_1->flt_noise_floor);
689
24.8k
    }
690
62.5k
    if (ec_flag) {
691
0
      if ((!ptr_header_data_ch_0->usac_flag) || (audio_object_type == AOT_ER_AAC_ELD)) {
692
0
        if (!error_code && ptr_header_data_ch_0->err_flag) {
693
0
          memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, temp_sfb_nrg_prev,
694
0
                 MAX_FREQ_COEFFS * sizeof(WORD16));
695
0
          err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0, ptr_prev_data_ch_0,
696
0
                                      ptr_prev_data_ch_1, ptr_common_tables, audio_object_type,
697
0
                                      ec_flag);
698
699
0
          if (err) return err;
700
0
        }
701
0
      }
702
62.5k
    } else {
703
62.5k
      if ((!usac_flag) || (audio_object_type == AOT_ER_AAC_ELD)) {
704
25.0k
        if (!error_code && ptr_header_data_ch_0->err_flag) {
705
1.96k
          err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0, ptr_prev_data_ch_0,
706
1.96k
                                      ptr_prev_data_ch_1, ptr_common_tables, audio_object_type,
707
1.96k
                                      ec_flag);
708
709
1.96k
          if (err) return err;
710
1.96k
        }
711
25.0k
      }
712
62.5k
    }
713
714
62.5k
    if (ptr_sbr_data_ch_0->coupling_mode) {
715
17.7k
      ptr_sbr_data_ch_0->num_noise_sfac =
716
17.7k
          ptr_header_data_ch_1->pstr_freq_band_data->num_nf_bands *
717
17.7k
          ptr_sbr_data_ch_1->str_frame_info_details.num_noise_env;
718
17.7k
      ixheaacd_sbr_env_dequant_coup_fix(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
719
17.7k
                                        ptr_sbr_data_ch_1, ptr_common_tables);
720
721
17.7k
      ixheaacd_sbr_env_dequant_coup(ptr_sbr_data_ch_0, ptr_sbr_data_ch_1);
722
17.7k
    }
723
62.5k
  }
724
725
179k
  return 0;
726
179k
}
727
IA_ERRORCODE ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
728
                                   ia_sbr_frame_info_data_struct *ptr_sbr_data,
729
                                   ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
730
                                   ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
731
                                   ixheaacd_misc_tables *pstr_common_tables,
732
249k
                                   WORD32 audio_object_type, WORD32 ec_flag) {
733
249k
  FLAG error_code;
734
249k
  WORD32 err;
735
249k
  WORD16 env_sf_local_arr[MAX_FREQ_COEFFS];
736
249k
  WORD32 enh_sbr = ptr_header_data->enh_sbr;
737
249k
  WORD32 usac_flag = enh_sbr | ptr_header_data->usac_flag;
738
249k
  WORD32 temp_1 =
739
249k
      ptr_prev_data_ch_0->end_position - ptr_header_data->num_time_slots;
740
741
249k
  if (temp_1 < 0) return IA_FATAL_ERROR;
742
249k
  temp_1 = ptr_sbr_data->str_frame_info_details.border_vec[0] - temp_1;
743
744
249k
  if ((!ptr_header_data->err_flag_prev) && (!ptr_header_data->err_flag) &&
745
249k
      (temp_1 != 0)) {
746
11.6k
    if (ptr_sbr_data->del_cod_dir_arr[0] == DTDF_DIR_TIME) {
747
2.83k
      ptr_header_data->err_flag = 1;
748
8.83k
    } else {
749
8.83k
      ptr_header_data->err_flag_prev = 1;
750
8.83k
    }
751
11.6k
  }
752
249k
  if (ec_flag) {
753
0
    if (ptr_header_data->err_flag_prev && (!ptr_header_data->err_flag)) {
754
0
      if (ptr_sbr_data->del_cod_dir_arr[0] != 0) {
755
0
        ptr_header_data->err_flag = 1;
756
0
      }
757
0
    }
758
0
  }
759
249k
  if (ec_flag && ptr_header_data->err_flag &&
760
249k
      ((!ptr_header_data->usac_flag) || (audio_object_type == AOT_ER_AAC_ELD))) {
761
0
    ixheaacd_lean_sbrconcealment(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0);
762
763
0
    ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0);
764
249k
  } else if (ptr_header_data->err_flag &&
765
249k
             ((!usac_flag) || (audio_object_type == AOT_ER_AAC_ELD))) {
766
38.0k
    ixheaacd_lean_sbrconcealment(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0);
767
768
38.0k
    ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0);
769
211k
  } else {
770
211k
    WORD32 num = ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
771
211k
    if (ptr_header_data->err_flag_prev && ((!usac_flag) ||
772
41.8k
        (audio_object_type == AOT_ER_AAC_ELD))) {
773
6.09k
      WORD16 *ptr1, *ptr2;
774
6.09k
      WORD32 i;
775
776
6.09k
      err = ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
777
6.09k
                                             ptr_prev_data_ch_0,
778
6.09k
                                             pstr_common_tables);
779
780
6.09k
      if (err) return err;
781
782
6.09k
      if (ptr_sbr_data->coupling_mode !=
783
6.09k
          (WORD16)ptr_prev_data_ch_0->coupling_mode) {
784
1.47k
        if (ptr_prev_data_ch_0->coupling_mode == COUPLING_BAL) {
785
190
          memcpy(ptr_prev_data_ch_0->sfb_nrg_prev,
786
190
                 ptr_prev_data_ch_1->sfb_nrg_prev, sizeof(WORD16) * num);
787
1.28k
        } else {
788
1.28k
          if (ptr_sbr_data->coupling_mode == COUPLING_LEVEL) {
789
610
            ptr1 = ptr_prev_data_ch_0->sfb_nrg_prev;
790
610
            ptr2 = ptr_prev_data_ch_1->sfb_nrg_prev;
791
792
8.18k
            for (i = 0; i < num; i++) {
793
7.57k
              *ptr1 = (add16_m(*ptr1, *ptr2) >> 1);
794
7.57k
              ptr2++;
795
7.57k
              ptr1++;
796
7.57k
            }
797
675
          } else {
798
675
            if (ptr_sbr_data->coupling_mode == COUPLING_BAL) {
799
382
              memset(ptr_prev_data_ch_0->sfb_nrg_prev, SBR_ENERGY_PAN_OFFSET,
800
382
                     sizeof(WORD16) * num);
801
382
            }
802
675
          }
803
1.28k
        }
804
1.47k
      }
805
6.09k
    }
806
807
211k
    memcpy(env_sf_local_arr, ptr_prev_data_ch_0->sfb_nrg_prev,
808
211k
           sizeof(WORD16) * MAX_FREQ_COEFFS);
809
810
211k
    ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data,
811
211k
                                      ptr_prev_data_ch_0);
812
813
211k
    if ((!usac_flag)||(audio_object_type == AOT_ER_AAC_ELD)) {
814
25.5k
      error_code = ixheaacd_check_env_data(ptr_header_data, ptr_sbr_data,
815
25.5k
                                           ptr_prev_data_ch_0);
816
817
25.5k
      if (error_code) {
818
5.51k
        ptr_header_data->err_flag = 1;
819
820
5.51k
        memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, env_sf_local_arr,
821
5.51k
               sizeof(WORD16) * MAX_FREQ_COEFFS);
822
823
5.51k
        err = ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0,
824
5.51k
                                    ptr_prev_data_ch_1, pstr_common_tables, audio_object_type,
825
5.51k
                                    ec_flag);
826
827
5.51k
        if (err) return err;
828
5.51k
        return 0;
829
5.51k
      }
830
25.5k
    }
831
211k
  }
832
244k
  if (ec_flag) {
833
0
    if ((!ptr_header_data->usac_flag) || (audio_object_type == AOT_ER_AAC_ELD)) {
834
0
      ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res);
835
0
    }
836
244k
  } else {
837
244k
    if ((!usac_flag) || (audio_object_type == AOT_ER_AAC_ELD)) {
838
58.0k
      ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res);
839
58.0k
    }
840
244k
  }
841
842
244k
  return 0;
843
249k
}
844
845
VOID ixheaacd_adj_timeslot(WORD32 *ptr_buf_real, WORD32 *ptr_buf_imag,
846
                           WORD16 *ptr_filt_buf, WORD16 *ptr_filt_buf_noise,
847
                           WORD16 *ptr_gain_buf, WORD16 *ptr_noise_floor,
848
                           WORD16 *ptr_sine_lvl_buf, WORD16 noise_floor_exp,
849
                           WORD16 *ptr_harm_index, WORD16 sub_band_start,
850
                           WORD16 num_sub_bands, WORD16 scale_change,
851
                           WORD16 smooth_ratio, FLAG num_noise_flg,
852
                           WORD16 *ptr_phase_index,
853
805k
                           ia_sbr_tables_struct *ptr_sbr_tables) {
854
805k
  WORD16 k;
855
805k
  WORD16 *ptr_smoothed_gain, *ptr_smoothed_noise;
856
805k
  WORD16 direct_ratio;
857
805k
  WORD32 index = *ptr_phase_index;
858
805k
  WORD32 harm_idx = *ptr_harm_index;
859
805k
  WORD32 freq_inv_flag;
860
805k
  const WORD32 *ptr_rand_ph_buf;
861
805k
  WORD32 factor = 0;
862
863
805k
  direct_ratio = ixheaac_sub16_sat(0x7fff, smooth_ratio);
864
805k
  freq_inv_flag = (sub_band_start & 1);
865
866
805k
  scale_change = scale_change - 1;
867
868
805k
  ptr_rand_ph_buf = &ptr_sbr_tables->sbr_rand_ph[index];
869
805k
  *ptr_phase_index =
870
805k
      (WORD16)((index + num_sub_bands) & (SBR_NF_NO_RANDOM_VAL - 1));
871
872
805k
  if (smooth_ratio) {
873
74.1k
    WORD16 *ptr_filt_buf_local = &ptr_filt_buf[0];
874
74.1k
    WORD16 *ptr_gain_buf_local = &ptr_gain_buf[0];
875
74.1k
    WORD16 *ptr_filt_noise_local = &ptr_filt_buf_noise[0];
876
74.1k
    WORD16 *ptr_noise_floor_local = &ptr_noise_floor[0];
877
878
74.1k
    WORD16 tmp, tmp1;
879
880
1.80M
    for (k = 0; k < num_sub_bands; k++) {
881
1.73M
      tmp = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_buf_local),
882
1.73M
                    mult16x16_16(direct_ratio, *ptr_gain_buf_local++));
883
884
1.73M
      ptr_gain_buf_local++;
885
886
1.73M
      tmp1 = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_noise_local),
887
1.73M
                     mult16x16_16(direct_ratio, *ptr_noise_floor_local++));
888
889
1.73M
      ptr_noise_floor_local++;
890
891
1.73M
      *ptr_filt_buf_local++ = tmp << 1;
892
1.73M
      ptr_filt_buf_local++;
893
1.73M
      *ptr_filt_noise_local++ = tmp1 << 1;
894
1.73M
    }
895
74.1k
    ptr_smoothed_gain = ptr_filt_buf;
896
74.1k
    ptr_smoothed_noise = ptr_filt_buf_noise;
897
74.1k
    factor = 1;
898
730k
  } else {
899
730k
    ptr_smoothed_gain = ptr_gain_buf;
900
730k
    ptr_smoothed_noise = ptr_noise_floor;
901
730k
    factor = 2;
902
730k
  }
903
904
805k
  switch (harm_idx) {
905
202k
    case 0:
906
403k
    case 2:
907
403k
      ixheaacd_harm_idx_zerotwo(num_noise_flg, num_sub_bands, ptr_buf_real,
908
403k
                                ptr_buf_imag, ptr_smoothed_gain,
909
403k
                                ptr_smoothed_noise, factor, ptr_gain_buf,
910
403k
                                scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf,
911
403k
                                noise_floor_exp, harm_idx);
912
403k
      break;
913
201k
    case 1:
914
401k
    case 3:
915
401k
      ixheaacd_harm_idx_onethree(
916
401k
          num_noise_flg, num_sub_bands, ptr_buf_real, ptr_buf_imag,
917
401k
          ptr_smoothed_gain, ptr_smoothed_noise, factor, ptr_gain_buf,
918
401k
          scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf, noise_floor_exp,
919
401k
          freq_inv_flag, harm_idx);
920
401k
      break;
921
805k
  }
922
805k
  *ptr_harm_index = (WORD16)((harm_idx + 1) & 3);
923
805k
}