Commit a6ea0a05 authored by Arthur Tritthart's avatar Arthur Tritthart Committed by Sandesh Venkatesh
Browse files

rewritten all cov_smooth loops with better precision - with optional debug output

parent d0310b48
Loading
Loading
Loading
Loading

lib_com/ivas_cov_smooth_fx.c

100644 → 100755
+106 −33
Original line number Diff line number Diff line
@@ -42,6 +42,13 @@
 *-----------------------------------------------------------------------------------------*/

#define BAND_SMOOTH_REST_START_IDX ( 2 )
#define ONEeN20_Q97   0x5E728433     // 1e-20 in Q97  1.584.563.251

//#define DEBUG_ivas_compute_smooth_cov_fx
#ifdef DEBUG_ivas_compute_smooth_cov_fx
#include <math.h>
#endif


/*-----------------------------------------------------------------------------------------*
 * Function ivas_calculate_update_factor_fx()
@@ -87,8 +94,14 @@ static void ivas_calculate_smoothning_factor_fx(
    move16();

    tmp = BASOP_Util_Divide3232_Scale( update_factor, L_shl( L_deposit_l( min_pool_size ), Q22 ), &exp_diff ); // Q(31 - exp_diff)
    *Smoothing_factor = L_shl_sat( L_deposit_l( tmp ), add( Q16, exp_diff ) );                                 // Q31
    *Smoothing_factor = L_shl_sat( L_deposit_h( tmp ), exp_diff  );                                 // Q31
    move32();
#ifdef DEBUG_ivas_compute_smooth_cov_fx
    printf( "Smoothing_factor %g  update_factor %g  min_pool_size %d  j=%d\n", 
            (double) *Smoothing_factor * pow (2.0, -31),
            (double) update_factor + pow (2.0, -22.0), min_pool_size, j );
#endif


    IF( NE_32( smooth_mode, COV_SMOOTH_MC ) )
    {
@@ -264,19 +277,17 @@ void ivas_spar_covar_smooth_enc_close_fx(
    return;
}


/*-----------------------------------------------------------------------------------------*
 * Function ivas_compute_smooth_cov_fx()
 *
 * Compute smooth covariance real/imag.
 *-----------------------------------------------------------------------------------------*/

static void ivas_compute_smooth_cov_fx(
    ivas_cov_smooth_state_t *hCovState,
    ivas_filterbank_t *pFb,
    Word32 *pCov_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],       // i/o: Q(q_cov[i][j])
    Word32 *pPrior_cov_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], // i: hCovState->q_cov_real_per_band[i][j][k]
    const Word32 fac,
    const Word32 fac,                                           // i: ONEeN20_Q97 (1e-20 in Q97)
    const Word16 start_band,
    const Word16 end_band,
    const Word16 num_ch,
@@ -285,10 +296,15 @@ static void ivas_compute_smooth_cov_fx(
{
    Word16 i, j, k;
    Word16 prev_idx = hCovState->prior_bank_idx;
    Word32 factor = 0, L_tmp, L_tmp1;
    Word32 factor = 0, L_tmp0, L_tmp1;

    const Word16 q_fac = 97;
    const Word16 fac_e = sub(Q31, q_fac);

    Word16 cov_buf_e;

    Word16 sm_b;
    Word16 non_sm_b_idx;
    Word16 q_tmp[IVAS_MAX_NUM_BANDS];

    sm_b = BAND_SMOOTH_REST_START_IDX;
    move16();
@@ -296,7 +312,9 @@ static void ivas_compute_smooth_cov_fx(
    move32();

    assert( end_band <= pFb->filterbank_num_bands );

#ifdef DEBUG_ivas_compute_smooth_cov_fx
    printf( "\n" );
#endif
    test();
    IF( EQ_16( prev_idx, -1 ) || EQ_16( transient_det[1], 1 ) )
    {
@@ -309,11 +327,28 @@ static void ivas_compute_smooth_cov_fx(
        }
        FOR( i = 0; i < num_ch; i++ )
        {
#ifdef DEBUG_ivas_compute_smooth_cov_fx
            Word16 cov_buf_e = sub( Q31, q_cov[i][i] );
#endif
            FOR( k = start_band; k < end_band; k++ )
            {
                L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac );                                                        // (Q31, Q31) -> Q31
                pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( hCovState->q_cov_real_per_band[i][i][k], Q31 ) ) ); // hCovState->q_cov_real_per_band[i][j][k]
                /* ref: pCov_buf[i][i][k] += ( hCovState->pSmoothing_factor[k] * fac ); */
#ifdef DEBUG_ivas_compute_smooth_cov_fx
                Word32 L_buf = pCov_buf[i][i][k];  /* debug !! */
#endif
                pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e, &cov_buf_e );
                move32();
                hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e );
                move16();
#ifdef DEBUG_ivas_compute_smooth_cov_fx
                printf( "A: pCov_buf[%d][%d][%d] %g (0x%08X 0x%04X) fac %g  sm-factor %g  buf %g\n", i, i, k, 
                                    (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ), 
                                    pCov_buf[i][i][k], 
                                    hCovState->q_cov_real_per_band[i][i][k] & 0xFFFF, 
                                    (double) fac * pow( 2.0, (double) -q_fac ), 
                                    (double) hCovState->pSmoothing_factor_fx[k] *pow (2.0, -31.0),
                                    (double) L_buf * pow(2.0, (double) -q_cov[i][i]));
#endif
            }
        }
    }
