Coverage Report

Created: 2026-04-12 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxaac/encoder/ixheaace_sbr_missing_harmonics_det.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 <float.h>
24
#include "ixheaac_type_def.h"
25
#include "ixheaac_constants.h"
26
#include "ixheaac_error_standards.h"
27
#include "ixheaace_aac_constants.h"
28
#include "ixheaac_basic_ops32.h"
29
#include "ixheaac_basic_ops16.h"
30
#include "ixheaac_basic_ops40.h"
31
#include "ixheaac_basic_ops.h"
32
33
#include "ixheaace_sbr_header.h"
34
#include "ixheaace_sbr_def.h"
35
#include "ixheaace_resampler.h"
36
#include "ixheaace_sbr_rom.h"
37
#include "ixheaace_common_rom.h"
38
#include "ixheaace_sbr_hbe.h"
39
#include "ixheaace_sbr_qmf_enc.h"
40
#include "ixheaace_sbr_tran_det.h"
41
#include "ixheaace_sbr_frame_info_gen.h"
42
#include "ixheaace_sbr_env_est.h"
43
#include "ixheaace_sbr_code_envelope.h"
44
#include "ixheaace_sbr_main.h"
45
#include "ixheaace_sbr_missing_harmonics_det.h"
46
#include "ixheaace_sbr_inv_filtering_estimation.h"
47
#include "ixheaace_sbr_noise_floor_est.h"
48
49
#include "ixheaace_sbr_ton_corr.h"
50
#include "iusace_esbr_pvc.h"
51
#include "iusace_esbr_inter_tes.h"
52
#include "ixheaace_sbr.h"
53
#include "ixheaace_common_utils.h"
54
55
static VOID ia_enhaacplus_enc_diff(FLOAT32 *ptr_tonal_orig, FLOAT32 *ptr_diff_map_2_scfb,
56
                                   const UWORD8 *ptr_freq_band_tab, WORD32 n_scfb,
57
1.10M
                                   WORD8 *ptr_idx_vx) {
58
1.10M
  WORD32 i, ll, lu, k;
59
1.10M
  FLOAT32 max_val_orig, max_val_sbr;
60
15.0M
  for (i = 0; i < n_scfb; i++) {
61
13.9M
    ll = ptr_freq_band_tab[i];
62
13.9M
    lu = ptr_freq_band_tab[i + 1];
63
13.9M
    max_val_orig = max_val_sbr = 0;
64
65
46.0M
    for (k = ll; k < lu; k++) {
66
32.0M
      if (ptr_tonal_orig[k] > max_val_orig) {
67
16.3M
        max_val_orig = ptr_tonal_orig[k];
68
16.3M
      }
69
32.0M
      if (ptr_tonal_orig[ptr_idx_vx[k]] > max_val_sbr) {
70
15.2M
        max_val_sbr = ptr_tonal_orig[ptr_idx_vx[k]];
71
15.2M
      }
72
32.0M
    }
73
74
13.9M
    ptr_diff_map_2_scfb[i] = (max_val_sbr > 1) ? max_val_orig / max_val_sbr : max_val_orig;
75
13.9M
  }
76
1.10M
}
77
78
static VOID ia_enhaacplus_enc_calculate_flatness_measure(FLOAT32 *ptr_quota_buf,
79
                                                         WORD8 *ptr_idx_vx, FLOAT32 *ptr_sfm_orig,
80
                                                         FLOAT32 *ptr_sfm_sbr,
81
                                                         const UWORD8 *ptr_freq_band_tab,
82
1.10M
                                                         WORD32 num_sfb) {
83
1.10M
  WORD32 i, j;
84
85
1.10M
  FLOAT32 am_org, am_transp, gm_org, gm_transp, sfm_org, sfm_transp;
86
87
1.10M
  i = 0;
88
15.0M
  while (i < num_sfb) {
89
13.9M
    WORD32 band_low = ptr_freq_band_tab[i];
90
13.9M
    WORD32 band_high = ptr_freq_band_tab[i + 1];
91
92
13.9M
    ptr_sfm_orig[i] = 1.0f;
93
13.9M
    ptr_sfm_sbr[i] = 1.0f;
94
95
13.9M
    if (band_high - band_low > 1) {
96
10.9M
      am_org = 0;
97
10.9M
      am_transp = 0;
98
10.9M
      gm_org = 1.0f;
99
10.9M
      gm_transp = 1.0f;
100
101
39.9M
      for (j = band_low; j < band_high; j++) {
102
29.0M
        sfm_org = ptr_quota_buf[j];
103
29.0M
        sfm_transp = ptr_quota_buf[ptr_idx_vx[j]];
104
105
29.0M
        am_org += sfm_org;
106
29.0M
        gm_org += sfm_org;
107
29.0M
        am_transp += sfm_transp;
108
29.0M
        gm_transp += sfm_transp;
109
29.0M
      }
110
111
10.9M
      am_org /= band_high - band_low;
112
10.9M
      am_transp /= band_high - band_low;
113
10.9M
      gm_org = (FLOAT32)pow(gm_org, 1.0f / (band_high - band_low));
114
10.9M
      gm_transp = (FLOAT32)pow(gm_transp, 1.0f / (band_high - band_low));
115
116
10.9M
      if (am_org) {
117
9.00M
        ptr_sfm_orig[i] = gm_org / am_org;
118
9.00M
      }
119
120
10.9M
      if (am_transp) {
121
9.00M
        ptr_sfm_sbr[i] = gm_transp / am_transp;
122
9.00M
      }
123
10.9M
    }
124
13.9M
    i++;
125
13.9M
  }
126
1.10M
}
127
128
static VOID ia_enhaacplus_enc_calculate_detector_input(
129
    FLOAT32 **ptr_quota_buf, WORD8 *ptr_idx_vx, FLOAT32 **ptr_tonal_diff, FLOAT32 **ptr_sfm_orig,
130
    FLOAT32 **ptr_sfm_sbr, const UWORD8 *ptr_freq_band_tab, WORD32 num_sfb,
131
550k
    WORD32 no_est_per_frame, WORD32 move, WORD32 no_qmf_bands) {
132
550k
  WORD32 est;
133
134
1.53M
  for (est = 0; est < move; est++) {
135
982k
    memcpy(ptr_tonal_diff[est], ptr_tonal_diff[est + no_est_per_frame],
136
982k
           no_qmf_bands * sizeof(ptr_tonal_diff[est][0]));
137
138
982k
    memcpy(ptr_sfm_orig[est], ptr_sfm_orig[est + no_est_per_frame],
139
982k
           no_qmf_bands * sizeof(ptr_sfm_orig[est][0]));
140
141
982k
    memcpy(ptr_sfm_sbr[est], ptr_sfm_sbr[est + no_est_per_frame],
142
982k
           no_qmf_bands * sizeof(ptr_sfm_sbr[est][0]));
143
982k
  }
144
145
1.65M
  for (est = 0; est < no_est_per_frame; est++) {
146
1.10M
    ia_enhaacplus_enc_diff(ptr_quota_buf[est + move], ptr_tonal_diff[est + move],
147
1.10M
                           ptr_freq_band_tab, num_sfb, ptr_idx_vx);
148
149
1.10M
    ia_enhaacplus_enc_calculate_flatness_measure(
150
1.10M
        ptr_quota_buf[est + move], ptr_idx_vx, ptr_sfm_orig[est + move], ptr_sfm_sbr[est + move],
151
1.10M
        ptr_freq_band_tab, num_sfb);
152
1.10M
  }
153
550k
}
154
155
static WORD32 ia_enhaacplus_enc_isDetectionOfNewToneAllowed(
156
    const ixheaace_str_frame_info_sbr *ptr_frame_info, WORD32 prev_transient_frame,
157
    WORD32 prev_transient_pos, WORD32 prev_trans_flag, WORD32 trans_pos_offset,
158
    WORD32 transient_flag, WORD32 transient_pos,
159
550k
    ixheaace_pstr_sbr_missing_harmonics_detector pstr_sbr_missing_harmonics_detector) {
160
550k
  WORD32 transient_frame, new_detection_allowed;
161
162
550k
  transient_frame = 0;
163
164
550k
  if (transient_flag) {
165
130k
    if (transient_pos + trans_pos_offset < ptr_frame_info->borders[ptr_frame_info->n_envelopes]) {
166
116k
      transient_frame = 1;
167
116k
    }
168
419k
  } else {
169
419k
    if (prev_trans_flag && !prev_transient_frame) {
170
3.34k
      transient_frame = 1;
171
3.34k
    }
172
419k
  }
173
174
550k
  new_detection_allowed = 0;
175
176
550k
  if (transient_frame) {
177
119k
    new_detection_allowed = 1;
178
430k
  } else {
179
430k
    if (prev_transient_frame &&
180
52.8k
        ixheaac_abs32(ptr_frame_info->borders[0] -
181
52.8k
                      (prev_transient_pos + trans_pos_offset -
182
52.8k
                       pstr_sbr_missing_harmonics_detector->time_slots)) < DELTA_TIME) {
183
40.2k
      new_detection_allowed = 1;
184
40.2k
    }
185
430k
  }
186
187
550k
  pstr_sbr_missing_harmonics_detector->prev_trans_flag = transient_flag;
188
550k
  pstr_sbr_missing_harmonics_detector->prev_trans_frame = transient_frame;
189
550k
  pstr_sbr_missing_harmonics_detector->prev_trans_pos = transient_pos;
190
191
550k
  return (new_detection_allowed);
192
550k
}
193
194
static VOID ia_enhaacplus_enc_transient_cleanup(FLOAT32 **ptr_quota_buf, WORD32 num_sfb,
195
                                                UWORD8 **ptr_detection_vectors,
196
                                                const UWORD8 *ptr_freq_band_tab,
197
                                                ixheaace_str_guide_vectors ptr_guide_vectors,
198
159k
                                                WORD32 start, WORD32 stop) {
199
159k
  WORD32 sfb, band, low_band, up_band, est;
200
201
159k
  UWORD8 ptr_harm_vec[MAXIMUM_FREQ_COEFFS];
202
203
159k
  memset(ptr_harm_vec, 0, sizeof(ptr_harm_vec));
204
205
432k
  for (est = start; est < stop; est++) {
206
3.27M
    for (sfb = 0; sfb < num_sfb - 1; sfb++) {
207
2.99M
      ptr_harm_vec[sfb] = ptr_harm_vec[sfb] || ptr_detection_vectors[est][sfb];
208
2.99M
    }
209
272k
  }
210
211
1.96M
  for (sfb = 0; sfb < num_sfb - 1; sfb++) {
212
1.80M
    if (ptr_harm_vec[sfb] && ptr_harm_vec[sfb + 1]) {
213
127k
      FLOAT32 max_val_1, max_val_2;
214
127k
      WORD32 maxPos1, maxPos2;
215
216
127k
      low_band = ptr_freq_band_tab[sfb];
217
127k
      up_band = ptr_freq_band_tab[sfb + 1];
218
127k
      maxPos1 = low_band;
219
220
127k
      max_val_1 = ptr_quota_buf[start][low_band];
221
322k
      for (band = low_band; band < up_band; band++) {
222
195k
        if (ptr_quota_buf[start][band] > max_val_1) {
223
33.9k
          max_val_1 = ptr_quota_buf[start][band];
224
33.9k
          maxPos1 = band;
225
33.9k
        }
226
195k
      }
227
228
210k
      for (est = start + 1; est < stop; est++) {
229
221k
        for (band = low_band; band < up_band; band++) {
230
138k
          if (ptr_quota_buf[est][band] > max_val_1) {
231
40.1k
            max_val_1 = ptr_quota_buf[est][band];
232
40.1k
            maxPos1 = band;
233
40.1k
          }
234
138k
        }
235
82.9k
      }
236
237
127k
      low_band = ptr_freq_band_tab[sfb + 1];
238
127k
      up_band = ptr_freq_band_tab[sfb + 2];
239
240
127k
      maxPos2 = low_band;
241
127k
      max_val_2 = ptr_quota_buf[start][low_band];
242
243
341k
      for (band = low_band; band < up_band; band++) {
244
213k
        if (ptr_quota_buf[start][band] > max_val_2) {
245
37.1k
          max_val_2 = ptr_quota_buf[start][band];
246
37.1k
          maxPos2 = band;
247
37.1k
        }
248
213k
      }
249
250
210k
      for (est = start + 1; est < stop; est++) {
251
236k
        for (band = low_band; band < up_band; band++) {
252
153k
          if (ptr_quota_buf[est][band] > max_val_2) {
253
40.5k
            max_val_2 = ptr_quota_buf[est][band];
254
40.5k
            maxPos2 = band;
255
40.5k
          }
256
153k
        }
257
82.9k
      }
258
259
127k
      if (maxPos2 - maxPos1 < 2) {
260
81.5k
        if (max_val_1 > max_val_2) {
261
39.7k
          ptr_guide_vectors.ptr_guide_vector_detected[sfb + 1] = 0;
262
39.7k
          ptr_guide_vectors.ptr_guide_vec_orig[sfb + 1] = 0;
263
39.7k
          ptr_guide_vectors.ptr_guide_vec_diff[sfb + 1] = 0;
264
265
102k
          for (est = start; est < stop; est++) {
266
63.0k
            ptr_detection_vectors[est][sfb + 1] = 0;
267
63.0k
          }
268
41.7k
        } else {
269
41.7k
          ptr_guide_vectors.ptr_guide_vector_detected[sfb] = 0;
270
41.7k
          ptr_guide_vectors.ptr_guide_vec_diff[sfb] = 0;
271
41.7k
          ptr_guide_vectors.ptr_guide_vec_orig[sfb] = 0;
272
273
104k
          for (est = start; est < stop; est++) {
274
63.2k
            ptr_detection_vectors[est][sfb] = 0;
275
63.2k
          }
276
41.7k
        }
277
81.5k
      }
278
127k
    }
279
1.80M
  }
280
159k
}
281
282
static VOID ia_enhaacplus_enc_detection(FLOAT32 *ptr_quota_buf, FLOAT32 *ptr_diff_vec_scfb,
283
                                        WORD32 num_sfb, UWORD8 *ptr_harm_vec,
284
                                        const UWORD8 *ptr_freq_band_tab, FLOAT32 *ptr_sfm_orig,
285
                                        FLOAT32 *ptr_sfm_sbr,
286
                                        ixheaace_str_guide_vectors *ptr_guide_vectors,
287
1.76M
                                        ixheaace_str_guide_vectors *ptr_new_guide_vectors) {
288
1.76M
  WORD32 i, j;
289
1.76M
  WORD32 lower_band, upper_band;
290
1.76M
  FLOAT32 thr, thr_org;
291
292
24.1M
  for (i = 0; i < num_sfb; i++) {
293
22.4M
    if (ptr_guide_vectors->ptr_guide_vec_diff[i]) {
294
1.33M
      if (SBR_DECAY_GUIDE_DIFF * ptr_guide_vectors->ptr_guide_vec_diff[i] > SBR_THR_DIFF_GUIDE) {
295
1.33M
        thr = SBR_DECAY_GUIDE_DIFF * ptr_guide_vectors->ptr_guide_vec_diff[i];
296
1.33M
      } else {
297
0
        thr = SBR_THR_DIFF_GUIDE;
298
0
      }
299
1.33M
      if (thr > SBR_THR_DIFF) {
300
1.32M
        thr = SBR_THR_DIFF;
301
1.32M
      }
302
21.1M
    } else {
303
21.1M
      thr = SBR_THR_DIFF;
304
21.1M
    }
305
306
22.4M
    if (ptr_diff_vec_scfb[i] > thr) {
307
2.51M
      ptr_harm_vec[i] = 1;
308
2.51M
      ptr_new_guide_vectors->ptr_guide_vec_diff[i] = ptr_diff_vec_scfb[i];
309
19.9M
    } else {
310
19.9M
      if (ptr_guide_vectors->ptr_guide_vec_diff[i]) {
311
829k
        ptr_guide_vectors->ptr_guide_vec_orig[i] = SBR_THR_TONE_GUIDE;
312
829k
      }
313
19.9M
    }
314
22.4M
  }
315
316
24.1M
  for (i = 0; i < num_sfb; i++) {
317
22.4M
    lower_band = ptr_freq_band_tab[i];
318
22.4M
    upper_band = ptr_freq_band_tab[i + 1];
319
320
22.4M
    if (ptr_guide_vectors->ptr_guide_vec_orig[i] * SBR_DECAY_GUIDE_ORIG > SBR_THR_TONE_GUIDE) {
321
858k
      thr_org = ptr_guide_vectors->ptr_guide_vec_orig[i] * SBR_DECAY_GUIDE_ORIG;
322
21.5M
    } else {
323
21.5M
      thr_org = SBR_THR_TONE_GUIDE;
324
21.5M
    }
325
22.4M
    if (thr_org > SBR_THR_TONE) {
326
815k
      thr_org = SBR_THR_TONE;
327
815k
    }
328
22.4M
    if (ptr_guide_vectors->ptr_guide_vec_orig[i]) {
329
5.20M
      for (j = lower_band; j < upper_band; j++) {
330
3.48M
        if (ptr_quota_buf[j] > thr_org) {
331
2.55M
          ptr_harm_vec[i] = 1;
332
2.55M
          ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[j];
333
2.55M
        }
334
3.48M
      }
335
1.71M
    }
336
22.4M
  }
337
338
1.76M
  thr_org = SBR_THR_TONE;
339
340
24.1M
  for (i = 0; i < num_sfb; i++) {
341
22.4M
    lower_band = ptr_freq_band_tab[i];
342
22.4M
    upper_band = ptr_freq_band_tab[i + 1];
343
344
22.4M
    if (upper_band - lower_band > 1) {
345
64.9M
      for (j = lower_band; j < upper_band; j++) {
346
47.1M
        if (ptr_quota_buf[j] > thr_org && ptr_sfm_sbr[i] > SBR_THR_SFM_SBR &&
347
675k
            ptr_sfm_orig[i] > SBR_THR_SFM_ORG) {
348
116k
          ptr_harm_vec[i] = 1;
349
116k
          ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[j];
350
116k
        }
351
47.1M
      }
352
17.7M
    } else {
353
4.66M
      if (1 < (num_sfb - 1)) {
354
4.66M
        lower_band = ptr_freq_band_tab[i];
355
356
4.66M
        if (i > 0) {
357
3.40M
          if (ptr_quota_buf[lower_band] > SBR_THR_TONE &&
358
1.04M
              (ptr_diff_vec_scfb[i - 1] < SBR_INV_THR_TONE ||
359
691k
               ptr_diff_vec_scfb[i + 1] < SBR_INV_THR_TONE)) {
360
503k
            ptr_harm_vec[i] = 1;
361
503k
            ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[lower_band];
362
503k
          }
363
3.40M
        } else {
364
1.26M
          if (ptr_quota_buf[lower_band] > SBR_THR_TONE &&
365
378k
              ptr_diff_vec_scfb[i + 1] < SBR_INV_THR_TONE) {
366
97.2k
            ptr_harm_vec[i] = 1;
367
97.2k
            ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[lower_band];
368
97.2k
          }
369
1.26M
        }
370
4.66M
      }
371
4.66M
    }
372
22.4M
  }
373
1.76M
}
374
375
static VOID ia_enhaacplus_enc_detection_with_prediction(
376
    FLOAT32 **ptr_quota_buf, FLOAT32 **ptr_diff_vec_sfb, WORD32 num_sfb,
377
    const UWORD8 *ptr_freq_band_tab, FLOAT32 **ptr_sfm_orig, FLOAT32 **ptr_sfm_sbr,
378
    UWORD8 **ptr_detection_vectors, UWORD8 *ptr_prev_frame_sfb_harm,
379
    ixheaace_str_guide_vectors *ptr_guide_vectors, WORD32 no_est_per_frame, WORD32 tot_no_est,
380
550k
    WORD32 new_detection_allowed, UWORD8 *ptr_add_harmonics_sfbs) {
381
550k
  WORD32 est = 0, i;
382
550k
  WORD32 start;
383
384
550k
  memset(ptr_add_harmonics_sfbs, 0, num_sfb * sizeof(ptr_add_harmonics_sfbs[0]));
385
386
550k
  if (new_detection_allowed) {
387
159k
    if (tot_no_est > 1) {
388
159k
      start = no_est_per_frame;
389
159k
      memcpy(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_diff,
390
159k
             ptr_guide_vectors[0].ptr_guide_vec_diff,
391
159k
             num_sfb * sizeof(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_diff[0]));
392
393
159k
      memcpy(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_orig,
394
159k
             ptr_guide_vectors[0].ptr_guide_vec_orig,
395
159k
             num_sfb * sizeof(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_orig[0]));
396
397
159k
      memset(
398
159k
          ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vector_detected, 0,
399
159k
          num_sfb * sizeof(ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vector_detected[0]));
400
159k
    } else {
401
0
      start = 0;
402
0
    }
403
390k
  } else {
404
390k
    start = 0;
405
390k
  }
406
407
2.31M
  for (est = start; est < tot_no_est; est++) {
408
1.76M
    if (est > 0) {
409
1.37M
      memcpy(ptr_guide_vectors[est].ptr_guide_vector_detected, ptr_detection_vectors[est - 1],
410
1.37M
             num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vector_detected[0]));
411
1.37M
    }
412
413
1.76M
    memset(ptr_detection_vectors[est], 0, num_sfb * sizeof(ptr_detection_vectors[est][0]));
414
415
1.76M
    if (est < tot_no_est - 1) {
416
1.21M
      memset(ptr_guide_vectors[est + 1].ptr_guide_vec_diff, 0,
417
1.21M
             num_sfb * sizeof(ptr_guide_vectors[est + 1].ptr_guide_vec_diff[0]));
418
419
1.21M
      memset(ptr_guide_vectors[est + 1].ptr_guide_vec_orig, 0,
420
1.21M
             num_sfb * sizeof(ptr_guide_vectors[est + 1].ptr_guide_vec_orig[0]));
421
422
1.21M
      memset(ptr_guide_vectors[est + 1].ptr_guide_vector_detected, 0,
423
1.21M
             num_sfb * sizeof(ptr_guide_vectors[est + 1].ptr_guide_vector_detected[0]));
424
425
1.21M
      ia_enhaacplus_enc_detection(ptr_quota_buf[est], ptr_diff_vec_sfb[est], num_sfb,
426
1.21M
                                  ptr_detection_vectors[est], ptr_freq_band_tab,
427
1.21M
                                  ptr_sfm_orig[est], ptr_sfm_sbr[est], &(ptr_guide_vectors[est]),
428
1.21M
                                  &(ptr_guide_vectors[est + 1]));
429
1.21M
    } else {
430
550k
      memset(ptr_guide_vectors[est].ptr_guide_vec_diff, 0,
431
550k
             num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vec_diff[0]));
432
433
550k
      memset(ptr_guide_vectors[est].ptr_guide_vec_orig, 0,
434
550k
             num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vec_orig[0]));
