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

Merge branch 'stereo_mdct_core_enc_updates' into 'main'

Updates in stereo_mdct_core_enc_fx for precision improvement [allow regression]

See merge request !1386
parents 8d9f712d 2d7c39d4
Loading
Loading
Loading
Loading
+0 −143
Original line number Diff line number Diff line
@@ -7555,146 +7555,3 @@ void rfft_fx(

    return;
}

Word16 find_guarded_bits_fx( Word32 n )
{
    // return n <= 1 ? 0 : n <= 2 ? 1
    //   : n <= 4 ? 2
    //   : n <= 8 ? 3
    //   : n <= 16 ? 4
    //   : n <= 32 ? 5
    //   : n <= 64 ? 6
    //   : n <= 128 ? 7
    //   : n <= 256 ? 8
    //   : n <= 512 ? 9
    //   : n <= 1024 ? 10
    //   : n <= 2048 ? 11
    //   : n <= 4096 ? 12
    //   : n <= 8192 ? 13
    //   : n <= 16384 ? 14
    //   : 15;
    /*Word16 val = 0;
    move32();
    test();
    WHILE( GT_32( n, L_shl( 1, val ) ) && LT_32( val, 16 ) )
    {
        val = add( val, 1 );
    }*/
    IF( LE_32( n, 1 ) )
    {
        return 0;
    }
    ELSE
    {

        return sub( 31, norm_l( L_sub( n, 1 ) ) );
    }
}

Word16 L_norm_arr( const Word32 *arr, Word16 size )
{
    Word16 q = 31;
    move16();
    FOR( Word16 i = 0; i < size; i++ )
    {
        Word16 q_tst;

        q_tst = norm_l( arr[i] );
        if ( arr[i] != 0 )
        {
            q = s_min( q, q_tst );
        }
    }

    return q;
}

Word16 norm_arr( Word16 *arr, Word16 size )
{
    Word16 q = 15;
    Word16 exp = 0;
    move16();
    move16();
    FOR( Word16 i = 0; i < size; i++ )
    {
        if ( arr[i] != 0 )
        {
            exp = norm_s( arr[i] );
        }
        if ( arr[i] != 0 )
        {
            q = s_min( q, exp );
        }
    }
    return q;
}

Word16 W_norm_arr( Word64 *arr, Word16 size )
{
    Word16 q = 63;
    Word16 exp = 0;
    move16();
    move16();
    FOR( Word16 i = 0; i < size; i++ )
    {
        if ( arr[i] != 0 )
        {
            exp = W_norm( arr[i] );
        }
        if ( arr[i] != 0 )
        {
            q = s_min( q, exp );
        }
    }
    return q;
}

Word16 get_min_scalefactor( Word32 x, Word32 y )
{
    Word16 scf_y;
    Word16 scf = Q31;
    move16();

    test();
    if ( x == 0 && y == 0 )
    {
        scf = 0;
        move16();
    }

    if ( x != 0 )
    {
        scf = norm_l( x );
    }

    scf_y = norm_l( y );
    if ( y != 0 )
    {
        scf = s_min( scf_y, scf );
    }

    return scf;
}


Flag is_zero_arr( Word32 *arr, Word16 size )
{
    FOR( Word16 i = 0; i < size; i++ )
    IF( arr[i] != 0 )
    {
        return 0;
    }

    return 1;
}

