Coverage Report

Created: 2026-05-30 06:39

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.09M
                                   WORD8 *ptr_idx_vx) {
58
1.09M
  WORD32 i, ll, lu, k;
59
1.09M
  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
45.9M
    for (k = ll; k < lu; k++) {
66
31.9M
      if (ptr_tonal_orig[k] > max_val_orig) {
67
16.4M
        max_val_orig = ptr_tonal_orig[k];
68
16.4M
      }
69
31.9M
      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
31.9M
    }
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.09M
}
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.09M
                                                         WORD32 num_sfb) {
83
1.09M
  WORD32 i, j;
84
85
1.09M
  FLOAT32 am_org, am_transp, gm_org, gm_transp, sfm_org, sfm_transp;
86
87
1.09M
  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.8M
      for (j = band_low; j < band_high; j++) {
102
28.9M
        sfm_org = ptr_quota_buf[j];
103
28.9M
        sfm_transp = ptr_quota_buf[ptr_idx_vx[j]];
104
105
28.9M
        am_org += sfm_org;
106
28.9M
        gm_org += sfm_org;
107
28.9M
        am_transp += sfm_transp;
108
28.9M
        gm_transp += sfm_transp;
109
28.9M
      }
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.02M
        ptr_sfm_orig[i] = gm_org / am_org;
118
9.02M
      }
119
120
10.9M
      if (am_transp) {
121
9.01M
        ptr_sfm_sbr[i] = gm_transp / am_transp;
122
9.01M
      }
123
10.9M
    }
124
13.9M
    i++;
125
13.9M
  }
126
1.09M
}
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
546k
    WORD32 no_est_per_frame, WORD32 move, WORD32 no_qmf_bands) {
132
546k
  WORD32 est;
133
134
1.53M
  for (est = 0; est < move; est++) {
135
985k
    memcpy(ptr_tonal_diff[est], ptr_tonal_diff[est + no_est_per_frame],
136
985k
           no_qmf_bands * sizeof(ptr_tonal_diff[est][0]));
137
138
985k
    memcpy(ptr_sfm_orig[est], ptr_sfm_orig[est + no_est_per_frame],
139
985k
           no_qmf_bands * sizeof(ptr_sfm_orig[est][0]));
140
141
985k
    memcpy(ptr_sfm_sbr[est], ptr_sfm_sbr[est + no_est_per_frame],
142
985k
           no_qmf_bands * sizeof(ptr_sfm_sbr[est][0]));
143
985k
  }
144
145
1.63M
  for (est = 0; est < no_est_per_frame; est++) {
146
1.09M
    ia_enhaacplus_enc_diff(ptr_quota_buf[est + move], ptr_tonal_diff[est + move],
147
1.09M
                           ptr_freq_band_tab, num_sfb, ptr_idx_vx);
148
149
1.09M
    ia_enhaacplus_enc_calculate_flatness_measure(
150
1.09M
        ptr_quota_buf[est + move], ptr_idx_vx, ptr_sfm_orig[est + move], ptr_sfm_sbr[est + move],
151
1.09M
        ptr_freq_band_tab, num_sfb);
152
1.09M
  }
153
546k
}
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
546k
    ixheaace_pstr_sbr_missing_harmonics_detector pstr_sbr_missing_harmonics_detector) {
160
546k
  WORD32 transient_frame, new_detection_allowed;
161
162
546k
  transient_frame = 0;
163
164
546k
  if (transient_flag) {
165
129k
    if (transient_pos + trans_pos_offset < ptr_frame_info->borders[ptr_frame_info->n_envelopes]) {
166
114k
      transient_frame = 1;
167
114k
    }
168
416k
  } else {
169
416k
    if (prev_trans_flag && !prev_transient_frame) {
170
3.17k
      transient_frame = 1;
171
3.17k
    }
172
416k
  }
173
174
546k
  new_detection_allowed = 0;
175
176
546k
  if (transient_frame) {
177
118k
    new_detection_allowed = 1;
178
428k
  } else {
179
428k
    if (prev_transient_frame &&
180
53.9k
        ixheaac_abs32(ptr_frame_info->borders[0] -
181
53.9k
                      (prev_transient_pos + trans_pos_offset -
182
53.9k
                       pstr_sbr_missing_harmonics_detector->time_slots)) < DELTA_TIME) {
183
41.2k
      new_detection_allowed = 1;
184
41.2k
    }
185
428k
  }
186
187
546k
  pstr_sbr_missing_harmonics_detector->prev_trans_flag = transient_flag;
188
546k
  pstr_sbr_missing_harmonics_detector->prev_trans_frame = transient_frame;
189
546k
  pstr_sbr_missing_harmonics_detector->prev_trans_pos = transient_pos;
190
191
546k
  return (new_detection_allowed);
192
546k
}
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
435k
  for (est = start; est < stop; est++) {
206
3.31M
    for (sfb = 0; sfb < num_sfb - 1; sfb++) {
207
3.04M
      ptr_harm_vec[sfb] = ptr_harm_vec[sfb] || ptr_detection_vectors[est][sfb];
208
3.04M
    }
209
276k
  }
