Coverage Report

Created: 2026-01-25 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_fd_quant.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 <math.h>
23
#include "iusace_type_def.h"
24
#include "ixheaac_error_standards.h"
25
#include "ixheaace_error_codes.h"
26
#include "ixheaace_mps_common_define.h"
27
#include "iusace_cnst.h"
28
#include "iusace_block_switch_const.h"
29
#include "iusace_bitbuffer.h"
30
#include "impd_drc_common_enc.h"
31
#include "impd_drc_uni_drc.h"
32
#include "impd_drc_api.h"
33
#include "impd_drc_uni_drc_eq.h"
34
#include "impd_drc_uni_drc_filter_bank.h"
35
#include "impd_drc_gain_enc.h"
36
#include "impd_drc_struct_def.h"
37
38
#include "ixheaace_memory_standards.h"
39
#include "iusace_tns_usac.h"
40
#include "iusace_psy_mod.h"
41
#include "iusace_config.h"
42
#include "iusace_ms.h"
43
#include "ixheaace_adjust_threshold_data.h"
44
#include "iusace_fd_qc_util.h"
45
#include "iusace_arith_enc.h"
46
#include "iusace_fd_quant.h"
47
#include "iusace_signal_classifier.h"
48
#include "iusace_block_switch_struct_def.h"
49
#include "ixheaace_sbr_header.h"
50
#include "ixheaace_config.h"
51
#include "ixheaace_asc_write.h"
52
#include "iusace_main.h"
53
#include "iusace_write_bitstream.h"
54
#include "ixheaace_nf.h"
55
#include "iusace_fd_qc_adjthr.h"
56
#include "iusace_block_switch_const.h"
57
#include "iusace_rom.h"
58
#include "ixheaace_cplx_pred.h"
59
#include "ixheaace_aac_constants.h"
60
61
static WORD32 iusace_window_shape[5] = {WIN_SEL_1, WIN_SEL_0, WIN_SEL_0, WIN_SEL_1, WIN_SEL_0};
62
63
22.0k
static WORD32 iusace_count_ms_bits(WORD32 sfb_count, WORD32 sfb_per_grp, WORD32 max_sfb_per_grp) {
64
22.0k
  WORD32 ms_bits = 0, sfb_offs, sfb;
65
78.4k
  for (sfb_offs = 0; sfb_offs < sfb_count; sfb_offs += sfb_per_grp) {
66
1.11M
    for (sfb = 0; sfb < max_sfb_per_grp; sfb++) {
67
1.06M
      ms_bits++;
68
1.06M
    }
69
56.3k
  }
70
22.0k
  return (ms_bits);
71
22.0k
}
72
73
static WORD32 iusace_count_static_bits(ia_usac_data_struct *ptr_usac_data,
74
                                       ia_usac_encoder_config_struct *ptr_usac_config,
75
                                       ia_sfb_params_struct *pstr_sfb_params,
76
                                       ia_psy_mod_out_data_struct *pstr_psy_out, WORD32 channels,
77
224k
                                       WORD32 chn, WORD32 usac_independency_flag, WORD32 ele_id) {
78
224k
  WORD32 ms_mask = ptr_usac_data->str_ms_info[chn].ms_mask;
79
224k
  WORD32 noise_filling = ptr_usac_data->noise_filling[ele_id];
80
224k
  WORD32 stat_bits = 0, i;
81
224k
  WORD32 tns_active = 0, tns_present_both = 0;
82
224k
  WORD32 max_sfb = pstr_psy_out[chn].max_sfb_per_grp;
83
224k
  (VOID) ptr_usac_config;
84
85
224k
  if (channels == 1) {
86
41.5k
    stat_bits += 1;  // core mode
87
41.5k
    stat_bits += 1;  // tns active
88
89
41.5k
    switch (pstr_psy_out[chn].window_sequence) {
90
22.9k
      case ONLY_LONG_SEQUENCE:
91
27.6k
      case LONG_START_SEQUENCE:
92
31.2k
      case LONG_STOP_SEQUENCE:
93
31.2k
        stat_bits += SI_ICS_INFO_BITS_LONG;
94
31.2k
        break;
95
10.1k
      case EIGHT_SHORT_SEQUENCE:
96
10.1k
        stat_bits += SI_ICS_INFO_BITS_SHORT;
97
10.1k
        break;
98
41.5k
    }
99
183k
  } else {
100
183k
    stat_bits += 2;  // core mode
101
183k
    stat_bits += 2;  // tns and common window
102
103
183k
    switch (pstr_psy_out[chn].window_sequence) {
104
76.8k
      case ONLY_LONG_SEQUENCE:
105
98.2k
      case LONG_START_SEQUENCE:
106
117k
      case LONG_STOP_SEQUENCE:
107
117k
        stat_bits += SI_ICS_INFO_BITS_LONG;
108
117k
        break;
109
65.3k
      case EIGHT_SHORT_SEQUENCE:
110
65.3k
        stat_bits += SI_ICS_INFO_BITS_SHORT;
111
65.3k
        break;
112
183k
    }
113
114
183k
    stat_bits += 1;  // common_max_sfb
115
183k
    stat_bits += SI_CPE_MS_MASK_BITS;
116
117
183k
    if (ms_mask != 3) {
118
166k
      if (ms_mask == 1) {
119
22.0k
        stat_bits += iusace_count_ms_bits(pstr_psy_out[chn].sfb_count,
120
22.0k
                                          pstr_psy_out[chn].sfb_per_group, max_sfb);
121
22.0k
      }
122
166k
    } else {
123
16.6k
      stat_bits += iusace_write_cplx_pred_data(
124
16.6k
          NULL, pstr_sfb_params->num_window_groups[chn], max_sfb,
125
16.6k
          ptr_usac_data->complex_coef[chn], ptr_usac_data->pred_coef_re[chn],
126
16.6k
          ptr_usac_data->pred_coef_im[chn], iusace_huffman_code_table, usac_independency_flag,
127
16.6k
          ptr_usac_data->pred_dir_idx[chn], ptr_usac_data->cplx_pred_used[chn],
128
16.6k
          ptr_usac_data->cplx_pred_all[chn], ptr_usac_data->temp_pred_coef_re_prev[chn],
129
16.6k
          ptr_usac_data->temp_pred_coef_im_prev[chn], &ptr_usac_data->delta_code_time[chn]);
130
16.6k
    }
131
132
183k
    if (ptr_usac_data->pstr_tns_info[chn] != NULL &&
133
82.9k
        ptr_usac_data->pstr_tns_info[chn + 1] != NULL) {
134
82.9k
      tns_active = ptr_usac_data->pstr_tns_info[chn]->tns_data_present ||
135
40.8k
                   ptr_usac_data->pstr_tns_info[chn + 1]->tns_data_present;
136
82.9k
      tns_present_both = ptr_usac_data->pstr_tns_info[chn]->tns_data_present &&
137
42.0k
                         ptr_usac_data->pstr_tns_info[chn + 1]->tns_data_present;
138
82.9k
    }
139
183k
    if (tns_active) {
140
46.8k
      stat_bits += 1;  // common_tns
141
142
46.8k
      stat_bits += 1;  // tns_present_both
143
144
46.8k
      if (!tns_present_both) {
145
12.1k
        stat_bits += 1;  // tns_data_present1
146
12.1k
      }
147
46.8k
    }
148
183k
  }
149
150
632k
  for (i = chn; i < chn + channels; i++) {
151
407k
    stat_bits += 8;  // global_gain
152
153
407k
    if (noise_filling) {
154
178k
      stat_bits += 8;
155
178k
    }
156
407k
  }
157
158
632k
  for (i = chn; i < chn + channels; i++) {
159
407k
    if (ptr_usac_data->pstr_tns_info[i] != NULL &&
160
173k
        ptr_usac_data->pstr_tns_info[i]->tns_data_present == 1) {
161
85.7k
      stat_bits += iusace_write_tns_data(NULL, ptr_usac_data->pstr_tns_info[i],
162
85.7k
                                         pstr_psy_out[i].window_sequence, 0);
163
85.7k
    }
164
165
407k
    if (!usac_independency_flag) {
166
388k
      stat_bits += 1;  // arith_reset_flag
167
388k
    }
168
169
407k
    stat_bits += 1;  // fac_data_present
170
407k
    stat_bits += ptr_usac_data->str_scratch.ptr_num_fac_bits[i];
171
407k
  }
172
173
224k
  stat_bits += (ptr_usac_data->num_sbr_bits + ptr_usac_data->num_drc_bits);
174
175
224k
  return stat_bits;
176
224k
}
177
178
static VOID iusace_sort_for_grouping(WORD32 *sfb_offset, const WORD32 *sfb_width_table,
179
                                     FLOAT64 *ptr_scratch, FLOAT64 *ptr_spec,
180
                                     WORD32 num_window_groups, const WORD32 *window_group_length,
181
140k
                                     WORD32 nr_of_sfb, WORD32 ccfl) {
182
140k
  WORD32 i, j, ii;
183
140k
  WORD32 index = 0;
184
140k
  WORD32 group_offset = 0;
185
140k
  WORD32 k = 0;
186
140k
  WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG;
187
188
140k
  sfb_offset[k] = 0;
189
2.06M
  for (k = 1; k < nr_of_sfb + 1; k++) {
190
1.92M
    sfb_offset[k] = sfb_offset[k - 1] + sfb_width_table[k - 1];
191
1.92M
  }
192
193
140k
  index = 0;
194
140k
  group_offset = 0;
195
682k
  for (i = 0; i < num_window_groups; i++) {
196
7.92M
    for (k = 0; k < nr_of_sfb; k++) {
197
22.7M
      for (j = 0; j < window_group_length[i]; j++) {
198
144M
        for (ii = 0; ii < sfb_width_table[k]; ii++) {
199
129M
          ptr_scratch[index++] =
200
129M
              ptr_spec[ii + sfb_offset[k] + frame_len_short * j + group_offset];
201
129M
        }
202
15.3M
      }
203
7.38M
    }
204
541k
    group_offset += frame_len_short * window_group_length[i];
205
541k
  }
206
207
140k
  memcpy(ptr_spec, ptr_scratch, ccfl * sizeof(ptr_spec[0]));
208
209
140k
  index = 0;
210
140k
  sfb_offset[index++] = 0;
211
682k
  for (i = 0; i < num_window_groups; i++) {
212
7.92M
    for (k = 0; k < nr_of_sfb; k++) {
213
7.38M
      sfb_offset[index] = sfb_offset[index - 1] + sfb_width_table[k] * window_group_length[i];
214
7.38M
      index++;
215
7.38M
    }
216
541k
  }
217
218
140k
  return;
219
140k
}
220
221
static VOID iusace_degroup_int(const WORD32 *ptr_grouped_sfb_offsets, WORD32 sfb_per_group,
222
                               WORD32 *ptr_scratch, WORD32 *ptr_spec, WORD32 num_window_groups,
223
                               const WORD32 *window_group_length, WORD32 ccfl)
