Coverage Report

Created: 2026-10-14 07:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_psy_mod.c
Line
Count
Source
1
/******************************************************************************
2
 *                                                                            *
3
 * Copyright (C) 2023 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 <stdlib.h>
22
#include <math.h>
23
24
#include <string.h>
25
26
#include "ixheaac_type_def.h"
27
#include "ixheaac_constants.h"
28
#include "impd_drc_common_enc.h"
29
#include "impd_drc_uni_drc.h"
30
#include "impd_drc_tables.h"
31
#include "impd_drc_api.h"
32
#include "ixheaace_api.h"
33
#include "ixheaace_aac_constants.h"
34
#include "ixheaac_error_standards.h"
35
#include "ixheaace_psy_const.h"
36
#include "ixheaace_tns.h"
37
#include "ixheaace_tns_params.h"
38
#include "ixheaace_rom.h"
39
#include "ixheaace_common_rom.h"
40
#include "ixheaace_bitbuffer.h"
41
42
#include "ixheaac_basic_ops32.h"
43
#include "ixheaac_basic_ops16.h"
44
#include "ixheaac_basic_ops40.h"
45
#include "ixheaac_basic_ops.h"
46
47
#include "ixheaace_block_switch.h"
48
#include "ixheaace_psy_utils_spreading.h"
49
#include "ixheaace_psy_utils.h"
50
#include "ixheaace_calc_ms_band_energy.h"
51
#include "ixheaace_tns.h"
52
#include "ixheaace_adjust_threshold_data.h"
53
#include "ixheaace_dynamic_bits.h"
54
#include "ixheaace_qc_data.h"
55
#include "ixheaace_psy_data.h"
56
#include "ixheaace_ms_stereo.h"
57
#include "ixheaace_interface.h"
58
59
#include "ixheaace_write_bitstream.h"
60
#include "ixheaace_psy_configuration.h"
61
#include "ixheaace_psy_mod.h"
62
#include "ixheaace_stereo_preproc.h"
63
#include "ixheaace_enc_main.h"
64
#include "ixheaace_group_data.h"
65
66
#include "ixheaace_tns_func.h"
67
68
#include "ixheaace_tns_params.h"
69
#include "ixheaace_common_utils.h"
70
#include "ixheaace_fft.h"
71
72
static WORD32 ia_enhaacplus_enc_block_type_to_window_shape_lc[] = {KBD_WINDOW, SINE_WINDOW,
73
                                                                   SINE_WINDOW, KBD_WINDOW};
74
75
static WORD32 ia_enhaacplus_enc_block_type_to_window_shape_ld[] = {SINE_WINDOW, LD_WINDOW,
76
                                                                   LD_WINDOW, SINE_WINDOW};
77
78
WORD32 ia_enhaacplus_enc_psy_new(ixheaace_psy_kernel *pstr_h_psy, WORD32 num_chan,
79
                                 WORD32 *ptr_shared_buffer_2, WORD32 long_frame_len)
80
81
4.68k
{
82
4.68k
  WORD32 i;
83
11.5k
  for (i = 0; i < num_chan; i++) {
84
6.86k
    pstr_h_psy->psy_data[i]->ptr_spec_coeffs =
85
6.86k
        (FLOAT32 *)(&ptr_shared_buffer_2[i * long_frame_len]);
86
87
6.86k
    memset(pstr_h_psy->psy_data[i]->ptr_spec_coeffs, 0,
88
6.86k
           long_frame_len * sizeof(*pstr_h_psy->psy_data[i]->ptr_spec_coeffs));
89
6.86k
  }
90
91
4.68k
  pstr_h_psy->p_scratch_tns_float = (FLOAT32 *)(&ptr_shared_buffer_2[2 * long_frame_len]);
92
4.68k
  if (long_frame_len == FRAME_LEN_960) {
93
1.01k
    pstr_h_psy->p_scratch_tns_float = pstr_h_psy->p_scratch_tns_float + 128;
94
1.01k
  }
95
96
4.68k
  memset(pstr_h_psy->p_scratch_tns_float, 0,
97
4.68k
         long_frame_len * sizeof(*pstr_h_psy->p_scratch_tns_float));
98
99
4.68k
  return IA_NO_ERROR;
100
4.68k
}
101
102
IA_ERRORCODE ia_enhaacplus_enc_psy_main_init(ixheaace_psy_kernel *pstr_h_psy, WORD32 sample_rate,
103
                                             WORD32 bit_rate, WORD32 channels, WORD32 tns_mask,
104
                                             WORD32 bandwidth, WORD32 aot,
105
                                             ixheaace_aac_tables *pstr_aac_tables,
106
                                             WORD32 frame_len_long)
107
108
4.68k
{
109
4.68k
  WORD32 ch;
110
4.68k
  IA_ERRORCODE err;
111
112
4.68k
  err = ia_enhaacplus_enc_init_psy_configuration(bit_rate / channels, sample_rate, bandwidth, aot,
113
4.68k
                                                 &(pstr_h_psy->psy_conf_long), pstr_aac_tables,
114
4.68k
                                                 frame_len_long);
115
4.68k
  if (err != IA_NO_ERROR) {
116
0
    return err;
117
0
  }
118
119
4.68k
  if (!err) {
120
4.68k
    err = ia_enhaacplus_enc_init_tns_configuration(
121
4.68k
        bit_rate, sample_rate, channels, &pstr_h_psy->psy_conf_long.str_tns_conf,
122
4.68k
        &(pstr_h_psy->psy_conf_long), (WORD32)(tns_mask & 1), pstr_aac_tables->pstr_tns_tab,
123
4.68k
        frame_len_long, aot);
124
125
4.68k
    if (err != IA_NO_ERROR) {
126
0
      return err;
127
0
    }
128
4.68k
  }
129
4.68k
  if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
130
2.96k
    if (!err) {
131
2.96k
      err = ia_enhaacplus_enc_init_psy_configuration_short(
132
2.96k
          bit_rate / channels, sample_rate, bandwidth, aot, &pstr_h_psy->psy_conf_short,
133
2.96k
          pstr_aac_tables, frame_len_long / BLK_SWITCH_WIN);
134
2.96k
      if (err != IA_NO_ERROR) {
135
0
        return err;
136
0
      }
137
2.96k
    }
138
139
2.96k
    if (!err) {
140
2.96k
      err = ia_enhaacplus_enc_init_tns_configuration_short(
141
2.96k
          bit_rate, sample_rate, channels, &pstr_h_psy->psy_conf_short.str_tns_conf,
142
2.96k
          &(pstr_h_psy->psy_conf_short), (WORD32)(tns_mask & 1), pstr_aac_tables->pstr_tns_tab,
143
2.96k
          frame_len_long / BLK_SWITCH_WIN, aot);
144
2.96k
      if (err != IA_NO_ERROR) {
145
0
        return err;
146
0
      }
147
2.96k
    }
148
2.96k
  }
149
150
4.68k
  if (!err) {
151
    /* pstr_h_psy->psy_data[] */