210
211
1.95M
  for (sfb = 0; sfb < num_sfb - 1; sfb++) {
212
1.79M
    if (ptr_harm_vec[sfb] && ptr_harm_vec[sfb + 1]) {
213
125k
      FLOAT32 max_val_1, max_val_2;
214
125k
      WORD32 maxPos1, maxPos2;
215
216
125k
      low_band = ptr_freq_band_tab[sfb];
217
125k
      up_band = ptr_freq_band_tab[sfb + 1];
218
125k
      maxPos1 = low_band;
219
220
125k
      max_val_1 = ptr_quota_buf[start][low_band];
221
319k
      for (band = low_band; band < up_band; band++) {
222
193k
        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
193k
      }
227
228
215k
      for (est = start + 1; est < stop; est++) {
229
234k
        for (band = low_band; band < up_band; band++) {
230
145k
          if (ptr_quota_buf[est][band] > max_val_1) {
231
43.4k
            max_val_1 = ptr_quota_buf[est][band];
232
43.4k
            maxPos1 = band;
233
43.4k
          }
234
145k
        }
235
89.3k
      }
236
237
125k
      low_band = ptr_freq_band_tab[sfb + 1];
238
125k
      up_band = ptr_freq_band_tab[sfb + 2];
239
240
125k
      maxPos2 = low_band;
241
125k
      max_val_2 = ptr_quota_buf[start][low_band];
242
243
339k
      for (band = low_band; band < up_band; band++) {
244
214k
        if (ptr_quota_buf[start][band] > max_val_2) {
245
38.4k
          max_val_2 = ptr_quota_buf[start][band];
246
38.4k
          maxPos2 = band;
247
38.4k
        }
248
214k
      }
249
250
215k
      for (est = start + 1; est < stop; est++) {
251
251k
        for (band = low_band; band < up_band; band++) {
252
162k
          if (ptr_quota_buf[est][band] > max_val_2) {
253
43.7k
            max_val_2 = ptr_quota_buf[est][band];
254
43.7k
            maxPos2 = band;
255
43.7k
          }
256
162k
        }
257
89.3k
      }
258
259
125k
      if (maxPos2 - maxPos1 < 2) {
260
79.5k
        if (max_val_1 > max_val_2) {
261
39.9k
          ptr_guide_vectors.ptr_guide_vector_detected[sfb + 1] = 0;
262
39.9k
          ptr_guide_vectors.ptr_guide_vec_orig[sfb + 1] = 0;
263
39.9k
          ptr_guide_vectors.ptr_guide_vec_diff[sfb + 1] = 0;
264
265
106k
          for (est = start; est < stop; est++) {
266
66.8k
            ptr_detection_vectors[est][sfb + 1] = 0;
267
66.8k
          }
268
39.9k
        } else {
269
39.6k
          ptr_guide_vectors.ptr_guide_vector_detected[sfb] = 0;
270
39.6k
          ptr_guide_vectors.ptr_guide_vec_diff[sfb] = 0;
271
39.6k
          ptr_guide_vectors.ptr_guide_vec_orig[sfb] = 0;
272
273
102k
          for (est = start; est < stop; est++) {
274
62.9k
            ptr_detection_vectors[est][sfb] = 0;
275
62.9k
          }
276
39.6k
        }
277
79.5k
      }
278
125k
    }
279
1.79M
  }
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.75M
                                        ixheaace_str_guide_vectors *ptr_new_guide_vectors) {
288
1.75M
  WORD32 i, j;
289
1.75M
  WORD32 lower_band, upper_band;
290
1.75M
  FLOAT32 thr, thr_org;
291
292
24.2M
  for (i = 0; i < num_sfb; i++) {
293
22.4M
    if (ptr_guide_vectors->ptr_guide_vec_diff[i]) {
294
1.31M
      if (SBR_DECAY_GUIDE_DIFF * ptr_guide_vectors->ptr_guide_vec_diff[i] > SBR_THR_DIFF_GUIDE) {
295
1.31M
        thr = SBR_DECAY_GUIDE_DIFF * ptr_guide_vectors->ptr_guide_vec_diff[i];
296
1.31M
      } else {
297
0
        thr = SBR_THR_DIFF_GUIDE;
298
0
      }
299
1.31M
      if (thr > SBR_THR_DIFF) {
300
1.30M
        thr = SBR_THR_DIFF;
301
1.30M
      }
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.50M
      ptr_harm_vec[i] = 1;
308
2.50M
      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
813k
        ptr_guide_vectors->ptr_guide_vec_orig[i] = SBR_THR_TONE_GUIDE;
312
813k
      }
313
19.9M
    }
314
22.4M
  }