224
225
199k
{
226
199k
  WORD32 i, j, k, n;
227
199k
  WORD32 index, group_offset;
228
199k
  WORD32 loop1, loop2;
229
199k
  WORD32 frame_len_short = (ccfl * FRAME_LEN_SHORT_128) / FRAME_LEN_LONG;
230
199k
  index = 0;
231
199k
  group_offset = 0;
232
233
199k
  memset(ptr_scratch, 0, ccfl * sizeof(WORD32));
234
235
961k
  for (i = 0; i < num_window_groups; i++) {
236
10.7M
    for (j = 0; j < sfb_per_group; j++) {
237
10.0M
      WORD32 idx = i * sfb_per_group + j;
238
10.0M
      loop1 = ((ptr_grouped_sfb_offsets[idx + 1] - ptr_grouped_sfb_offsets[idx]) /
239
10.0M
               window_group_length[i]);
240
241
31.0M
      for (k = 0; k < window_group_length[i]; k++) {
242
20.9M
        loop2 = ((ptr_grouped_sfb_offsets[idx] - group_offset) / window_group_length[i]) +
243
20.9M
                frame_len_short * k + group_offset;
244
245
195M
        for (n = 0; n < loop1; n++) {
246
174M
          ptr_scratch[n + loop2] = ptr_spec[index++];
247
174M
        }
248
20.9M
      }
249
10.0M
    }
250
762k
    group_offset += frame_len_short * window_group_length[i];
251
762k
  }
252
253
199k
  memcpy(ptr_spec, ptr_scratch, ccfl * sizeof(WORD32));
254
255
199k
  return;
256
199k
}
257
258
IA_ERRORCODE iusace_stereo_proc(ia_sfb_params_struct *pstr_sfb_prms,
259
                                WORD32 usac_independancy_flag, ia_usac_data_struct *ptr_usac_data,
260
183k
                                ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn) {
261
183k
  IA_ERRORCODE err_code;
262
183k
  WORD32 i = 0;
263
183k
  WORD32 j = 0;
264
183k
  iusace_scratch_mem *pstr_scratch = &ptr_usac_data->str_scratch;
265
183k
  ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data;
266
183k
  ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data;
267
183k
  WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb;
268
183k
  WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups;
269
183k
  WORD32 ccfl = ptr_usac_config->ccfl;
270
183k
  ia_ms_info_struct *pstr_ms_info = &ptr_usac_data->str_ms_info[chn];
271
272
183k
  FLOAT64 tmp = 0.0f;
273
183k
  FLOAT32 nrg_mid = 0.0f, nrg_side = 0.0f, nrg_left = 0.0f, nrg_right = 0.0f;
274
183k
  FLOAT64 *ptr_scratch_spec = pstr_scratch->p_quant_spectrum_spec_scratch;
275
183k
  FLOAT32 ratio_mid = 0.0f, ratio_side = 0.0f;
276
183k
  FLOAT32 eps = 1.0e-6f;
277
  /* Save a copy of left and right channel MDCT spectra before they are modified */
278
183k
  memcpy(ptr_usac_data->left_chan_save[chn], ptr_usac_data->spectral_line_vector[chn],
279
183k
         ccfl * sizeof(FLOAT64));
280
183k
  memcpy(ptr_usac_data->right_chan_save[chn], ptr_usac_data->spectral_line_vector[chn + 1],
281
183k
         ccfl * sizeof(FLOAT64));
282
283
183k
  if (ptr_usac_config->cmplx_pred_flag == 1) {
284
    /* Refinement - decision on whether to use complex prediction or MS */
285
104M
    for (i = 0; i < ccfl; i++) {
286
104M
      tmp = ptr_usac_data->spectral_line_vector[chn][i];
287
104M
      ptr_scratch_spec[i] = 0.5f * (ptr_usac_data->spectral_line_vector[chn][i] +
288
104M
                                    ptr_usac_data->spectral_line_vector[chn + 1][i]);
289
104M
      ptr_scratch_spec[ccfl + i] = 0.5f * (tmp - ptr_usac_data->spectral_line_vector[chn + 1][i]);
290
104M
    }
291
292
104M
    for (i = 0; i < ccfl; i++) {
293
104M
      nrg_mid += (FLOAT32)(ptr_scratch_spec[i] * ptr_scratch_spec[i]);
294
104M
      nrg_side += (FLOAT32)(ptr_scratch_spec[ccfl + i] * ptr_scratch_spec[ccfl + i]);
295
104M
      nrg_left += (FLOAT32)(ptr_usac_data->spectral_line_vector[chn][i] *
296
104M
                            ptr_usac_data->spectral_line_vector[chn][i]);
297
104M
      nrg_right += (FLOAT32)(ptr_usac_data->spectral_line_vector[chn + 1][i] *
298
104M
                             ptr_usac_data->spectral_line_vector[chn + 1][i]);
299
104M
    }
300
301
116k
    ratio_mid = nrg_mid / (MAX(nrg_left, nrg_right) + eps);
302
116k
    ratio_side = nrg_side / (MAX(nrg_left, nrg_right) + eps);
303
304
116k
    if (ratio_mid >= 0.8f || ratio_side >= 0.8f || nrg_mid == 0.f || nrg_side == 0.f) {
305
82.9k
      pstr_ms_info->ms_mask = 0;
306
82.9k
    } else {
307
33.6k
      pstr_ms_info->ms_mask = 3;
308
33.6k
    }
309
116k
  }
310
311
183k
  if (pstr_ms_info->ms_mask != 3) {
312
149k
    WORD32 idx = 0;
313
149k
    WORD32 sfb;
314
315
5.28M
    for (sfb = 0; sfb < ptr_num_sfb[chn]; sfb++) {
316
5.13M
      ptr_usac_data->pred_coef_re_prev[chn][sfb] = 0;
317
5.13M
      ptr_usac_data->pred_coef_im_prev[chn][sfb] = 0;
318
5.13M
      ptr_usac_data->temp_pred_coef_re_prev[chn][sfb] = 0;
319
5.13M
      ptr_usac_data->temp_pred_coef_im_prev[chn][sfb] = 0;
320
5.13M
    }
321
322
149k
    memset(ptr_usac_data->str_ms_info[chn].ms_used, 0,
323
149k
           MAX_SFB_LONG * MAX_SHORT_WINDOWS * sizeof(WORD32));
324
325
149k
    iusace_ms_apply(pstr_psy_data, ptr_usac_data->spectral_line_vector[chn],
326
149k
                    ptr_usac_data->spectral_line_vector[chn + 1],
327
149k
                    &ptr_usac_data->str_ms_info[chn].ms_mask,
328
149k
                    ptr_usac_data->str_ms_info[chn].ms_used,
329
149k
                    ptr_num_window_groups[chn] * ptr_num_sfb[chn], ptr_num_sfb[chn],
330
149k
                    pstr_psy_out[chn].max_sfb_per_grp, pstr_sfb_prms->grouped_sfb_offset[chn],
331
149k
                    chn, ptr_usac_config->cmplx_pred_flag == 1 ? ptr_scratch_spec : NULL);
332
333
433k
    for (i = 0; i < ptr_num_window_groups[chn]; i++) {
334
7.27M
      for (j = 0; j < ptr_num_sfb[chn]; j++) {
335
6.98M
        pstr_psy_out[chn].ms_used[idx++] = ptr_usac_data->str_ms_info[chn].ms_used[i][j];
336
6.98M
      }
337
283k
    }
338
149k
  } else {
339
    /* Reset buffer to zero */
340
302k
    for (WORD32 group = 0; group < MAX_SHORT_WINDOWS; group++) {
341
268k
      memset(ptr_usac_data->cplx_pred_used[chn][group], 0, MAX_SFB_LONG * sizeof(WORD32));
342
268k
    }
343
344
33.6k
    ptr_usac_data->cplx_pred_all[chn] = 1; /* Disable bandwise switching to L/R */
345
118k
    for (i = 0; i < ptr_num_window_groups[chn]; i++) {
346
863k
      for (j = 0; j < ptr_num_sfb[chn]; j += 2) {
347
778k
        ptr_usac_data->cplx_pred_used[chn][i][j] = 1;
348
778k
        if ((j + 1) < ptr_num_sfb[chn]) {
349
753k
          ptr_usac_data->cplx_pred_used[chn][i][j + 1] = ptr_usac_data->cplx_pred_used[chn][i][j];
350
753k
        }
351
778k
      }
352
85.3k
    }
353
354
33.6k
    err_code = iusace_cplx_pred_proc(
355
33.6k
        ptr_usac_data, ptr_usac_config, usac_independancy_flag, pstr_sfb_prms, chn, pstr_psy_data,
356
33.6k
        pstr_sfb_prms->grouped_sfb_offset[chn], pstr_scratch->p_cmpx_mdct_temp_buf,
357
33.6k
        ptr_scratch_spec, nrg_mid, nrg_side);
358
33.6k
    if (err_code != IA_NO_ERROR) {
359
0
      return err_code;
360
0
    }
361
33.6k
  }
362
183k
  return IA_NO_ERROR;
363
183k
}
364
365
IA_ERRORCODE iusace_grouping(ia_sfb_params_struct *pstr_sfb_prms, WORD32 num_chans,
366
                             ia_usac_data_struct *ptr_usac_data,
367
                             ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn,
368
224k
                             WORD32 ele_id) {
369
224k
  WORD32 i = 0, grp, sfb, wnd;
370
224k
  WORD32 j = 0;
371
224k
  WORD32 k;
372
224k
  WORD32 ch;
373
224k
  ia_psy_mod_struct *pstr_psy_config = &ptr_usac_data->str_psy_mod;
374
224k
  ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data;
375
224k
  WORD32 *ptr_window_sequence = pstr_sfb_prms->window_sequence;
376
224k
  WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb;
377
224k
  WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups;
378
224k
  ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data;
379
380
632k
  for (ch = chn; ch < chn + num_chans; ch++) {
381
407k
    if (ptr_window_sequence[ch] == EIGHT_SHORT_SEQUENCE) {
382
140k
      iusace_sort_for_grouping(
383
140k
          pstr_sfb_prms->grouped_sfb_offset[ch], pstr_sfb_prms->sfb_width_table[ch],
384
140k
          ptr_usac_data->str_scratch.p_sort_grouping_scratch,
385
140k
          ptr_usac_data->spectral_line_vector[ch], ptr_num_window_groups[ch],
386
140k
          pstr_sfb_prms->window_group_length[ch], ptr_num_sfb[ch], ptr_usac_config->ccfl);
387
266k
    } else if ((ptr_window_sequence[ch] == ONLY_LONG_SEQUENCE) ||
388
90.2k
               (ptr_window_sequence[ch] == LONG_START_SEQUENCE) ||
389
42.6k
               (ptr_window_sequence[ch] == LONG_STOP_SEQUENCE) ||
390
266k
               (ptr_window_sequence[ch] == STOP_START_SEQUENCE)) {
391
266k
      pstr_sfb_prms->grouped_sfb_offset[ch][0] = 0;
392
266k
      k = 0;
393
11.8M
      for (i = 0; i < ptr_num_sfb[ch]; i++) {
394
11.5M
        pstr_sfb_prms->grouped_sfb_offset[ch][i] = k;
395
11.5M
        k += pstr_sfb_prms->sfb_width_table[ch][i];
396
11.5M
      }
397
266k
      pstr_sfb_prms->grouped_sfb_offset[ch][i] = k;
398
266k
    } else {
399
0
      return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_WINDOW_TYPE;
400
0
    }
401
407k
  }
402
403
632k
  for (ch = chn; ch < chn + num_chans; ch++) {
404
407k
    if (pstr_psy_data[ch].window_sequence == 2) {
405
140k
      i = 0;
406
682k
      for (grp = 0; grp < ptr_num_window_groups[ch]; grp++) {
407
7.92M
        for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) {
408
7.38M
          pstr_psy_out[ch].sfb_min_snr[i++] =
409
7.38M
              pstr_psy_config->str_psy_short_config[ele_id].sfb_min_snr[sfb];
410
7.38M
        }
411
541k
      }
412
140k
      wnd = 0;
413
140k
      i = 0;
414
682k
      for (grp = 0; grp < ptr_num_window_groups[ch]; grp++) {
415
7.92M
        for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) {
416
7.38M
          FLOAT32 threshold = pstr_psy_data[ch].sfb_thr_short[wnd][sfb];
417
7.38M
          FLOAT32 energy = pstr_psy_data[ch].sfb_energy_short[wnd][sfb];
418
7.38M
          FLOAT32 energy_ms = pstr_psy_data[ch].ptr_sfb_energy_short_ms[wnd][sfb];
419
7.38M
          FLOAT32 spread_energy = pstr_psy_data[ch].sfb_spreaded_energy_short[wnd][sfb];
420
15.3M
          for (j = 1; j < pstr_sfb_prms->window_group_length[ch][grp]; j++) {
421
7.97M
            threshold = threshold + pstr_psy_data[ch].sfb_thr_short[wnd + j][sfb];
422
7.97M
            energy = energy + pstr_psy_data[ch].sfb_energy_short[wnd + j][sfb];
423
7.97M
            spread_energy =
424
7.97M
                spread_energy + pstr_psy_data[ch].sfb_spreaded_energy_short[wnd + j][sfb];
425
7.97M
            energy_ms = energy_ms + pstr_psy_data[ch].ptr_sfb_energy_short_ms[wnd + j][sfb];
426
7.97M
          }
427
7.38M
          pstr_psy_data[ch].ptr_sfb_thr_long[i] = threshold;
428
7.38M
          pstr_psy_data[ch].ptr_sfb_energy_long[i] = energy;
429
7.38M
          pstr_psy_data[ch].ptr_sfb_energy_long_ms[i] = energy_ms;
430
7.38M
          pstr_psy_data[ch].ptr_sfb_spreaded_energy_long[i++] = spread_energy;
431
7.38M
        }
432
541k
        wnd += pstr_sfb_prms->window_group_length[ch][grp];
433
541k
      }
434
266k
    } else {
435
11.8M
      for (sfb = 0; sfb < ptr_num_sfb[ch]; sfb++) {
436
11.5M
        pstr_psy_out[ch].sfb_min_snr[sfb] =
437
11.5M
            pstr_psy_config->str_psy_long_config[ele_id].sfb_min_snr[sfb];
438
11.5M
      }
439
266k
    }