152
11.5k
    for (ch = 0; ch < channels; ch++) {
153
6.86k
      switch (aot) {
154
1.51k
        case AOT_AAC_LC:
155
4.11k
        case AOT_SBR:
156
4.34k
        case AOT_PS:
157
4.34k
          iaace_init_block_switching(&pstr_h_psy->psy_data[ch]->blk_switch_cntrl, bit_rate,
158
4.34k
                                     channels);
159
4.34k
          break;
160
161
752
        case AOT_AAC_LD:
162
2.52k
        case AOT_AAC_ELD:
163
2.52k
          pstr_h_psy->psy_data[ch]->blk_switch_cntrl.win_seq = LONG_WINDOW;
164
2.52k
          pstr_h_psy->psy_data[ch]->blk_switch_cntrl.nxt_win_seq = LONG_WINDOW;
165
2.52k
          break;
166
6.86k
      }
167
6.86k
      ia_enhaacplus_enc_init_pre_echo_control(pstr_h_psy->psy_data[ch]->sfb_threshold_nm1_float,
168
6.86k
                                              pstr_h_psy->psy_conf_long.sfb_cnt,
169
6.86k
                                              pstr_h_psy->psy_conf_long.sfb_threshold_quiet);
170
6.86k
    }
171
4.68k
  }
172
173
4.68k
  return IA_NO_ERROR;