435
436
550k
      memset(ptr_guide_vectors[est].ptr_guide_vector_detected, 0,
437
550k
             num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vector_detected[0]));
438
439
550k
      ia_enhaacplus_enc_detection(ptr_quota_buf[est], ptr_diff_vec_sfb[est], num_sfb,
440
550k
                                  ptr_detection_vectors[est], ptr_freq_band_tab,
441
550k
                                  ptr_sfm_orig[est], ptr_sfm_sbr[est], &(ptr_guide_vectors[est]),
442
550k
                                  &(ptr_guide_vectors[est]));
443
550k
    }
444
1.76M
  }
445
446
550k
  if (new_detection_allowed) {
447
159k
    if (tot_no_est > 1) {
448
159k
      ia_enhaacplus_enc_transient_cleanup(ptr_quota_buf, num_sfb, ptr_detection_vectors,
449
159k
                                          ptr_freq_band_tab, ptr_guide_vectors[no_est_per_frame],
450
159k
                                          start, tot_no_est);
451
159k
    } else {
452
0
      ia_enhaacplus_enc_transient_cleanup(ptr_quota_buf, num_sfb, ptr_detection_vectors,
453
0
                                          ptr_freq_band_tab, ptr_guide_vectors[0], start,
454
0
                                          tot_no_est);
455
0
    }
456
159k
  }