440
407k
  }
441
224k
  return IA_NO_ERROR;
442
224k
}
443
444
IA_ERRORCODE iusace_quantize_spec(ia_sfb_params_struct *pstr_sfb_prms,
445
                                  WORD32 usac_independancy_flag, WORD32 num_chans,
446
                                  ia_usac_data_struct *ptr_usac_data,
447
                                  ia_usac_encoder_config_struct *ptr_usac_config, WORD32 chn,
448
                                  WORD32 ele_id, WORD32 *is_quant_spec_zero,
449
224k
                                  WORD32 *is_gain_limited) {
450
224k
  IA_ERRORCODE err_code;
451
224k
  WORD32 i = 0, sfb;
452
224k
  WORD32 j = 0;
453
224k
  WORD32 k;
454
224k
  WORD32 max_bits;
455
224k
  WORD32 ch;
456
224k
  iusace_scratch_mem *pstr_scratch = &ptr_usac_data->str_scratch;
457
224k
  WORD32 num_scfs[2];
458
224k
  FLOAT32 **sfb_form_fac = &pstr_scratch->ptr_sfb_form_fac[0];
459
224k
  WORD32 max_ch_dyn_bits[2] = {0};
460
224k
  FLOAT32 ch_bit_dist[2];
461
224k
  WORD32 constraints_fulfilled;
462
224k
  WORD32 iterations = 0;
463
224k
  WORD32 max_val;
464
224k
  WORD32 kk, idx = 0;
465
466
224k
  FLOAT32 *ptr_exp_spec = pstr_scratch->p_exp_spec;
467
224k
  FLOAT32 *ptr_mdct_spec_float = pstr_scratch->p_mdct_spec_float;
468
224k
  ia_psy_mod_data_struct *pstr_psy_data = ptr_usac_data->str_psy_mod.str_psy_data;
469
224k
  ia_qc_out_data_struct *pstr_qc_out = &ptr_usac_data->str_qc_main.str_qc_out;
470
224k
  ia_psy_mod_out_data_struct *pstr_psy_out = ptr_usac_data->str_psy_mod.str_psy_out_data;
471
224k
  ia_qc_data_struct *pstr_qc_data = &ptr_usac_data->str_qc_main.str_qc_data[ele_id];
472
224k
  ia_adj_thr_elem_struct *pstr_adj_thr_elem = &pstr_qc_data->str_adj_thr_ele;
473
224k
  WORD32 *ptr_window_sequence = pstr_sfb_prms->window_sequence;
474
224k
  WORD32 *ptr_max_sfb = pstr_sfb_prms->max_sfb;
475
224k
  WORD32 *ptr_num_sfb = pstr_sfb_prms->num_sfb;
476
224k
  WORD32 *ptr_num_window_groups = pstr_sfb_prms->num_window_groups;
477
224k
  WORD32 bitres_bits, bitres_diff;
478
224k
  WORD32 gain;
479
480
224k
  memset(num_scfs, 0, 2 * sizeof(num_scfs[0]));
481
482
632k
  for (ch = chn; ch < chn + num_chans; ch++) {
483
407k
    num_scfs[idx] = ptr_num_sfb[ch] * ptr_num_window_groups[ch];
484
485
407k
    pstr_psy_out[ch].sfb_count = num_scfs[idx];
486
407k
    pstr_psy_out[ch].sfb_per_group = num_scfs[idx] / ptr_num_window_groups[ch];
487
407k
    pstr_psy_out[ch].window_sequence = pstr_psy_data[ch].window_sequence;
488
407k
    pstr_psy_out[ch].window_shape = iusace_window_shape[pstr_psy_data[ch].window_sequence];
489
407k
    pstr_psy_out[ch].ptr_spec_coeffs = ptr_usac_data->spectral_line_vector[ch];
490
407k
    pstr_psy_out[ch].ptr_sfb_energy = pstr_psy_data[ch].ptr_sfb_energy_long;
491
407k
    pstr_psy_out[ch].ptr_sfb_thr = pstr_psy_data[ch].ptr_sfb_thr_long;
492
407k
    pstr_psy_out[ch].ptr_sfb_spread_energy = pstr_psy_data[ch].ptr_sfb_spreaded_energy_long;
493
494
19.3M
    for (j = 0; j < num_scfs[idx]; j++) {
495
18.9M
      pstr_psy_out[ch].sfb_offsets[j] = pstr_sfb_prms->grouped_sfb_offset[ch][j];
496
18.9M
    }
497
407k
    pstr_psy_out[ch].sfb_offsets[num_scfs[idx]] =
498
407k
        pstr_sfb_prms->grouped_sfb_offset[ch][num_scfs[idx]];
499
500
24.8M
    for (j = 0; j < MAX_NUM_GROUPED_SFB; j++) {
501
24.4M
      sfb_form_fac[idx][j] = MIN_FLT_VAL;
502
24.4M
    }
503
504
407k
    iusace_calc_form_fac_per_chan(&pstr_psy_out[ch], pstr_scratch, idx);
505
407k
    idx++;
506
407k
  }
507
508
224k
  pstr_qc_out->static_bits =
509
224k
      iusace_count_static_bits(ptr_usac_data, ptr_usac_config, pstr_sfb_prms, pstr_psy_out,
510
224k
                               num_chans, chn, usac_independancy_flag, ele_id);
511
512
224k
  iusace_adj_bitrate(pstr_qc_data, pstr_qc_data->ch_bitrate, ptr_usac_config->core_sample_rate,
513
224k
                     ptr_usac_config->ccfl);
514
224k
  err_code =
515
224k
      iusace_adj_thr(pstr_adj_thr_elem, pstr_psy_out, ch_bit_dist, pstr_qc_out,
516
224k
                     pstr_qc_data->avg_bits - pstr_qc_out->static_bits, pstr_qc_data->bit_res_lvl,
517
224k
                     pstr_qc_data->max_bitres_bits, pstr_qc_out->static_bits,
518
224k
                     &pstr_qc_data->max_bit_fac, num_chans, chn, pstr_scratch);
519
224k
  if (err_code != IA_NO_ERROR) {
520
0
    return err_code;
521
0
  }
522
523
224k
  iusace_estimate_scfs_chan(pstr_psy_out, pstr_qc_out->str_qc_out_chan, num_chans, chn,
524
224k
                            pstr_scratch);
525
224k
  idx = 0;
526
632k
  for (ch = 0; ch < num_chans; ch++) {
527
407k
    max_ch_dyn_bits[ch] = (WORD32)floor(
528
407k
        ch_bit_dist[ch] * (FLOAT32)(pstr_qc_data->avg_bits + pstr_qc_data->bit_res_lvl - 7 -
529
407k
                                    pstr_qc_out->static_bits));
530
407k
    idx++;
531
407k
  }
532
533
224k
  pstr_qc_out->dyn_bits = 0;
534
224k
  idx = 0;
535
632k
  for (ch = chn; ch < chn + num_chans; ch++) {
536
407k
    iterations = 0;
537
407k
    gain = 0;
538
383M
    for (kk = 0; kk < ptr_usac_config->ccfl; kk++) {
539
382M
      ptr_exp_spec[kk] = (FLOAT32)pstr_psy_out[ch].ptr_spec_coeffs[kk];
540
382M
      ptr_mdct_spec_float[kk] = (FLOAT32)pstr_psy_out[ch].ptr_spec_coeffs[kk];
541
382M
    }
542
493k
    do {
543
493k
      constraints_fulfilled = 1;
544
493k
      WORD32 quant_spec_is_zero = 1;
545
493k
      if (iterations > 0) {
546
332k
        for (WORD32 sfb_offs = 0; sfb_offs < pstr_psy_out[ch].sfb_count;
547
247k
             sfb_offs += pstr_psy_out[ch].sfb_per_group) {
548
2.60M
          for (sfb = 0; sfb < pstr_psy_out[ch].max_sfb_per_grp; sfb++) {
549
2.35M
            WORD32 scalefactor = pstr_qc_out->str_qc_out_chan[idx].scalefactor[sfb + sfb_offs];
550
2.35M
            gain = MAX(gain, pstr_qc_out->str_qc_out_chan[idx].global_gain - scalefactor);
551
2.35M
            iusace_quantize_lines(
552
2.35M
                pstr_qc_out->str_qc_out_chan[idx].global_gain - scalefactor,
553
2.35M
                pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb + 1] -
554
2.35M
                    pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb],
555
2.35M
                ptr_exp_spec + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb],
556
2.35M
                pstr_qc_out->str_qc_out_chan[idx].quant_spec +
557
2.35M
                    pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb],
558
2.35M
                ptr_mdct_spec_float + pstr_psy_out[ch].sfb_offsets[sfb_offs + sfb]);
559
2.35M
          }
560
247k
        }
