libxaac/encoder/ixheaace_sbr_missing_harmonics_det.c
Akshay Ragir 56716426e2 Fix for the Global-buffer-overflow READ 4 in iusace_quantize_lines
These changes handle the global-buffer-overflow runtime error
reported when the tonal difference in the SBR module becomes
zero.

Bug: ossFuzz: 62261
Test: poc in bug
2023-10-03 19:14:29 +05:30

747 lines
27 KiB
C

/******************************************************************************
* *
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*****************************************************************************
* Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include <math.h>
#include <float.h>
#include "ixheaac_type_def.h"
#include "ixheaac_constants.h"
#include "ixheaac_error_standards.h"
#include "ixheaace_aac_constants.h"
#include "ixheaac_basic_ops32.h"
#include "ixheaac_basic_ops16.h"
#include "ixheaac_basic_ops40.h"
#include "ixheaac_basic_ops.h"
#include "ixheaace_sbr_header.h"
#include "ixheaace_sbr_def.h"
#include "ixheaace_resampler.h"
#include "ixheaace_sbr_rom.h"
#include "ixheaace_common_rom.h"
#include "ixheaace_sbr_hbe.h"
#include "ixheaace_sbr_qmf_enc.h"
#include "ixheaace_sbr_tran_det.h"
#include "ixheaace_sbr_frame_info_gen.h"
#include "ixheaace_sbr_env_est.h"
#include "ixheaace_sbr_code_envelope.h"
#include "ixheaace_sbr_main.h"
#include "ixheaace_sbr_missing_harmonics_det.h"
#include "ixheaace_sbr_inv_filtering_estimation.h"
#include "ixheaace_sbr_noise_floor_est.h"
#include "ixheaace_sbr_ton_corr.h"
#include "iusace_esbr_pvc.h"
#include "iusace_esbr_inter_tes.h"
#include "ixheaace_sbr.h"
#include "ixheaace_common_utils.h"
static VOID 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) {
WORD32 i, ll, lu, k;
FLOAT32 max_val_orig, max_val_sbr;
for (i = 0; i < n_scfb; i++) {
ll = ptr_freq_band_tab[i];
lu = ptr_freq_band_tab[i + 1];
max_val_orig = max_val_sbr = 0;
for (k = ll; k < lu; k++) {
if (ptr_tonal_orig[k] > max_val_orig) {
max_val_orig = ptr_tonal_orig[k];
}
if (ptr_tonal_orig[ptr_idx_vx[k]] > max_val_sbr) {
max_val_sbr = ptr_tonal_orig[ptr_idx_vx[k]];
}
}
ptr_diff_map_2_scfb[i] = (max_val_sbr > 1) ? max_val_orig / max_val_sbr : max_val_orig;
}
}
static VOID 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) {
WORD32 i, j;
FLOAT32 am_org, am_transp, gm_org, gm_transp, sfm_org, sfm_transp;
i = 0;
while (i < num_sfb) {
WORD32 band_low = ptr_freq_band_tab[i];
WORD32 band_high = ptr_freq_band_tab[i + 1];
ptr_sfm_orig[i] = 1.0f;
ptr_sfm_sbr[i] = 1.0f;
if (band_high - band_low > 1) {
am_org = 0;
am_transp = 0;
gm_org = 1.0f;
gm_transp = 1.0f;
for (j = band_low; j < band_high; j++) {
sfm_org = ptr_quota_buf[j];
sfm_transp = ptr_quota_buf[ptr_idx_vx[j]];
am_org += sfm_org;
gm_org += sfm_org;
am_transp += sfm_transp;
gm_transp += sfm_transp;
}
am_org /= band_high - band_low;
am_transp /= band_high - band_low;
gm_org = (FLOAT32)pow(gm_org, 1.0f / (band_high - band_low));
gm_transp = (FLOAT32)pow(gm_transp, 1.0f / (band_high - band_low));
if (am_org) {
ptr_sfm_orig[i] = gm_org / am_org;
}
if (am_transp) {
ptr_sfm_sbr[i] = gm_transp / am_transp;
}
}
i++;
}
}
static VOID 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) {
WORD32 est;
for (est = 0; est < move; est++) {
memcpy(ptr_tonal_diff[est], ptr_tonal_diff[est + no_est_per_frame],
no_qmf_bands * sizeof(ptr_tonal_diff[est][0]));
memcpy(ptr_sfm_orig[est], ptr_sfm_orig[est + no_est_per_frame],
no_qmf_bands * sizeof(ptr_sfm_orig[est][0]));
memcpy(ptr_sfm_sbr[est], ptr_sfm_sbr[est + no_est_per_frame],
no_qmf_bands * sizeof(ptr_sfm_sbr[est][0]));
}
for (est = 0; est < no_est_per_frame; est++) {
ia_enhaacplus_enc_diff(ptr_quota_buf[est + move], ptr_tonal_diff[est + move],
ptr_freq_band_tab, num_sfb, ptr_idx_vx);
ia_enhaacplus_enc_calculate_flatness_measure(
ptr_quota_buf[est + move], ptr_idx_vx, ptr_sfm_orig[est + move], ptr_sfm_sbr[est + move],
ptr_freq_band_tab, num_sfb);
}
}
static WORD32 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) {
WORD32 transient_frame, new_detection_allowed;
transient_frame = 0;
if (transient_flag) {
if (transient_pos + trans_pos_offset < ptr_frame_info->borders[ptr_frame_info->n_envelopes]) {
transient_frame = 1;
}
} else {
if (prev_trans_flag && !prev_transient_frame) {
transient_frame = 1;
}
}
new_detection_allowed = 0;
if (transient_frame) {
new_detection_allowed = 1;
} else {
if (prev_transient_frame &&
ixheaac_abs32(ptr_frame_info->borders[0] -
(prev_transient_pos + trans_pos_offset -
pstr_sbr_missing_harmonics_detector->time_slots)) < DELTA_TIME) {
new_detection_allowed = 1;
}
}
pstr_sbr_missing_harmonics_detector->prev_trans_flag = transient_flag;
pstr_sbr_missing_harmonics_detector->prev_trans_frame = transient_frame;
pstr_sbr_missing_harmonics_detector->prev_trans_pos = transient_pos;
return (new_detection_allowed);
}
static VOID 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) {
WORD32 sfb, band, low_band, up_band, est;
UWORD8 ptr_harm_vec[MAXIMUM_FREQ_COEFFS];
memset(ptr_harm_vec, 0, sizeof(ptr_harm_vec));
for (est = start; est < stop; est++) {
for (sfb = 0; sfb < num_sfb - 1; sfb++) {
ptr_harm_vec[sfb] = ptr_harm_vec[sfb] || ptr_detection_vectors[est][sfb];
}
}
for (sfb = 0; sfb < num_sfb - 1; sfb++) {
if (ptr_harm_vec[sfb] && ptr_harm_vec[sfb + 1]) {
FLOAT32 max_val_1, max_val_2;
WORD32 maxPos1, maxPos2;
low_band = ptr_freq_band_tab[sfb];
up_band = ptr_freq_band_tab[sfb + 1];
maxPos1 = low_band;
max_val_1 = ptr_quota_buf[start][low_band];
for (band = low_band; band < up_band; band++) {
if (ptr_quota_buf[start][band] > max_val_1) {
max_val_1 = ptr_quota_buf[start][band];
maxPos1 = band;
}
}
for (est = start + 1; est < stop; est++) {
for (band = low_band; band < up_band; band++) {
if (ptr_quota_buf[est][band] > max_val_1) {
max_val_1 = ptr_quota_buf[est][band];
maxPos1 = band;
}
}
}
low_band = ptr_freq_band_tab[sfb + 1];
up_band = ptr_freq_band_tab[sfb + 2];
maxPos2 = low_band;
max_val_2 = ptr_quota_buf[start][low_band];
for (band = low_band; band < up_band; band++) {
if (ptr_quota_buf[start][band] > max_val_2) {
max_val_2 = ptr_quota_buf[start][band];
maxPos2 = band;
}
}
for (est = start + 1; est < stop; est++) {
for (band = low_band; band < up_band; band++) {
if (ptr_quota_buf[est][band] > max_val_2) {
max_val_2 = ptr_quota_buf[est][band];
maxPos2 = band;
}
}
}
if (maxPos2 - maxPos1 < 2) {
if (max_val_1 > max_val_2) {
ptr_guide_vectors.ptr_guide_vector_detected[sfb + 1] = 0;
ptr_guide_vectors.ptr_guide_vec_orig[sfb + 1] = 0;
ptr_guide_vectors.ptr_guide_vec_diff[sfb + 1] = 0;
for (est = start; est < stop; est++) {
ptr_detection_vectors[est][sfb + 1] = 0;
}
} else {
ptr_guide_vectors.ptr_guide_vector_detected[sfb] = 0;
ptr_guide_vectors.ptr_guide_vec_diff[sfb] = 0;
ptr_guide_vectors.ptr_guide_vec_orig[sfb] = 0;
for (est = start; est < stop; est++) {
ptr_detection_vectors[est][sfb] = 0;
}
}
}
}
}
}
static VOID 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) {
WORD32 i, j;
WORD32 lower_band, upper_band;
FLOAT32 thr, thr_org;
for (i = 0; i < num_sfb; i++) {
if (ptr_guide_vectors->ptr_guide_vec_diff[i]) {
if (SBR_DECAY_GUIDE_DIFF * ptr_guide_vectors->ptr_guide_vec_diff[i] > SBR_THR_DIFF_GUIDE) {
thr = SBR_DECAY_GUIDE_DIFF * ptr_guide_vectors->ptr_guide_vec_diff[i];
} else {
thr = SBR_THR_DIFF_GUIDE;
}
if (thr > SBR_THR_DIFF) {
thr = SBR_THR_DIFF;
}
} else {
thr = SBR_THR_DIFF;
}
if (ptr_diff_vec_scfb[i] > thr) {
ptr_harm_vec[i] = 1;
ptr_new_guide_vectors->ptr_guide_vec_diff[i] = ptr_diff_vec_scfb[i];
} else {
if (ptr_guide_vectors->ptr_guide_vec_diff[i]) {
ptr_guide_vectors->ptr_guide_vec_orig[i] = SBR_THR_TONE_GUIDE;
}
}
}
for (i = 0; i < num_sfb; i++) {
lower_band = ptr_freq_band_tab[i];
upper_band = ptr_freq_band_tab[i + 1];
if (ptr_guide_vectors->ptr_guide_vec_orig[i] * SBR_DECAY_GUIDE_ORIG > SBR_THR_TONE_GUIDE) {
thr_org = ptr_guide_vectors->ptr_guide_vec_orig[i] * SBR_DECAY_GUIDE_ORIG;
} else {
thr_org = SBR_THR_TONE_GUIDE;
}
if (thr_org > SBR_THR_TONE) {
thr_org = SBR_THR_TONE;
}
if (ptr_guide_vectors->ptr_guide_vec_orig[i]) {
for (j = lower_band; j < upper_band; j++) {
if (ptr_quota_buf[j] > thr_org) {
ptr_harm_vec[i] = 1;
ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[j];
}
}
}
}
thr_org = SBR_THR_TONE;
for (i = 0; i < num_sfb; i++) {
lower_band = ptr_freq_band_tab[i];
upper_band = ptr_freq_band_tab[i + 1];
if (upper_band - lower_band > 1) {
for (j = lower_band; j < upper_band; j++) {
if (ptr_quota_buf[j] > thr_org && ptr_sfm_sbr[i] > SBR_THR_SFM_SBR &&
ptr_sfm_orig[i] > SBR_THR_SFM_ORG) {
ptr_harm_vec[i] = 1;
ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[j];
}
}
} else {
if (1 < (num_sfb - 1)) {
lower_band = ptr_freq_band_tab[i];
if (i > 0) {
if (ptr_quota_buf[lower_band] > SBR_THR_TONE &&
(ptr_diff_vec_scfb[i - 1] < SBR_INV_THR_TONE ||
ptr_diff_vec_scfb[i + 1] < SBR_INV_THR_TONE)) {
ptr_harm_vec[i] = 1;
ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[lower_band];
}
} else {
if (ptr_quota_buf[lower_band] > SBR_THR_TONE &&
ptr_diff_vec_scfb[i + 1] < SBR_INV_THR_TONE) {
ptr_harm_vec[i] = 1;
ptr_new_guide_vectors->ptr_guide_vec_orig[i] = ptr_quota_buf[lower_band];
}
}
}
}
}
}
static VOID 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) {
WORD32 est = 0, i;
WORD32 start;
memset(ptr_add_harmonics_sfbs, 0, num_sfb * sizeof(ptr_add_harmonics_sfbs[0]));
if (new_detection_allowed) {
if (tot_no_est > 1) {
start = no_est_per_frame;
memcpy(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_diff,
ptr_guide_vectors[0].ptr_guide_vec_diff,
num_sfb * sizeof(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_diff[0]));
memcpy(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_orig,
ptr_guide_vectors[0].ptr_guide_vec_orig,
num_sfb * sizeof(ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_orig[0]));
memset(
ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vector_detected, 0,
num_sfb * sizeof(ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vector_detected[0]));
} else {
start = 0;
}
} else {
start = 0;
}
for (est = start; est < tot_no_est; est++) {
if (est > 0) {
memcpy(ptr_guide_vectors[est].ptr_guide_vector_detected, ptr_detection_vectors[est - 1],
num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vector_detected[0]));
}
memset(ptr_detection_vectors[est], 0, num_sfb * sizeof(ptr_detection_vectors[est][0]));
if (est < tot_no_est - 1) {
memset(ptr_guide_vectors[est + 1].ptr_guide_vec_diff, 0,
num_sfb * sizeof(ptr_guide_vectors[est + 1].ptr_guide_vec_diff[0]));
memset(ptr_guide_vectors[est + 1].ptr_guide_vec_orig, 0,
num_sfb * sizeof(ptr_guide_vectors[est + 1].ptr_guide_vec_orig[0]));
memset(ptr_guide_vectors[est + 1].ptr_guide_vector_detected, 0,
num_sfb * sizeof(ptr_guide_vectors[est + 1].ptr_guide_vector_detected[0]));
ia_enhaacplus_enc_detection(ptr_quota_buf[est], ptr_diff_vec_sfb[est], num_sfb,
ptr_detection_vectors[est], ptr_freq_band_tab,
ptr_sfm_orig[est], ptr_sfm_sbr[est], &(ptr_guide_vectors[est]),
&(ptr_guide_vectors[est + 1]));
} else {
memset(ptr_guide_vectors[est].ptr_guide_vec_diff, 0,
num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vec_diff[0]));
memset(ptr_guide_vectors[est].ptr_guide_vec_orig, 0,
num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vec_orig[0]));
memset(ptr_guide_vectors[est].ptr_guide_vector_detected, 0,
num_sfb * sizeof(ptr_guide_vectors[est].ptr_guide_vector_detected[0]));
ia_enhaacplus_enc_detection(ptr_quota_buf[est], ptr_diff_vec_sfb[est], num_sfb,
ptr_detection_vectors[est], ptr_freq_band_tab,
ptr_sfm_orig[est], ptr_sfm_sbr[est], &(ptr_guide_vectors[est]),
&(ptr_guide_vectors[est]));
}
}
if (new_detection_allowed) {
if (tot_no_est > 1) {
ia_enhaacplus_enc_transient_cleanup(ptr_quota_buf, num_sfb, ptr_detection_vectors,
ptr_freq_band_tab, ptr_guide_vectors[no_est_per_frame],
start, tot_no_est);
} else {
ia_enhaacplus_enc_transient_cleanup(ptr_quota_buf, num_sfb, ptr_detection_vectors,
ptr_freq_band_tab, ptr_guide_vectors[0], start,
tot_no_est);
}
}
for (i = 0; i < num_sfb; i++) {
for (est = start; est < tot_no_est; est++) {
ptr_add_harmonics_sfbs[i] = ptr_add_harmonics_sfbs[i] || ptr_detection_vectors[est][i];
}
}
if (!new_detection_allowed) {
for (i = 0; i < num_sfb; i++) {
if (ptr_add_harmonics_sfbs[i] - ptr_prev_frame_sfb_harm[i] > 0) {
ptr_add_harmonics_sfbs[i] = 0;
}
}
}
}
static VOID 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) {
WORD32 i, j, l;
memset(ptr_env_compensation, 0, num_sfb * sizeof(ptr_env_compensation[0]));
FLOAT32 max_val;
WORD32 lower_band, upper_band;
WORD32 max_pos_band, max_pos_est;
WORD8 comp_val;
for (i = 0; i < num_sfb; i++) {
if (ptr_add_harmonics_sfbs[i]) {
lower_band = ptr_freq_band_tab[i];
upper_band = ptr_freq_band_tab[i + 1];
max_pos_band = 0;
max_pos_est = 0;
max_val = 0;
for (j = 0; j < tot_no_est; j++) {
for (l = lower_band; l < upper_band; l++) {
if (ptr_tonality[j][l] > max_val) {
max_val = ptr_tonality[j][l];
max_pos_band = l;
max_pos_est = j;
}
}
}
if (max_pos_band == lower_band && i) {
comp_val =
(WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i - 1] + SBR_EPS)) + 0.5f);
if (comp_val > SBR_MAX_COMP) {
comp_val = SBR_MAX_COMP;
}
if (!ptr_add_harmonics_sfbs[i - 1]) {
if (ptr_tonality[max_pos_est][max_pos_band - 1] >
SBR_TONALITY_QUOTA * ptr_tonality[max_pos_est][max_pos_band]) {
ptr_env_compensation[i - 1] = -1 * comp_val;
}
}
}
if (max_pos_band == (upper_band - 1) && (i + 1) < num_sfb) {
comp_val =
(WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i + 1] + SBR_EPS)) + 0.5f);
if (comp_val > SBR_MAX_COMP) {
comp_val = SBR_MAX_COMP;
}
if (!ptr_add_harmonics_sfbs[i + 1]) {
if (ptr_tonality[max_pos_est][max_pos_band + 1] >
SBR_TONALITY_QUOTA * ptr_tonality[max_pos_est][max_pos_band]) {
ptr_env_compensation[i + 1] = comp_val;
}
}
}
if (i && i < (num_sfb - 1)) {
comp_val =
(WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i - 1] + SBR_EPS)) + 0.5f);
if (comp_val > SBR_MAX_COMP) {
comp_val = SBR_MAX_COMP;
}
if (ixheaace_div32((FLOAT32)1.0f, ptr_diff[max_pos_est][i - 1]) >
(SBR_DIFF_QUOTA * ptr_diff[max_pos_est][i])) {
ptr_env_compensation[i - 1] = -1 * comp_val;
}
comp_val =
(WORD8)(fabs(SBR_INV_LOG_2 * log(ptr_diff[max_pos_est][i + 1] + SBR_EPS)) + 0.5f);
if (comp_val > SBR_MAX_COMP) {
comp_val = SBR_MAX_COMP;
}
if (ixheaace_div32((FLOAT32)1.0f, ptr_diff[max_pos_est][i + 1]) >
(SBR_DIFF_QUOTA * ptr_diff[max_pos_est][i])) {
ptr_env_compensation[i + 1] = comp_val;
}
}
}
}
if (!new_detection_allowed) {
for (i = 0; i < num_sfb; i++) {
if (ptr_env_compensation[i] != 0 && ptr_prev_env_compensation[i] == 0) {
ptr_env_compensation[i] = 0;
}
}
}
}
VOID 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) {
WORD32 i;
WORD32 transient_flag = ptr_tran_info[1];
WORD32 transient_pos = ptr_tran_info[0];
WORD32 new_detection_allowed;
UWORD8 **ptr_detection_vectors = pstr_sbr_mhd_et->ptr_detection_vectors;
WORD32 move = pstr_sbr_mhd_et->move;
WORD32 no_est_per_frame = pstr_sbr_mhd_et->no_est_per_frame;
WORD32 tot_no_est = pstr_sbr_mhd_et->tot_no_est;
WORD32 prev_trans_flag = pstr_sbr_mhd_et->prev_trans_flag;
WORD32 prev_transient_frame = pstr_sbr_mhd_et->prev_trans_frame;
WORD32 trans_pos_offset = pstr_sbr_mhd_et->trans_pos_offset;
WORD32 prev_transient_pos = pstr_sbr_mhd_et->prev_trans_pos;
ixheaace_str_guide_vectors *ptr_guide_vectors = pstr_sbr_mhd_et->guide_vectors;
FLOAT32 **ptr_sfm_sbr = pstr_sbr_mhd_et->ptr_sfm_sbr;
FLOAT32 **ptr_sfm_orig = pstr_sbr_mhd_et->ptr_sfm_orig;
FLOAT32 **ptr_tonal_diff = pstr_sbr_mhd_et->ptr_tonal_diff;
WORD32 no_qmf_bands = ptr_freq_band_tab[num_sfb] - ptr_freq_band_tab[0];
new_detection_allowed = ia_enhaacplus_enc_isDetectionOfNewToneAllowed(
ptr_frame_info, prev_transient_frame, prev_transient_pos, prev_trans_flag, trans_pos_offset,
transient_flag, transient_pos, pstr_sbr_mhd_et);
ia_enhaacplus_enc_calculate_detector_input(ptr_quota_buf, ptr_idx_vx, ptr_tonal_diff,
ptr_sfm_orig, ptr_sfm_sbr, ptr_freq_band_tab,
num_sfb, no_est_per_frame, move, no_qmf_bands);
ia_enhaacplus_enc_detection_with_prediction(
ptr_quota_buf, ptr_tonal_diff, num_sfb, ptr_freq_band_tab, ptr_sfm_orig, ptr_sfm_sbr,
ptr_detection_vectors, pstr_sbr_mhd_et->ptr_guide_scfb, ptr_guide_vectors, no_est_per_frame,
tot_no_est, new_detection_allowed, ptr_add_harmonics_sfbs);
ia_enhaacplus_enc_calculate_comp_vector(
ptr_add_harmonics_sfbs, ptr_quota_buf, ptr_env_compensation, num_sfb, ptr_freq_band_tab,
ptr_tonal_diff, tot_no_est, pstr_sbr_mhd_et->sbr_prev_env_compensation,
new_detection_allowed);
*ptr_add_harmonics_flag = 0;
for (i = 0; i < num_sfb; i++) {
if (ptr_add_harmonics_sfbs[i]) {
*ptr_add_harmonics_flag = 1;
break;
}
}
memcpy(pstr_sbr_mhd_et->sbr_prev_env_compensation, ptr_env_compensation,
num_sfb * sizeof(pstr_sbr_mhd_et->sbr_prev_env_compensation[0]));
memcpy(pstr_sbr_mhd_et->ptr_guide_scfb, ptr_add_harmonics_sfbs,
num_sfb * sizeof(pstr_sbr_mhd_et->ptr_guide_scfb[0]));
memcpy(ptr_guide_vectors[0].ptr_guide_vector_detected, ptr_add_harmonics_sfbs,
num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vector_detected[0]));
if (tot_no_est > no_est_per_frame) {
memcpy(ptr_guide_vectors[0].ptr_guide_vec_diff,
ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_diff,
num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_diff[0]));
memcpy(ptr_guide_vectors[0].ptr_guide_vec_orig,
ptr_guide_vectors[no_est_per_frame].ptr_guide_vec_orig,
num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_orig[0]));
} else {
memcpy(ptr_guide_vectors[0].ptr_guide_vec_diff,
ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vec_diff,
num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_diff[0]));
memcpy(ptr_guide_vectors[0].ptr_guide_vec_orig,
ptr_guide_vectors[no_est_per_frame - 1].ptr_guide_vec_orig,
num_sfb * sizeof(ptr_guide_vectors[0].ptr_guide_vec_orig[0]));
}
for (i = 0; i < num_sfb; i++) {
#ifdef _WIN32
#pragma warning(suppress : 6385)
#endif
if ((ptr_guide_vectors[0].ptr_guide_vec_diff[i] ||
ptr_guide_vectors[0].ptr_guide_vec_orig[i]) &&
!ptr_add_harmonics_sfbs[i]) {
ptr_guide_vectors[0].ptr_guide_vec_diff[i] = 0;
ptr_guide_vectors[0].ptr_guide_vec_orig[i] = 0;
}
}
}
VOID 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) {
WORD32 i;
WORD32 *ptr_fix;
FLOAT32 *ptr_mem;
ixheaace_pstr_sbr_missing_harmonics_detector pstr_sbr_detector_handle = pstr_sbr_mhdet;
memset(pstr_sbr_detector_handle, 0, sizeof(ixheaace_str_sbr_missing_har_detector));
pstr_sbr_detector_handle->trans_pos_offset = 4;
pstr_sbr_detector_handle->time_slots = 16;
pstr_sbr_detector_handle->qmf_num_ch = qmf_num_ch;
pstr_sbr_detector_handle->sample_freq = sample_freq;
pstr_sbr_detector_handle->num_scf = num_sfb;
pstr_sbr_detector_handle->tot_no_est = tot_no_est;
pstr_sbr_detector_handle->move = move;
pstr_sbr_detector_handle->no_est_per_frame = no_est_per_frame;
ptr_fix = &ptr_common_buffer[ch * 5 * NO_OF_ESTIMATES * MAXIMUM_FREQ_COEFFS];
ptr_mem = (FLOAT32 *)ptr_fix;
for (i = 0; i < tot_no_est; i++) {
pstr_sbr_detector_handle->ptr_tonal_diff[i] = ptr_mem;
ptr_mem += MAXIMUM_FREQ_COEFFS;
memset(pstr_sbr_detector_handle->ptr_tonal_diff[i], 0,
sizeof(pstr_sbr_detector_handle->ptr_tonal_diff[0][0]) * MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->ptr_sfm_orig[i] = ptr_mem;
ptr_mem += MAXIMUM_FREQ_COEFFS;
memset(pstr_sbr_detector_handle->ptr_sfm_orig[i], 0,
sizeof(pstr_sbr_detector_handle->ptr_sfm_orig[0][0]) * MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->ptr_sfm_sbr[i] = ptr_mem;
ptr_mem += MAXIMUM_FREQ_COEFFS;
memset(pstr_sbr_detector_handle->ptr_sfm_sbr[i], 0,
sizeof(pstr_sbr_detector_handle->ptr_sfm_sbr[0][0]) * MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff = ptr_mem;
ptr_mem += MAXIMUM_FREQ_COEFFS;
memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff, 0,
sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_diff[0]) *
MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig = ptr_mem;
ptr_mem += MAXIMUM_FREQ_COEFFS;
memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig, 0,
sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vec_orig[0]) *
MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->ptr_detection_vectors[i] =
&(pstr_sbr_detector_handle->sbr_detection_vectors[i * MAXIMUM_FREQ_COEFFS]);
memset(pstr_sbr_detector_handle->ptr_detection_vectors[i], 0,
sizeof(pstr_sbr_detector_handle->ptr_detection_vectors[0][0]) * MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected =
&(pstr_sbr_detector_handle->sbr_guide_vector_detected[i * MAXIMUM_FREQ_COEFFS]);
memset(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected, 0,
sizeof(pstr_sbr_detector_handle->guide_vectors[i].ptr_guide_vector_detected[0]) *
MAXIMUM_FREQ_COEFFS);
}
pstr_sbr_detector_handle->ptr_prev_env_compensation =
&(pstr_sbr_detector_handle->sbr_prev_env_compensation[0]);
memset(pstr_sbr_detector_handle->ptr_prev_env_compensation, 0,
sizeof(pstr_sbr_detector_handle->ptr_prev_env_compensation[0]) * MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->ptr_guide_scfb = &(pstr_sbr_detector_handle->sbr_guide_scfb[0]);
memset(pstr_sbr_detector_handle->ptr_guide_scfb, 0,
sizeof(pstr_sbr_detector_handle->ptr_guide_scfb[0]) * MAXIMUM_FREQ_COEFFS);
pstr_sbr_detector_handle->prev_trans_flag = 0;
pstr_sbr_detector_handle->prev_trans_frame = 0;
pstr_sbr_detector_handle->prev_trans_pos = 0;
}