457
458
7.54M
  for (i = 0; i < num_sfb; i++) {
459
29.4M
    for (est = start; est < tot_no_est; est++) {
460
22.4M
      ptr_add_harmonics_sfbs[i] = ptr_add_harmonics_sfbs[i] || ptr_detection_vectors[est][i];
461
22.4M
    }
462
6.99M
  }
463
464
550k
  if (!new_detection_allowed) {
465
5.42M
    for (i = 0; i < num_sfb; i++) {
466
5.03M
      if (ptr_add_harmonics_sfbs[i] - ptr_prev_frame_sfb_harm[i] > 0) {
467
1.08M
        ptr_add_harmonics_sfbs[i] = 0;
468
1.08M
      }
469
5.03M
    }
470
390k
  }
471
550k
}
472
473
static VOID ia_enhaacplus_enc_calculate_comp_vector(
474
    UWORD8 *ptr_add_harmonics_sfbs, FLOAT32 **ptr_tonality, WORD8 *ptr_env_compensation,
475
    WORD32 num_sfb, const UWORD8 *ptr_freq_band_tab, FLOAT32 **ptr_diff, WORD32 tot_no_est,
476
550k
    WORD8 *ptr_prev_env_compensation, WORD32 new_detection_allowed) {
477
550k
  WORD32 i, j, l;
478
479
550k
  memset(ptr_env_compensation, 0, num_sfb * sizeof(ptr_env_compensation[0]));
480
481
550k
  FLOAT32 max_val;
482
550k
  WORD32 lower_band, upper_band;
483
550k
  WORD32 max_pos_band, max_pos_est;
484
550k
  WORD8 comp_val;
485
486
7.54M
  for (i = 0; i < num_sfb; i++) {
487
6.99M
    if (ptr_add_harmonics_sfbs[i]) {
488
644k
      lower_band = ptr_freq_band_tab[i];
489
644k
      upper_band = ptr_freq_band_tab[i + 1];
490
491
644k
      max_pos_band = 0;
492
644k
      max_pos_est = 0;
493
644k
      max_val = 0;
494
495
3.13M
      for (j = 0; j < tot_no_est; j++) {
496
7.67M
        for (l = lower_band; l < upper_band; l++) {
497
5.18M
          if (ptr_tonality[j][l] > max_val) {
498
1.54M
            max_val = ptr_tonality[j][l];
499
1.54M
            max_pos_band = l;
500
1.54M
            max_pos_est = j;
501
1.54M
          }
502
5.18M
        }
503
2.48M
      }
504
505
644k
      if (max_pos_band == lower_band && i) {
506
357k
        comp_val =
507
357k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i - 1] + SBR_EPS)) + 0.5f);
508
357k
        if (comp_val > SBR_MAX_COMP) {
509
187k
          comp_val = SBR_MAX_COMP;
510
187k
        }