Flag is_zero_arr16( Word16 *arr, Word16 size )
{
    FOR( Word16 i = 0; i < size; i++ )
    IF( arr[i] != 0 )
    {
        return 0;
    }

    return 1;
}
+7 −0
Original line number Diff line number Diff line
@@ -1444,6 +1444,13 @@ void scale_sig32(
    const Word16 lg,  /* i  : size of x[]                     Q0        */
    const Word16 exp0 /* i  : exponent: x = round(x << exp)   Qx xx exp  */
);
void Scale_sig64(
    Word64 x[], /* i/o: signal to scale                 Qx        */
    Word16 len, /* i  : size of x[]                     Q0        */
    Word16 exp  /* i  : exponent: x = round(x << exp)   Qx  exp   */
);
void scale_sig32_r(
    Word32 x[],       /* i/o: signal to scale                 Qx        */
    const Word16 lg,  /* i  : size of x[]                     Q0        */
+164 −0
Original line number Diff line number Diff line
@@ -4526,3 +4526,167 @@ void v_add_fixed_me(

    return;
}

Word16 find_guarded_bits_fx( Word32 n )
{
    // return n <= 1 ? 0 : n <= 2 ? 1
    //   : n <= 4 ? 2
    //   : n <= 8 ? 3
    //   : n <= 16 ? 4
    //   : n <= 32 ? 5
    //   : n <= 64 ? 6
    //   : n <= 128 ? 7
    //   : n <= 256 ? 8
    //   : n <= 512 ? 9
    //   : n <= 1024 ? 10
    //   : n <= 2048 ? 11
    //   : n <= 4096 ? 12
    //   : n <= 8192 ? 13
    //   : n <= 16384 ? 14
    //   : 15;
    /*Word16 val = 0;
    move32();
    test();
    WHILE( GT_32( n, L_shl( 1, val ) ) && LT_32( val, 16 ) )
    {
        val = add( val, 1 );
    }*/
    IF( LE_32( n, 1 ) )
    {
        return 0;
    }
    ELSE
    {

        return sub( 31, norm_l( L_sub( n, 1 ) ) );
    }
}

Word16 L_norm_arr( const Word32 *arr, Word16 size )
{
    Word16 q = 31;
    move16();
    FOR( Word16 i = 0; i < size; i++ )
    {
        Word16 q_tst;

        q_tst = norm_l( arr[i] );
        if ( arr[i] != 0 )
        {
            q = s_min( q, q_tst );
        }
    }

    return q;
}

Word16 norm_arr( Word16 *arr, Word16 size )
{
    Word16 q = 15;
    Word16 exp = 0;
    move16();
    move16();
    FOR( Word16 i = 0; i < size; i++ )
    {
        if ( arr[i] != 0 )
        {
            exp = norm_s( arr[i] );
        }
        if ( arr[i] != 0 )
        {
            q = s_min( q, exp );
        }
    }
    return q;
}

Word16 W_norm_arr( Word64 *arr, Word16 size )
{
    Word16 q = 63;
    Word16 exp = 0;
    move16();
    move16();
    FOR( Word16 i = 0; i < size; i++ )
    {
        if ( arr[i] != 0 )
        {
            exp = W_norm( arr[i] );
        }
        if ( arr[i] != 0 )
        {
            q = s_min( q, exp );
        }
    }
    return q;
}

Word16 get_min_scalefactor( Word32 x, Word32 y )
{
    Word16 scf_y;
    Word16 scf = Q31;
    move16();

    test();
    if ( x == 0 && y == 0 )
    {
        scf = 0;
        move16();
    }

    if ( x != 0 )
    {
        scf = norm_l( x );
    }

    scf_y = norm_l( y );
    if ( y != 0 )
    {
        scf = s_min( scf_y, scf );
    }

    return scf;
}


Flag is_zero_arr( Word32 *arr, Word16 size )
{
    FOR( Word16 i = 0; i < size; i++ )
    IF( arr[i] != 0 )
    {
        return 0;
    }

    return 1;
}

Flag is_zero_arr16( Word16 *arr, Word16 size )
{
    FOR( Word16 i = 0; i < size; i++ )
    IF( arr[i] != 0 )
    {
        return 0;
    }

    return 1;
}

void Scale_sig64(
    Word64 x[], /* i/o: signal to scale                 Qx        */
    Word16 len, /* i  : size of x[]                     Q0        */
    Word16 exp  /* i  : exponent: x = round(x << exp)   Qx exp    */
)
{
    Word16 i;
    assert( exp <= 63 && exp >= -63 );
    IF( exp == 0 )
    {
        return;
    }

    FOR( i = 0; i < len; i++ )
    {
        /* saturation can occur here */
        x[i] = W_shl( x[i], exp );
        move64();
    }
}
+148 −62
Original line number Diff line number Diff line
@@ -135,10 +135,8 @@ void stereo_mdct_core_enc_fx(
{
    Word32 orig_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* MDCT output (L/R). */
    Word32 *orig_spectrum_fx[CPE_CHANNELS][NB_DIV];    /* Pointers to MDCT output for a short block (L/R) */
    Word32 powerSpec_fx[CPE_CHANNELS][N_MAX];
    Word32 powerSpec_fx_tmp[CPE_CHANNELS][N_MAX]; /* This 32 bit buffer is created to preserve the precision for original separate Q calculation of powerSpec_fx buffer ( Related to 3gpp issue #1192 ) */
    Word32 *p_powerSpec_fx[CPE_CHANNELS];
    Word16 exp_powerSpec[CPE_CHANNELS][N_MAX + L_MDCT_OVLP_MAX];
    Word64 powerSpec64[CPE_CHANNELS][N_MAX];
    Word16 exp_powerSpec64[CPE_CHANNELS][NB_DIV];
    Word32 powerSpecMsInv_long_fx[CPE_CHANNELS][N_MAX]; /* MS inv power spectrum, also inverse MDST spectrum */
    Word32 *powerSpecMsInv_fx[CPE_CHANNELS][NB_DIV];
    Word32 quantized_spectrum_long_fx[CPE_CHANNELS][N_MAX]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */
@@ -153,7 +151,7 @@ void stereo_mdct_core_enc_fx(
    Word32 *p_mdst_spectrum_long_fx[CPE_CHANNELS];
    Word32 mdst_spectrum_long_fx[CPE_CHANNELS][N_MAX];
    Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV];
    Word16 q_powSpec[MCT_MAX_CHANNELS], q_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s;
    Word16 q_powSpecMsInv[MCT_MAX_CHANNELS], q_spec, tmp_s;
    Word16 tmp_q_powSpec[N_MAX], tmp_q_powSpecInv[N_MAX], *tmp_q_psi[2];
    Word64 W_tmp;
    Encoder_State *st, **sts;
@@ -184,12 +182,11 @@ void stereo_mdct_core_enc_fx(
        p_orig_spectrum_long_fx[ch] = orig_spectrum_long_fx[ch];
        orig_spectrum_fx[ch][0] = orig_spectrum_long_fx[ch];
        orig_spectrum_fx[ch][1] = orig_spectrum_long_fx[ch] + N_TCX10_MAX;
        set16_fx( exp_powerSpec[ch], 0, N_MAX + L_MDCT_OVLP_MAX );
        set16_fx( exp_powerSpec64[ch], 0, NB_DIV );
    }

    set16_fx( tmp_q_powSpecInv, 63, N_MAX );
    set16_fx( tmp_q_powSpec, 63, N_MAX );
    set16_fx( q_powSpec, 31, MCT_MAX_CHANNELS );
    set16_fx( q_powSpecMsInv, 31, MCT_MAX_CHANNELS );

    tmp_q_psi[0] = tmp_q_powSpecInv;
@@ -264,11 +261,10 @@ void stereo_mdct_core_enc_fx(
        inv_spectrum_fx[ch][1] = quantized_spectrum_fx[ch][1];
        mdst_spectrum_fx[ch][0] = mdst_spectrum_long_fx[ch];
        mdst_spectrum_fx[ch][1] = mdst_spectrum_long_fx[ch] + N_TCX10_MAX;
        set64_fx( powerSpec64[ch], 0, N_MAX );
        set32_fx( powerSpecMsInv_long_fx[ch], 0, N_MAX );
        set32_fx( quantized_spectrum_long_fx[ch], 0, N_MAX );
        set32_fx( mdst_spectrum_long_fx[ch], 0, N_MAX );
        set32_fx( powerSpec_fx[ch], 0, N_MAX );
        set32_fx( powerSpec_fx_tmp[ch], 0, N_MAX );
        set32_fx( powerSpecMsInv_long_fx[ch], 0, N_MAX );
        sts[ch]->hTcxEnc->tns_ms_flag[0] = 0;
        move16();
@@ -383,7 +379,7 @@ void stereo_mdct_core_enc_fx(
            }
        }

        q_spec = sub( add( hdrm_min, q_spec ), 2 ); /* 2 guard bits to avoid over-flows (1 for stereo_coder_tcx_fx and other for power spectrum calculation )*/
        q_spec = sub( add( hdrm_min, q_spec ), 1 ); /* 1 guard bit to avoid over-flows in stereo_coder_tcx_fx */

        FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
        {
@@ -407,7 +403,8 @@ void stereo_mdct_core_enc_fx(
    /*--------------------------------------------------------------*
     * Power spectrum calculation
     *---------------------------------------------------------------*/
    Word16 length;
    Word16 length, exp, shift1, shift2, norm;
    Word32 mdct, mdst;

    FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
    {
@@ -437,17 +434,13 @@ void stereo_mdct_core_enc_fx(

            IF( sts[ch]->hTcxEnc->tns_ms_flag[n] )
            {
                exp = add( s_max( mdst_spectrum_e[ch][n], sts[ch]->hTcxEnc->spectrum_e[n] ), 1 );
                shift1 = sub( mdst_spectrum_e[ch][n], exp );
                shift2 = sub( sts[ch]->hTcxEnc->spectrum_e[n], exp );

                /* power spectrum: MDCT^2 + MDST^2 */
                FOR( i = 0; i < L_subframeTCX; i++ )
                {
                    W_tmp = W_mac_32_32( W_mult_32_32( mdst_spectrum_fx[ch][n][i], mdst_spectrum_fx[ch][n][i] ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); /* 2*q_spec+1 */
                    tmp_s = W_norm( W_tmp );
                    W_tmp = W_shl( W_tmp, tmp_s );                                                                  /* 2*q_spec+1+tmp_s */
                    powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp );                         /* 2*q_spec+1+tmp_s-32 */
                    tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
                    move32();
                    move16();

                    W_tmp = W_mac_32_32( W_mult_32_32( inv_mdst_spectrum_fx[ch][n][i], inv_mdst_spectrum_fx[ch][n][i] ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); /* 2*q_spec+1 */
                    tmp_s = W_norm( W_tmp );
                    W_tmp = W_shl( W_tmp, tmp_s );                                     /* 2*q_spec+1+tmp_s */
@@ -455,7 +448,14 @@ void stereo_mdct_core_enc_fx(
                    tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
                    move32();
                    move16();

                    mdst = L_shl( mdst_spectrum_fx[ch][n][i], shift1 );                                             // exp: exp
                    mdct = L_shl( sts[ch]->hTcxEnc->spectrum_fx[n][i], shift2 );                                    // exp: exp
                    powerSpec64[ch][i + n * L_subframeTCX] = W_mac_32_32( W_mult_32_32( mdct, mdct ), mdst, mdst ); // exp: 2*exp
                    move64();
                }
                exp_powerSpec64[ch][n] = shl( exp, 1 );
                move16();
            }
            ELSE
            {
@@ -493,53 +493,31 @@ void stereo_mdct_core_enc_fx(
                }

                /* power spectrum: MDCT^2 + MDST^2 */
                W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][0], sts[ch]->hTcxEnc->spectrum_fx[n][0] ); /* 2*q_spec+1 */
                tmp_s = W_norm( W_tmp );
                W_tmp = W_shl( W_tmp, tmp_s );                                                      /* 2*q_spec+1+tmp_s */
                powerSpec_fx[ch][n * L_subframeTCX] = W_extract_h( W_tmp );                         /* 2*q_spec+1+tmp_s-32 */
                tmp_q_powSpec[n * L_subframeTCX] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
                move32();
                move16();
                mdct = L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][0], 1 );          // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1
                powerSpec64[ch][n * L_subframeTCX] = W_mult_32_32( mdct, mdct ); // exp: 2(sts[ch]->hTcxEnc->spectrum_e[n]+1)
                move64();

                FOR( i = 1; i < L_subframeTCX - 1; i++ )
                {
                    Word32 mdst_fx = L_sub( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], sts[ch]->hTcxEnc->spectrum_fx[n][i - 1] ); /* An MDST estimate q_spec*/

                    W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), sts[ch]->hTcxEnc->spectrum_fx[n][i], sts[ch]->hTcxEnc->spectrum_fx[n][i] ); /* 2*q_spec+1 */
                    tmp_s = W_norm( W_tmp );
                    W_tmp = W_shl( W_tmp, tmp_s );                                                                  /* 2*q_spec+1+tmp_s */
                    powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp );                         /* 2*q_spec+1+tmp_s-32 */
                    tmp_q_powSpec[( i + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
                    move32();
                    move16();
                    mdct = L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i], 1 );                                                                   // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1
                    mdst = L_sub( L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i + 1], 1 ), L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][i - 1], 1 ) ); // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1
                    powerSpec64[ch][i + n * L_subframeTCX] = W_mac_32_32( W_mult_32_32( mdct, mdct ), mdst, mdst );                           // exp: 2(sts[ch]->hTcxEnc->spectrum_e[n]+1)
                    move64();
                }

                W_tmp = W_mult_32_32( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1] ); /* 2*q_spec+1 */
                tmp_s = W_norm( W_tmp );
                W_tmp = W_shl( W_tmp, tmp_s );                                                                                      /* 2*q_spec+1+tmp_s */
                powerSpec_fx[ch][( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = W_extract_h( W_tmp );                         /* 2*q_spec+1+tmp_s-32 */
                tmp_q_powSpec[( ( L_subframeTCX - 1 ) + ( n * L_subframeTCX ) )] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
                move32();
                mdct = L_shr( sts[ch]->hTcxEnc->spectrum_fx[n][L_subframeTCX - 1], 1 );              // exp: sts[ch]->hTcxEnc->spectrum_e[n]+1
                powerSpec64[ch][L_subframeTCX - 1 + n * L_subframeTCX] = W_mult_32_32( mdct, mdct ); // exp: 2(sts[ch]->hTcxEnc->spectrum_e[n]+1)
                move64();

                exp_powerSpec64[ch][n] = shl( add( sts[ch]->hTcxEnc->spectrum_e[n], 1 ), 1 );
                move16();
            }
        }

        /* Aligning the Q-factors */
        {
            q_powSpec[ch] = Q31;
            q_powSpecMsInv[ch] = Q31;
            move16();
            move16();
            FOR( i = 0; i < N_MAX; i++ )
            {
                IF( powerSpec_fx[ch][i] != 0 )
                {
                    q_powSpec[ch] = s_min( q_powSpec[ch], tmp_q_powSpec[i] );
                    move16();
                    exp_powerSpec[ch][i] = sub( Q31, tmp_q_powSpec[i] );
                    move16();
                }
            }
            FOR( n = 0; n < nSubframes; n++ )
            {
                FOR( i = 0; i < L_subframeTCX; i++ )
@@ -551,16 +529,11 @@ void stereo_mdct_core_enc_fx(
                    }
                }
            }

            FOR( n = 0; n < nSubframes; n++ )
            {
                FOR( i = 0; i < L_subframeTCX; i++ )
                {
                    powerSpecMsInv_fx[ch][n][i] = L_shr_sat( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpecMsInv[ch] ) );
                    /* Here precision is preserved for powerSpec_fx buffer by storing the fixed Q copy of same buffer in powerSpec_fx_tmp buffer */
                    /* powerSpec_fx implementation has separate Q for each index, powerSpec_fx_tmp has all indices in same Q beyond this point   */
                    powerSpec_fx_tmp[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i + ( n * L_subframeTCX )], q_powSpec[ch] ) ); /* q_powSpec */
                    move32();
                    move32();
                }
            }