174
4.68k
}
175
176
static VOID ia_enhaacplus_enc_advance_psy_long_ms(
177
    ixheaace_psy_data **psy_data,
178
105k
    ixheaace_psy_configuration_long *pstr_psy_conf_long) {
179
105k
  ia_enhaacplus_enc_calc_band_energy_ms(
180
105k
      psy_data[0]->ptr_spec_coeffs, psy_data[1]->ptr_spec_coeffs, pstr_psy_conf_long->sfb_offsets,
181
105k
      pstr_psy_conf_long->sfb_active, pstr_psy_conf_long->sfb_cnt,
182
105k
      psy_data[0]->sfb_energy_ms.long_nrg, &psy_data[0]->sfb_energy_sum_ms.long_nrg,
183
105k
      psy_data[1]->sfb_energy_ms.long_nrg, &psy_data[1]->sfb_energy_sum_ms.long_nrg);
184
105k
}
185
186
static VOID ia_enhaacplus_enc_advance_psy_short_ms(
187
    ixheaace_psy_data **psy_data,
188
33.6k
    ixheaace_psy_configuration_short *pstr_psy_conf_short, WORD32 ccfl) {
189
33.6k
  WORD32 w;
190
33.6k
  WORD32 frame_len_short = FRAME_LEN_SHORT_128;
191
192
33.6k
  if (ccfl == FRAME_LEN_960) {
193
15.5k
    frame_len_short = FRAME_LEN_SHORT_120;
194
15.5k
  }
195
302k
  for (w = 0; w < TRANS_FAC; w++) {
196
268k
    WORD32 w_offset = w * frame_len_short;
197
198
268k
    ia_enhaacplus_enc_calc_band_energy_ms(
199
268k
        psy_data[0]->ptr_spec_coeffs + w_offset, psy_data[1]->ptr_spec_coeffs + w_offset,
200
268k
        pstr_psy_conf_short->sfb_offsets, pstr_psy_conf_short->sfb_active,
201
268k
        pstr_psy_conf_short->sfb_cnt, psy_data[0]->sfb_energy_ms.short_nrg[w],
202
268k
        &psy_data[0]->sfb_energy_sum_ms.short_nrg[w], psy_data[1]->sfb_energy_ms.short_nrg[w],
203
268k
        &psy_data[1]->sfb_energy_sum_ms.short_nrg[w]);
204
268k
  }
205
33.6k
}
206
207
static IA_ERRORCODE ia_enhaacplus_enc_advance_psy_short(
208
    ixheaace_psy_data *pstr_psy_data, ixheaace_temporal_noise_shaping_data *pstr_tns_data,
209
    ixheaace_psy_configuration_short *pstr_psy_conf_short,
210
    ixheaace_psy_out_channel *pstr_psy_out_ch, FLOAT32 *ptr_tns_scratch,
211
    const ixheaace_temporal_noise_shaping_data *ptr_tns_data2, const WORD32 ch, WORD32 aot,
212
82.6k
    FLOAT32 *ptr_shared_buffer1, ixheaace_aac_tables *pstr_aac_tables, WORD32 frame_len_long) {
213
82.6k
  IA_ERRORCODE error_code = IA_NO_ERROR;
214
82.6k
  WORD32 w;
215
82.6k
  FLOAT32 energy_shift = 0.25f;
216
82.6k
  FLOAT32 clip_energy = pstr_psy_conf_short->clip_energy * energy_shift;
217
218
744k
  for (w = 0; w < TRANS_FAC; w++) {
219
661k
    WORD32 w_offset = w * frame_len_long;
220
661k
    WORD32 i, offset;
221
661k
    FLOAT32 *ptr_mdct =
222
661k
        &pstr_psy_data->ptr_spec_coeffs[pstr_psy_conf_short->lowpass_line + w_offset];
223
224
    /* Low pass */
225
661k
    offset = frame_len_long - pstr_psy_conf_short->lowpass_line;
226
661k
    memset(ptr_mdct, 0, sizeof(FLOAT32) * offset);
227
228
    /* Calc sfb-bandwise MDCT-energies for left and right channel */
229
661k
    ia_enhaacplus_enc_calc_band_energy(
230
661k
        pstr_psy_data->ptr_spec_coeffs + w_offset, pstr_psy_conf_short->sfb_offsets,
231
661k
        pstr_psy_conf_short->sfb_active, pstr_psy_data->sfb_energy.short_nrg[w],
232
661k
        pstr_psy_conf_short->sfb_cnt, &pstr_psy_data->sfb_energy_sum.short_nrg[w]);
233
234
    /* TNS Detect*/
235
661k
    error_code = ia_enhaacplus_enc_tns_detect(
236
661k
        pstr_tns_data, pstr_psy_conf_short->str_tns_conf, ptr_tns_scratch,
237
661k
        pstr_psy_conf_short->sfb_offsets, pstr_psy_data->ptr_spec_coeffs + w_offset, w,
238
661k
        pstr_psy_data->blk_switch_cntrl.win_seq, aot, pstr_psy_data->sfb_energy.short_nrg[w],
239
661k
        ptr_shared_buffer1, frame_len_long);
240
241
661k
    if (error_code != IA_NO_ERROR) {
242
0
      return error_code;
243
0
    }
244
245
    /*  TNS Sync */
246
661k
    if (ch == 1) {
247
268k
      ia_enhaacplus_enc_tns_sync(pstr_tns_data, ptr_tns_data2, pstr_psy_conf_short->str_tns_conf,
248
268k
                                 w, (WORD32)pstr_psy_data->blk_switch_cntrl.win_seq);
249
268k
    }
250
251
    /* TNS Encode */
252
661k
    ia_enhaacplus_enc_tns_encode(
253
661k
        &pstr_psy_out_ch->tns_info, pstr_tns_data, pstr_psy_conf_short->sfb_cnt,
254
661k
        pstr_psy_conf_short->str_tns_conf, pstr_psy_conf_short->lowpass_line,
255
661k
        pstr_psy_data->ptr_spec_coeffs + w_offset, w, pstr_psy_data->blk_switch_cntrl.win_seq,
256
661k
        pstr_aac_tables->pstr_tns_tab);
257
258
10.2M
    for (i = 0; i < pstr_psy_conf_short->sfb_cnt; i++) {
259
9.63M
      pstr_psy_data->sfb_threshold.short_nrg[w][i] =
260
9.63M
          pstr_psy_data->sfb_energy.short_nrg[w][i] * pstr_psy_conf_short->ratio_float;
261
262
9.63M
      pstr_psy_data->sfb_threshold.short_nrg[w][i] =
263
9.63M
          MIN(pstr_psy_data->sfb_threshold.short_nrg[w][i], clip_energy);
264
9.63M
    }
265
266
    /* Calc sfb-bandwise MDCT-energies for left and right channel again, if TNS has modified the
267
     * spectrum */
268
661k
    if (pstr_psy_out_ch->tns_info.tns_active[w]) {
269
154k
      ia_enhaacplus_enc_calc_band_energy(
270
154k
          pstr_psy_data->ptr_spec_coeffs + w_offset, pstr_psy_conf_short->sfb_offsets,
271
154k
          pstr_psy_conf_short->sfb_active, pstr_psy_data->sfb_energy.short_nrg[w],
272
154k
          pstr_psy_conf_short->sfb_cnt, &pstr_psy_data->sfb_energy_sum.short_nrg[w]);
273
154k
    }
274
275
    /* Spreading */
276
661k
    ia_enhaacplus_enc_spreading_max(
277
661k
        pstr_psy_conf_short->sfb_cnt, pstr_psy_conf_short->sfb_mask_low_factor,
278
661k
        pstr_psy_conf_short->sfb_mask_high_factor, pstr_psy_data->sfb_threshold.short_nrg[w]);
279
280
10.2M
    for (i = 0; i < pstr_psy_conf_short->sfb_cnt; i++) {
281
9.63M
      pstr_psy_data->sfb_threshold.short_nrg[w][i] =
282
9.63M
          MAX(pstr_psy_data->sfb_threshold.short_nrg[w][i],
283
9.63M
              (pstr_psy_conf_short->sfb_threshold_quiet[i] * energy_shift));
284
9.63M
    }
285
286
    /* Pre-echo Control */
287
661k
    ia_enhaacplus_enc_pre_echo_control(pstr_psy_data->sfb_threshold_nm1_float,
288
661k
                                       pstr_psy_conf_short->sfb_cnt,
289
661k
                                       pstr_psy_conf_short->min_remaining_threshold_factor,
290
661k
                                       pstr_psy_data->sfb_threshold.short_nrg[w]);
291
292
    /* Apply TNS mult table on CB thresholds */
293
661k
    if (pstr_psy_out_ch->tns_info.tns_active[w]) {
294
154k
      ia_enhaacplus_enc_apply_tns_mult_table_to_ratios(
295
154k
          pstr_psy_conf_short->str_tns_conf.tns_ratio_patch_lowest_cb,
296
154k
          pstr_psy_conf_short->str_tns_conf.tns_start_band,
297
154k
          pstr_psy_data->sfb_threshold.short_nrg[w]);
298
154k
    }
299
300
    /* Spreaded energy for avoid hole detection */
301
10.2M
    for (i = 0; i < pstr_psy_conf_short->sfb_cnt; i++) {
302
9.63M
      pstr_psy_data->sfb_sreaded_energy.short_nrg[w][i] =
303
9.63M
          pstr_psy_data->sfb_energy.short_nrg[w][i];
304
9.63M
    }
305
306
661k
    ia_enhaacplus_enc_spreading_max(pstr_psy_conf_short->sfb_cnt,
307
661k
                                    pstr_psy_conf_short->sfb_mask_low_factor_spread_nrg,
308
661k
                                    pstr_psy_conf_short->sfb_mask_high_factor_spread_nrg,
309
661k
                                    pstr_psy_data->sfb_sreaded_energy.short_nrg[w]);
310
661k
  }
311
82.6k
  return error_code;
312
82.6k
}
313
314
static IA_ERRORCODE ia_enhaacplus_enc_advance_psy_long(
315
    ixheaace_psy_data *pstr_psy_data, ixheaace_temporal_noise_shaping_data *pstr_tns_data,
316
    ixheaace_psy_configuration_long *pstr_psy_conf_long,
317
    ixheaace_psy_out_channel *pstr_psy_out_ch, FLOAT32 *ptr_scratch_tns,
318
    const ixheaace_temporal_noise_shaping_data *pstr_tns_data2, const WORD32 ch, WORD32 aot,
319
359k
    FLOAT32 *ptr_shared_buffer1, ixheaace_aac_tables *pstr_aac_tables, WORD32 frame_len_long) {
320
359k
  WORD32 i;
321
359k
  IA_ERRORCODE error_code = IA_NO_ERROR;
322
359k
  FLOAT32 energy_shift = 0.25f;
323
359k
  FLOAT32 clip_energy = pstr_psy_conf_long->clip_energy / 4;
324
359k
  FLOAT32 *ptr_sfb_energy_long = pstr_psy_data->sfb_energy.long_nrg;
325
359k
  FLOAT32 *ptr_sfb_spreaded_energy = pstr_psy_data->sfb_sreaded_energy.long_nrg;
326
327
  /* Low pass */
328
359k
  memset(&pstr_psy_data->ptr_spec_coeffs[pstr_psy_conf_long->lowpass_line], 0,
329
359k
         sizeof(*pstr_psy_data->ptr_spec_coeffs) *
330
359k
             (frame_len_long - pstr_psy_conf_long->lowpass_line));
331
332
  /* Calculate scale_factor_band - bandwise MDCT-energies for left and right channels */
333
359k
  ia_enhaacplus_enc_calc_band_energy(
334
359k
      pstr_psy_data->ptr_spec_coeffs, pstr_psy_conf_long->sfb_offsets,
335
359k
      pstr_psy_conf_long->sfb_active, pstr_psy_data->sfb_energy.long_nrg,
336
359k
      pstr_psy_conf_long->sfb_cnt, &pstr_psy_data->sfb_energy_sum.long_nrg);
337
338
  /* TNS Detect */
339
359k
  error_code = ia_enhaacplus_enc_tns_detect(
340
359k
      pstr_tns_data, pstr_psy_conf_long->str_tns_conf, ptr_scratch_tns,
341
359k
      pstr_psy_conf_long->sfb_offsets, pstr_psy_data->ptr_spec_coeffs, 0,
342
359k
      pstr_psy_data->blk_switch_cntrl.win_seq, aot, pstr_psy_data->sfb_energy.long_nrg,
343
359k
      ptr_shared_buffer1, frame_len_long);
344
345
359k
  if (error_code != IA_NO_ERROR) {
346
0
    return error_code;
347
0
  }
348
349
  /* TNS Sync */
350
359k
  if (ch == 1) {
351
105k
    ia_enhaacplus_enc_tns_sync(pstr_tns_data, pstr_tns_data2, pstr_psy_conf_long->str_tns_conf, 0,
352
105k
                               (WORD32)pstr_psy_data->blk_switch_cntrl.win_seq);
353
105k
  }
354
355
  /* TNS Encode */
356
359k
  ia_enhaacplus_enc_tns_encode(&pstr_psy_out_ch->tns_info, pstr_tns_data,
357
359k
                               pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->str_tns_conf,
358
359k
                               pstr_psy_conf_long->lowpass_line, pstr_psy_data->ptr_spec_coeffs,
359
359k
                               0, (WORD32)pstr_psy_data->blk_switch_cntrl.win_seq,
360
359k
                               pstr_aac_tables->pstr_tns_tab);
361
362
359k
  if (aot == AOT_AAC_ELD) {
363
2.76M
    for (i = 0; i < pstr_psy_conf_long->sfb_active; i++) {
364
2.64M
      pstr_psy_data->sfb_threshold.long_nrg[i] =
365
2.64M
          pstr_psy_data->sfb_energy.long_nrg[i] * pstr_psy_conf_long->ratio_float;
366
367
2.64M
      pstr_psy_data->sfb_threshold.long_nrg[i] =
368
2.64M
          MIN(pstr_psy_data->sfb_threshold.long_nrg[i], clip_energy);
369
2.64M
    }
370
245k
  } else {
371
10.6M
    for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) {
372
10.3M
      pstr_psy_data->sfb_threshold.long_nrg[i] =
373
10.3M
          pstr_psy_data->sfb_energy.long_nrg[i] * pstr_psy_conf_long->ratio_float;
374
375
10.3M
      pstr_psy_data->sfb_threshold.long_nrg[i] =
376
10.3M
          MIN(pstr_psy_data->sfb_threshold.long_nrg[i], clip_energy);
377
10.3M
    }
378
245k
  }