511
512
357k
        if (!ptr_add_harmonics_sfbs[i - 1]) {
513
294k
          if (ptr_tonality[max_pos_est][max_pos_band - 1] >
514
294k
              SBR_TONALITY_QUOTA * ptr_tonality[max_pos_est][max_pos_band]) {
515
165k
            ptr_env_compensation[i - 1] = -1 * comp_val;
516
165k
          }
517
294k
        }
518
357k
      }
519
520
644k
      if (max_pos_band == (upper_band - 1) && (i + 1) < num_sfb) {
521
335k
        comp_val =
522
335k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i + 1] + SBR_EPS)) + 0.5f);
523
335k
        if (comp_val > SBR_MAX_COMP) {
524
178k
          comp_val = SBR_MAX_COMP;
525
178k
        }
526
527
335k
        if (!ptr_add_harmonics_sfbs[i + 1]) {
528
290k
          if (ptr_tonality[max_pos_est][max_pos_band + 1] >
529
290k
              SBR_TONALITY_QUOTA * ptr_tonality[max_pos_est][max_pos_band]) {
530
151k
            ptr_env_compensation[i + 1] = comp_val;
531
151k
          }
532
290k
        }
533
335k
      }
534
535
644k
      if (i && i < (num_sfb - 1)) {
536
550k
        comp_val =
537
550k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i - 1] + SBR_EPS)) + 0.5f);
538
550k
        if (comp_val > SBR_MAX_COMP) {
539
263k
          comp_val = SBR_MAX_COMP;
540
263k
        }