@@ -596,8 +569,9 @@ void stereo_mdct_core_enc_fx(
             * and quantization (0: tonal, 1: noise-like).               *
             * Detect low pass if present.                               *
             *-----------------------------------------------------------*/
            ComputeSpectrumNoiseMeasure_fx( powerSpec_fx_tmp[ch], L_subframeTCX, i_mult( st->hTcxEnc->nmStartLine, idiv1616( L_subframeTCX, st->hTcxEnc->L_frameTCX ) ),
                                            NE_32( imult3216( st->last_sr_core, st->L_frame ), imult3216( st->sr_core, st->L_frame_past ) ) || NE_16( st->last_core, TCX_20_CORE ), st->hTcxEnc->memQuantZeros, L_subframeTCX );
            ComputeSpectrumNoiseMeasure_ivas_fx( powerSpec64[ch], L_subframeTCX, i_mult( st->hTcxEnc->nmStartLine, idiv1616( L_subframeTCX, st->hTcxEnc->L_frameTCX ) ),
                                                 NE_32( imult3216( st->last_sr_core, st->L_frame ), imult3216( st->sr_core, st->L_frame_past ) ) || NE_16( st->last_core, TCX_20_CORE ),
                                                 st->hTcxEnc->memQuantZeros, L_subframeTCX );
        }

        st->hTcxEnc->measuredBwRatio = ONE_IN_Q14; /* No bandwidth limit for the noise filling Q14*/