@@ -326,38 +361,63 @@ static void ivas_compute_smooth_cov_fx(
            {
                IF( EQ_16( i, j ) )
                {
                    factor = fac; // Q31
                    factor = fac; // Q97
                    move32();
                }
                ELSE
                {
                    factor = 0;
                    factor = 0;   // Q97
                    move32();
                }

                set16_fx( q_tmp, q_cov[i][j], sub( end_band, start_band ) );
                FOR( k = start_band; k < non_sm_b_idx; k++ )
                {
                    L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] );                                                                                   // (Q31, q_cov[i][j]) -> q_cov[i][j]
                    L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] );                                                       // (Q31, hCovState->q_cov_real_per_band[i][j][k]) -> hCovState->q_cov_real_per_band[i][j][k]
                    pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &q_tmp[k] ); // Q(31 - q_tmp[k])
                    /* ref: pCov_buf[i][j][k] = pPrior_cov_buf[i][j][k] + ( hCovState->pSmoothing_factor[k] * ( pCov_buf[i][j][k] - pPrior_cov_buf[i][j][k] + factor ) ); */
                    /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + 
                                                    pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) +
                                                        factor * hCovState->pSmoothing_factor[k] ); */
#ifdef DEBUG_ivas_compute_smooth_cov_fx
                    Word32 L_buf = pCov_buf[i][j][k];
#endif
                    L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] );                            // q_tmp0: q_cov[i][j]                                                                                  // (Q31, q_cov[i][j]) -> q_cov[i][j]
                    L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // q_tmp1: hCovState->q_prior_cov_real_per_band[i][j][k]
                    L_tmp0 = BASOP_Util_Add_Mant32Exp( L_tmp0, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &cov_buf_e );
                    pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp0, cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), fac_e, &cov_buf_e );
                    move32();
                    q_tmp[k] = sub( Q31, q_tmp[k] ); // Q of pConv_buf[i][j][k] is now q_tmp[k]
                    hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k]
                    move16();
                    L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_tmp[k], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_tmp[k]
                    pCov_buf[i][j][k] = L_add( pCov_buf[i][j][k], L_tmp );                                          // q_tmp[k]
                    move32();

#ifdef DEBUG_ivas_compute_smooth_cov_fx
                    printf( "B1: pCov_buf[%d][%d][%d] %g  fac %g  sm-factor %g  prior %g  buf %g (q=%d)\n", i, j, k, 
                                      (double) pCov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][j][k] ),
                                      (double) factor * pow( 2.0, (double) -q_fac ),
                                      (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ),
                                      (double) pPrior_cov_buf[i][j][k] * pow( 2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ),
                                      (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] );
#endif

                }
                Copy( q_tmp, hCovState->q_cov_real_per_band[i][j], sub( end_band, start_band ) ); // Q of pCov_buf[i][j][k] is hCovState->q_cov_real_per_band[i][j][j]
            }
        }
        FOR( i = 0; i < num_ch; i++ )
        {
            FOR( k = non_sm_b_idx; k < end_band; k++ )
            {
                L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac );                                                        // (Q31, Q31) -> Q31
                pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( hCovState->q_cov_real_per_band[i][i][k], Q31 ) ) ); // hCovState->q_cov_real_per_band[i][j][j]
                /* ref: pCov_buf[i][i][k] += ( hCovState->pSmoothing_factor[k] * fac ); */
#ifdef DEBUG_ivas_compute_smooth_cov_fx
                Word32 L_buf = pCov_buf[i][i][k];
#endif
                pCov_buf[i][i][k] = BASOP_Util_Add_Mant32Exp( pCov_buf[i][i][k], sub( Q31, q_cov[i][i] ), Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ), fac_e , &cov_buf_e);
                move32();
                hCovState->q_cov_real_per_band[i][i][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][i][k]
                move16();