379
380
  /* Calculate scale factor band - bandwise MDCT-energies for left and right channel again, if TNS
381
   * has modified the spectrum */
382
359k
  if (pstr_psy_out_ch->tns_info.tns_active[0] == 1) {
383
168k
    ia_enhaacplus_enc_calc_band_energy(
384
168k
        pstr_psy_data->ptr_spec_coeffs, pstr_psy_conf_long->sfb_offsets,
385
168k
        pstr_psy_conf_long->sfb_active, pstr_psy_data->sfb_energy.long_nrg,
386
168k
        pstr_psy_conf_long->sfb_cnt, &pstr_psy_data->sfb_energy_sum.long_nrg);
387
168k
  }
388
389
  /* Spreading */
390
359k
  if (aot == AOT_AAC_ELD) {
391
113k
    ia_enhaacplus_enc_spreading_max(
392
113k
        pstr_psy_conf_long->sfb_active, pstr_psy_conf_long->sfb_mask_low_factor,
393
113k
        pstr_psy_conf_long->sfb_mask_high_factor, pstr_psy_data->sfb_threshold.long_nrg);
394
245k
  } else {
395
245k
    ia_enhaacplus_enc_spreading_max(
396
245k
        pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->sfb_mask_low_factor,
397
245k
        pstr_psy_conf_long->sfb_mask_high_factor, pstr_psy_data->sfb_threshold.long_nrg);
398
245k
  }