561
85.6k
      }
562
493k
      max_val =
563
493k
          iusace_calc_max_val_in_sfb(pstr_psy_out[ch].sfb_count, pstr_psy_out[ch].max_sfb_per_grp,
564
493k
                                     pstr_psy_out[ch].sfb_per_group, pstr_psy_out[ch].sfb_offsets,
565
493k
                                     pstr_qc_out->str_qc_out_chan[idx].quant_spec);
566
493k
      if (max_val > MAX_QUANT) {
567
0
        constraints_fulfilled = 0;
568
0
      }
569
570
23.1M
      for (k = 0; k < num_scfs[idx]; k++) {
571
22.6M
        for (i = pstr_sfb_prms->grouped_sfb_offset[ch][k];
572
472M
             i < pstr_sfb_prms->grouped_sfb_offset[ch][k + 1]; i++) {
573
450M
          ptr_usac_data->str_quant_info[idx].quant_degroup[i] =
574
450M
              (WORD32)pstr_qc_out->str_qc_out_chan[idx].quant_spec[i];
575
450M
          if (ptr_usac_data->str_quant_info[idx].quant_degroup[i] != 0) {
576
100M
            quant_spec_is_zero = 0;
577
100M
          }
578
450M
        }
579
22.6M
      }
580
581
493k
      if (ptr_window_sequence[ch] == EIGHT_SHORT_SEQUENCE) {
582
199k
        iusace_degroup_int(pstr_sfb_prms->grouped_sfb_offset[ch], ptr_num_sfb[ch],
583
199k
                           ptr_usac_data->str_scratch.p_degroup_scratch,
584
199k
                           ptr_usac_data->str_quant_info[idx].quant_degroup,
585
199k
                           ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch],
586
199k
                           ptr_usac_config->ccfl);