#ifdef DEBUG_ivas_compute_smooth_cov_fx
                printf( "B2: pCov_buf[%d][%d][%d] %g  fac %g  sm-factor %g  buf %g (q=%d)\n", i, i, k, 
                                  (double) pCov_buf[i][i][k] * pow( 2.0, (double) -hCovState->q_cov_real_per_band[i][i][k] ),
                                  (double) fac * pow( 2.0, (double) -q_fac ),
                                  (double) hCovState->pSmoothing_factor_fx[k] * pow( 2.0, -Q31 ),
                                  (double) L_buf * pow( 2.0, (double) -q_cov[i][i] ), q_cov[i][i]);
#endif
            }
        }
    }
@@ -369,28 +429,41 @@ static void ivas_compute_smooth_cov_fx(
            {
                IF( EQ_16( i, j ) )
                {
                    factor = fac; // Q31
                    factor = fac; // Q97
                    move32();
                }
                ELSE
                {
                    factor = 0;
                    factor = 0;  // Q97
                    move32();
                }

                FOR( k = start_band; k < end_band; k++ )
                {
                    L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] );                                                                                   // (Q31, q_cov[i][j]) -> q_cov[i][j]
                    L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] );                                                       // (Q31, hCovState->q_cov_real_per_band[i][j][k]) -> hCovState->q_cov_real_per_band[i][j][k]
                    pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &q_tmp[k] ); // Q(31 - q_tmp[k])
                    /* ref: pCov_buf[i][j][k] = pPrior_cov_buf[i][j][k] + ( hCovState->pSmoothing_factor[k] * ( pCov_buf[i][j][k] - pPrior_cov_buf[i][j][k] + factor ) ); */
                    /* mod: pCov_buf[i][j][k] = pCov_buf[i][j][k] * hCovState->pSmoothing_factor[k] + 
                                                pPrior_cov_buf[i][j][k] * (1.0 - hCovState->pSmoothing_factor[k]) +
                                                factor * hCovState->pSmoothing_factor[k] ); */
#ifdef DEBUG_ivas_compute_smooth_cov_fx
                    Word32 L_buf = pCov_buf[i][j][k]; /* debug !! */
#endif
                    L_tmp0 = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] );    // q_tmp0: q_cov[i][j]                                                                                  // (Q31, q_cov[i][j]) -> q_cov[i][j]
                    L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // q_tmp1: hCovState->q_prior_cov_real_per_band[i][j][k]
                    L_tmp0 = BASOP_Util_Add_Mant32Exp( L_tmp0, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_prior_cov_real_per_band[i][j][k] ), &cov_buf_e );
                    pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp0, cov_buf_e, Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), fac_e, &cov_buf_e );
                    move32();
                    q_tmp[k] = sub( Q31, q_tmp[k] ); // Q of pConv_buf[i][j][k] is now q_tmp[k]
                    hCovState->q_cov_real_per_band[i][j][k] = sub( Q31, cov_buf_e ); // Q of pCov_buf[i][j][k]
                    move16();
                    L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_tmp[k], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_tmp[k]
                    pCov_buf[i][j][k] = L_add( pCov_buf[i][j][k], L_tmp );                                          // q_tmp[k]
                    move32();
#ifdef DEBUG_ivas_compute_smooth_cov_fx
                    printf( "C: pCov_buf[%d][%d][%d] %g  factor %g  sm-factor %g  prior %g  buf %g (q=%d)\n", i, j, k, 
                                (double) pCov_buf[i][j][k] * pow(2.0, (double) -hCovState->q_cov_real_per_band[i][j][k]),
                                (double) factor * pow(2.0, (double) -q_fac),
                                (double) hCovState->pSmoothing_factor_fx[k] * pow(2.0, -Q31),
                                (double) pPrior_cov_buf[i][j][k] * pow(2.0, (double) -hCovState->q_prior_cov_real_per_band[i][j][k] ),
                                (double) L_buf * pow( 2.0, (double) -q_cov[i][j] ), q_cov[i][j] );
#endif
                    
                }
                Copy( q_tmp, hCovState->q_cov_real_per_band[i][j], sub( end_band, start_band ) ); // Q of pCov_buf[i][j][k] is hCovState->q_cov_real_per_band[i][j][j]
            }
        }
    }
@@ -418,7 +491,7 @@ void ivas_cov_smooth_process_fx(
    Word16 i, j, k;
    Word16 num_bands = sub( end_band, start_band );

    ivas_compute_smooth_cov_fx( hCovState, pFb, cov_real, hCovState->pPrior_cov_real_fx, 0, start_band, end_band, num_ch, transient_det, q_cov );
    ivas_compute_smooth_cov_fx( hCovState, pFb, cov_real, hCovState->pPrior_cov_real_fx, ONEeN20_Q97, start_band, end_band, num_ch, transient_det, q_cov );

    FOR( i = 0; i < num_ch; i++ )
    {