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

Optimize eig2x2_fx part 1.

parent 4048efa5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -30,7 +30,6 @@

*******************************************************************************************************/

#include "move.h"
#include <stdint.h>
#include "options.h"
#include "ivas_cnst.h"
@@ -40,6 +39,7 @@
#include "ivas_stat_enc.h"
#include <math.h>
#include "wmc_auto.h"
#include "move.h"
#include "ivas_prot_fx.h"


+131 −0
Original line number Diff line number Diff line
@@ -3518,6 +3518,31 @@ static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked_fx(
    return;
}

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

static void check(
    Word32 computed_fx,
    Word16 computed_q,
    Word32 expected_fx,
    Word16 expected_q,
    Word32 max_abs_err )
{
    Word16 qd = computed_q - expected_q;
    Word32 cf = computed_fx >> +max( qd, 0 );
    Word32 ef = expected_fx >> -min( qd, 0 );
    Word32 abs_error = abs( cf - ef );
    if ( abs_error >= max_abs_err )
    {
        assert( false );
    }
}
#endif

static void eig2x2_fx(
    const Word32 E1_fx, /*q_E*/
@@ -3532,6 +3557,7 @@ static void eig2x2_fx(
    Word32 D_fx[BINAURAL_CHANNELS], /*q_D*/
    Word16 *q_D )
{
#if 0
    Word16 chA, chB, ch;
    Word32 s_fx, normVal_fx, crossSquare_fx, a_fx, pm_fx, add_fx;
    Word32 tmp1, tmp2, tmp3, e1, e2, c_re, c_im;
@@ -3672,7 +3698,112 @@ static void eig2x2_fx(
        *q_D = sub( q_tmp2, 1 );
        move16();
    }
#else
    Word16 chA, chB, ch;
    FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ )
    {
        FOR( chB = 0; chB < BINAURAL_CHANNELS; chB++ )
        {
            Ure_fx[chA][chB] = 0;
            move32();
            Uim_fx[chA][chB] = 0;
            move32();
        }
    }

    // ===================================================================================================
    /*crossSquare_fx = (c_re * c_re) + (c_im * c_im)
    a_fx = (e1 + e2) * (e1 + e2) - 4.0f * ((e1 * e2) - crossSquare_fx) = (e1 - e2)^2 + 4 * crossSquare_fx
    pm_fx = 0.5f * sqrtf(max(0.0f, a_fx))
    add_fx = 0.5f * (e1 + e2)*/

    Word16 q1, q2, qm, qd, lshift;

    // (e1 - e2)^2 -> Q: 2 * q_E
    q1 = shl( q_E, 1 );
    // 4 * ((c_re * c_re) + (c_im * c_im)) -> Q: 2 * q_C - 2
    q2 = sub( shl( q_C, 1 ), 2 );

    // (e1 - e2)^2
    Word32 es = L_sub( E1_fx, E2_fx );
    Word64 es2 = W_mult0_32_32( es, es );
    lshift = sub( W_norm( es2 ), 1 );
    es2 = W_shl( es2, lshift );
    q1 = add( q1, lshift );
    if ( !es2 )
    {
        q1 = 63;
        move16();
    }

    // 4 * ((c_re * c_re) + (c_im * c_im))
    Word64 cs = W_add( W_mult0_32_32( Cre_fx, Cre_fx ), W_mult0_32_32( Cim_fx, Cim_fx ) ); // 2*q_C-2
    lshift = sub( W_norm( cs ), 1 );
    cs = W_shl( cs, lshift );
    q2 = add( q2, lshift );
    if ( !cs )
    {
        q2 = 63;
        move16();
    }

    Word32 crossSquare_fx = (Word32) ( cs >> 32 ); // FIXME
    Word16 q_crossSquare = 2 * q_C + lshift - 32;  // FIXME

    // a = max(0, (e1 - e2)^2 + 4 * crossSquare_fx)
    qm = s_min( q1, q2 );
    qd = sub( q1, q2 );
    Word64 a = W_max( W_add( W_shr( es2, s_max( qd, 0 ) ), W_shr( cs, negate( s_min( qd, 0 ) ) ) ), 0 );

    // pm = 0.5f * sqrtf(a)
    // a = 0.5f * ( E1 + E2 );
    lshift = W_norm( a );
    Word32 pm = W_extract_h( W_shl( a, lshift ) );
    Word16 e = sub( sub( 63, lshift ), qm );
    pm = L_shr( Sqrt32( pm, &e ), 1 );
    q2 = sub( 31, e );
    // check( pm, q2, pm_fx, q_tmp2, 1 << 16 );
    a = L_add( E1_fx, E2_fx );
    lshift = sub( norm_l( a ), 1 );
    a = W_shl( a, lshift );
    q1 = add( add( q_E, 1 ), lshift );
    // check( a, q1, add_fx, q_tmp1, 1 << 16 );

    Word32 add_fx = a;  // FIXME
    Word16 q_tmp1 = q1; // FIXME
    Word32 pm_fx = pm;  // FIXME
    Word16 q_tmp2 = q2; // FIXME

    // D[0] = add + pm;
    // D[1] = max( 0.0f, add - pm );
    qm = s_min( q1, q2 );
    qd = sub( q1, q2 );
    a = W_shr( a, s_max( qd, 0 ) );
    pm = W_shr( pm, negate( s_min( qd, 0 ) ) );
    Word32 d0 = L_add( a, pm );
    Word32 d1 = L_max( L_sub( a, pm ), 0 );
    // check( d0, qm, D_fx[0], *q_D, 1 << 16 );
    // check( d1, qm, D_fx[1], *q_D, 1 << 16 );

    D_fx[0] = d0; // FIXME
    D_fx[1] = d1; // FIXME
    *q_D = qm;    // FIXME

    Word32 tmp1, tmp2, tmp3, e1, e2, s_fx, normVal_fx, c_re, c_im; // FIXME
    Word16 q_U_1, q_U_2, q_c, q_e, exp, exp_tmp3;                  // FIXME
    Word32 epsilon_mant = 1180591621;                              // FIXME
    Word16 epsilon_exp = -39;                                      // FIXME

    exp = sub( get_min_scalefactor( Cre_fx, Cim_fx ), 2 ); // FIXME
    c_re = L_shl( Cre_fx, exp );                           // FIXME
    c_im = L_shl( Cim_fx, exp );                           // FIXME
    q_c = add( q_C, exp );                                 // FIXME

    exp = sub( get_min_scalefactor( E1_fx, E2_fx ), 2 ); // FIXME
    e1 = L_shl( E1_fx, exp );                            // FIXME
    e2 = L_shl( E2_fx, exp );                            // FIXME
    q_e = add( q_E, exp );                               // FIXME
#endif
    /* Numeric case, when input is practically zeros */
    // IF( D_fx[0] < EPSILON_FX )