587
199k
      }
588
589
493k
      ptr_usac_data->str_quant_info[idx].max_spec_coeffs = 0;
590
13.5M
      for (k = 0; k < ptr_max_sfb[ch]; k++) {
591
13.0M
        ptr_usac_data->str_quant_info[idx].max_spec_coeffs +=
592
13.0M
            pstr_sfb_prms->sfb_width_table[ch][k];
593
13.0M
      }
594
595
23.1M
      for (i = 0; i < num_scfs[idx]; i++) {
596
22.6M
        ptr_usac_data->str_quant_info[idx].scale_factor[i] =
597
22.6M
            pstr_qc_out->str_qc_out_chan[idx].global_gain -
598
22.6M
            pstr_qc_out->str_qc_out_chan[idx].scalefactor[i] + SF_OFFSET;
599
22.6M
      }
600
601
493k
      max_bits = iusace_count_fd_bits(pstr_sfb_prms, ptr_usac_data, usac_independancy_flag,
602
493k
                                      ptr_usac_config, ch, idx);
603
604
493k
      if (max_bits > max_ch_dyn_bits[idx]) {
605
89.3k
        constraints_fulfilled = 0;
606
89.3k
      }
607
493k
      if (quant_spec_is_zero == 1) {
608
113k
        constraints_fulfilled = 1;
609
        /*Bit consuption is exceding bit reservoir, there is no scope left for bit consumption
610
          reduction, as spectrum is zero. Hence breaking the quantization loop. */
611
113k
        if (iterations > 0) {
612
415
          *is_quant_spec_zero = 1;
613
415
          max_bits = max_ch_dyn_bits[idx];
614
415
        }
615
113k
      }
