Coverage Report

Created: 2025-11-10 06:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/iusace_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 <string.h>
22
#include "iusace_cnst.h"
23
#include "iusace_type_def.h"
24
#include "iusace_block_switch_const.h"
25
#include "iusace_block_switch_struct_def.h"
26
#include "iusace_bitbuffer.h"
27
#include "iusace_tns_usac.h"
28
#include "impd_drc_common_enc.h"
29
#include "impd_drc_uni_drc.h"
30
#include "impd_drc_api.h"
31
#include "impd_drc_uni_drc_eq.h"
32
#include "impd_drc_uni_drc_filter_bank.h"
33
#include "impd_drc_gain_enc.h"
34
#include "impd_drc_struct_def.h"
35
#include "iusace_cnst.h"
36
#include "iusace_tns_usac.h"
37
#include "iusace_psy_mod.h"
38
#include "iusace_psy_utils.h"
39
40
#include "ixheaac_error_standards.h"
41
#include "iusace_type_def.h"
42
#include "iusace_cnst.h"
43
44
#include "iusace_ms.h"
45
46
#include "iusace_psy_utils.h"
47
#include "ixheaace_adjust_threshold_data.h"
48
#include "iusace_fd_qc_util.h"
49
#include "ixheaace_memory_standards.h"
50
#include "iusace_config.h"
51
#include "iusace_arith_enc.h"
52
#include "iusace_fd_quant.h"
53
#include "iusace_signal_classifier.h"
54
#include "iusace_block_switch_const.h"
55
#include "ixheaace_sbr_header.h"
56
#include "ixheaace_config.h"
57
#include "ixheaace_asc_write.h"
58
#include "iusace_main.h"
59
60
VOID iusace_psy_mod_init(ia_psy_mod_struct *pstr_psy_mod, WORD32 sample_rate, WORD32 bit_rate,
61
                         WORD32 band_width, WORD32 num_channels, WORD32 ch, WORD32 ele_id,
62
3.85k
                         WORD32 ccfl) {
63
3.85k
  WORD32 i;
64
65
10.4k
  for (i = 0; i < num_channels; i++) {
66
6.60k
    iusace_psy_long_config_init(bit_rate / num_channels, sample_rate, band_width,
67
6.60k
                                &(pstr_psy_mod->str_psy_long_config[ele_id]), ccfl);
68
69
6.60k
    iusace_psy_short_config_init(bit_rate / num_channels, sample_rate, band_width,
70
6.60k
                                 &(pstr_psy_mod->str_psy_short_config[ele_id]), ccfl);
71
72
6.60k
    pstr_psy_mod->str_psy_data[ch].ptr_sfb_thr_long =
73
6.60k
        (FLOAT32 *)pstr_psy_mod->str_psy_data[ch].sfb_thr_short;
74
6.60k
    pstr_psy_mod->str_psy_data[ch].ptr_sfb_energy_long =
75
6.60k
        (FLOAT32 *)pstr_psy_mod->str_psy_data[ch].sfb_energy_short;
76
6.60k
    pstr_psy_mod->str_psy_data[ch].ptr_sfb_spreaded_energy_long =
77
6.60k
        (FLOAT32 *)pstr_psy_mod->str_psy_data[ch].sfb_spreaded_energy_short;
78
79
6.60k
    memcpy(pstr_psy_mod->str_psy_data[ch].sfb_thr_nm1,
80
6.60k
           pstr_psy_mod->str_psy_long_config[ele_id].sfb_thr_quiet,
81
6.60k
           pstr_psy_mod->str_psy_long_config[ele_id].sfb_count * sizeof(FLOAT32));
82
83
6.60k
    ch++;
84
6.60k
  }
85
86
3.85k
  return;
87
3.85k
}
88
89
VOID iusace_psy_mod_lb(ia_psy_mod_struct *pstr_psy_mod, ia_sfb_params_struct *pstr_sfb_prms,
90
                       FLOAT64 *ptr_spec_in, ia_tns_info *pstr_tns_info[MAX_TIME_CHANNELS],
91
                       WORD32 tns_select, WORD32 i_ch, WORD32 chn, WORD32 channel_type,
92
                       FLOAT64 *scratch_tns_filter, WORD32 elem_idx, FLOAT64 *ptr_tns_scratch,
93
327k
                       WORD32 ccfl) {
94
327k
  ia_psy_mod_data_struct *pstr_psy_data = &(pstr_psy_mod->str_psy_data[i_ch]);
95
327k
  ia_psy_mod_long_config_struct *pstr_psy_config = &(pstr_psy_mod->str_psy_long_config[elem_idx]);
96
327k
  WORD32 window_sequence = pstr_sfb_prms->window_sequence[i_ch];
97
327k
  WORD32 num_sfb = pstr_sfb_prms->num_sfb[i_ch];
98
327k
  ia_tns_info *ptr_tns_info = pstr_tns_info[i_ch];
99
327k
  WORD32 sfb, line;
100
327k
  WORD32 i;
101
327k
  WORD32 frame_len_long = ccfl;
102
327k
  FLOAT32 energy_shift = 0.25f;
103
327k
  FLOAT32 clip_energy = pstr_psy_config->clip_energy * energy_shift;
104
327k
  (VOID) channel_type;
105
106
327k
  pstr_psy_data->window_sequence = window_sequence;
107
327k
  memset(&ptr_spec_in[pstr_psy_config->low_pass_line], 0,
108
327k
         (frame_len_long - pstr_psy_config->low_pass_line) * sizeof(FLOAT64));
109
110
327k
  iusace_calc_band_energy(ptr_spec_in, pstr_psy_config->sfb_offset, pstr_psy_config->sfb_active,
111
327k
                          pstr_psy_data->ptr_sfb_energy_long, pstr_psy_config->sfb_count);
112
113
327k
  if (tns_select != 0) {
114
142k
    ia_tns_info *ptr_tns_info_ch2 = pstr_tns_info[i_ch - chn];
115
142k
    ptr_tns_info->number_of_bands = num_sfb;
116
142k
    ptr_tns_info->block_type = window_sequence;
117
142k
    ptr_tns_info->spec = ptr_spec_in;
118
142k
    iusace_tns_encode(ptr_tns_info_ch2, ptr_tns_info, pstr_psy_data->ptr_sfb_energy_long, 0, chn,
119
142k
                      pstr_psy_config->low_pass_line, scratch_tns_filter, 0, ptr_tns_scratch);
120
142k
  }
121
122
14.5M
  for (i = 0; i < pstr_psy_config->sfb_count; i++) {
123
14.2M
    pstr_psy_data->ptr_sfb_thr_long[i] =
124
14.2M
        pstr_psy_data->ptr_sfb_energy_long[i] * pstr_psy_config->ratio;
125
14.2M
    pstr_psy_data->ptr_sfb_thr_long[i] = MIN(pstr_psy_data->ptr_sfb_thr_long[i], clip_energy);
126
14.2M
  }
127
128
327k
  if (tns_select != 0) {
129
142k
    if (ptr_tns_info->tns_data_present == 1) {
130
89.6k
      iusace_calc_band_energy(ptr_spec_in, pstr_psy_config->sfb_offset,
131
89.6k
                              pstr_psy_config->sfb_active, pstr_psy_data->ptr_sfb_energy_long,
132
89.6k
                              pstr_psy_config->sfb_count);
133
89.6k
    }
134
142k
  }
135
136
327k
  iusace_find_max_spreading(pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac,
137
327k
                            pstr_psy_config->sfb_mask_high_fac, pstr_psy_data->ptr_sfb_thr_long);
138
139
14.5M
  for (i = 0; i < pstr_psy_config->sfb_count; i++) {
140
14.2M
    pstr_psy_data->ptr_sfb_thr_long[i] = MAX(pstr_psy_data->ptr_sfb_thr_long[i],
141
14.2M
                                             (pstr_psy_config->sfb_thr_quiet[i] * energy_shift));
142
14.2M
  }
143
144
327k
  if (pstr_psy_data->window_sequence == LONG_STOP_SEQUENCE) {
145
2.30M
    for (i = 0; i < pstr_psy_config->sfb_count; i++) {
146
2.25M
      pstr_psy_data->sfb_thr_nm1[i] = 1.0e20f;
147
2.25M
    }
148
52.3k
  }
149
150
327k
  iusace_pre_echo_control(pstr_psy_data->sfb_thr_nm1, pstr_psy_config->sfb_count,
151
327k
                          pstr_psy_config->max_allowed_inc_fac,
152
327k
                          pstr_psy_config->min_remaining_thr_fac,
153
327k
                          pstr_psy_data->ptr_sfb_thr_long);
154
155
327k
  if (pstr_psy_data->window_sequence == LONG_START_SEQUENCE) {
156
2.56M
    for (i = 0; i < pstr_psy_config->sfb_count; i++) {
157
2.50M
      pstr_psy_data->sfb_thr_nm1[i] = 1.0e20f;
158
2.50M
    }
159
58.1k
  }
160
161
14.5M
  for (i = 0; i < pstr_psy_config->sfb_count; i++) {
162
14.2M
    pstr_psy_data->ptr_sfb_spreaded_energy_long[i] = pstr_psy_data->ptr_sfb_energy_long[i];
163
14.2M
  }
164
327k
  iusace_find_max_spreading(
165
327k
      pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac_spr_ener,
166
327k
      pstr_psy_config->sfb_mask_high_fac_spr_ener, pstr_psy_data->ptr_sfb_spreaded_energy_long);
167
168
1.96M
  for (sfb = pstr_psy_config->sfb_count - 1; sfb >= 0; sfb--) {
169
1.94M
    for (line = pstr_psy_config->sfb_offset[sfb + 1] - 1;
170
60.4M
         line >= pstr_psy_config->sfb_offset[sfb]; line--) {
171
58.7M
      if (ptr_spec_in[line] != 0) break;
172
58.7M
    }
173
1.94M
    if (line >= pstr_psy_config->sfb_offset[sfb]) break;
174
1.94M
  }
175
176
327k
  pstr_psy_mod->str_psy_out_data[i_ch].max_sfb_per_grp = sfb + 1;
177
178
327k
  return;
179
327k
}
180
181
VOID iusace_psy_mod_sb(ia_psy_mod_struct *pstr_psy_mod, ia_sfb_params_struct *pstr_sfb_prms,
182
                       FLOAT64 *ptr_spec_in, ia_tns_info *pstr_tns_info[MAX_TIME_CHANNELS],
183
                       WORD32 tns_select, WORD32 i_ch, WORD32 chn, WORD32 channel_type,
184
                       FLOAT64 *scratch_tns_filter, WORD32 elem_idx, FLOAT64 *ptr_tns_scratch,
185
167k
                       WORD32 ccfl) {
186
167k
  ia_psy_mod_data_struct *pstr_psy_data = &(pstr_psy_mod->str_psy_data[i_ch]);
187
167k
  ia_psy_mod_short_config_struct *pstr_psy_config =
188
167k
      &(pstr_psy_mod->str_psy_short_config[elem_idx]);
189
167k
  WORD32 max_sfb = 0, sfb, line;
190
167k
  WORD32 window_sequence = pstr_sfb_prms->window_sequence[i_ch];
191
167k
  WORD32 num_sfb = pstr_sfb_prms->num_sfb[i_ch];
192
167k
  ia_tns_info *ptr_tns_info = pstr_tns_info[i_ch];
193
167k
  WORD32 i, w;
194
167k
  WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG;
195
167k
  FLOAT32 energy_shift = 0.25f;
196
167k
  FLOAT32 clip_energy = pstr_psy_config->clip_energy * energy_shift;
197
167k
  (VOID) channel_type;
198
199
167k
  pstr_psy_data->window_sequence = window_sequence;
200
201
1.50M
  for (w = 0; w < MAX_SHORT_WINDOWS; w++) {
202
1.33M
    WORD32 w_offset = w * frame_len_short;
203
1.33M
    WORD32 offset;
204
1.33M
    FLOAT64 *pmdct_double = &ptr_spec_in[pstr_psy_config->low_pass_line + w_offset];
205
206
1.33M
    offset = frame_len_short - pstr_psy_config->low_pass_line;
207
208
1.33M
    memset(pmdct_double, 0, sizeof(FLOAT64) * offset);
209
210
1.33M
    iusace_calc_band_energy(ptr_spec_in + w_offset, pstr_psy_config->sfb_offset,
211
1.33M
                            pstr_psy_config->sfb_active, pstr_psy_data->sfb_energy_short[w],
212
1.33M
                            pstr_psy_config->sfb_count);
213
214
1.33M
    if (tns_select != 0) {
215
548k
      ia_tns_info *ptr_tns_info_ch2 = pstr_tns_info[i_ch - chn];
216
548k
      ptr_tns_info->number_of_bands = num_sfb;
217
548k
      ptr_tns_info->block_type = window_sequence;
218
548k
      ptr_tns_info->spec = ptr_spec_in + w_offset;
219
548k
      iusace_tns_encode(ptr_tns_info_ch2, ptr_tns_info, pstr_psy_data->sfb_energy_short[w], w,
220
548k
                        chn, pstr_psy_config->low_pass_line, scratch_tns_filter, 0,
221
548k
                        ptr_tns_scratch);
222
548k
    }
223
224
19.6M
    for (i = 0; i < pstr_psy_config->sfb_count; i++) {
225
18.3M
      pstr_psy_data->sfb_thr_short[w][i] =
226
18.3M
          pstr_psy_data->sfb_energy_short[w][i] * pstr_psy_config->ratio;
227
18.3M
      pstr_psy_data->sfb_thr_short[w][i] = MIN(pstr_psy_data->sfb_thr_short[w][i], clip_energy);
228
18.3M
    }
229
230
1.33M
    if (tns_select != 0) {
231
548k
      if (ptr_tns_info->tns_data_present == 1) {
232
179k
        iusace_calc_band_energy(ptr_spec_in + w_offset, pstr_psy_config->sfb_offset,
233
179k
                                pstr_psy_config->sfb_active, pstr_psy_data->sfb_energy_short[w],
234
179k
                                pstr_psy_config->sfb_count);
235
179k
      }
236
548k
    }
237
238
1.33M
    iusace_find_max_spreading(pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac,
239
1.33M
                              pstr_psy_config->sfb_mask_high_fac,
240
1.33M
                              pstr_psy_data->sfb_thr_short[w]);
241
242
19.6M
    for (i = 0; i < pstr_psy_config->sfb_count; i++) {
243
18.3M
      pstr_psy_data->sfb_thr_short[w][i] =
244
18.3M
          MAX(pstr_psy_data->sfb_thr_short[w][i], (pstr_psy_config->sfb_thr_quiet[i] * 0.25f));
245
18.3M
    }
246
247
1.33M
    iusace_pre_echo_control(pstr_psy_data->sfb_thr_nm1, pstr_psy_config->sfb_count,
248
1.33M
                            pstr_psy_config->max_allowed_inc_fac,
249
1.33M
                            pstr_psy_config->min_remaining_thr_fac,
250
1.33M
                            pstr_psy_data->sfb_thr_short[w]);
251
252
19.6M
    for (i = 0; i < pstr_psy_config->sfb_count; i++) {
253
18.3M
      pstr_psy_data->sfb_spreaded_energy_short[w][i] = pstr_psy_data->sfb_energy_short[w][i];
254
18.3M
    }
255
1.33M
    iusace_find_max_spreading(
256
1.33M
        pstr_psy_config->sfb_count, pstr_psy_config->sfb_mask_low_fac_spr_ener,
257
1.33M
        pstr_psy_config->sfb_mask_high_fac_spr_ener, pstr_psy_data->sfb_spreaded_energy_short[w]);
258
1.33M
  }
259
260
1.50M
  for (WORD32 wnd = 0; wnd < MAX_SHORT_WINDOWS; wnd++) {
261
5.43M
    for (sfb = pstr_psy_config->sfb_count - 1; sfb >= max_sfb; sfb--) {
262
5.20M
      for (line = pstr_psy_config->sfb_offset[sfb + 1] - 1;
263
47.9M
           line >= pstr_psy_config->sfb_offset[sfb]; line--) {
264
43.8M
        if (ptr_spec_in[wnd * frame_len_short + line] != 0.0) break;
265
43.8M
      }
266
5.20M
      if (line >= pstr_psy_config->sfb_offset[sfb]) break;
267
5.20M
    }
268
1.33M
    max_sfb = MAX(max_sfb, sfb);
269
1.33M
  }
270
167k
  max_sfb = max_sfb > 0 ? max_sfb : 0;
271
272
167k
  pstr_psy_mod->str_psy_out_data[i_ch].max_sfb_per_grp = max_sfb + 1;
273
274
167k
  return;
275
167k
}