From 441ff193c37c7659224f572a260bd08de6a596ce Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 9 Dec 2024 10:55:35 +0530 Subject: [PATCH] Fixed point changes for NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO to address potential division by zero in hq_classifier --- lib_com/options.h | 1 + lib_enc/hq_classifier_enc_fx.c | 132 +++++++++++++++++++-------------- 2 files changed, 78 insertions(+), 55 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index e7fd49fc6..2d52463ed 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -81,4 +81,5 @@ #define FIX_QMETADATA_PENALTY /* Nokia: transform penalty calculation in qmetadata into integer operations */ #define FIX_1013_CRASH_HQ_CORE_DEC /* Ittiam: Saturation added on the lines of EVS */ #define NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS /* DLB: adjust prerendering and mixing gain in OSBA encoder. This is fix to float codes*/ +#define NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO /* Eri: issue 1233: Address possible division by zero in hf_spectrum_sparseness() */ #endif diff --git a/lib_enc/hq_classifier_enc_fx.c b/lib_enc/hq_classifier_enc_fx.c index f2475ef8d..b63ebeb3a 100644 --- a/lib_enc/hq_classifier_enc_fx.c +++ b/lib_enc/hq_classifier_enc_fx.c @@ -57,9 +57,12 @@ static Word16 hf_spectrum_sparseness_fx( Word32 crest_mod_fx; const Word16 *p_num_fx; Word32 A_fx[960]; - int16_t result; + Word16 result; Word32 *crest_lp_fx; Word32 *crest_mod_lp_fx; + Word32 hq_crest_threshold, hq_crest_mod_threshold; + Word16 inv_rms32_e = 0; + move16(); crest_lp_fx = &st->hHQ_core->crest_lp_fx; crest_mod_lp_fx = &st->hHQ_core->crest_mod_lp_fx; @@ -81,73 +84,92 @@ static Word16 hf_spectrum_sparseness_fx( crest_mod_fx = 0; move32(); maximum_l( A_fx, L_SPEC_HB, &Amax_fx ); - thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); - movmean_fx = 0; /* avoid uninitialized warning */ - // p_num = &inv_tbl[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ - p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ - FOR( i = 0; i < L_SPEC_HB; i++ ) +#ifdef NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO + IF( Amax_fx == 0 ) { - // inv_rms += A[i] * A[i]; - inv_rms_fx = W_add( inv_rms_fx, W_shr( W_mult0_32_32( A_fx[i], A_fx[i] ), Q9 ) ); // 2*Q12 -Q9 (Q9 for guard bits - - if ( LT_32( A_fx[i], thr_fx ) ) - { - low_count_fx = add( low_count_fx, 1 ); - } - IF( LE_16( i, HALF_WIN_LENGTH ) ) + /* For all-zero input the crest is 1.0 */ + crest_fx = L_shl( 1, st->hHQ_core->crest_lp_q ); + crest_mod_fx = L_shl( 1, st->hHQ_core->crest_mod_lp_q ); + low_count_fx = 0; + move16(); + } + ELSE + { +#endif + thr_fx = Mpy_32_32( Amax_fx, PEAK_THRESHOLD_FX ); + movmean_fx = 0; /* avoid uninitialized warning */ + // p_num = &inv_tbl[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ + p_num_fx = &inv_tbl_fx[HALF_WIN_LENGTH + 1]; /* Table for division 1./(11:21) */ + FOR( i = 0; i < L_SPEC_HB; i++ ) { - IF( i == 0 ) + // inv_rms += A[i] * A[i]; + inv_rms_fx = W_add( inv_rms_fx, W_shr( W_mult0_32_32( A_fx[i], A_fx[i] ), Q9 ) ); // 2*Q12 -Q9 (Q9 for guard bits + + if ( LT_32( A_fx[i], thr_fx ) ) { - movmean_fx = Mpy_32_16_1( sum_l_fx( &A_fx[0], i + HALF_WIN_LENGTH + 1 ), ( *p_num_fx ) ); // Q12 + low_count_fx = add( low_count_fx, 1 ); } - ELSE + IF( LE_16( i, HALF_WIN_LENGTH ) ) { - - p_num_fx++; - movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], movmean_fx ), ( *p_num_fx ) ) ); // Q12 - } - } - ELSE - { - IF( LE_16( L_SPEC_HB, i + HALF_WIN_LENGTH ) ) - { - - p_num_fx--; - movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( movmean_fx, A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12 + IF( i == 0 ) + { + movmean_fx = Mpy_32_16_1( sum_l_fx( &A_fx[0], i + HALF_WIN_LENGTH + 1 ), ( *p_num_fx ) ); // Q12 + } + ELSE + { + + p_num_fx++; + movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], movmean_fx ), ( *p_num_fx ) ) ); // Q12 + } } ELSE { - movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12 + IF( LE_16( L_SPEC_HB, i + HALF_WIN_LENGTH ) ) + { + + p_num_fx--; + movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( movmean_fx, A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12 + } + ELSE + { + movmean_fx = L_add( movmean_fx, Mpy_32_16_1( L_sub( A_fx[i + HALF_WIN_LENGTH], A_fx[i - HALF_WIN_LENGTH - 1] ), ( *p_num_fx ) ) ); // Q12 + } } - } - if ( LT_32( crest_mod_fx, movmean_fx ) ) - { - crest_mod_fx = movmean_fx; // Q12 - move32(); + if ( LT_32( crest_mod_fx, movmean_fx ) ) + { + crest_mod_fx = movmean_fx; // Q12 + move32(); + } } + Word16 l_shift = W_norm( inv_rms_fx ); + inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32 + Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms + inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_cadence( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); + inv_rms32_e = sub( 31, add( sub( Q31, inv_rms32_e ), q_rms ) ); + // inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB ); + inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); + + crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e + crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e + *crest_lp_fx = L_shr( *crest_lp_fx, sub( st->hHQ_core->crest_lp_q, sub( Q12, inv_rms32_e ) ) ); + move32(); + st->hHQ_core->crest_lp_q = sub( Q12, inv_rms32_e ); + move16(); + *crest_mod_lp_fx = L_shr( *crest_mod_lp_fx, sub( st->hHQ_core->crest_mod_lp_q, sub( Q12, inv_rms32_e ) ) ); + move32(); + st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e ); + move16(); +#ifdef NONBE_1233_HQ_CLASSIFIER_DIV_BY_ZERO } - Word16 l_shift = W_norm( inv_rms_fx ); - inv_rms32_fx = W_extract_h( W_shl( inv_rms_fx, l_shift ) ); // Q15+l_shift-32 - Word16 q_rms = sub( add( Q15, l_shift ), 32 ); // q_rms - Word16 inv_rms32_e = 0; - move16(); - inv_rms32_div_fx = BASOP_Util_Divide3232_Scale_cadence( inv_rms32_fx, L_SPEC_HB, &inv_rms32_e ); - inv_rms32_e = sub( 31, add( sub( Q31, inv_rms32_e ), q_rms ) ); - // inv_rms = 1.0f / (float) sqrtf( inv_rms / L_SPEC_HB ); - inv_rms32_fx = ISqrt32( inv_rms32_div_fx, &inv_rms32_e ); - - crest_fx = Mpy_32_32( Amax_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e - crest_mod_fx = Mpy_32_32( crest_mod_fx, inv_rms32_fx ); // Q12 + (Q31-inv_rms32_e) -Q31 = Q12 - inv_rms32_e - *crest_lp_fx = L_shr( *crest_lp_fx, sub( st->hHQ_core->crest_lp_q, sub( Q12, inv_rms32_e ) ) ); +#endif + *crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_lp_fx ) ), Mpy_32_32( ONE_IN_Q31 - HQ_CREST_FAC_SM_FX, crest_fx ) ); /* Q(st->hHQ_core->crest_lp_q) */ move32(); - st->hHQ_core->crest_lp_q = sub( Q12, inv_rms32_e ); - *crest_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_lp_fx ) ), Mpy_32_32( ONE_IN_Q31 - HQ_CREST_FAC_SM_FX, crest_fx ) ); // Q12 - inv_rms32_e - *crest_mod_lp_fx = L_shr( *crest_mod_lp_fx, sub( st->hHQ_core->crest_mod_lp_q, sub( Q12, inv_rms32_e ) ) ); - st->hHQ_core->crest_mod_lp_q = sub( Q12, inv_rms32_e ); - *crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_mod_lp_fx ) ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), crest_mod_fx ) ); // Q12 - inv_rms32_e - Word32 hq_crest_threshold = L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, sub( Q12, inv_rms32_e ) ) ); - Word32 hq_crest_mod_threshold = L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, sub( Q12, inv_rms32_e ) ) ); + *crest_mod_lp_fx = L_add( Mpy_32_32( HQ_CREST_FAC_SM_FX, ( *crest_mod_lp_fx ) ), Mpy_32_32( L_sub( ONE_IN_Q31, HQ_CREST_FAC_SM_FX ), crest_mod_fx ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */ + move32(); + + hq_crest_threshold = L_shr( HQ_CREST_THRESHOLD_FX, sub( Q28, st->hHQ_core->crest_lp_q ) ); /* Q(st->hHQ_core->crest_lp_q) */ + hq_crest_mod_threshold = L_shr( HQ_CREST_MOD_THRESHOLD_FX, sub( Q29, st->hHQ_core->crest_mod_lp_q ) ); /* Q(st->hHQ_core->crest_mod_lp_q) */ test(); test(); if ( GT_32( ( *crest_lp_fx ), hq_crest_threshold ) && GT_32( ( *crest_mod_lp_fx ), hq_crest_mod_threshold ) && GT_16( low_count_fx, LOW_COUNT_THRESHOLD ) ) -- GitLab