315
316
24.2M
  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
847k
      thr_org = ptr_guide_vectors->ptr_guide_vec_orig[i] * SBR_DECAY_GUIDE_ORIG;
322
21.6M
    } else {
323
21.6M
      thr_org = SBR_THR_TONE_GUIDE;
324
21.6M
    }
325
22.4M
    if (thr_org > SBR_THR_TONE) {
326
802k
      thr_org = SBR_THR_TONE;
327
802k
    }
328
22.4M
    if (ptr_guide_vectors->ptr_guide_vec_orig[i]) {
329
5.08M
      for (j = lower_band; j < upper_band; j++) {
330
3.40M
        if (ptr_quota_buf[j] > thr_org) {
331
2.49M
          ptr_harm_vec[i] = 1;
332
2.49M
          ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[j];
333
2.49M
        }
334
3.40M
      }
335
1.68M
    }
336
22.4M
  }
337
338
1.75M
  thr_org = SBR_THR_TONE;
339
340
24.2M
  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
645k
            ptr_sfm_orig[i] > SBR_THR_SFM_ORG) {
348
115k
          ptr_harm_vec[i] = 1;
349
115k
          ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[j];
350
115k
        }
351
47.1M
      }
352
17.7M
    } else {
353
4.71M
      if (1 < (num_sfb - 1)) {
354
4.71M
        lower_band = ptr_freq_band_tab[i];
355
356
4.71M
        if (i > 0) {
357
3.44M
          if (ptr_quota_buf[lower_band] > SBR_THR_TONE &&
358
1.08M
              (ptr_diff_vec_scfb[i - 1] < SBR_INV_THR_TONE ||
359
725k
               ptr_diff_vec_scfb[i + 1] < SBR_INV_THR_TONE)) {
360
525k
            ptr_harm_vec[i] = 1;
361
525k
            ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[lower_band];
362
525k
          }
363
3.44M
        } else {
364
1.26M
          if (ptr_quota_buf[lower_band] > SBR_THR_TONE &&
365
376k
              ptr_diff_vec_scfb[i + 1] < SBR_INV_THR_TONE) {
366
92.4k
            ptr_harm_vec[i] = 1;
367
92.4k
            ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[lower_band];
368
92.4k
          }
369
1.26M
        }
370
4.71M
      }
371
4.71M
    }
372
22.4M
  }
373
1.75M
}
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
546k
    WORD32 new_detection_allowed, UWORD8 *ptr_add_harmonics_sfbs) {
381
546k
  WORD32 est = 0, i;
382
546k
  WORD32 start;
383
384
546k
  memset(ptr_add_harmonics_sfbs, 0, num_sfb * sizeof(ptr_add_harmonics_sfbs[0]));
385
386
546k
  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
387k
  } else {
404
387k
    start = 0;
405
387k
  }