616
493k
      if ((gain == MAX_GAIN_INDEX) && (constraints_fulfilled == 0)) {
617
        /* Bit consuption is exceding bit reservoir, there is no scope left for bit consumption
618
           reduction, as gain has reached the maximum value. Hence breaking the quantization
619
           loop. */
620
14
        constraints_fulfilled = 1;
621
14
        *is_gain_limited = 1;
622
14
        max_bits = max_ch_dyn_bits[idx];
623
14
      }
624
493k
      if (!constraints_fulfilled) {
625
85.6k
        pstr_qc_out->str_qc_out_chan[idx].global_gain++;
626
85.6k
      }
627
493k
      iterations++;
628
493k
    } while (!constraints_fulfilled);
629
630
407k
    pstr_qc_out->dyn_bits += max_bits;
631
632
407k
    if (ptr_usac_data->noise_filling[ele_id]) {
633
178k
      WORD32 max_nf_sfb = ptr_max_sfb[ch];
634
635
178k
      if (ptr_window_sequence[ch] != EIGHT_SHORT_SEQUENCE) {
636
120k
        iusace_noise_filling(
637
120k
            &ptr_usac_data->noise_level[idx], &ptr_usac_data->noise_offset[idx],
638
120k
            ptr_usac_data->spectral_line_vector[ch], &ptr_usac_data->str_quant_info[idx],
639
120k
            pstr_sfb_prms->grouped_sfb_offset[ch], max_nf_sfb, ptr_usac_config->ccfl,
640
120k
            ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch], 160,
641
120k
            ptr_usac_data->str_scratch.p_noise_filling_highest_tone);
642
120k
      } else {
643
57.2k
        iusace_noise_filling(
644
57.2k
            &ptr_usac_data->noise_level[idx], &ptr_usac_data->noise_offset[idx],
645
57.2k
            ptr_usac_data->spectral_line_vector[ch], &ptr_usac_data->str_quant_info[idx],
646
57.2k
            pstr_sfb_prms->grouped_sfb_offset[ch], max_nf_sfb, ptr_usac_config->ccfl >> 3,
647
57.2k
            ptr_num_window_groups[ch], pstr_sfb_prms->window_group_length[ch], 20,
648
57.2k
            (FLOAT64 *)ptr_usac_data->str_scratch.p_noise_filling_highest_tone);
649
57.2k
      }