541
542
550k
        if (ixheaace_div32((FLOAT32)1.0f, ptr_diff[max_pos_est][i - 1]) >
543
550k
            (SBR_DIFF_QUOTA * ptr_diff[max_pos_est][i])) {
544
161k
          ptr_env_compensation[i - 1] = -1 * comp_val;
545
161k
        }
546
547
550k
        comp_val =
548
550k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i + 1] + SBR_EPS)) + 0.5f);
549
550k
        if (comp_val > SBR_MAX_COMP) {
550
245k
          comp_val = SBR_MAX_COMP;
551
245k
        }
552
553
550k
        if (ixheaace_div32((FLOAT32)1.0f, ptr_diff[max_pos_est][i + 1]) >
554
550k
            (SBR_DIFF_QUOTA * ptr_diff[max_pos_est][i])) {
555
176k
          ptr_env_compensation[i + 1] = comp_val;
556
176k
        }
557
550k
      }
558
644k
    }
559
6.99M
  }
560
561
550k
  if (!new_detection_allowed) {
562
5.42M
    for (i = 0; i < num_sfb; i++) {
563
5.03M
      if (ptr_env_compensation[i] != 0 && ptr_prev_env_compensation[i] == 0) {
564
110k
        ptr_env_compensation[i] = 0;
565
110k
      }
566
5.03M
    }
567
390k
  }