406
407
2.30M
  for (est = start; est < tot_no_est; est++) {
408
1.75M
    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.75M
    memset(ptr_detection_vectors[est], 0, num_sfb * sizeof(ptr_detection_vectors[est][0]));
414
415
1.75M
    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
546k
      memset(ptr_guide_vectors[est].ptr_guide_vec_diff, 0,
431
546k
             num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vec_diff[0]));
432
433
546k
      memset(ptr_guide_vectors[est].ptr_guide_vec_orig, 0,
434
546k
             num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vec_orig[0]));
435
436
546k
      memset(ptr_guide_vectors[est].ptr_guide_vector_detected, 0,
437
546k
             num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vector_detected[0]));
438
439
546k
      ia_enhaacplus_enc_detection(ptr_quota_buf[est], ptr_diff_vec_sfb[est], num_sfb,
440
546k
                                  ptr_detection_vectors[est], ptr_freq_band_tab,
441
546k
                                  ptr_sfm_orig[est], ptr_sfm_sbr[est], &(ptr_guide_vectors[est]),
442
546k
                                  &(ptr_guide_vectors[est]));
443
546k
    }
444
1.75M
  }
445
446
546k
  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.51M
  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.97M
  }
463
464
546k
  if (!new_detection_allowed) {
465
5.40M
    for (i = 0; i < num_sfb; i++) {
466
5.01M
      if (ptr_add_harmonics_sfbs[i] - ptr_prev_frame_sfb_harm[i] > 0) {
467
1.07M
        ptr_add_harmonics_sfbs[i] = 0;
468
1.07M
      }
469
5.01M
    }
470
387k
  }
471
546k
}
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
546k
    WORD8 *ptr_prev_env_compensation, WORD32 new_detection_allowed) {
477
546k
  WORD32 i, j, l;
478
479
546k
  memset(ptr_env_compensation, 0, num_sfb * sizeof(ptr_env_compensation[0]));
480
481
546k
  FLOAT32 max_val;
482
546k
  WORD32 lower_band, upper_band;
483
546k
  WORD32 max_pos_band, max_pos_est;
484
546k
  WORD8 comp_val;
485
486
7.51M
  for (i = 0; i < num_sfb; i++) {
487
6.97M
    if (ptr_add_harmonics_sfbs[i]) {
488
632k
      lower_band = ptr_freq_band_tab[i];
489
632k
      upper_band = ptr_freq_band_tab[i + 1];
490
491
632k
      max_pos_band = 0;
492
632k
      max_pos_est = 0;
493
632k
      max_val = 0;
494
495
3.08M
      for (j = 0; j < tot_no_est; j++) {
496
7.56M
        for (l = lower_band; l < upper_band; l++) {
497
5.11M
          if (ptr_tonality[j][l] > max_val) {
498
1.51M
            max_val = ptr_tonality[j][l];
499
1.51M
            max_pos_band = l;
500
1.51M
            max_pos_est = j;
501
1.51M
          }
502
5.11M
        }
503
2.45M
      }
504
505
632k
      if (max_pos_band == lower_band && i) {
506
353k
        comp_val =
507
353k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i - 1] + SBR_EPS)) + 0.5f);
508
353k
        if (comp_val > SBR_MAX_COMP) {
509
180k
          comp_val = SBR_MAX_COMP;
510
180k
        }
511
512
353k
        if (!ptr_add_harmonics_sfbs[i - 1]) {
513
292k
          if (ptr_tonality[max_pos_est][max_pos_band - 1] >
514
292k
              SBR_TONALITY_QUOTA * ptr_tonality[max_pos_est][max_pos_band]) {
515
163k
            ptr_env_compensation[i - 1] = -1 * comp_val;
516
163k
          }
517
292k
        }
518
353k
      }
519
520
632k
      if (max_pos_band == (upper_band - 1) && (i + 1) < num_sfb) {
521
327k
        comp_val =
522
327k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i + 1] + SBR_EPS)) + 0.5f);
523
327k
        if (comp_val > SBR_MAX_COMP) {
524
174k
          comp_val = SBR_MAX_COMP;
525
174k
        }
526
527
327k
        if (!ptr_add_harmonics_sfbs[i + 1]) {
528
282k
          if (ptr_tonality[max_pos_est][max_pos_band + 1] >
529
282k
              SBR_TONALITY_QUOTA * ptr_tonality[max_pos_est][max_pos_band]) {
530
140k
            ptr_env_compensation[i + 1] = comp_val;
531
140k
          }
532
282k
        }