399
400
  /* Threshold in quiet */
401
359k
  if (aot == AOT_AAC_ELD) {
402
2.76M
    for (i = 0; i < pstr_psy_conf_long->sfb_active; i++) {
403
2.64M
      pstr_psy_data->sfb_threshold.long_nrg[i] =
404
2.64M
          MAX(pstr_psy_data->sfb_threshold.long_nrg[i],
405
2.64M
              (pstr_psy_conf_long->sfb_threshold_quiet[i] * energy_shift));
406
2.64M
    }
407
245k
  } else {
408
10.6M
    for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) {
409
10.3M
      pstr_psy_data->sfb_threshold.long_nrg[i] =
410
10.3M
          MAX(pstr_psy_data->sfb_threshold.long_nrg[i],
411
10.3M
              (pstr_psy_conf_long->sfb_threshold_quiet[i] * energy_shift));
412
10.3M
    }
413
245k
  }
414
415
  /* Pre-echo control */
416
359k
  if (pstr_psy_data->blk_switch_cntrl.win_seq == STOP_WINDOW) {
417
    /* Prevent pre-echo control from comparing stop thresholds with short thresholds */
418
842k
    for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) {
419
823k
      pstr_psy_data->sfb_threshold_nm1_float[i] = 1.0e20f;
420
823k
    }
421
18.6k
  }
422
423
359k
  ia_enhaacplus_enc_pre_echo_control(
424
359k
      pstr_psy_data->sfb_threshold_nm1_float, pstr_psy_conf_long->sfb_cnt,
425
359k
      pstr_psy_conf_long->min_remaining_threshold_factor, pstr_psy_data->sfb_threshold.long_nrg);
426
427
359k
  if (pstr_psy_data->blk_switch_cntrl.win_seq == START_WINDOW) {
428
    /* Prevent pre-echo control in next frame from comparing start thresholds with short
429
     * thresholds */
430
945k
    for (i = 0; i < pstr_psy_conf_long->sfb_cnt; i++) {
431
924k
      pstr_psy_data->sfb_threshold_nm1_float[i] = 1.0e20f;
432
924k
    }
433
20.8k
  }
434
435
  /* Apply TNS mult table on CB thresholds */
436
359k
  if (pstr_psy_out_ch->tns_info.tns_active[0]) {
437
168k
    ia_enhaacplus_enc_apply_tns_mult_table_to_ratios(
438
168k
        pstr_psy_conf_long->str_tns_conf.tns_ratio_patch_lowest_cb,
439
168k
        pstr_psy_conf_long->str_tns_conf.tns_start_band, pstr_psy_data->sfb_threshold.long_nrg);
440
168k
  }
