Coverage Report

Created: 2025-10-13 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_sf_estimation.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 <math.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <limits.h>
25
26
#include "ixheaac_type_def.h"
27
#include "ixheaac_constants.h"
28
#include "ixheaace_aac_constants.h"
29
#include "ixheaac_basic_ops32.h"
30
#include "ixheaac_basic_ops16.h"
31
#include "ixheaac_basic_ops40.h"
32
#include "ixheaac_basic_ops.h"
33
34
#include "ixheaace_psy_const.h"
35
#include "ixheaace_block_switch.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
#include "ixheaace_psy_data.h"
42
#include "ixheaace_interface.h"
43
#include "ixheaace_adjust_threshold_data.h"
44
#include "ixheaace_dynamic_bits.h"
45
#include "ixheaace_qc_data.h"
46
47
#include "ixheaace_sf_estimation.h"
48
#include "ixheaace_quant.h"
49
#include "ixheaace_bits_count.h"
50
#include "ixheaace_tns_params.h"
51
#include "ixheaace_common_utils.h"
52
53
VOID iaace_calc_form_fac_per_chan(FLOAT32 *ptr_sfb_form_factor,
54
                                  FLOAT32 *ptr_sfb_num_relevant_lines,
55
                                  ixheaace_psy_out_channel *pstr_psy_out_chan,
56
461k
                                  FLOAT32 *ptr_sfb_ld_energy) {
57
461k
  WORD32 i, j, sfb_offs;
58
461k
  WORD32 sfb, sfb_width;
59
60
461k
  memset(ptr_sfb_num_relevant_lines, 0,
61
461k
         sizeof(*ptr_sfb_num_relevant_lines) * pstr_psy_out_chan->sfb_count);
62
63
461k
  memset(ptr_sfb_ld_energy, 0, sizeof(*ptr_sfb_ld_energy) * pstr_psy_out_chan->sfb_count);
64
65
1.15M
  for (sfb_offs = 0; sfb_offs < pstr_psy_out_chan->sfb_count;
66
694k
       sfb_offs += pstr_psy_out_chan->sfb_per_group) {
67
694k
    i = sfb_offs;
68
13.6M
    for (sfb = 0; sfb < pstr_psy_out_chan->max_sfb_per_grp; sfb++, i++) {
69
13.0M
      ptr_sfb_form_factor[i] = MIN_FLT_VAL;
70
13.0M
      if (pstr_psy_out_chan->ptr_sfb_energy[i] > pstr_psy_out_chan->ptr_sfb_thr[i]) {
71
7.22M
        FLOAT32 avg_form_factor;
72
73
95.3M
        for (j = pstr_psy_out_chan->sfb_offsets[i]; j < pstr_psy_out_chan->sfb_offsets[i + 1];
74
88.0M
             j++) {
75
88.0M
          ptr_sfb_form_factor[i] += (FLOAT32)sqrt(fabs(pstr_psy_out_chan->ptr_spec_coeffs[j]));
76
88.0M
        }
77
78
7.22M
        sfb_width = pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i];
79
7.22M
        avg_form_factor =
80
7.22M
            (FLOAT32)pow(pstr_psy_out_chan->ptr_sfb_energy[i] / (FLOAT32)sfb_width, 0.25f);
81
7.22M
        ptr_sfb_num_relevant_lines[i] = ptr_sfb_form_factor[i] / avg_form_factor;
82
7.22M
        ptr_sfb_ld_energy[i] = (FLOAT32)(log(pstr_psy_out_chan->ptr_sfb_energy[i]) * LOG2_1);
83
7.22M
      }
84
13.0M
    }
85
694k
  }
