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