441
442
  /* Spreaded energy for avoid hole detection */
443
444
359k
  memcpy(&ptr_sfb_spreaded_energy[0], &ptr_sfb_energy_long[0],
445
359k
         sizeof(ptr_sfb_spreaded_energy[0]) * pstr_psy_conf_long->sfb_cnt);
446
447
359k
  if (aot == AOT_AAC_ELD) {
448
113k
    ia_enhaacplus_enc_spreading_max(pstr_psy_conf_long->sfb_active,
449
113k
                                    pstr_psy_conf_long->sfb_mask_low_factor_spread_nrg,
450
113k
                                    pstr_psy_conf_long->sfb_mask_high_factor_spread_nrg,
451
113k
                                    pstr_psy_data->sfb_sreaded_energy.long_nrg);
452
245k
  } else {
453
245k
    ia_enhaacplus_enc_spreading_max(pstr_psy_conf_long->sfb_cnt,
454
245k
                                    pstr_psy_conf_long->sfb_mask_low_factor_spread_nrg,
455
245k
                                    pstr_psy_conf_long->sfb_mask_high_factor_spread_nrg,
456
245k
                                    pstr_psy_data->sfb_sreaded_energy.long_nrg);
457
245k
  }
458
459
359k
  return error_code;
460
359k
}
461
462
IA_ERRORCODE ia_enhaacplus_enc_psy_main(
463
    WORD32 time_sn_stride, ixheaace_element_info *pstr_elem_info, const FLOAT32 *ptr_time_signal,
464
    WORD32 aot, ixheaace_psy_data **psy_data,
465
    ixheaace_temporal_noise_shaping_data **tns_data,
466
    ixheaace_psy_configuration_long *pstr_psy_conf_long,
467
    ixheaace_psy_configuration_short *pstr_psy_conf_short,
468
    ixheaace_psy_out_channel **psy_out_ch,
469
    ixheaace_psy_out_element *pstr_psy_out_element, FLOAT32 *ptr_scratch_tns,
470
    FLOAT32 *ptr_shared_buffer1, WORD8 *ptr_shared_buffer5, ixheaace_aac_tables *pstr_aac_tables,
471
    WORD32 frame_len_long)
472
473
303k
{
474
303k
  IA_ERRORCODE error_code = IA_NO_ERROR;
475
303k
  WORD32 grouped_sfb_offset[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND +
476
303k
                                                       1]; /* plus one for last dummy offset ! */
477
303k
  FLOAT32 grouped_sfb_min_snr[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
478
303k
  WORD32 max_sfb_per_grp[IXHEAACE_MAX_CH_IN_BS_ELE] = {0};
479
303k
  WORD32 ch, sfb, line;
480
303k
  WORD32 num_channels = pstr_elem_info->n_channels_in_el;
481
482
303k
  if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
483
201k
    if (pstr_elem_info->el_type != ID_LFE) {
484
465k
      for (ch = 0; ch < num_channels; ch++) {
485
277k
        iaace_block_switching(&psy_data[ch]->blk_switch_cntrl,
486
277k
                              ptr_time_signal + pstr_elem_info->channel_index[ch], frame_len_long,
487
277k
                              num_channels);
488
277k
      }
489
188k
    } else {
490
25.5k
      for (ch = 0; ch < num_channels; ch++) {
491
12.7k
        psy_data[ch]->blk_switch_cntrl.win_seq = LONG_WINDOW;
492
12.7k
      }
493
12.7k
    }
494
495
    /* synch left and right block type */
496
201k
    if (num_channels == NUM_CHANS_MONO) {
497
112k
      iaace_sync_block_switching(&psy_data[0]->blk_switch_cntrl, NULL, num_channels);
498
112k
    }
499
88.8k
    else {
500
88.8k
      iaace_sync_block_switching(&psy_data[0]->blk_switch_cntrl, &psy_data[1]->blk_switch_cntrl,
501
88.8k
                                 num_channels);
502
88.8k
    }
503
201k
  } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
504
253k
    for (ch = 0; ch < num_channels; ch++) {
505
151k
      psy_data[ch]->blk_switch_cntrl.win_seq_ld = LONG_WINDOW;
506
151k
      psy_data[ch]->blk_switch_cntrl.next_win_seq_ld = LONG_WINDOW;
507
151k
      psy_data[ch]->blk_switch_cntrl.win_seq = LONG_WINDOW;
508
151k
      psy_data[ch]->blk_switch_cntrl.nxt_win_seq = LONG_WINDOW;
509
151k
      psy_data[ch]->blk_switch_cntrl.total_groups_cnt = 1;
510
151k
    }
511
101k
  }
512
  /* transform */
513
745k
  for (ch = 0; ch < num_channels; ch++) {
514
441k
    if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
515
290k
      ixheaace_transform_real_lc_ld(
516
290k
          psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch],
517
290k
          time_sn_stride, psy_data[ch]->ptr_spec_coeffs, psy_data[ch]->blk_switch_cntrl.win_seq,
518
290k
          frame_len_long, ptr_shared_buffer5);
519
290k
    } else if (aot == AOT_AAC_LD) {
520
38.0k
      if (frame_len_long == FRAME_LEN_480) {
521
13.7k
        ia_enhaacplus_enc_transform_real(
522
13.7k
            psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch],
523
13.7k
            time_sn_stride, psy_data[ch]->ptr_spec_coeffs, pstr_aac_tables->pstr_mdct_tab,
524
13.7k
            ptr_scratch_tns, ptr_shared_buffer5, frame_len_long);
525
24.2k
      } else {
526
24.2k
        ixheaace_transform_real_lc_ld(
527
24.2k
            psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch],
528
24.2k
            time_sn_stride, psy_data[ch]->ptr_spec_coeffs, psy_data[ch]->blk_switch_cntrl.win_seq,
529
24.2k
            frame_len_long, ptr_shared_buffer5);