@@ -630,8 +604,48 @@ void stereo_mdct_core_enc_fx(
                IF( ( NE_16( hStereoMdct->mdct_stereo_mode[n], hStereoMdct->IGFStereoMode[n] ) || EQ_16( hStereoMdct->mdct_stereo_mode[n], SMDCT_BW_MS ) ) && !hStereoMdct->isSBAStereoMode )
                {
                    IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS];
                    p_powerSpec_fx[0] = powerSpec_fx_tmp[0];
                    p_powerSpec_fx[1] = powerSpec_fx_tmp[1];
                    Word32 powerSpec_fx[CPE_CHANNELS][N_MAX], *p_powerSpec_fx[CPE_CHANNELS];
                    Word16 q_powSpec[CPE_CHANNELS];
                    p_powerSpec_fx[0] = powerSpec_fx[0];
                    p_powerSpec_fx[1] = powerSpec_fx[1];
                    {
                        /* Copy powerSpec values from 64 bit buffer to 32 bit buffer */
                        FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
                        {
                            Word16 n1, nsub = 1;
                            length = sts[ch]->hTcxEnc->L_frameTCX;
                            move16();
                            move16();
                            IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
                            {
                                length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 );
                                nsub = NB_DIV;
                                move16();
                            }
                            IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) )
                            {
                                length = add( length, shr( length, 2 ) );
                            }
                            exp = sub( exp_powerSpec64[ch][0], W_norm_arr( powerSpec64[ch], length ) );
                            IF( EQ_16( nsub, 2 ) )
                            {
                                exp = s_max( exp, sub( exp_powerSpec64[ch][1], W_norm_arr( powerSpec64[ch] + length, length ) ) );
                            }
                            FOR( n1 = 0; n1 < nsub; n1++ )
                            {
                                shift1 = sub( sub( exp_powerSpec64[ch][n1], exp ), 32 );
                                FOR( i = 0; i < length; i++ )
                                {
                                    /* This doesn't result in saturation */
                                    powerSpec_fx[ch][i + n1 * length] = W_shl_sat_l( powerSpec64[ch][i + n1 * length], shift1 ); // exp: exp
                                    move32();
                                }
                            }
                            set32_fx( powerSpec_fx[ch] + length, 0, sub( N_MAX, length ) );
                            q_powSpec[ch] = sub( 31, exp ); // exp: exp
                            move16();
                        }
                    }
                    hIGFEnc[0] = sts[0]->hIGFEnc;
                    hIGFEnc[1] = sts[1]->hIGFEnc;

