Commit 8670cb13 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Fix for 3GPP issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input

Link #1165
parent 78cb4903
Loading
Loading
Loading
Loading
Loading
+147 −0
Original line number Diff line number Diff line
@@ -631,6 +631,153 @@ Word16 lpc2lsp_fx(
    return ( 1 );
}

#ifdef FIX_ISSUE_1165
/*===================================================================*/
/* FUNCTION : lpc2lsp_ivas_fx () */
/*-------------------------------------------------------------------*/
/* PURPOSE : Convert LPC coefficients to LSP coefficients */
/*-------------------------------------------------------------------*/
/* INPUT ARGUMENTS : */
/* */
/* _ (Word32 []) a : LPC coefficients, Q27 */
/* _ (Word16 []) old_freq: Previous frame LSP coefficients, Q15 */
/* _ (Word16 []) order: LPC order */
/*-------------------------------------------------------------------*/
/* OUTPUT ARGUMENTS : */
/* _ (Word16 []) freq: LSP coefficients, Q15 */
/*-------------------------------------------------------------------*/
/* INPUT/OUTPUT ARGUMENTS : */
/* _ None */
/*-------------------------------------------------------------------*/
/* RETURN ARGUMENTS : */
/* _ (Word16) flag: 1 means all 10 LSPs are found, 0 otherwise */
/*===================================================================*/

/*NOTE: This function was created to avoid a crash that happens in the*/
/*      first for loop of this function while performing L_shl on a in*/
/*      lpc2lsp_fx, this computation assigns value to Lacc, which is  */
/*      kept in Q26 here to avoid L_shl when a has saturated value.   */
Word16 lpc2lsp_ivas_fx(
    Word32 *a,
    Word16 *freq,
    Word16 *old_freq,
    Word16 order )
{
    Word16 i;
    Word16 rt, low, high, prev_rt, rc;
    Word32 p[11], q[11]; /*  Q26 */
    Word32 Ltemp, v_low;
    Word32 Lacc;
    Word16 tfreq[21];

    /* First construct the P,Q polynomial */
    /* p[0] = q[0] = 1 */
    /* p[i] = -lpcCoeff[i] - lpcCoeff[11-i] - p[i-1] ( 1<=i<=5)*/
    /* q[i] = -lpcCoeff[i] + lpcCoeff[11-i] + q[i-1] ( 1<=i<=5)*/
    Ltemp = L_deposit_h( 0x400 ); /*  Ltemp is 1.0 in Q26 */

    p[0] = Ltemp;
    move32();
    q[0] = Ltemp;
    move32();

    FOR( i = 1; i < ( order / 2 ) + 1; i++ )
    {
        Lacc = L_shr( a[order - i], 1 );
        move32();                                   /* Q26 */
        Lacc = L_sub( Lacc, L_shr( a[i - 1], 1 ) ); /*  Lacc=-lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */
        q[i] = L_add( ( Lacc ), q[i - 1] );
        move32(); /* Q26 */

        Lacc = L_add( Lacc, a[i - 1] ); /*  Lacc=lpcCoeff[i-1] + lpcCoeff[order-i]//Q26 */

        p[i] = L_sub( L_negate( Lacc ), p[i - 1] );
        move32(); /* Q26 */
    }

    /* Search roots of the P and Q polynomials */

    v_low = polynomial_eval_fx( 0, p, order ); /* Q25 */
    move16();
    move16();
    move16();
    move16();
    low = 0;
    high = 8;
    prev_rt = 0;
    rc = 0; /*  root counter */
    FOR( i = 0; i < 32; i++ )
    {
        rt = root_search_fx( low, high, &v_low, p, order );
        low = high;
        move16();
        high = add( high, 8 );

        IF( GE_16( rt, prev_rt ) )
        {
            tfreq[rc] = rt;
            move16();
            rc = add( rc, 2 );
        }
        prev_rt = add( rt, 6 );
    } /*  End for P roots */

    tfreq[rc] = 0x3f80;
    move16(); /*  Set a high enough value as fake root for Q search */

    IF( LT_16( rc, order ) )
    {
        /*  lost P root */
        /* copy from previous LSP and return */
        FOR( i = 0; i < order; i++ )
        {
            move16();
            freq[i] = old_freq[i];
        }
        return ( 0 );
    }
    ELSE
    {
        /*  Search for Q roots between P roots */
        v_low = L_deposit_h( 0x800 ); /* Init a positive value for v_low */
        rc = 1;
        move16();
        FOR( i = 0; i < order / 2; i++ )
        {
            low = shr( tfreq[rc - 1], 6 );
            high = add( shr( tfreq[rc + 1], 6 ), 1 );
            rt = root_search_fx( low, high, &v_low, q, order );

            IF( rt < 0 )
            {
                /* No Q root in this interval */
                /* copy from previous LSP and return */
                FOR( i = 0; i < order; i++ )
                {
                    move16();
                    freq[i] = old_freq[i];
                }
                return ( 0 );
            }
            ELSE
            {
                move16();
                tfreq[rc] = rt;
                rc = add( rc, 2 );
            } /*  end else, find Q root */
        }     /*  end for */
    }         /* end else */

    FOR( i = 0; i < order; i++ )
    {
        freq[i] = tfreq[i];
        move16();
    }

    return ( 1 );
}
#endif

/*===================================================================*/
/* FUNCTION      :  lsp2lpc_fx ()                                    */
/*-------------------------------------------------------------------*/
+1 −0
Original line number Diff line number Diff line
@@ -122,4 +122,5 @@
#define FIX_1113_OPT_DIRAC_BIN_REND             /* FhG: Various optimizations to ivas_dirac_dec_binaual_functions.c */
#define FIX_ISSUE_1187                          /* Ittiam: Fix for issue 1187: Assertion error observed in evs_enc_fx (with option stereo_dmx_evs) from bass_pf_enc_fx function*/
#define FIX_ISSUE_1186                          /* Ittiam: Fix for Issue 1186: Energy/scaling issue for ISM-1 at all bitrates */
#define FIX_ISSUE_1165                          /* Ittiam: Fix for issue 1165: Assertion in lpc2lsp_fx for OMASA LTV input */
#endif
+8 −0
Original line number Diff line number Diff line
@@ -808,6 +808,14 @@ Word16 lpc2lsp_fx(
    Word16 *old_freq,
    Word16 order );
#ifdef FIX_ISSUE_1165
Word16 lpc2lsp_ivas_fx(
    Word32 *a,
    Word16 *freq,
    Word16 *old_freq,
    Word16 order );
#endif
void lsp2lpc_fx(
    Word16 *a,
    Word16 *freq,
+5 −1
Original line number Diff line number Diff line
@@ -1392,7 +1392,11 @@ void wb_tbe_enc_ivas_fx(
        move32();
    }

#ifdef FIX_ISSUE_1165
    lpc2lsp_ivas_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB );
#else
    lpc2lsp_fx( &lpc_wb_32_fx[1], lsp_wb_temp_fx, st_fx->prev_lsp_wb_temp_fx, LPC_SHB_ORDER_WB );
#endif

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