568
550k
}
569
570
VOID ixheaace_sbr_missing_harmonics_detector_qmf(
571
    ixheaace_pstr_sbr_missing_harmonics_detector pstr_sbr_mhd_et, FLOAT32 **ptr_quota_buf,
572
    WORD8 *ptr_idx_vx, const ixheaace_str_frame_info_sbr *ptr_frame_info,
573
    const WORD32 *ptr_tran_info, WORD32 *ptr_add_harmonics_flag, UWORD8 *ptr_add_harmonics_sfbs,
574
550k
    const UWORD8 *ptr_freq_band_tab, WORD32 num_sfb, WORD8 *ptr_env_compensation) {
575
550k
  WORD32 i;
576
550k
  WORD32 transient_flag = ptr_tran_info[1];
577
550k
  WORD32 transient_pos = ptr_tran_info[0];
578
550k
  WORD32 new_detection_allowed;
579
580
550k
  UWORD8 **ptr_detection_vectors = pstr_sbr_mhd_et->ptr_detection_vectors;
581
550k
  WORD32 move = pstr_sbr_mhd_et->move;
582
550k
  WORD32 no_est_per_frame = pstr_sbr_mhd_et->no_est_per_frame;
583
550k
  WORD32 tot_no_est = pstr_sbr_mhd_et->tot_no_est;
584
550k
  WORD32 prev_trans_flag = pstr_sbr_mhd_et->prev_trans_flag;
585
550k
  WORD32 prev_transient_frame = pstr_sbr_mhd_et->prev_trans_frame;
586
550k
  WORD32 trans_pos_offset = pstr_sbr_mhd_et->trans_pos_offset;
587
550k
  WORD32 prev_transient_pos = pstr_sbr_mhd_et->prev_trans_pos;
588
550k
  ixheaace_str_guide_vectors *ptr_guide_vectors = pstr_sbr_mhd_et->guide_vectors;
589
590
550k
  FLOAT32 **ptr_sfm_sbr = pstr_sbr_mhd_et->ptr_sfm_sbr;
591
550k
  FLOAT32 **ptr_sfm_orig = pstr_sbr_mhd_et->ptr_sfm_orig;
592
550k
  FLOAT32 **ptr_tonal_diff = pstr_sbr_mhd_et->ptr_tonal_diff;
593
594
550k
  WORD32 no_qmf_bands = ptr_freq_band_tab[num_sfb] - ptr_freq_band_tab[0];
595
596
550k
  new_detection_allowed = ia_enhaacplus_enc_isDetectionOfNewToneAllowed(
597
550k
      ptr_frame_info, prev_transient_frame, prev_transient_pos, prev_trans_flag, trans_pos_offset,
598
550k
      transient_flag, transient_pos, pstr_sbr_mhd_et);
599
600
550k
  ia_enhaacplus_enc_calculate_detector_input(ptr_quota_buf, ptr_idx_vx, ptr_tonal_diff,
601
550k
                                             ptr_sfm_orig, ptr_sfm_sbr, ptr_freq_band_tab,
602
550k
                                             num_sfb, no_est_per_frame, move, no_qmf_bands);
603
604
550k
  ia_enhaacplus_enc_detection_with_prediction(
605
550k
      ptr_quota_buf, ptr_tonal_diff, num_sfb, ptr_freq_band_tab, ptr_sfm_orig, ptr_sfm_sbr,
606
550k
      ptr_detection_vectors, pstr_sbr_mhd_et->ptr_guide_scfb, ptr_guide_vectors, no_est_per_frame,
607
550k
      tot_no_est, new_detection_allowed, ptr_add_harmonics_sfbs);
608
609
550k
  ia_enhaacplus_enc_calculate_comp_vector(
610
550k
      ptr_add_harmonics_sfbs, ptr_quota_buf, ptr_env_compensation, num_sfb, ptr_freq_band_tab,
611
550k
      ptr_tonal_diff, tot_no_est, pstr_sbr_mhd_et->sbr_prev_env_compensation,
612
550k
      new_detection_allowed);
613
614
550k
  *ptr_add_harmonics_flag = 0;
615
616
5.52M
  for (i = 0; i < num_sfb; i++) {
617
5.16M
    if (ptr_add_harmonics_sfbs[i]) {
618
196k
      *ptr_add_harmonics_flag = 1;
619
196k
      break;
620
196k
    }
621
5.16M
  }
622
623
550k
  memcpy(pstr_sbr_mhd_et->sbr_prev_env_compensation, ptr_env_compensation,
624
550k
         num_sfb * sizeof(pstr_sbr_mhd_et->sbr_prev_env_compensation[0]));
625
626
550k
  memcpy(pstr_sbr_mhd_et->ptr_guide_scfb, ptr_add_harmonics_sfbs,
627
550k
         num_sfb * sizeof(pstr_sbr_mhd_et->ptr_guide_scfb[0]));
628
629
550k
  memcpy(ptr_guide_vectors[0].ptr_guide_vector_detected, ptr_add_harmonics_sfbs,
630
550k
         num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vector_detected[0]));