@@ -677,6 +691,42 @@ void stereo_mdct_core_enc_fx(
                }
                ELSE
                {
                    Word32 powerSpec_fx[CPE_CHANNELS][N_MAX]; // each value has a different exponent
                    Word16 exp_powerSpec[CPE_CHANNELS][N_MAX + L_MDCT_OVLP_MAX];
                    {
                        /* Copy powerSpec values from 64 bit buffer to 32 bit buffer */
                        FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
                        {
                            Word16 n1, nsub;
                            nsub = 1;
                            length = sts[ch]->hTcxEnc->L_frameTCX;
                            move16();
                            move16();
                            IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
                            {
                                length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 );
                                nsub = NB_DIV;
                                move16();
                            }
                            IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) )
                            {
                                length = add( length, shr( length, 2 ) );
                            }
                            FOR( n1 = 0; n1 < nsub; n1++ )
                            {
                                FOR( i = 0; i < length; i++ )
                                {
                                    norm = W_norm( powerSpec64[ch][i + n1 * length] );
                                    powerSpec_fx[ch][i + n1 * length] = W_extract_h( W_shl( powerSpec64[ch][i + n1 * length], norm ) ); // exp = exp_powerSpec64[ch][n1]-norm
                                    exp_powerSpec[ch][i + n1 * length] = sub( exp_powerSpec64[ch][n1], norm );
                                    move32();
                                    move16();
                                }
                            }
                            set32_fx( powerSpec_fx[ch] + length, 0, sub( N_MAX, length ) );
                            set16_fx( exp_powerSpec[ch] + length, 0, sub( N_MAX + L_MDCT_OVLP_MAX, length ) );
                        }
                    }
                    FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
                    {
                        st = sts[ch];
@@ -703,6 +753,42 @@ void stereo_mdct_core_enc_fx(
        }
        ELSE
        {
            Word32 powerSpec_fx[CPE_CHANNELS][N_MAX]; // each value has a different exponent
            Word16 exp_powerSpec[CPE_CHANNELS][N_MAX + L_MDCT_OVLP_MAX];
            {
                /* Copy powerSpec values from 64 bit buffer to 32 bit buffer */
                FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
                {
                    Word16 n1, nsub;
                    nsub = 1;
                    length = sts[ch]->hTcxEnc->L_frameTCX;
                    move16();
                    move16();
                    IF( NE_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
                    {
                        length = shr( sts[ch]->hTcxEnc->L_frameTCX, 1 );
                        nsub = NB_DIV;
                        move16();
                    }
                    IF( EQ_16( sts[ch]->last_core, ACELP_CORE ) )
                    {
                        length = add( length, shr( length, 2 ) );
                    }
                    FOR( n1 = 0; n1 < nsub; n1++ )
                    {
                        FOR( i = 0; i < length; i++ )
                        {
                            norm = W_norm( powerSpec64[ch][i + n1 * length] );
                            powerSpec_fx[ch][i + n1 * length] = W_extract_h( W_shl( powerSpec64[ch][i + n1 * length], norm ) ); // exp = exp_powerSpec64[ch][n1]-norm
                            exp_powerSpec[ch][i + n1 * length] = sub( exp_powerSpec64[ch][n1], norm );
                            move32();
                            move16();
                        }
                    }
                    set32_fx( powerSpec_fx[ch] + length, 0, sub( N_MAX, length ) );
                    set16_fx( exp_powerSpec[ch] + length, 0, sub( N_MAX + L_MDCT_OVLP_MAX, length ) );
                }
            }
            FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
            {
                st = sts[ch];
+8 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading