Commit af00b514 authored by Nicolas Roussin's avatar Nicolas Roussin
Browse files

Implement ivas_iir_2_filter_fx64.

parent f7c63865
Loading
Loading
Loading
Loading
+82 −11
Original line number Diff line number Diff line
@@ -43,8 +43,8 @@
 *------------------------------------------------------------------------------------------*/

static void ivas_iir_2_filter_fx( ivas_filters_process_state_t *filter_state, Word32 *pIn_Out_fx, const Word16 length, const Word16 stage, Word16 *pIn_Out_e );
static void ivas_iir_2_filter_fixed_fx( ivas_filters_process_state_t *filter_state, Word32 *pIn_Out_fx, const Word16 length, const Word16 stage, Word16 q );

static void ivas_iir_2_filter_fx32( ivas_filters_process_state_t *filter_state, Word32 *pIn_Out_fx, const Word16 length, const Word16 stage, Word16 q );
static void ivas_iir_2_filter_fx64( ivas_filters_process_state_t *filter_state, Word64 *pIn_Out_fx, const Word16 length, const Word16 stage, Word16 q );

/*-----------------------------------------------------------------------------------------*
 * Function ivas_filters_init()
@@ -342,7 +342,7 @@ static void ivas_iir_2_filter_fx(
    return;
}

void ivas_filter_process_fixed_fx(
void ivas_filter_process_fx32(
    ivas_filters_process_state_t *filter_state, /* i/o: filter state handle             */
    Word32 *pIn_Out_fx,                         /* i/o: signal subject to filtering Q(q_factor)   */
    const Word16 length,                        /* i  : filter order                    */
@@ -351,11 +351,11 @@ void ivas_filter_process_fixed_fx(
    SWITCH( filter_state->order )
    {
        case IVAS_FILTER_ORDER_1:
            ivas_iir_2_filter_fixed_fx( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q );
            ivas_iir_2_filter_fx32( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q );
            BREAK;
        case IVAS_FILTER_ORDER_4:
            ivas_iir_2_filter_fixed_fx( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q );
            ivas_iir_2_filter_fixed_fx( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_1, q );
            ivas_iir_2_filter_fx32( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q );
            ivas_iir_2_filter_fx32( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_1, q );
            BREAK;
        default:
            BREAK;
@@ -364,17 +364,38 @@ void ivas_filter_process_fixed_fx(
    return;
}

static void ivas_iir_2_filter_fixed_fx(
void ivas_filter_process_fx64(
    ivas_filters_process_state_t *filter_state, /* i/o: filter state handle             */
    Word64 *pIn_Out_fx,                         /* i/o: signal subject to filtering Q(q_factor)   */
    const Word16 length,                        /* i  : filter order                    */
    Word16 q )
{
    SWITCH( filter_state->order )
    {
        case IVAS_FILTER_ORDER_1:
            ivas_iir_2_filter_fx64( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q );
            BREAK;
        case IVAS_FILTER_ORDER_4:
            ivas_iir_2_filter_fx64( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_0, q );
            ivas_iir_2_filter_fx64( filter_state, pIn_Out_fx, length, IVAS_FILTER_STAGE_1, q );
            BREAK;
        default:
            BREAK;
    }

    return;
}

static void ivas_iir_2_filter_fx32(
    ivas_filters_process_state_t *filter_state,
    Word32 *pIn_Out_fx, // Q(31-*pIn_Out_e)
    Word32 *pIn_Out_fx,
    const Word16 length,
    const Word16 stage,
    Word16 q )
{
    Word16 i, j, shift;

    Word64 tmp_prod, tmp;
    Word32 in, out;
    Word16 i, j, shift;

    FOR( i = 0; i < length; i++ )
    {
@@ -398,7 +419,57 @@ static void ivas_iir_2_filter_fixed_fx(
            shift = filter_state->den_q[stage][j] + q - filter_state->state64_q[stage];
            tmp_prod = W_shr( W_mult0_32_32( filter_state->den_fx[stage][j], out ), shift );

            filter_state->state64_fx[stage][j - 1] = W_add( tmp, W_neg( tmp_prod ) );
            filter_state->state64_fx[stage][j - 1] = W_sub( tmp, tmp_prod );
            move32();
        }
    }

    return;
}

static Word64 Mpy_64_32( Word64 W_var1, Word32 L_var2 )
{
    Word32 var1_l;
    Word64 var_out;
    var1_l = W_extract_l( W_var1 );                                               // 1
    var_out = W_mult0_32_32( L_and( var1_l, 1 ), L_var2 );                        // 2
    var_out = W_mac_32_32( var_out, L_lshr( var1_l, 1 ), L_var2 );                // 2
    var_out = W_mac_32_32( W_shr( var_out, 31 ), W_extract_h( W_var1 ), L_var2 ); // 3
    return var_out;
}

static void ivas_iir_2_filter_fx64(
    ivas_filters_process_state_t *filter_state,
    Word64 *pIn_Out_fx,
    const Word16 length,
    const Word16 stage,
    Word16 q )
{
    Word64 tmp_prod, tmp, in, out;
    Word16 i, j, shift;

    FOR( i = 0; i < length; i++ )
    {
        in = pIn_Out_fx[i];
        move32();

        shift = ( filter_state->num_q[stage][0] + q - 31 ) - q;
        tmp_prod = W_shr( Mpy_64_32( in, filter_state->num_fx[stage][0] ), shift );

        pIn_Out_fx[i] = out = W_add( filter_state->state64_fx[stage][0], tmp_prod );
        move32();

        FOR( j = 1; j < filter_state->filt_len; j++ )
        {
            shift = ( filter_state->num_q[stage][j] + q - 31 ) - q;
            tmp_prod = W_shr( Mpy_64_32( in, filter_state->num_fx[stage][j] ), shift );

            tmp = W_add( filter_state->state64_fx[stage][j], tmp_prod );

            shift = ( filter_state->den_q[stage][j] + q - 31 ) - q;
            tmp_prod = W_shr( Mpy_64_32( out, filter_state->den_fx[stage][j] ), shift );

            filter_state->state64_fx[stage][j - 1] = W_sub( tmp, tmp_prod );
            move32();
        }
    }
+8 −1
Original line number Diff line number Diff line
@@ -3817,13 +3817,20 @@ void ivas_filter_process_exp_fx(
    Word16 *pIn_Out_e 
);

void ivas_filter_process_fixed_fx(
void ivas_filter_process_fx32(
    ivas_filters_process_state_t *filter_state,                 /* i/o: filter state handle                             */
    Word32 *pIn_Out_fx,                                         /* i  : signal subject to filtering                     */
    const Word16 length,                                        /* i  : filter order                                    */
    Word16 q 
);

void ivas_filter_process_fx64(
    ivas_filters_process_state_t *filter_state,                 /* i/o: filter state handle                             */
    Word64 *pIn_Out_fx,                                         /* i  : signal subject to filtering                     */
    const Word16 length,                                        /* i  : filter order                                    */
    Word16 q 
);

ivas_error ivas_osba_enc_open_fx(
    Encoder_Struct *st_ivas                                     /* i/o: IVAS encoder handle                             */
);
+100 −74
Original line number Diff line number Diff line
@@ -376,24 +376,24 @@ static Word32 ivas_calc_duck_gain_fx(
 *-----------------------------------------------------------------------------------------*/

#if 0
static void check( Word32 computed_fx, Word16 computed_q, Word32 expected_fx, Word16 expected_q );
static void check( Word64 computed_fx, Word16 computed_q, Word64 expected_fx, Word16 expected_q );

static void check( Word32 computed_fx, Word16 computed_q, Word32 expected_fx, Word16 expected_q )
static void check( Word64 computed_fx, Word16 computed_q, Word64 expected_fx, Word16 expected_q )
{
    Word32 cfx, efx;
    Word64 cfx, efx;
    Word16 q_diff = computed_q - expected_q;
    if ( q_diff >= 0 )
    {
        cfx = L_shr( computed_fx, +q_diff );
        cfx = W_shr( computed_fx, +q_diff );
        efx = expected_fx;
    }
    else
    {
        cfx = computed_fx;
        efx = L_shr( expected_fx, -q_diff );
        efx = W_shr( expected_fx, -q_diff );
    }
    Word32 error = abs( cfx - efx );
    if ( error > ( 1 << 16 ) )
    Word64 error = llabs( cfx - efx );
    if ( error > ( (Word64) 1 << 16 ) )
    {
        assert( false );
    }
@@ -409,7 +409,6 @@ void ivas_td_decorr_get_ducking_gains_fx(
    const Word16 tdet_flag /*Q0*/ )
{
    Word16 i;
    Word32 e_fast_fx[L_FRAME48k], e_slow_fx[L_FRAME48k];
    Word32 in_duck_gain = hTranDet->in_duck_gain; /*Q30*/
    move32();
    Word32 out_duck_gain = hTranDet->out_duck_gain; /*Q30*/
@@ -421,17 +420,22 @@ void ivas_td_decorr_get_ducking_gains_fx(
    Word32 duck_mult_fac = hTranDet->duck_mult_fac; /*Q29*/
    move32();

    Copy32( pIn_pcm, e_fast_fx, frame_len ); /*Q11*/
#ifdef OPT_2239_IVAS_FILTER_PROCESS
    Word64 e_fast_fx[L_FRAME48k], e_slow_fx[L_FRAME48k];

    for ( i = 0; i < frame_len; i++ )
    {
        e_fast_fx[i] = ( (Word64) pIn_pcm[i] ) << 32;
    }


#ifdef OPT_2239_IVAS_FILTER_PROCESS
    /* env hpf */
    Word16 q_fast = Q11;
    Word16 q_fast = Q11 + 32;

    ivas_filter_process_fixed_fx( &hTranDet->env_hpf, e_fast_fx, frame_len, q_fast );
    ivas_filter_process_fx64( &hTranDet->env_hpf, e_fast_fx, frame_len, q_fast );

    Word32 env_eps_fx = IVAS_TDET_PARM_ENV_EPS_fx;
    Word16 env_eps_q = Q31;
    Word64 env_eps_fx = ( (Word64) IVAS_TDET_PARM_ENV_EPS_fx ) << 32;
    Word16 env_eps_q = Q31 + 32;

    Word16 q_diff = sub( q_fast, env_eps_q );
    q_fast = s_min( q_fast, env_eps_q );
@@ -440,7 +444,7 @@ void ivas_td_decorr_get_ducking_gains_fx(
    {
        FOR( i = 0; i < frame_len; i++ )
        {
            e_fast_fx[i] = L_add( L_abs( L_shr( e_fast_fx[i], q_diff ) ), env_eps_fx );
            e_fast_fx[i] = W_add( W_abs( W_shr( e_fast_fx[i], q_diff ) ), env_eps_fx );
            move32();
            e_slow_fx[i] = e_fast_fx[i];
            move32();
@@ -448,10 +452,10 @@ void ivas_td_decorr_get_ducking_gains_fx(
    }
    ELSE
    {
        env_eps_fx = L_shl( env_eps_fx, q_diff );
        env_eps_fx = W_shl( env_eps_fx, q_diff );
        FOR( i = 0; i < frame_len; i++ )
        {
            e_fast_fx[i] = L_add( L_abs( e_fast_fx[i] ), env_eps_fx );
            e_fast_fx[i] = W_add( W_abs( e_fast_fx[i] ), env_eps_fx );
            move32();
            e_slow_fx[i] = e_fast_fx[i];
            move32();
@@ -461,17 +465,24 @@ void ivas_td_decorr_get_ducking_gains_fx(
    Word16 q_slow = q_fast;

    /* env fast*/
    ivas_filter_process_fixed_fx( &hTranDet->env_fast, e_fast_fx, frame_len, q_fast );
    ivas_filter_process_fx64( &hTranDet->env_fast, e_fast_fx, frame_len, q_fast );

    /* env slow */
    ivas_filter_process_fixed_fx( &hTranDet->env_slow, e_slow_fx, frame_len, q_slow );
    ivas_filter_process_fx64( &hTranDet->env_slow, e_slow_fx, frame_len, q_slow );


    IF( tdet_flag )
    {
        FOR( i = 0; i < frame_len; i++ )
        {
            in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, e_slow_fx[i], 31 - q_slow, e_fast_fx[i], 31 - q_fast, duck_mult_fac ); /*Q30*/
            Word16 fast_e = W_norm( e_fast_fx[i] );
            Word32 fast_fx = W_extract_h( W_shl( e_fast_fx[i], fast_e ) );
            fast_e = 31 - ( q_fast + fast_e - 32 );
            Word16 slow_e = W_norm( e_slow_fx[i] );
            Word32 slow_fx = W_extract_h( W_shl( e_slow_fx[i], slow_e ) );
            slow_e = 31 - ( q_slow + slow_e - 32 );

            in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, slow_fx, slow_e, fast_fx, fast_e, duck_mult_fac ); /*Q30*/
            pIn_duck_gains[i] = in_duck_gain;                                                                                      /*Q30*/
            move32();
        }
@@ -482,10 +493,17 @@ void ivas_td_decorr_get_ducking_gains_fx(
    {
        FOR( i = 0; i < frame_len; i++ )
        {
            in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, e_slow_fx[i], 31 - q_slow, e_fast_fx[i], 31 - q_fast, duck_mult_fac ); /*Q30*/
            Word16 fast_e = W_norm( e_fast_fx[i] );
            Word32 fast_fx = W_extract_h( W_shl( e_fast_fx[i], fast_e ) );
            fast_e = 31 - ( q_fast + fast_e - 32 );
            Word16 slow_e = W_norm( e_slow_fx[i] );
            Word32 slow_fx = W_extract_h( W_shl( e_slow_fx[i], slow_e ) );
            slow_e = 31 - ( q_slow + slow_e - 32 );

            in_duck_gain = ivas_calc_duck_gain_fx( in_duck_gain, in_duck_coeff, slow_fx, slow_e, fast_fx, fast_e, duck_mult_fac ); /*Q30*/
            pIn_duck_gains[i] = in_duck_gain;                                                                                      /*Q30*/
            move32();
            out_duck_gain = ivas_calc_duck_gain_fx( out_duck_gain, out_duck_coeff, e_fast_fx[i], 31 - q_fast, e_slow_fx[i], 31 - q_slow, duck_mult_fac ); /*Q30*/
            out_duck_gain = ivas_calc_duck_gain_fx( out_duck_gain, out_duck_coeff, fast_fx, fast_e, slow_fx, slow_e, duck_mult_fac ); /*Q30*/
            pOut_duck_gains[i] = out_duck_gain;                                                                                       /*Q30*/
            move32();
        }
@@ -495,6 +513,9 @@ void ivas_td_decorr_get_ducking_gains_fx(
        move32();
    }
#else
    Word32 e_fast_fx[L_FRAME48k], e_slow_fx[L_FRAME48k];
    Copy32( pIn_pcm, e_fast_fx, frame_len ); /*Q11*/

    Word16 e_fast_e[L_FRAME48k], e_slow_e[L_FRAME48k];

    set16_fx( e_fast_e, 31 - Q11, L_FRAME48k );
@@ -504,10 +525,15 @@ void ivas_td_decorr_get_ducking_gains_fx(


    // ====================================================================================================
    Word32 test_e_fast_fx[L_FRAME48k];
    Word16 q_fast = Q11;
    Copy32( pIn_pcm, test_e_fast_fx, frame_len ); /*Q11*/
    ivas_filter_process_fixed_fx( &hTranDet->test_env_hpf, test_e_fast_fx, frame_len, q_fast );
    Word64 test_e_fast_fx[L_FRAME48k];
    Word16 q_fast = Q11 + 32;

    for ( i = 0; i < frame_len; i++ )
    {
        test_e_fast_fx[i] = (Word64) pIn_pcm[i] << 32;
    }

    ivas_filter_process_fx64( &hTranDet->test_env_hpf, test_e_fast_fx, frame_len, q_fast );

    for ( i = 0; i < frame_len; i++ )
    {
@@ -528,65 +554,65 @@ void ivas_td_decorr_get_ducking_gains_fx(
    }

    // ====================================================================================================
    Word32 test_e_slow_fx[L_FRAME48k];
    Word32 env_eps_fx = IVAS_TDET_PARM_ENV_EPS_fx;
    Word16 env_eps_q = Q31;

    Word16 q_diff = sub( q_fast, env_eps_q );
    q_fast = s_min( q_fast, env_eps_q );

    if ( q_diff >= 0 )
    {
        for ( i = 0; i < frame_len; i++ )
        {
            test_e_fast_fx[i] = L_add( L_abs( L_shr( test_e_fast_fx[i], q_diff ) ), env_eps_fx );
            move32();
            test_e_slow_fx[i] = test_e_fast_fx[i];
            move32();
        }
    }
    else
    {
        env_eps_fx = L_shl( env_eps_fx, q_diff );
        for ( i = 0; i < frame_len; i++ )
        {
            test_e_fast_fx[i] = L_add( L_abs( test_e_fast_fx[i] ), env_eps_fx );
            move32();
            test_e_slow_fx[i] = test_e_fast_fx[i];
            move32();
        }
    }

    Word16 q_slow = q_fast;

    for ( i = 0; i < frame_len; i++ )
    {
        check( test_e_fast_fx[i], q_fast, e_fast_fx[i], 31 - e_fast_e[i] );
    }
    // Word32 test_e_slow_fx[L_FRAME48k];
    // Word32 env_eps_fx = IVAS_TDET_PARM_ENV_EPS_fx;
    // Word16 env_eps_q = Q31;

    // Word16 q_diff = sub( q_fast, env_eps_q );
    // q_fast = s_min( q_fast, env_eps_q );

    // if ( q_diff >= 0 )
    // {
    //     for ( i = 0; i < frame_len; i++ )
    //     {
    //         test_e_fast_fx[i] = L_add( L_abs( L_shr( test_e_fast_fx[i], q_diff ) ), env_eps_fx );
    //         move32();
    //         test_e_slow_fx[i] = test_e_fast_fx[i];
    //         move32();
    //     }
    // }
    // else
    // {
    //     env_eps_fx = L_shl( env_eps_fx, q_diff );
    //     for ( i = 0; i < frame_len; i++ )
    //     {
    //         test_e_fast_fx[i] = L_add( L_abs( test_e_fast_fx[i] ), env_eps_fx );
    //         move32();
    //         test_e_slow_fx[i] = test_e_fast_fx[i];
    //         move32();
    //     }
    // }

    // Word16 q_slow = q_fast;

    // for ( i = 0; i < frame_len; i++ )
    // {
    //     check( test_e_fast_fx[i], q_fast, e_fast_fx[i], 31 - e_fast_e[i] );
    // }
    // ====================================================================================================

    /* env fast*/
    ivas_filter_process_exp_fx( &hTranDet->env_fast, e_fast_fx, frame_len, e_fast_e );

    // ====================================================================================================
    ivas_filter_process_fixed_fx( &hTranDet->test_env_fast, test_e_fast_fx, frame_len, q_fast );
    // ivas_filter_process_fx32( &hTranDet->test_env_fast, test_e_fast_fx, frame_len, q_fast );

    for ( i = 0; i < frame_len; i++ )
    {
        check( test_e_fast_fx[i], q_fast, e_fast_fx[i], 31 - e_fast_e[i] );
    }
    // for ( i = 0; i < frame_len; i++ )
    // {
    //     check( test_e_fast_fx[i], q_fast, e_fast_fx[i], 31 - e_fast_e[i] );
    // }
    // ====================================================================================================

    /* env slow */
    ivas_filter_process_exp_fx( &hTranDet->env_slow, e_slow_fx, frame_len, e_slow_e );

    // ====================================================================================================
    ivas_filter_process_fixed_fx( &hTranDet->test_env_slow, test_e_slow_fx, frame_len, q_slow );
    // ivas_filter_process_fx32( &hTranDet->test_env_slow, test_e_slow_fx, frame_len, q_slow );

    for ( i = 0; i < frame_len; i++ )
    {
        check( test_e_slow_fx[i], q_slow, e_slow_fx[i], 31 - e_slow_e[i] );
    }
    // for ( i = 0; i < frame_len; i++ )
    // {
    //     check( test_e_slow_fx[i], q_slow, e_slow_fx[i], 31 - e_slow_e[i] );
    // }
    // ====================================================================================================

    IF( tdet_flag )