530
24.2k
      }
531
113k
    } else if (aot == AOT_AAC_ELD) {
532
113k
      if (frame_len_long == FRAME_LEN_480) {
533
50.9k
        ia_enhaacplus_enc_transform_real(
534
50.9k
            psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch],
535
50.9k
            time_sn_stride, psy_data[ch]->ptr_spec_coeffs, pstr_aac_tables->pstr_mdct_tab,
536
50.9k
            ptr_scratch_tns, ptr_shared_buffer5, frame_len_long);
537
62.7k
      } else {
538
62.7k
        ia_enhaacplus_enc_transform_real_eld(
539
62.7k
            psy_data[ch]->ptr_mdct_delay_buf, ptr_time_signal + pstr_elem_info->channel_index[ch],
540
62.7k
            time_sn_stride, psy_data[ch]->ptr_spec_coeffs, ptr_shared_buffer5, frame_len_long);
541
62.7k
      }
542
113k
    }
543
441k
  }
544
545
745k
  for (ch = 0; ch < num_channels; ch++) {
546
441k
    if (psy_data[ch]->blk_switch_cntrl.win_seq != SHORT_WINDOW) {
547
359k
      error_code = ia_enhaacplus_enc_advance_psy_long(
548
359k
          psy_data[ch], tns_data[ch], pstr_psy_conf_long, psy_out_ch[ch], ptr_scratch_tns,
549
359k
          tns_data[1 - ch], ch, aot, ptr_shared_buffer1, pstr_aac_tables, frame_len_long);
550
551
359k
      if (error_code != IA_NO_ERROR) {
552
0
        return error_code;
553
0
      }
554
555
5.79M
      for (sfb = pstr_psy_conf_long->sfb_cnt - 1; sfb >= 0; sfb--) {
556
5.71M
        for (line = pstr_psy_conf_long->sfb_offsets[sfb + 1] - 1;
557
172M
             line >= pstr_psy_conf_long->sfb_offsets[sfb]; line--) {
558
167M
          if (psy_data[ch]->ptr_spec_coeffs[line] != 0) {
559
281k
            break;
560
281k
          }
561
167M
        }
562
5.71M
        if (line >= pstr_psy_conf_long->sfb_offsets[sfb]) {
563
281k
          break;
564
281k
        }
565
5.71M
      }
566
567
359k
      max_sfb_per_grp[ch] = sfb + 1;
568
569
      /* Calculate bandwise energies for mid and side channels - only if 2 channels exist */
570
359k
      if (ch == 1) {
571
105k
        ia_enhaacplus_enc_advance_psy_long_ms(psy_data, pstr_psy_conf_long);
572
105k
      }
573
359k
    } else {
574
82.6k
      error_code = ia_enhaacplus_enc_advance_psy_short(
575
82.6k
          psy_data[ch], tns_data[ch], pstr_psy_conf_short, psy_out_ch[ch], ptr_scratch_tns,
576
82.6k
          tns_data[1 - ch], ch, aot, ptr_shared_buffer1, pstr_aac_tables, frame_len_long / 8);
577
578
82.6k
      if (error_code != IA_NO_ERROR) {
579
0
        return error_code;
580
0
      }
581
582
      /* Calculate bandwise energies for mid and side channels - only if 2 channels exist */
583
82.6k
      if (ch == 1) {
584
33.6k
        ia_enhaacplus_enc_advance_psy_short_ms(psy_data, pstr_psy_conf_short, frame_len_long);
585
33.6k
      }
586
82.6k
    }
587
441k
  }
588
589
  /* Group short data (max_sfb for short blocks is determined here) */
590
303k
  if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
591
491k
    for (ch = 0; ch < num_channels; ch++) {
592
290k
      if (psy_data[ch]->blk_switch_cntrl.win_seq == SHORT_WINDOW) {
593
82.6k
        iaace_group_short_data(psy_data[ch]->ptr_spec_coeffs, ptr_scratch_tns,
594
82.6k
                               &psy_data[ch]->sfb_threshold, &psy_data[ch]->sfb_energy,
595
82.6k
                               &psy_data[ch]->sfb_energy_ms, &psy_data[ch]->sfb_sreaded_energy,
596
82.6k
                               pstr_psy_conf_short->sfb_cnt, pstr_psy_conf_short->sfb_offsets,
597
82.6k
                               pstr_psy_conf_short->sfb_min_snr, grouped_sfb_offset[ch],
598
82.6k
                               &max_sfb_per_grp[ch], grouped_sfb_min_snr[ch],
599
82.6k
                               psy_data[ch]->blk_switch_cntrl.total_groups_cnt,
600
82.6k
                               psy_data[ch]->blk_switch_cntrl.group_len, frame_len_long);
601
82.6k
      }
602
290k
    }
603
201k
  }
604
605
303k
#if (IXHEAACE_MAX_CH_IN_BS_ELE > 1)
606
  /* Stereo Processing */