631
632
550k
  if (tot_no_est > no_est_per_frame) {
633
550k
    memcpy(ptr_guide_vectors[0].ptr_guide_vec_diff,
634
550k
           ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_diff,
635
550k
           num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_diff[0]));
636
550k
    memcpy(ptr_guide_vectors[0].ptr_guide_vec_orig,
637
550k
           ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_orig,
638
550k
           num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_orig[0]));
639
550k
  } else {
640
0
    memcpy(ptr_guide_vectors[0].ptr_guide_vec_diff,
641
0
           ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vec_diff,
642
0
           num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_diff[0]));
643
644
0
    memcpy(ptr_guide_vectors[0].ptr_guide_vec_orig,
645
0
           ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vec_orig,
646
0
           num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_orig[0]));
647
0
  }
648
649
7.54M
  for (i = 0; i < num_sfb; i++) {
650
#ifdef _WIN32
651
#pragma warning(suppress : 6385)
652
#endif
653
6.99M
    if ((ptr_guide_vectors[0].ptr_guide_vec_diff[i] ||
654
6.36M
         ptr_guide_vectors[0].ptr_guide_vec_orig[i]) &&
655
1.03M
        !ptr_add_harmonics_sfbs[i]) {
656
595k
      ptr_guide_vectors[0].ptr_guide_vec_diff[i] = 0;
657
595k
      ptr_guide_vectors[0].ptr_guide_vec_orig[i] = 0;
658
595k
    }
659
6.99M
  }