650
651
178k
      if (ptr_usac_data->noise_level[idx] == 0 && ptr_usac_data->noise_offset[idx] != 0 &&
652
0
          pstr_sfb_prms->common_win[ch]) {
653
0
        ptr_usac_data->complex_coef[ch] = 0;
654
0
      }
655
178k
    }
656
407k
    idx++;
657
407k
  }
658
659
224k
  pstr_adj_thr_elem->dyn_bits_last = pstr_qc_out->dyn_bits;
660
661
224k
  bitres_bits = pstr_qc_data->max_bitres_bits - pstr_qc_data->bit_res_lvl;
662
224k
  bitres_diff = pstr_qc_data->avg_bits - (pstr_qc_out->static_bits + pstr_qc_out->dyn_bits);
663
224k
  pstr_qc_out->fill_bits = MAX(0, (bitres_diff - bitres_bits));
664
665
224k
  if (pstr_qc_data->avg_bits > 0) {
666
224k
    pstr_qc_data->bit_res_lvl +=
667
224k
        pstr_qc_data->avg_bits -
668
224k
        (pstr_qc_out->static_bits + pstr_qc_out->dyn_bits + pstr_qc_out->fill_bits);
669
224k
  } else {
670
0
    pstr_qc_data->bit_res_lvl = pstr_qc_data->max_bits;
671
0
  }
672
673
224k
  if (pstr_qc_data->bit_res_lvl < 0 ||
674
222k
      pstr_qc_data->bit_res_lvl > pstr_qc_data->max_bitres_bits) {
675
2.63k
    return IA_EXHEAACE_EXE_FATAL_USAC_INVALID_BIT_RSVR_LVL;
676
2.63k
  }
677
678
222k
  return IA_NO_ERROR;
679
224k
}