Commit c4a32b8a authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Precision improvements, comments update for MR !1096 and fft-func updates

parent 6c6563c3
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1233,6 +1233,7 @@ enum
#define SPC                                 0.0234952f
#define SPC_plus                            SPC * 1.001f
#define ALPHA_SQ                            ( ( 0.5f / PI2 ) * ( 0.5f / PI2 ) )
#define ALPHA_SQ_Q30                        (6799549) /* ( ( 0.5f / PI2 ) * ( 0.5f / PI2 ) ) in Q30 */

#define NC                                  M / 2
#define LSF_GAP                             50.0f
+162 −0
Original line number Diff line number Diff line
@@ -301,6 +301,168 @@ void fft_rel(
    return;
}

void fft_rel_16_32fx(
    Word16 x[],  /* i/o: input/output vector Qx   */
    Word16 *q_x, /* extra scaling added on speech buffer*/
    Word16 i_subfr,
    const Word16 n, /* i  : vector length          */
    const Word16 m  /* i  : log2 of vector length  */
)
{
    Word16 i, j, k, n1, n2, n4;
    Word16 step;
    Word32 xt, t1, t2;
    Word32 *x0, *x1, *x2;
    const Word16 *s, *c;
    Word32 *xi2, *xi3, *xi4, *xi1;

    Word32 fft_bff32[L_FFT];
    Copy_Scale_sig_16_32_no_sat( x, fft_bff32, L_FFT, 0 ); // copying x to fft_bff32 without scaling

    /*-----------------------------------------------------------------*
     * Digit reverse counter
     *-----------------------------------------------------------------*/

    j = 0;
    move16();
    x0 = &fft_bff32[0]; // Qx
    FOR( i = 0; i < n - 1; i++ )
    {
        IF( LT_16( i, j ) )
        {
            xt = fft_bff32[j]; // Qx
            move32();
            fft_bff32[j] = *x0; // Qx
            move32();
            *x0 = xt; // Qx
            move32();
        }
        x0++;
        k = shr( n, 1 );
        WHILE( ( k <= j ) )
        {
            j = sub( j, k );
            k = shr( k, 1 );
        }
        j = add( j, k );
    }

    /*-----------------------------------------------------------------*
     * Length two butterflies
     *-----------------------------------------------------------------*/

    x0 = &fft_bff32[0];
    x1 = &fft_bff32[1];
    FOR( i = 0; i < ( n >> 1 ); i++ )
    {
        xt = *x0;
        move32();
        *x0 = L_add( xt, *x1 );
        move32();
        *x1 = L_sub( xt, *x1 );
        move32();
        x0++;
        x0++;
        x1++;
        x1++;
    }

    /*-----------------------------------------------------------------*
     * Other butterflies
     *
     * The implementation described in [1] has been changed by using
     * table lookup for evaluating sine and cosine functions.  The
     * variable ind and its increment step are needed to access table
     * entries.  Note that this implementation assumes n4 to be so
     * small that ind will never exceed the table.  Thus the input
     * argument n and the constant N_MAX_SAS must be set properly.
     *-----------------------------------------------------------------*/

    n2 = 1;
    move16();
    /* step = N_MAX_SAS/4; */
    FOR( k = 2; k <= m; k++ )
    {
        n4 = n2;
        move16();
        n2 = shl( n4, 1 );
        n1 = shl( n2, 1 );

        step = idiv1616( N_MAX_SAS, n1 );

        x0 = fft_bff32;
        x1 = fft_bff32 + n2;
        x2 = fft_bff32 + add( n2, n4 );
        FOR( i = 0; i < n; i += n1 )
        {
            xt = *x0;
            move32(); /* xt = x[i];   */
            *x0 = L_add( xt, *x1 );
            move32(); /* x[i] = xt + x[i+n2];    */
            *x1 = L_sub( xt, *x1 );
            move32(); /* x[i+n2] = xt - x[i+n2];      */
            *x2 = L_negate( *x2 );
            move32(); /* x[i+n2+n4] = -x[i+n2+n4];     */


            s = sincos_t_fx + step; // Q15
            c = s + 64;             // Q15
            xi1 = fft_bff32 + add( i, 1 );
            xi3 = xi1 + n2;
            xi2 = xi3 - 2;
            xi4 = xi1 + sub( n1, 2 );

            FOR( j = 1; j < n4; j++ )
            {
                t1 = L_add( Mpy_32_16_1( *xi3, *c ), Mpy_32_16_1( *xi4, *s ) ); /* t1 = *xi3**(pt_c+ind) + *xi4**(pt_s+ind); Qx  */
                t2 = L_sub( Mpy_32_16_1( *xi3, *s ), Mpy_32_16_1( *xi4, *c ) ); /* t2 = *xi3**(pt_s+ind) - *xi4**(pt_c+ind); Qx    */
                *xi4 = L_sub( *xi2, t2 );
                move32();
                *xi3 = L_negate( L_add( *xi2, t2 ) );
                move32();
                *xi2 = L_sub( *xi1, t1 );
                move32();
                *xi1 = L_add( *xi1, t1 );
                move32();

                xi4--;
                xi2--;
                xi3++;
                xi1++;
                c += step;
                s += step; /* autoincrement by ar0 */
            }

            x0 += n1;
            x1 += n1;
            x2 += n1;
        }
        /* step = shr(step, 1); */
    }
    Word16 norm = L_norm_arr( fft_bff32, L_FFT );
    IF( i_subfr == 0 )
    {
        Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm );
        *q_x = sub( norm, 16 );
        move16();
    }
    ELSE
    {
        IF( LT_16( sub( norm, 16 ), *q_x ) )
        {
            scale_sig( x - L_FFT, L_FFT, sub( sub( norm, 16 ), *q_x ) );
            Copy_Scale_sig32_16( fft_bff32, x, L_FFT, norm );
            *q_x = sub( norm, 16 );
            move16();
        }
        ELSE
        {
            Copy_Scale_sig32_16( fft_bff32, x, L_FFT, add( 16, *q_x ) );
        }
    }

    return;
}

void fft_rel_fx(
    Word16 x[],     /* i/o: input/output vector Qx   */
+74 −0
Original line number Diff line number Diff line
@@ -1505,6 +1505,80 @@ void lsp_weights_fx(
    move16();
}

void lsp_weights_ivas_fx(
    Word16 lsp_nq_fx[],
    Word16 w[],
    Word16 Order,
    Word16 *Qout )
{
    Word16 i;
    Word16 q_weight[20];
    Word32 weight[20];
    Word16 delta1, delta2;
    Word32 L_tmp;
    Word16 q_min;

    delta1 = lsp_nq_fx[0]; // Q15
    move16();
    delta2 = sub( lsp_nq_fx[1], lsp_nq_fx[0] ); // Q15

    L_tmp = L_mult0( delta1, delta2 );                                            // Q30                    // Q30
    L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[0] ); // q_weight[0]

    weight[0] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[0]-8
    q_weight[0] = sub( q_weight[0], 8 );
    move32();
    move16();

    q_min = q_weight[0];
    move16();

    FOR( i = 1; i < Order - 1; i++ )
    {
        delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] ); // Q15
        delta2 = sub( lsp_nq_fx[i + 1], lsp_nq_fx[i] ); // Q15

        L_tmp = L_mult0( delta1, delta2 );                                            // Q30
        L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i]

        weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i]
        q_weight[i] = sub( q_weight[i], 8 );
        move32();
        move16();

        q_min = s_min( q_min, q_weight[i] );
    }
    delta1 = sub( lsp_nq_fx[i], lsp_nq_fx[i - 1] );      // Q15
    delta2 = sub( 16384 /* 0.5 in Q15*/, lsp_nq_fx[i] ); // Q15

    L_tmp = L_mult0( delta1, delta2 );                                            // Q30
    L_tmp = root_a_over_b_ivas_fx( ALPHA_SQ_Q30, Q30, L_tmp, Q30, &q_weight[i] ); // q_weight[i]

    weight[i] = Mpy_32_16_1( L_tmp, 32000 /* 250 in Q7*/ ); // q_weight[i]
    q_weight[i] = sub( q_weight[i], 8 );
    move32();
    move16();

    q_min = s_min( q_min, q_weight[i] );

    FOR( i = 0; i < Order; i++ )
    {
        w[i] = round_fx( L_shl( weight[i], sub( q_min, q_weight[i] ) ) ); /* q_min-16 */
        move16();
    }

    IF( Order != LPC_SHB_ORDER_WB )
    {
        w[3] = round_fx( L_shl( L_mult( w[3], 18022 ), 1 ) ); /* q_min-16 */
        w[4] = round_fx( L_shl( L_mult( w[4], 18022 ), 1 ) ); /* q_min-16 */
        move16();
        move16();
    }

    *Qout = sub( q_min, 16 );
    move16();
}

/*
 * E_LPC_isf_isp_conversion
 *
+20 −0
Original line number Diff line number Diff line
@@ -1084,6 +1084,12 @@ void lsp_weights_fx(
    Word16 Order,
    Word16 *Qout );
void lsp_weights_ivas_fx(
    Word16 lsp_nq_fx[],
    Word16 w[],
    Word16 Order,
    Word16 *Qout );
void space_lsfs_fx(
    Word16 *lsfs,      /* i/o: Line spectral frequencies   */
    const Word16 order /* i  : order of LP analysis        */
@@ -1472,6 +1478,13 @@ void fft_rel_fx(
    const Word16 n, /* i  : vector length          */
    const Word16 m  /* i  : log2 of vector length  */
);
void fft_rel_16_32fx(
    Word16 x[],  /* i/o: input/output vector Qx   */
    Word16 *q_x, /* extra scaling added on speech buffer*/
    Word16 i_subfr,
    const Word16 n, /* i  : vector length          */
    const Word16 m  /* i  : log2 of vector length  */
);
void fft_rel_fx32(
    Word32 x[],     /* i/o: i  /output vector    */
    const Word16 n, /* i  : vector length          */
@@ -10297,6 +10310,13 @@ Word32 root_a_over_b_fx(
    Word16 Q_b,
    Word16 *exp_out );
Word32 root_a_over_b_ivas_fx(
    Word32 a, /* Q(Q_a) */
    Word16 Q_a,
    Word32 b, /* Q(Q_b) */
    Word16 Q_b,
    Word16 *exp_out );
void fir_fx( const Word16 x[], /* i  : input vector                              Qx*/
             const Word16 h[], /* i  : impulse response of the FIR filter        Q12*/
             Word16 y[],       /* o  : output vector (result of filtering)       Qx*/
+103 −0
Original line number Diff line number Diff line
@@ -2505,6 +2505,109 @@ Word32 root_a_over_b_fx(
    return L_tmp;
}

Word32 root_a_over_b_ivas_fx(
    Word32 a, /* Q(Q_a) */
    Word16 Q_a,
    Word32 b, /* Q(Q_b) */
    Word16 Q_b,
    Word16 *q_out )
{
    Word16 shift_a, shift_b, shift;
    Word32 mod_a, mod_b, one_in_Q_a, one_in_Q_b, half_in_Q_a, half_in_Q_b;
    Word32 a_sqr, b_sqr, p0, p1, p2, approx;
    Word16 exp;

    test();
    IF( ( a <= 0 ) || ( b <= 0 ) )
    {
        *q_out = 0;
        move16();
        return 0;
    }

    one_in_Q_a = L_shl( 1, Q_a );         // 1.0f in Q_a
    one_in_Q_b = L_shl( 1, Q_b );         // 1.0f in Q_b
    half_in_Q_a = L_shr( one_in_Q_a, 1 ); // 0.5f in Q_a
    half_in_Q_b = L_shr( one_in_Q_b, 1 ); // 0.5f in Q_b

    a = L_add( a, one_in_Q_a );
    b = L_add( b, one_in_Q_b );

    /* This next piece of code implements a "norm" function */
    /* and returns the shift needed to scale "a" to have a  */
    /* 1 in the (MSB-1) position. This is equivalent to     */
    /* giving a value between 0.5 & 1.0.                    */

    mod_a = a;
    move32();

    shift_a = 0;
    move16();
    WHILE( GT_32( mod_a, one_in_Q_a ) )
    {
        mod_a = L_shr( mod_a, 1 );
        shift_a = sub( shift_a, 1 );
    }

    WHILE( LT_32( mod_a, half_in_Q_a ) )
    {
        mod_a = L_shl( mod_a, 1 );
        shift_a = add( shift_a, 1 );
    }

    shift_a = s_and( shift_a, -2 );
    mod_a = L_shl( a, shift_a ); // Q_a

    /* This next piece of code implements a "norm" function */
    /* and returns the shift needed to scale "b" to have a  */
    /* 1 in the (MSB-1) position. This is equivalent to     */
    /* giving a value between 0.5 & 1.0.                    */
    mod_b = b;
    move32();

    shift_b = 0;
    move16();
    WHILE( GT_32( mod_b, one_in_Q_b ) )
    {
        mod_b = L_shr( mod_b, 1 );
        shift_b = sub( shift_b, 1 );
    }

    WHILE( LT_32( mod_b, half_in_Q_b ) )
    {
        mod_b = L_shl( mod_b, 1 );
        shift_b = add( shift_b, 1 );
    }

    shift_b = s_and( shift_b, -2 );
    mod_b = L_shl( b, shift_b ); // Q_b

    shift = shr( sub( shift_b, shift_a ), 1 );

    a_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_a, mod_a ), sub( 32, Q_a ) ) ); // Q_a
    b_sqr = W_extract_h( W_shl( W_mult0_32_32( mod_b, mod_b ), sub( 32, Q_b ) ) ); // Q_b

    p2 = L_shl( -408505077 /* -0.7609f in Q29 */, sub( Q_b, 31 ) ); // Qb-2
    p1 = L_shl( 1444612250 /* 2.6908f in Q29 */, sub( Q_b, 31 ) );  // Qb-2
    p0 = L_shl( 385258566 /* 0.7176f in Q29 */, sub( Q_b, 31 ) );   // Qb-2

    p2 = Madd_32_32( Madd_32_32( p2, 501759554 /* 0.9346f in Q29*/, mod_b ), -252060893 /* -0.4695f in Q29 */, b_sqr );   // Q_b-2
    p1 = Madd_32_32( Madd_32_32( p1, -1774680487 /* -3.3056f in Q29 */, mod_b ), 891635211 /* 1.6608f in Q29 */, b_sqr ); // Q_b-2
    p0 = Madd_32_32( Madd_32_32( p0, -473251709 /* -0.8815f in Q29 */, mod_b ), 237780127 /* 0.4429f in Q29 */, b_sqr );  // Q_b-2

    /* approx = p0 + p1 * mod_a + p2 * mod_a * mod_a; */
    approx = Madd_32_32( Mpy_32_32( p1, mod_a ), p2, a_sqr ); // Q_a+Q_b-33
    approx = L_add( approx, L_shl( p0, sub( Q_a, 31 ) ) );    // Q_a+Q_b-33

    exp = sub( norm_l( approx ), 1 );
    approx = L_shl( approx, exp ); // // Q_a+Q_b-33+exp

    *q_out = sub( add( sub( add( Q_a, Q_b ), 33 ), exp ), shift );
    move16();

    return approx;
}

/*===================================================================*/
/* FUNCTION      :  fir_fx ()                     */
/*-------------------------------------------------------------------*/
Loading