533
327k
      }
534
535
632k
      if (i && i < (num_sfb - 1)) {
536
541k
        comp_val =
537
541k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i - 1] + SBR_EPS)) + 0.5f);
538
541k
        if (comp_val > SBR_MAX_COMP) {
539
254k
          comp_val = SBR_MAX_COMP;
540
254k
        }
541
542
541k
        if (ixheaace_div32((FLOAT32)1.0f, ptr_diff[max_pos_est][i - 1]) >
543
541k
            (SBR_DIFF_QUOTA * ptr_diff[max_pos_est][i])) {
544
156k
          ptr_env_compensation[i - 1] = -1 * comp_val;
545
156k
        }
546
547
541k
        comp_val =
548
541k
            (WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i + 1] + SBR_EPS)) + 0.5f);
549
541k
        if (comp_val > SBR_MAX_COMP) {
550
236k
          comp_val = SBR_MAX_COMP;
551
236k
        }
552
553
541k
        if (ixheaace_div32((FLOAT32)1.0f, ptr_diff[max_pos_est][i + 1]) >
554
541k
            (SBR_DIFF_QUOTA * ptr_diff[max_pos_est][i])) {
555
170k
          ptr_env_compensation[i + 1] = comp_val;
556
170k
        }
557
541k
      }
558
632k
    }
559
6.97M
  }
560
561
546k
  if (!new_detection_allowed) {
562
5.40M
    for (i = 0; i < num_sfb; i++) {
563
5.01M
      if (ptr_env_compensation[i] != 0 && ptr_prev_env_compensation[i] == 0) {
564
106k
        ptr_env_compensation[i] = 0;
565
106k
      }
566
5.01M
    }
567
387k
  }
568
546k
}
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
546k
    const UWORD8 *ptr_freq_band_tab, WORD32 num_sfb, WORD8 *ptr_env_compensation) {
575
546k
  WORD32 i;
576
546k
  WORD32 transient_flag = ptr_tran_info[1];
577
546k
  WORD32 transient_pos = ptr_tran_info[0];
578
546k
  WORD32 new_detection_allowed;
579
580
546k
  UWORD8 **ptr_detection_vectors = pstr_sbr_mhd_et->ptr_detection_vectors;
581
546k
  WORD32 move = pstr_sbr_mhd_et->move;
582
546k
  WORD32 no_est_per_frame = pstr_sbr_mhd_et->no_est_per_frame;
583
546k
  WORD32 tot_no_est = pstr_sbr_mhd_et->tot_no_est;
584
546k
  WORD32 prev_trans_flag = pstr_sbr_mhd_et->prev_trans_flag;
585
546k
  WORD32 prev_transient_frame = pstr_sbr_mhd_et->prev_trans_frame;
586
546k
  WORD32 trans_pos_offset = pstr_sbr_mhd_et->trans_pos_offset;
587
546k
  WORD32 prev_transient_pos = pstr_sbr_mhd_et->prev_trans_pos;
588
546k
  ixheaace_str_guide_vectors *ptr_guide_vectors = pstr_sbr_mhd_et->guide_vectors;
589
590
546k
  FLOAT32 **ptr_sfm_sbr = pstr_sbr_mhd_et->ptr_sfm_sbr;
591
546k
  FLOAT32 **ptr_sfm_orig = pstr_sbr_mhd_et->ptr_sfm_orig;
592
546k
  FLOAT32 **ptr_tonal_diff = pstr_sbr_mhd_et->ptr_tonal_diff;
593
594
546k
  WORD32 no_qmf_bands = ptr_freq_band_tab[num_sfb] - ptr_freq_band_tab[0];
595
596
546k
  new_detection_allowed = ia_enhaacplus_enc_isDetectionOfNewToneAllowed(
597
546k
      ptr_frame_info, prev_transient_frame, prev_transient_pos, prev_trans_flag, trans_pos_offset,
598
546k
      transient_flag, transient_pos, pstr_sbr_mhd_et);
599
600
546k
  ia_enhaacplus_enc_calculate_detector_input(ptr_quota_buf, ptr_idx_vx, ptr_tonal_diff,
601
546k
                                             ptr_sfm_orig, ptr_sfm_sbr, ptr_freq_band_tab,
602
546k
                                             num_sfb, no_est_per_frame, move, no_qmf_bands);
603
604
546k
  ia_enhaacplus_enc_detection_with_prediction(
605
546k
      ptr_quota_buf, ptr_tonal_diff, num_sfb, ptr_freq_band_tab, ptr_sfm_orig, ptr_sfm_sbr,
606
546k
      ptr_detection_vectors, pstr_sbr_mhd_et->ptr_guide_scfb, ptr_guide_vectors, no_est_per_frame,
607
546k
      tot_no_est, new_detection_allowed, ptr_add_harmonics_sfbs);
608
609
546k
  ia_enhaacplus_enc_calculate_comp_vector(
610
546k
      ptr_add_harmonics_sfbs, ptr_quota_buf, ptr_env_compensation, num_sfb, ptr_freq_band_tab,
611
546k
      ptr_tonal_diff, tot_no_est, pstr_sbr_mhd_et->sbr_prev_env_compensation,
612
546k
      new_detection_allowed);
613
614
546k
  *ptr_add_harmonics_flag = 0;
615
616
5.49M
  for (i = 0; i < num_sfb; i++) {
617
5.14M
    if (ptr_add_harmonics_sfbs[i]) {
618
196k
      *ptr_add_harmonics_flag = 1;
619
196k
      break;
620
196k
    }
621
5.14M
  }
622
623
546k
  memcpy(pstr_sbr_mhd_et->sbr_prev_env_compensation, ptr_env_compensation,
624
546k
         num_sfb * sizeof(pstr_sbr_mhd_et->sbr_prev_env_compensation[0]));
625
626
546k
  memcpy(pstr_sbr_mhd_et->ptr_guide_scfb, ptr_add_harmonics_sfbs,
627
546k
         num_sfb * sizeof(pstr_sbr_mhd_et->ptr_guide_scfb[0]));
628
629
546k
  memcpy(ptr_guide_vectors[0].ptr_guide_vector_detected, ptr_add_harmonics_sfbs,
630
546k
         num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vector_detected[0]));