660
550k
}
661
662
VOID ixheaace_create_sbr_missing_harmonics_detector(
663
    WORD32 ch, ixheaace_pstr_sbr_missing_harmonics_detector pstr_sbr_mhdet, WORD32 sample_freq,
664
    WORD32 num_sfb, WORD32 qmf_num_ch, WORD32 tot_no_est, WORD32 move, WORD32 no_est_per_frame,
665
8.86k
    WORD32 *ptr_common_buffer) {
666
8.86k
  WORD32 i;
667
8.86k
  WORD32 *ptr_fix;
668
8.86k
  FLOAT32 *ptr_mem;
669
8.86k
  ixheaace_pstr_sbr_missing_harmonics_detector pstr_sbr_detector_handle = pstr_sbr_mhdet;
670
671
8.86k
  memset(pstr_sbr_detector_handle, 0, sizeof(ixheaace_str_sbr_missing_har_detector));
672
673
8.86k
  pstr_sbr_detector_handle->trans_pos_offset = 4;
674
8.86k
  pstr_sbr_detector_handle->time_slots = 16;
675
676
8.86k
  pstr_sbr_detector_handle->qmf_num_ch = qmf_num_ch;
677
8.86k
  pstr_sbr_detector_handle->sample_freq = sample_freq;
678
8.86k
  pstr_sbr_detector_handle->num_scf = num_sfb;
679
680
8.86k
  pstr_sbr_detector_handle->tot_no_est = tot_no_est;
681
8.86k
  pstr_sbr_detector_handle->move = move;
682
8.86k
  pstr_sbr_detector_handle->no_est_per_frame = no_est_per_frame;
683
684
8.86k
  ptr_fix = &ptr_common_buffer[ch * 5 * NO_OF_ESTIMATES * MAXIMUM_FREQ_COEFFS];
685
8.86k
  ptr_mem = (FLOAT32 *)ptr_fix;
686
42.4k
  for (i = 0; i < tot_no_est; i++) {
687
33.5k
    pstr_sbr_detector_handle->ptr_tonal_diff[i] = ptr_mem;
688
33.5k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
689
690
33.5k
    memset(pstr_sbr_detector_handle->ptr_tonal_diff[i], 0,
691
33.5k
           sizeof(pstr_sbr_detector_handle->ptr_tonal_diff[0][0]) * MAXIMUM_FREQ_COEFFS);
692
693
33.5k
    pstr_sbr_detector_handle->ptr_sfm_orig[i] = ptr_mem;
694
33.5k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
695
696
33.5k
    memset(pstr_sbr_detector_handle->ptr_sfm_orig[i], 0,
697
33.5k
           sizeof(pstr_sbr_detector_handle->ptr_sfm_orig[0][0]) * MAXIMUM_FREQ_COEFFS);
698
699
33.5k
    pstr_sbr_detector_handle->ptr_sfm_sbr[i] = ptr_mem;
700
33.5k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
701
702
33.5k
    memset(pstr_sbr_detector_handle->ptr_sfm_sbr[i], 0,
703
33.5k
           sizeof(pstr_sbr_detector_handle->ptr_sfm_sbr[0][0]) * MAXIMUM_FREQ_COEFFS);
704
705
33.5k
    pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff = ptr_mem;
706
33.5k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
707
708
33.5k
    memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff, 0,
709
33.5k
           sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff[0]) *
710
33.5k
               MAXIMUM_FREQ_COEFFS);
711
712
33.5k
    pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig = ptr_mem;
713
33.5k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
714
715
33.5k
    memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig, 0,
716
33.5k
           sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig[0]) *
717
33.5k
               MAXIMUM_FREQ_COEFFS);
718
719
33.5k
    pstr_sbr_detector_handle->ptr_detection_vectors[i] =
720
33.5k
        &(pstr_sbr_detector_handle->sbr_detection_vectors[i * MAXIMUM_FREQ_COEFFS]);
721
722
33.5k
    memset(pstr_sbr_detector_handle->ptr_detection_vectors[i], 0,
723
33.5k
           sizeof(pstr_sbr_detector_handle->ptr_detection_vectors[0][0]) * MAXIMUM_FREQ_COEFFS);
724
725
33.5k
    pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected =
726
33.5k
        &(pstr_sbr_detector_handle->sbr_guide_vector_detected[i * MAXIMUM_FREQ_COEFFS]);
727
728
33.5k
    memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected, 0,
729
33.5k
           sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected[0]) *
730
33.5k
               MAXIMUM_FREQ_COEFFS);
731
33.5k
  }
732
733
8.86k
  pstr_sbr_detector_handle->ptr_prev_env_compensation =
734
8.86k
      &(pstr_sbr_detector_handle->sbr_prev_env_compensation[0]);
735
736
8.86k
  memset(pstr_sbr_detector_handle->ptr_prev_env_compensation, 0,
737
8.86k
         sizeof(pstr_sbr_detector_handle->ptr_prev_env_compensation[0]) * MAXIMUM_FREQ_COEFFS);
738
739
8.86k
  pstr_sbr_detector_handle->ptr_guide_scfb = &(pstr_sbr_detector_handle->sbr_guide_scfb[0]);
740
741
8.86k
  memset(pstr_sbr_detector_handle->ptr_guide_scfb, 0,
742
8.86k
         sizeof(pstr_sbr_detector_handle->ptr_guide_scfb[0]) * MAXIMUM_FREQ_COEFFS);
743
744
8.86k
  pstr_sbr_detector_handle->prev_trans_flag = 0;
745
8.86k
  pstr_sbr_detector_handle->prev_trans_frame = 0;
746
8.86k
  pstr_sbr_detector_handle->prev_trans_pos = 0;
747
8.86k
}