86
461k
}
87
88
static VOID iaace_calculate_exp_spec(const WORD32 num_lines, FLOAT32 *ptr_exp_spec,
89
6.36M
                                     FLOAT32 *ptr_ptr_mdct_spec) {
90
6.36M
  WORD32 line;
91
92
83.5M
  for (line = 0; line < num_lines; line++) {
93
77.2M
    FLOAT32 tmp = ptr_ptr_mdct_spec[line];
94
77.2M
    ptr_exp_spec[line] = (FLOAT32)sqrt(fabs(tmp));
95
77.2M
    ptr_exp_spec[line] *= (FLOAT32)sqrt(ptr_exp_spec[line]);
96
77.2M
  }
97
6.36M
}
98
99
129M
static WORD32 iaace_scf_delta_bit_count(WORD32 delta) {
100
129M
  if (delta > 60) {
101
1.15k
    return (ixheaace_huffman_code_table[120][0]);
102
1.15k
  }
103
129M
  if (delta < -60) {
104
1
    return (ixheaace_huffman_code_table[0][0]);
105
1
  }
106
129M
  return (ixheaace_huffman_code_table[delta + 60][0]);
107
129M
}
108
109
39.9M
static WORD32 iaace_count_single_scf_bits(WORD32 scf, WORD32 left_scf, WORD32 right_scf) {
110
39.9M
  WORD32 scf_bits;
111
112
39.9M
  scf_bits =
113
39.9M
      iaace_scf_delta_bit_count(left_scf - scf) + iaace_scf_delta_bit_count(scf - right_scf);
114
115
39.9M
  return scf_bits;
116
39.9M
}
117
118
static FLOAT32 iaace_calc_single_spec_pe(WORD32 scf, FLOAT32 sfb_const_pe_part,
119
39.9M
                                         FLOAT32 num_lines) {
120
39.9M
  FLOAT32 spec_pe;
121
39.9M
  FLOAT32 ld_ratio;
122
123
39.9M
  ld_ratio = sfb_const_pe_part - (FLOAT32)0.375f * (FLOAT32)scf;
124
125
39.9M
  if (ld_ratio >= PE_C1) {
126
27.4M
    spec_pe = (FLOAT32)0.7f * num_lines * ld_ratio;
127
27.4M
  } else {
128
12.4M
    spec_pe = (FLOAT32)0.7f * num_lines * (PE_C2 + PE_C3 * ld_ratio);
129
12.4M
  }
130
131
39.9M
  return spec_pe;
132
39.9M
}
133
134
static WORD32 iaace_count_scf_bits_diff(WORD16 *ptr_sfb_prev, WORD16 *ptr_sfb_new,
135
3.75M
                                        WORD32 sfb_count, WORD32 start_sfb, WORD32 stop_sfb) {
136
3.75M
  WORD32 scf_bits_diff = 0;
137
3.75M
  WORD32 sfb = 0, sfb_last;
138
3.75M
  WORD32 sfb_prev, sfb_next;
139
140
3.75M
  sfb_last = start_sfb;
141
142
3.75M
  while ((sfb_last < stop_sfb) && (ptr_sfb_prev[sfb_last] == SHRT_MIN)) {
143
0
    sfb_last++;
144
0
  }
145
146
3.75M
  sfb_prev = start_sfb - 1;
147
148
8.00M
  while ((sfb_prev >= 0) && (ptr_sfb_prev[sfb_prev] == SHRT_MIN)) {
149
4.24M
    sfb_prev--;
150
4.24M
  }
151
152
3.75M
  if (sfb_prev >= 0) {
153
1.65M
    scf_bits_diff += iaace_scf_delta_bit_count(ptr_sfb_new[sfb_prev] - ptr_sfb_new[sfb_last]) -
154
1.65M
                     iaace_scf_delta_bit_count(ptr_sfb_prev[sfb_prev] - ptr_sfb_prev[sfb_last]);
155
1.65M
  }
156
157
37.6M
  for (sfb = sfb_last + 1; sfb < stop_sfb; sfb++) {
158
33.9M
    if (ptr_sfb_prev[sfb] != SHRT_MIN) {
159
20.1M
      scf_bits_diff += iaace_scf_delta_bit_count(ptr_sfb_new[sfb_last] - ptr_sfb_new[sfb]) -
160
20.1M
                       iaace_scf_delta_bit_count(ptr_sfb_prev[sfb_last] - ptr_sfb_prev[sfb]);
161
162
20.1M
      sfb_last = sfb;
163
20.1M
    }
164
33.9M
  }
165
166
3.75M
  sfb_next = stop_sfb;
167
168
3.75M
  while ((sfb_next < sfb_count) && (ptr_sfb_prev[sfb_next] == SHRT_MIN)) {
169
0
    sfb_next++;
170
0
  }
171
172
3.75M
  if (sfb_next < sfb_count) {
173
3.13M
    scf_bits_diff += iaace_scf_delta_bit_count(ptr_sfb_new[sfb_last] - ptr_sfb_new[sfb_next]) -
174
3.13M
                     iaace_scf_delta_bit_count(ptr_sfb_prev[sfb_last] - ptr_sfb_prev[sfb_next]);
175
3.13M
  }
176
177
3.75M
  return scf_bits_diff;
178
3.75M
}
179
180
static FLOAT32 iaace_calc_spec_pe_diff(ixheaace_psy_out_channel *pstr_psy_out,
181
                                       WORD16 *ptr_scf_prev, WORD16 *ptr_scf_new,
182
                                       FLOAT32 *ptr_sfb_const_pe_part, FLOAT32 *ptr_sfb_form_fac,
183
                                       FLOAT32 *ptr_sfb_num_rel_lines, WORD32 start_sfb,
184
3.75M
                                       WORD32 stop_sfb) {
185
3.75M
  FLOAT32 spec_pe_diff = 0.0f;
186
3.75M
  WORD32 sfb;
187
188
41.4M
  for (sfb = start_sfb; sfb < stop_sfb; sfb++) {
189
37.6M
    if (ptr_scf_prev[sfb] != SHRT_MIN) {
190
23.9M
      FLOAT32 ld_ratio_prev, ld_ratio_new, pe_prev, pe_new;
191
192
23.9M
      if (ptr_sfb_const_pe_part[sfb] == MIN_FLT_VAL) {
193
1.44M
        ptr_sfb_const_pe_part[sfb] = (FLOAT32)log(pstr_psy_out->ptr_sfb_energy[sfb] *
194
1.44M
                                                  (FLOAT32)6.75f / ptr_sfb_form_fac[sfb]) *
195
1.44M
                                     LOG2_1;
196
1.44M
      }
197
198
23.9M
      ld_ratio_prev = ptr_sfb_const_pe_part[sfb] - 0.375f * ptr_scf_prev[sfb];
199
23.9M
      ld_ratio_new = ptr_sfb_const_pe_part[sfb] - 0.375f * ptr_scf_new[sfb];
200
201
23.9M
      if (ld_ratio_prev >= PE_C1) {
202
13.7M
        pe_prev = ld_ratio_prev;
203
13.7M
      } else {
204
10.1M
        pe_prev = PE_C2 + PE_C3 * ld_ratio_prev;
205
10.1M
      }
206
207
23.9M
      if (ld_ratio_new >= PE_C1) {
208
20.2M
        pe_new = ld_ratio_new;
209
20.2M
      } else {
210
3.68M
        pe_new = PE_C2 + PE_C3 * ld_ratio_new;
211
3.68M
      }
212
213
23.9M
      spec_pe_diff += (FLOAT32)0.7f * ptr_sfb_num_rel_lines[sfb] * (pe_new - pe_prev);
214
23.9M
    }
215
37.6M
  }
216
217
3.75M
  return spec_pe_diff;
218
3.75M
}
219
220
static FLOAT32 iaace_calc_sfb_dist(const FLOAT32 *ptr_spec, const FLOAT32 *ptr_exp_spec,
221
31.7M
                                   WORD16 *ptr_quant_spec, WORD32 sfb_width, WORD32 gain) {
222
31.7M
  WORD32 i = 0;
223
31.7M
  FLOAT32 dist = 0;
224
31.7M
  FLOAT32 k = -0.0946f + 0.5f;
225
31.7M
  FLOAT32 quantizer = ixheaace_fd_quant_table[gain + 128];
226
31.7M
  FLOAT32 inv_quantizer = ixheaace_fd_inv_quant_table[gain + 128];
227
228
335M
  while (i < sfb_width) {
229
304M
    FLOAT32 iq_val;
230
304M
    FLOAT32 diff;
231
232
304M
    ptr_quant_spec[i] = (WORD16)(k + quantizer * ptr_exp_spec[i]);
233
234
304M
    if (ptr_quant_spec[i] < 64) {
235
294M
      iq_val = ixheaace_pow_4_3_table[ptr_quant_spec[i]] * inv_quantizer;
236
294M
    } else {
237
9.56M
      iq_val = (FLOAT32)((pow((FLOAT32)abs(ptr_quant_spec[i]), 4.0f / 3.0f)) * inv_quantizer);
238
9.56M
    }
239
240
304M
    diff = (FLOAT32)fabs(ptr_spec[i]) - iq_val;
241
242
304M
    dist += diff * diff;
243
244
304M
    i++;
245
304M
  }
246
247
31.7M
  return dist;
248
31.7M
}
249
250
static WORD16 iaace_improve_scf(FLOAT32 *ptr_spec, FLOAT32 *ptr_exp_spec, WORD16 *ptr_quant_spec,
251
                                WORD16 *ptr_quant_spec_temp, WORD32 sfb_width, FLOAT32 threshold,
252
                                WORD16 scf, WORD16 min_scf, FLOAT32 *dist,
253
6.36M
                                WORD16 *ptr_min_calc_scf) {
254
6.36M
  FLOAT32 sfb_dist;
255
6.36M
  WORD16 best_scf = scf;
256
6.36M
  WORD32 j;
257
258
6.36M
  sfb_dist = iaace_calc_sfb_dist(ptr_spec, ptr_exp_spec, ptr_quant_spec, sfb_width, scf);
259
260
6.36M
  *ptr_min_calc_scf = scf;
261
262
6.36M
  if (sfb_dist > (1.25 * threshold)) {
263
1.21M
    FLOAT32 best_sfb_dist = sfb_dist;
264
265
1.21M
    if (scf > min_scf) {
266
1.21M
      scf--;
267
268
1.21M
      sfb_dist = iaace_calc_sfb_dist(ptr_spec, ptr_exp_spec, ptr_quant_spec_temp, sfb_width, scf);
269
270
1.21M
      if (sfb_dist < best_sfb_dist) {
271
1.07M
        best_scf = scf;
272
1.07M
        best_sfb_dist = sfb_dist;
273
274
11.9M
        for (j = 0; j < sfb_width; j++) {
275
10.8M
          ptr_quant_spec[j] = ptr_quant_spec_temp[j];
276
10.8M
        }
277
1.07M
      }
278
279
1.21M
      *ptr_min_calc_scf = scf;
280
1.21M
    }
281
1.21M
    *dist = best_sfb_dist;
282
5.14M
  } else {
283
5.14M
    FLOAT32 best_sfb_dist = sfb_dist;
284
5.14M
    FLOAT32 allowed_sfb_dist = MIN(sfb_dist * 1.25f, threshold);
285
5.14M
    WORD32 count;
286
287
15.4M
    for (count = SCF_COUNT_LIMIT_AAC; count >= 0; count--) {
288
10.2M
      scf++;
289
290
10.2M
      sfb_dist = iaace_calc_sfb_dist(ptr_spec, ptr_exp_spec, ptr_quant_spec_temp, sfb_width, scf);
291
292
10.2M
      if (sfb_dist < allowed_sfb_dist) {
293
1.36M
        *ptr_min_calc_scf = best_scf + 1;
294
295
1.36M
        best_scf = scf;
296
1.36M
        best_sfb_dist = sfb_dist;
297
298
17.9M
        for (j = 0; j < sfb_width; j++) {
299
16.6M
          ptr_quant_spec[j] = ptr_quant_spec_temp[j];
300
16.6M
        }
301
1.36M
      }
302
10.2M
    }
303
5.14M
    *dist = best_sfb_dist;
304
5.14M
  }
305
306
83.5M
  for (j = 0; j < sfb_width; j++) {
307
77.2M
    if (ptr_spec[j] < 0) {
308
37.4M
      ptr_quant_spec[j] = -ptr_quant_spec[j];
309
37.4M
    }
310
77.2M
  }
311
312
6.36M
  return best_scf;
313
6.36M
}
314
315
static VOID iaace_assimilate_single_scf(ixheaace_psy_out_channel *pstr_psy_out,
316
                                        FLOAT32 *ptr_exp_spec, WORD16 *ptr_quant_spec,
317
                                        WORD16 *ptr_quant_spec_temp, WORD16 *ptr_scf,
318
                                        WORD16 *ptr_min_scf, FLOAT32 *ptr_sfb_dist,
319
                                        FLOAT32 *ptr_sfb_const_pe_part, FLOAT32 *ptr_sfb_form_fac,
320
                                        FLOAT32 *ptr_sfb_num_lines, WORD16 *ptr_min_calc_scf,
321
461k
                                        FLOAT32 *ptr_ptr_mdct_spec) {
322
461k
  WORD32 sfb_prev, sfb_act, sfb_next;
323
461k
  WORD16 scf_act = 0, *scf_prev, *scf_next, min_scf, max_scf;
324
461k
  WORD32 sfb_width, sfb_offs;
325
461k
  FLOAT32 energy;
326
461k
  FLOAT32 sfb_pe_prev, sfb_pe_new;
327
461k
  FLOAT32 sfb_dist_new;
328
461k
  WORD32 j;
329
461k
  WORD32 success = 0;
330
461k
  FLOAT32 delta_pe = 0.0f, delta_pe_new, delta_pe_temp;
331
461k
  WORD16 prev_scf_last[MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
332
461k
      prev_scf_next[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
333
461k
  FLOAT32 delta_pe_last[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
334
461k
  WORD32 update_min_scf;
335
336
18.4M
  for (j = 0; j < pstr_psy_out->sfb_count; j++) {
337
17.9M
    prev_scf_last[j] = SHRT_MAX;
338
17.9M
    prev_scf_next[j] = SHRT_MAX;
339
17.9M
    delta_pe_last[j] = MAX_FLT_VAL;
340
17.9M
  }
341
342
461k
  sfb_prev = -1;
343
461k
  sfb_act = -1;
344
461k
  sfb_next = -1;
345
461k
  scf_prev = 0;
346
461k
  scf_next = 0;
347
461k
  min_scf = SHRT_MAX;
348
461k
  max_scf = SHRT_MAX;
349
350
38.3M
  do {
351
38.3M
    sfb_next++;
352
353
57.2M
    while ((sfb_next < pstr_psy_out->sfb_count) && (ptr_scf[sfb_next] == SHRT_MIN)) {
354
18.9M
      sfb_next++;
355
18.9M
    }
356
357
38.3M
    if ((sfb_prev >= 0) && (sfb_act >= 0) && (sfb_next < pstr_psy_out->sfb_count)) {
358
30.4M
      scf_act = ptr_scf[sfb_act];
359
360
30.4M
      scf_prev = ptr_scf + sfb_prev;
361
30.4M
      scf_next = ptr_scf + sfb_next;
362
363
30.4M
      min_scf = MIN(*scf_prev, *scf_next);
364
365
30.4M
      max_scf = MAX(*scf_prev, *scf_next);
366
30.4M
    } else {
367
7.83M
      if ((sfb_prev == -1) && (sfb_act >= 0) && (sfb_next < pstr_psy_out->sfb_count)) {
368
3.66M
        scf_act = ptr_scf[sfb_act];
369
370
3.66M
        scf_prev = &scf_act;
371
372
3.66M
        scf_next = ptr_scf + sfb_next;
373
374
3.66M
        min_scf = *scf_next;
375
376
3.66M
        max_scf = *scf_next;
377
4.17M
      } else {
378
4.17M
        if ((sfb_prev >= 0) && (sfb_act >= 0) && (sfb_next == pstr_psy_out->sfb_count)) {
379
335k
          scf_act = ptr_scf[sfb_act];
380
381
335k
          scf_prev = ptr_scf + sfb_prev;
382
383
335k
          scf_next = &scf_act;
384
385
335k
          min_scf = *scf_prev;
386
387
335k
          max_scf = *scf_prev;
388
335k
        }
389
4.17M
      }
390
7.83M
    }
391
392
38.3M
    if (sfb_act >= 0) {
393
34.4M
      min_scf = MAX(min_scf, ptr_min_scf[sfb_act]);
394
34.4M
    }
395
396
38.3M
    if ((sfb_act >= 0) && (sfb_prev >= 0 || sfb_next < pstr_psy_out->sfb_count) &&
397
34.4M
        (scf_act > min_scf) && (scf_act <= min_scf + MAX_SCF_DELTA) &&
398
16.2M
        (scf_act >= max_scf - MAX_SCF_DELTA) &&
399
16.1M
        (*scf_prev != prev_scf_last[sfb_act] || *scf_next != prev_scf_next[sfb_act] ||
400
9.57M
         delta_pe < delta_pe_last[sfb_act])) {
401
9.57M
      success = 0;
402
403
9.57M
      sfb_width = pstr_psy_out->sfb_offsets[sfb_act + 1] - pstr_psy_out->sfb_offsets[sfb_act];
404
405
9.57M
      sfb_offs = pstr_psy_out->sfb_offsets[sfb_act];
406
407
9.57M
      energy = pstr_psy_out->ptr_sfb_energy[sfb_act];
408
409
9.57M
      if (ptr_sfb_const_pe_part[sfb_act] == MIN_FLT_VAL) {
410
4.31M
        ptr_sfb_const_pe_part[sfb_act] =
411
4.31M
            (FLOAT32)log(energy * (FLOAT32)6.75f / ptr_sfb_form_fac[sfb_act]) * LOG2_1;
412
4.31M
      }
413
414
9.57M
      sfb_pe_prev = iaace_calc_single_spec_pe(scf_act, ptr_sfb_const_pe_part[sfb_act],
415
9.57M
                                              ptr_sfb_num_lines[sfb_act]) +
416
9.57M
                    (FLOAT32)iaace_count_single_scf_bits(scf_act, *scf_prev, *scf_next);
417
418
9.57M
      delta_pe_new = delta_pe;
419
9.57M
      update_min_scf = 1;
420
421
36.3M
      do {
422
36.3M
        scf_act--;
423
424
36.3M
        if (scf_act < ptr_min_calc_scf[sfb_act] && scf_act >= max_scf - MAX_SCF_DELTA) {
425
30.4M
          sfb_pe_new = iaace_calc_single_spec_pe(scf_act, ptr_sfb_const_pe_part[sfb_act],
426
30.4M
                                                 ptr_sfb_num_lines[sfb_act]) +
427
30.4M
                       (FLOAT32)iaace_count_single_scf_bits(scf_act, *scf_prev, *scf_next);
428
429
30.4M
          delta_pe_temp = delta_pe + sfb_pe_new - sfb_pe_prev;
430
431
30.4M
          if (delta_pe_temp < (FLOAT32)10.0f) {
432
10.9M
            sfb_dist_new =
433
10.9M
                iaace_calc_sfb_dist(ptr_ptr_mdct_spec + sfb_offs, ptr_exp_spec + sfb_offs,
434
10.9M
                                    ptr_quant_spec_temp + sfb_offs, sfb_width, scf_act);
435
436
10.9M
            if (sfb_dist_new < ptr_sfb_dist[sfb_act]) {
437
6.17M
              ptr_scf[sfb_act] = scf_act;
438
6.17M
              ptr_sfb_dist[sfb_act] = sfb_dist_new;
439
440
45.1M
              for (j = sfb_offs; j < sfb_offs + sfb_width; j++) {
441
38.9M
                ptr_quant_spec[j] = ptr_quant_spec_temp[j];
442
443
38.9M
                if (ptr_ptr_mdct_spec[j] < 0.0f) {
444
18.6M
                  ptr_quant_spec[j] = -ptr_quant_spec[j];
445
18.6M
                }
446
38.9M
              }
447
6.17M
              delta_pe_new = delta_pe_temp;
448
6.17M
              success = 1;
449
6.17M
            }
450
451
10.9M
            if (update_min_scf) {
452
10.3M
              ptr_min_calc_scf[sfb_act] = scf_act;
453
10.3M
            }
454
19.4M
          } else {
455
19.4M
            update_min_scf = 0;
456
19.4M
          }
457
30.4M
        }
458
36.3M
      } while (scf_act > min_scf);
459
460
9.57M
      delta_pe = delta_pe_new;
461
462
9.57M
      prev_scf_last[sfb_act] = *scf_prev;
463
9.57M
      prev_scf_next[sfb_act] = *scf_next;
464
9.57M
      delta_pe_last[sfb_act] = delta_pe;
465
9.57M
    }
466
467
38.3M
    if (success) {
468
3.37M
      sfb_prev = -1;
469
3.37M
      sfb_act = -1;
470
3.37M
      sfb_next = -1;
471
3.37M
      scf_prev = 0;
472
3.37M
      scf_next = 0;
473
3.37M
      min_scf = SHRT_MAX;
474
3.37M
      max_scf = SHRT_MAX;
475
3.37M
      success = 0;
476
34.9M
    } else {
477
34.9M
      sfb_prev = sfb_act;
478
34.9M
      sfb_act = sfb_next;
479
34.9M
    }
480
38.3M
  } while (sfb_next < pstr_psy_out->sfb_count);
481
461k
}
482
483
static VOID iaace_assimilate_multiple_scf(ixheaace_psy_out_channel *pstr_psy_out,
484
                                          FLOAT32 *ptr_exp_spec, WORD16 *ptr_quant_spec,
485
                                          WORD16 *ptr_quant_spec_temp, WORD16 *ptr_scf,
486
                                          WORD16 *ptr_min_scf, FLOAT32 *ptr_sfb_dist,
487
                                          FLOAT32 *ptr_sfb_const_pe_part,
488
                                          FLOAT32 *ptr_sfb_form_fac, FLOAT32 *ptr_sfb_num_lines,
489
461k
                                          FLOAT32 *ptr_ptr_mdct_spec) {
490
461k
  WORD32 sfb, start_sfb, stop_sfb;
491
461k
  WORD16 scf_temp[MAXIMUM_GROUPED_SCALE_FACTOR_BAND], min_scf, max_scf, scf_act;
492
461k
  WORD32 possible_region_found;
493
461k
  WORD32 sfb_width, sfb_offs, j;
494
461k
  FLOAT32 sfb_dist_new[MAXIMUM_GROUPED_SCALE_FACTOR_BAND] = {0};
495
461k
  FLOAT32 prev_dist_sum, new_dist_sum;
496
461k
  WORD32 delta_scf_bits;
497
461k
  FLOAT32 delta_spec_pe;
498
461k
  FLOAT32 delta_pe = 0.0f, delta_pe_new;
499
461k
  WORD32 sfb_count = pstr_psy_out->sfb_count;
500
501
461k
  min_scf = SHRT_MAX;
502
461k
  max_scf = SHRT_MIN;
503
504
18.4M
  for (sfb = 0; sfb < sfb_count; sfb++) {
505
17.9M
    if (ptr_scf[sfb] != SHRT_MIN) {
506
6.36M
      min_scf = MIN(min_scf, ptr_scf[sfb]);
507
508
6.36M
      max_scf = MAX(max_scf, ptr_scf[sfb]);
509
6.36M
    }
510
17.9M
  }
511
512
461k
  if (max_scf != SHRT_MIN && max_scf <= min_scf + MAX_SCF_DELTA) {
513
284k
    scf_act = max_scf;
514
2.85M
    do {
515
2.85M
      scf_act = scf_act - 2;
516
517
2.85M
      memcpy(scf_temp, ptr_scf, MAXIMUM_GROUPED_SCALE_FACTOR_BAND * sizeof(*ptr_scf));
518
519
2.85M
      stop_sfb = 0;
520
521
7.08M
      do {
522
7.08M
        sfb = stop_sfb;
523
524
77.1M
        while (sfb < sfb_count && (ptr_scf[sfb] == SHRT_MIN || ptr_scf[sfb] <= scf_act)) {
525
70.0M
          sfb++;
526
70.0M
        }
527
528
7.08M
        start_sfb = sfb;
529
530
7.08M
        sfb++;
531
532
47.1M
        while (sfb < sfb_count && (ptr_scf[sfb] == SHRT_MIN || ptr_scf[sfb] > scf_act)) {
533
40.0M
          sfb++;
534
40.0M
        }
535
536
7.08M
        stop_sfb = sfb;
537
538
7.08M
        possible_region_found = 0;
539
540
7.08M
        if (start_sfb < sfb_count) {
541
4.23M
          possible_region_found = 1;
542
543
42.0M
          for (sfb = start_sfb; sfb < stop_sfb; sfb++) {
544
38.3M
            if (ptr_scf[sfb] != SHRT_MIN) {
545
24.5M
              if (scf_act < ptr_min_scf[sfb]) {
546
484k
                possible_region_found = 0;
547
484k
                break;
548
484k
              }
549
24.5M
            }
550
38.3M
          }
551
4.23M
        }
552
553
7.08M
        if (possible_region_found) {
554
41.4M
          for (sfb = start_sfb; sfb < stop_sfb; sfb++) {
555
37.6M
            if (scf_temp[sfb] != SHRT_MIN) {
556
23.9M
              scf_temp[sfb] = scf_act;
557
23.9M
            }
558
37.6M
          }
559
560
3.75M
          delta_scf_bits =
561
3.75M
              iaace_count_scf_bits_diff(ptr_scf, scf_temp, sfb_count, start_sfb, stop_sfb);
562
563
3.75M
          delta_spec_pe =
564
3.75M
              iaace_calc_spec_pe_diff(pstr_psy_out, ptr_scf, scf_temp, ptr_sfb_const_pe_part,
565
3.75M
                                      ptr_sfb_form_fac, ptr_sfb_num_lines, start_sfb, stop_sfb);
566
567
3.75M
          delta_pe_new = delta_pe + (FLOAT32)delta_scf_bits + delta_spec_pe;
568
569
3.75M
          if (delta_pe_new < (FLOAT32)10.0f) {
570
1.33M
            prev_dist_sum = new_dist_sum = 0.0f;
571
572
7.79M
            for (sfb = start_sfb; sfb < stop_sfb; sfb++) {
573
6.68M
              if (scf_temp[sfb] != SHRT_MIN) {
574
2.92M
                prev_dist_sum += ptr_sfb_dist[sfb];
575
576
2.92M
                sfb_width = pstr_psy_out->sfb_offsets[sfb + 1] - pstr_psy_out->sfb_offsets[sfb];
577
578
2.92M
                sfb_offs = pstr_psy_out->sfb_offsets[sfb];
579
580
2.92M
                sfb_dist_new[sfb] =
581
2.92M
                    iaace_calc_sfb_dist(ptr_ptr_mdct_spec + sfb_offs, ptr_exp_spec + sfb_offs,
582
2.92M
                                        ptr_quant_spec_temp + sfb_offs, sfb_width, scf_act);
583
584
2.92M
                if (sfb_dist_new[sfb] > pstr_psy_out->ptr_sfb_thr[sfb]) {
585
220k
                  new_dist_sum = (FLOAT32)2.0f * prev_dist_sum;
586
220k
                  break;
587
220k
                }
588
589
2.70M
                new_dist_sum += sfb_dist_new[sfb];
590
2.70M
              }
591
6.68M
            }
592
593
1.33M
            if (new_dist_sum < prev_dist_sum) {
594
488k
              delta_pe = delta_pe_new;
595
596
3.58M
              for (sfb = start_sfb; sfb < stop_sfb; sfb++) {
597
3.09M
                if (ptr_scf[sfb] != SHRT_MIN) {
598
1.26M
                  sfb_width = pstr_psy_out->sfb_offsets[sfb + 1] - pstr_psy_out->sfb_offsets[sfb];
599
600
1.26M
                  sfb_offs = pstr_psy_out->sfb_offsets[sfb];
601
1.26M
                  ptr_scf[sfb] = scf_act;
602
1.26M
                  ptr_sfb_dist[sfb] = sfb_dist_new[sfb];
603
604
9.84M
                  for (j = sfb_offs; j < sfb_offs + sfb_width; j++) {
605
8.58M
                    ptr_quant_spec[j] = ptr_quant_spec_temp[j];
606
607
8.58M
                    if (ptr_ptr_mdct_spec[j] < 0.0f) {
608
3.88M
                      ptr_quant_spec[j] = -ptr_quant_spec[j];
609
3.88M
                    }
610
8.58M
                  }
611
1.26M
                }
612
3.09M
              }
613
488k
            }
614
1.33M
          }
615
3.75M
        }
616
617
7.08M
      } while (stop_sfb <= sfb_count);
618
619
2.85M
    } while (scf_act > min_scf);
620
284k
  }
621
461k
}
622
623
VOID iaace_estimate_scfs_chan(
624
    ixheaace_psy_out_channel **pstr_psy_out,
625
    ixheaace_qc_out_channel **pstr_qc_out_chan,
626
    FLOAT32 sfb_form_factor_ch[IXHEAACE_MAX_CH_IN_BS_ELE][MAXIMUM_GROUPED_SCALE_FACTOR_BAND],
627
    FLOAT32 sfb_num_relevant_lines_ch[][MAXIMUM_GROUPED_SCALE_FACTOR_BAND], WORD32 num_channels,
628
318k
    WORD32 chn, WORD32 frame_len_long) {
629
318k
  WORD16 *ptr_scalefactor;
630
318k
  WORD32 *global_gain;
631
318k
  FLOAT32 *ptr_sfb_form_factor;
632
318k
  FLOAT32 *ptr_sfb_num_relevant_lines_ch;
633
318k
  WORD16 *ptr_quant_spec;
634
318k
  WORD32 i, ch, j;
635
318k
  FLOAT32 thresh, energy, energy_part, thr_part;
636
318k
  FLOAT32 scf_float;
637
318k
  WORD16 scf_int = 0, min_scf = 0, max_scf = 0;
638
318k
  FLOAT32 max_spec = 0.0f;
639
318k
  WORD16 min_sf_max_quant[MAXIMUM_GROUPED_SCALE_FACTOR_BAND] = {0};
640
318k
  FLOAT32 sfb_dist[MAXIMUM_GROUPED_SCALE_FACTOR_BAND] = {0};
641
318k
  WORD16 min_calc_scf[MAXIMUM_GROUPED_SCALE_FACTOR_BAND] = {0};
642
318k
  WORD16 quant_spec_temp[FRAME_LEN_1024];
643
318k
  FLOAT32 ptr_exp_spec[FRAME_LEN_1024];
644
318k
  FLOAT32 ptr_mdct_spec[FRAME_LEN_1024];
645
646
318k
  memset(quant_spec_temp, 0, frame_len_long * sizeof(quant_spec_temp[0]));
647
318k
  memset(ptr_mdct_spec, 0, frame_len_long * sizeof(ptr_mdct_spec[0]));
648
318k
  memset(ptr_exp_spec, 0, frame_len_long * sizeof(ptr_exp_spec[0]));
649
650
779k
  for (ch = chn; ch < chn + num_channels; ch++) {
651
461k
    ixheaace_psy_out_channel *pstr_psy_out_chan = pstr_psy_out[ch];
652
461k
    pstr_qc_out_chan[ch]->global_gain = 0;
653
654
461k
    memset(pstr_qc_out_chan[ch]->scalefactor, 0,
655
461k
           sizeof(*pstr_qc_out_chan[ch]->scalefactor) * pstr_psy_out[ch]->sfb_count);
656
461k
    memset(pstr_qc_out_chan[ch]->quant_spec, 0,
657
461k
           sizeof(*pstr_qc_out_chan[ch]->quant_spec) * frame_len_long);
658
659
461k
    ptr_scalefactor = pstr_qc_out_chan[ch]->scalefactor;
660
461k
    global_gain = &pstr_qc_out_chan[ch]->global_gain;
661
461k
    ptr_sfb_form_factor = &sfb_form_factor_ch[ch][0];
662
461k
    ptr_sfb_num_relevant_lines_ch = &sfb_num_relevant_lines_ch[ch][0];
663
461k
    ptr_quant_spec = pstr_qc_out_chan[ch]->quant_spec;
664
665
18.4M
    for (i = 0; i < pstr_psy_out_chan->sfb_count; i++) {
666
17.9M
      thresh = pstr_psy_out_chan->ptr_sfb_thr[i];
667
17.9M
      energy = pstr_psy_out_chan->ptr_sfb_energy[i];
668
17.9M
      max_spec = 0.0f;
669
670
357M
      for (j = pstr_psy_out_chan->sfb_offsets[i]; j < pstr_psy_out_chan->sfb_offsets[i + 1];
671
339M
           j++) {
672
339M
        max_spec = (FLOAT32)MAX(max_spec, fabsf(pstr_psy_out_chan->ptr_spec_coeffs[j]));
673
339M
      }
674
675
17.9M
      ptr_scalefactor[i] = MIN_SHRT_VAL;
676
17.9M
      min_sf_max_quant[i] = MIN_SHRT_VAL;
677
678
17.9M
      if ((max_spec > 0.0) && (energy > thresh) && (ptr_sfb_form_factor[i] != MIN_FLT_VAL)) {
679
6.36M
        energy_part = (FLOAT32)log10(ptr_sfb_form_factor[i]);
680
681
6.36M
        thr_part = (FLOAT32)log10(6.75 * thresh + MIN_FLT_VAL);
682
6.36M
        scf_float = 8.8585f * (thr_part - energy_part);
683
6.36M
        scf_int = (WORD16)floor(scf_float);
684
6.36M
        min_sf_max_quant[i] = (WORD16)floor(C1_SF + C2_SF * log(max_spec));
685
6.36M
        scf_int = MAX(scf_int, min_sf_max_quant[i]);
686
6.36M
        scf_int = MAX(scf_int, MIN_GAIN_INDEX_AAC);
687
6.36M
        scf_int = MIN(scf_int, (MAX_GAIN_INDEX_AAC - SCF_COUNT_LIMIT_AAC - 1));
688
83.5M
        for (j = 0; j < pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i];
689
77.2M
             j++) {
690
77.2M
          ptr_exp_spec[pstr_psy_out_chan->sfb_offsets[i] + j] = (FLOAT32)(
691
77.2M
              pstr_psy_out_chan->ptr_spec_coeffs[pstr_psy_out_chan->sfb_offsets[i] + j]);
692
77.2M
          ptr_mdct_spec[pstr_psy_out_chan->sfb_offsets[i] + j] = (FLOAT32)(
693
77.2M
              pstr_psy_out_chan->ptr_spec_coeffs[pstr_psy_out_chan->sfb_offsets[i] + j]);
694
77.2M
        }
695
696
6.36M
        iaace_calculate_exp_spec(
697
6.36M
            pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i],
698
6.36M
            ptr_exp_spec + pstr_psy_out_chan->sfb_offsets[i],
699
6.36M
            ptr_mdct_spec + pstr_psy_out_chan->sfb_offsets[i]);
700
701
6.36M
        scf_int = iaace_improve_scf(
702
6.36M
            ptr_mdct_spec + pstr_psy_out_chan->sfb_offsets[i],
703
6.36M
            ptr_exp_spec + pstr_psy_out_chan->sfb_offsets[i],
704
6.36M
            ptr_quant_spec + pstr_psy_out_chan->sfb_offsets[i],
705
6.36M
            quant_spec_temp + pstr_psy_out_chan->sfb_offsets[i],
706
6.36M
            pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i], thresh,
707
6.36M
            scf_int, min_sf_max_quant[i], &sfb_dist[i], &min_calc_scf[i]);
708
709
6.36M
        ptr_scalefactor[i] = scf_int;
710
6.36M
      }
711
17.9M
    }
712
713
461k
    {
714
461k
      FLOAT32 sfb_const_pe_part[MAXIMUM_GROUPED_SCALE_FACTOR_BAND];
715
716
18.4M
      for (i = 0; i < pstr_psy_out_chan->sfb_count; i++) {
717
17.9M
        sfb_const_pe_part[i] = MIN_FLT_VAL;
718
17.9M
      }
719
720
461k
      iaace_assimilate_single_scf(pstr_psy_out_chan, ptr_exp_spec, ptr_quant_spec,
721
461k
                                  quant_spec_temp, ptr_scalefactor, min_sf_max_quant, sfb_dist,
722
461k
                                  sfb_const_pe_part, ptr_sfb_form_factor,
723
461k
                                  ptr_sfb_num_relevant_lines_ch, min_calc_scf, ptr_mdct_spec);
724
725
461k
      iaace_assimilate_multiple_scf(pstr_psy_out_chan, ptr_exp_spec, ptr_quant_spec,
726
461k
                                    quant_spec_temp, ptr_scalefactor, min_sf_max_quant, sfb_dist,
727
461k
                                    sfb_const_pe_part, ptr_sfb_form_factor,
728
461k
                                    ptr_sfb_num_relevant_lines_ch, ptr_mdct_spec);
729
461k
    }
730
731
461k
    max_scf = MIN_SHRT_VAL;
732
461k
    min_scf = MAX_SHRT_VAL;
733
18.4M
    for (i = 0; i < pstr_psy_out_chan->sfb_count; i++) {
734
17.9M
      if (max_scf < ptr_scalefactor[i]) {
735
493k
        max_scf = ptr_scalefactor[i];
736
493k
      }
737
17.9M
      if ((ptr_scalefactor[i] != MIN_SHRT_VAL) && (min_scf > ptr_scalefactor[i])) {
738
1.55M
        min_scf = ptr_scalefactor[i];
739
1.55M
      }
740
17.9M
    }
741
742
18.4M
    for (i = 0; i < pstr_psy_out[ch]->sfb_count; i++) {
743
17.9M
      if ((ptr_scalefactor[i] != MIN_SHRT_VAL) &&
744
6.36M
          (min_scf + MAX_SCF_DELTA) < ptr_scalefactor[i]) {
745
8.25k
        ptr_scalefactor[i] = min_scf + MAX_SCF_DELTA;
746
747
8.25k
        iaace_calc_sfb_dist(
748
8.25k
            ptr_mdct_spec + pstr_psy_out_chan->sfb_offsets[i],
749
8.25k
            ptr_exp_spec + pstr_psy_out_chan->sfb_offsets[i],
750
8.25k
            ptr_quant_spec + pstr_psy_out_chan->sfb_offsets[i],
751
8.25k
            pstr_psy_out_chan->sfb_offsets[i + 1] - pstr_psy_out_chan->sfb_offsets[i],
752
8.25k
            ptr_scalefactor[i]);
753
8.25k
      }
754
17.9M
    }
755
756
461k
    max_scf = MIN((min_scf + MAX_SCF_DELTA), max_scf);
757
758
461k
    if (max_scf > MIN_SHRT_VAL) {
759
292k
      *global_gain = max_scf;
760
11.6M
      for (i = 0; i < pstr_psy_out_chan->sfb_count; i++) {
761
11.3M
        if (ptr_scalefactor[i] == MIN_SHRT_VAL) {
762
5.01M
          ptr_scalefactor[i] = 0;
763
142M
          for (j = pstr_psy_out_chan->sfb_offsets[i]; j < pstr_psy_out_chan->sfb_offsets[i + 1];
764
137M
               j++) {
765
137M
            pstr_psy_out_chan->ptr_spec_coeffs[j] = 0.0f;
766
137M
          }
767
6.36M
        } else {
768
6.36M
          ptr_scalefactor[i] = max_scf - ptr_scalefactor[i];
769
6.36M
        }
770
11.3M
      }
771
292k
    } else {
772
169k
      *global_gain = 0;
773
6.75M
      for (i = 0; i < pstr_psy_out_chan->sfb_count; i++) {
774
6.58M
        ptr_scalefactor[i] = 0;
775
131M
        for (j = pstr_psy_out_chan->sfb_offsets[i]; j < pstr_psy_out_chan->sfb_offsets[i + 1];
776
125M
             j++) {
777
125M
          pstr_psy_out_chan->ptr_spec_coeffs[j] = 0.0f;
778
125M
        }
779
6.58M
      }
780
169k
    }
781
461k
  }
782
318k
}