631
632
546k
  if (tot_no_est > no_est_per_frame) {
633
546k
    memcpy(ptr_guide_vectors[0].ptr_guide_vec_diff,
634
546k
           ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_diff,
635
546k
           num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_diff[0]));
636
546k
    memcpy(ptr_guide_vectors[0].ptr_guide_vec_orig,
637
546k
           ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_orig,
638
546k
           num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_orig[0]));
639
546k
  } 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.51M
  for (i = 0; i < num_sfb; i++) {
650
#ifdef _WIN32
651
#pragma warning(suppress : 6385)
652
#endif
653
6.97M
    if ((ptr_guide_vectors[0].ptr_guide_vec_diff[i] ||
654
6.34M
         ptr_guide_vectors[0].ptr_guide_vec_orig[i]) &&
655
1.01M
        !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.97M
  }
660
546k
}
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.64k
    WORD32 *ptr_common_buffer) {
666
8.64k
  WORD32 i;
667
8.64k
  WORD32 *ptr_fix;
668
8.64k
  FLOAT32 *ptr_mem;
669
8.64k
  ixheaace_pstr_sbr_missing_harmonics_detector pstr_sbr_detector_handle = pstr_sbr_mhdet;
670
671
8.64k
  memset(pstr_sbr_detector_handle, 0, sizeof(ixheaace_str_sbr_missing_har_detector));
672
673
8.64k
  pstr_sbr_detector_handle->trans_pos_offset = 4;
674
8.64k
  pstr_sbr_detector_handle->time_slots = 16;
675
676
8.64k
  pstr_sbr_detector_handle->qmf_num_ch = qmf_num_ch;
677
8.64k
  pstr_sbr_detector_handle->sample_freq = sample_freq;
678
8.64k
  pstr_sbr_detector_handle->num_scf = num_sfb;
679
680
8.64k
  pstr_sbr_detector_handle->tot_no_est = tot_no_est;
681
8.64k
  pstr_sbr_detector_handle->move = move;
682
8.64k
  pstr_sbr_detector_handle->no_est_per_frame = no_est_per_frame;
683
684
8.64k
  ptr_fix = &ptr_common_buffer[ch * 5 * NO_OF_ESTIMATES * MAXIMUM_FREQ_COEFFS];
685
8.64k
  ptr_mem = (FLOAT32 *)ptr_fix;
686
41.4k
  for (i = 0; i < tot_no_est; i++) {
687
32.8k
    pstr_sbr_detector_handle->ptr_tonal_diff[i] = ptr_mem;
688
32.8k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
689
690
32.8k
    memset(pstr_sbr_detector_handle->ptr_tonal_diff[i], 0,
691
32.8k
           sizeof(pstr_sbr_detector_handle->ptr_tonal_diff[0][0]) * MAXIMUM_FREQ_COEFFS);
692
693
32.8k
    pstr_sbr_detector_handle->ptr_sfm_orig[i] = ptr_mem;
694
32.8k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
695
696
32.8k
    memset(pstr_sbr_detector_handle->ptr_sfm_orig[i], 0,
697
32.8k
           sizeof(pstr_sbr_detector_handle->ptr_sfm_orig[0][0]) * MAXIMUM_FREQ_COEFFS);
698
699
32.8k
    pstr_sbr_detector_handle->ptr_sfm_sbr[i] = ptr_mem;
700
32.8k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
701
702
32.8k
    memset(pstr_sbr_detector_handle->ptr_sfm_sbr[i], 0,
703
32.8k
           sizeof(pstr_sbr_detector_handle->ptr_sfm_sbr[0][0]) * MAXIMUM_FREQ_COEFFS);
704
705
32.8k
    pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff = ptr_mem;
706
32.8k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
707
708
32.8k
    memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff, 0,
709
32.8k
           sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff[0]) *
710
32.8k
               MAXIMUM_FREQ_COEFFS);