607
303k
  if (num_channels == 2) {
608
138k
    pstr_psy_out_element->tools_info.ms_digest = MS_NONE;
609
610
138k
    max_sfb_per_grp[0] = max_sfb_per_grp[1] = MAX(max_sfb_per_grp[0], max_sfb_per_grp[1]);
611
612
138k
    if (psy_data[0]->blk_switch_cntrl.win_seq != SHORT_WINDOW) {
613
105k
      iaace_ms_apply(
614
105k
          psy_data, psy_data[0]->ptr_spec_coeffs, psy_data[1]->ptr_spec_coeffs,
615
105k
          &pstr_psy_out_element->tools_info.ms_digest, pstr_psy_out_element->tools_info.ms_mask,
616
105k
          pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->sfb_cnt, max_sfb_per_grp[0],
617
105k
          pstr_psy_conf_long->sfb_offsets, &pstr_psy_out_element->weight_ms_lr_pe_ratio);
618
105k
    } else {
619
33.6k
      iaace_ms_apply(psy_data, psy_data[0]->ptr_spec_coeffs, psy_data[1]->ptr_spec_coeffs,
620
33.6k
                     &pstr_psy_out_element->tools_info.ms_digest,
621
33.6k
                     pstr_psy_out_element->tools_info.ms_mask,
622
33.6k
                     psy_data[0]->blk_switch_cntrl.total_groups_cnt *
623
33.6k
                     pstr_psy_conf_short->sfb_cnt,
624
33.6k
                     pstr_psy_conf_short->sfb_cnt, max_sfb_per_grp[0], grouped_sfb_offset[0],
625
33.6k
                     &pstr_psy_out_element->weight_ms_lr_pe_ratio);
626
33.6k
    }
627
138k
  }
628
303k
#endif
629
630
  /* Build output */
631
303k
  if (aot == AOT_AAC_LC || aot == AOT_SBR || aot == AOT_PS) {
632
491k
    for (ch = 0; ch < num_channels; ch++) {
633
290k
      if (psy_data[ch]->blk_switch_cntrl.win_seq != SHORT_WINDOW) {
634
207k
        ia_enhaacplus_enc_build_interface(
635
207k
            psy_data[ch]->ptr_spec_coeffs, &psy_data[ch]->sfb_threshold,
636
207k
            &psy_data[ch]->sfb_energy,
637
207k
            &psy_data[ch]->sfb_sreaded_energy, psy_data[ch]->sfb_energy_sum,
638
207k
            psy_data[ch]->sfb_energy_sum_ms, psy_data[ch]->blk_switch_cntrl.win_seq,
639
207k
            ia_enhaacplus_enc_block_type_to_window_shape_lc[psy_data[ch]
640
207k
                                                                ->blk_switch_cntrl.win_seq],
641
207k
            pstr_psy_conf_long->sfb_cnt, pstr_psy_conf_long->sfb_offsets, max_sfb_per_grp[ch],
642
207k
            pstr_psy_conf_long->sfb_min_snr, psy_data[ch]->blk_switch_cntrl.total_groups_cnt,
643
207k
            psy_data[ch]->blk_switch_cntrl.group_len, psy_out_ch[ch]);
644
207k
      } else {
645
82.6k
        ia_enhaacplus_enc_build_interface(
646
82.6k
            psy_data[ch]->ptr_spec_coeffs, &psy_data[ch]->sfb_threshold,
647
82.6k
            &psy_data[ch]->sfb_energy,
648
82.6k
            &psy_data[ch]->sfb_sreaded_energy, psy_data[ch]->sfb_energy_sum,
649
82.6k
            psy_data[ch]->sfb_energy_sum_ms, SHORT_WINDOW, SINE_WINDOW,
650
82.6k
            psy_data[ch]->blk_switch_cntrl.total_groups_cnt * pstr_psy_conf_short->sfb_cnt,
651
82.6k
            grouped_sfb_offset[ch], max_sfb_per_grp[ch], grouped_sfb_min_snr[ch],
652
82.6k
            psy_data[ch]->blk_switch_cntrl.total_groups_cnt,
653
82.6k
            psy_data[ch]->blk_switch_cntrl.group_len, psy_out_ch[ch]);
654
82.6k
      }
655
290k
    }
656
201k
  } else if (aot == AOT_AAC_LD || aot == AOT_AAC_ELD) {
657
253k
    for (ch = 0; ch < num_channels; ch++) {
658
151k
      ia_enhaacplus_enc_build_interface(
659
151k
          psy_data[ch]->ptr_spec_coeffs, &psy_data[ch]->sfb_threshold, &psy_data[ch]->sfb_energy,
660
151k
          &psy_data[ch]->sfb_sreaded_energy, psy_data[ch]->sfb_energy_sum,
661
151k
          psy_data[ch]->sfb_energy_sum_ms, LONG_WINDOW,
662
151k
          ia_enhaacplus_enc_block_type_to_window_shape_ld[psy_data[ch]
663
151k
                                                              ->blk_switch_cntrl.win_seq_ld],
664
151k
          ((aot == AOT_AAC_ELD) ? pstr_psy_conf_long->sfb_active : pstr_psy_conf_long->sfb_cnt),
665
151k
          pstr_psy_conf_long->sfb_offsets, max_sfb_per_grp[ch], pstr_psy_conf_long->sfb_min_snr,
666
151k
          psy_data[ch]->blk_switch_cntrl.total_groups_cnt,
667
151k
          psy_data[ch]->blk_switch_cntrl.group_len, psy_out_ch[ch]);
668
151k
    }
669
101k
  }
670
303k
  return error_code;
671
303k
}