711
712
32.8k
    pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig = ptr_mem;
713
32.8k
    ptr_mem += MAXIMUM_FREQ_COEFFS;
714
715
32.8k
    memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig, 0,
716
32.8k
           sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig[0]) *
717
32.8k
               MAXIMUM_FREQ_COEFFS);
718
719
32.8k
    pstr_sbr_detector_handle->ptr_detection_vectors[i] =
720
32.8k
        &(pstr_sbr_detector_handle->sbr_detection_vectors[i * MAXIMUM_FREQ_COEFFS]);
721
722
32.8k
    memset(pstr_sbr_detector_handle->ptr_detection_vectors[i], 0,
723
32.8k
           sizeof(pstr_sbr_detector_handle->ptr_detection_vectors[0][0]) * MAXIMUM_FREQ_COEFFS);
724
725
32.8k
    pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected =
726
32.8k
        &(pstr_sbr_detector_handle->sbr_guide_vector_detected[i * MAXIMUM_FREQ_COEFFS]);
727
728
32.8k
    memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected, 0,
729
32.8k
           sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected[0]) *
730
32.8k
               MAXIMUM_FREQ_COEFFS);
731
32.8k
  }
732
733
8.64k
  pstr_sbr_detector_handle->ptr_prev_env_compensation =
734
8.64k
      &(pstr_sbr_detector_handle->sbr_prev_env_compensation[0]);
735
736
8.64k
  memset(pstr_sbr_detector_handle->ptr_prev_env_compensation, 0,
737
8.64k
         sizeof(pstr_sbr_detector_handle->ptr_prev_env_compensation[0]) * MAXIMUM_FREQ_COEFFS);
738
739
8.64k
  pstr_sbr_detector_handle->ptr_guide_scfb = &(pstr_sbr_detector_handle->sbr_guide_scfb[0]);
740
741
8.64k
  memset(pstr_sbr_detector_handle->ptr_guide_scfb, 0,
742
8.64k
         sizeof(pstr_sbr_detector_handle->ptr_guide_scfb[0]) * MAXIMUM_FREQ_COEFFS);
743
744
8.64k
  pstr_sbr_detector_handle->prev_trans_flag = 0;
745
8.64k
  pstr_sbr_detector_handle->prev_trans_frame = 0;
746
8.64k
  pstr_sbr_detector_handle->prev_trans_pos = 0;
747
8.64k
}