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

Merge branch '3gpp_issue_1192_fix' into 'main'

Fix for 3GPP issue 1192: Energy bursts in BWE region for MDCT-stereo @80kbps FB

See merge request !996
parents d68c8f84 f694d57b
Loading
Loading
Loading
Loading
Loading
+45 −29
Original line number Diff line number Diff line
@@ -154,7 +154,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_spec, tmp_s;
    Word16 q_powSpec[MCT_MAX_CHANNELS], 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;
@@ -189,8 +189,10 @@ void stereo_mdct_core_enc_fx(
        orig_spectrum_fx[ch][1] = orig_spectrum_long_fx[ch] + N_TCX10_MAX;
    }

    set16_fx( tmp_q_powSpecInv, 63, L_FRAME48k );
    set16_fx( tmp_q_powSpec, 63, L_FRAME48k );
    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;
    tmp_q_psi[1] = &tmp_q_powSpecInv[N_TCX10_MAX];
@@ -416,7 +418,7 @@ void stereo_mdct_core_enc_fx(
                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 = sub( W_norm( W_tmp ), 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
@@ -424,7 +426,7 @@ void stereo_mdct_core_enc_fx(
                    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 = sub( W_norm( W_tmp ), 1 );
                    tmp_s = W_norm( W_tmp );
                    W_tmp = W_shl( W_tmp, tmp_s );                                     /* 2*q_spec+1+tmp_s */
                    powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp );                /* 2*q_spec+1+tmp_s-32 */
                    tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
@@ -438,7 +440,7 @@ void stereo_mdct_core_enc_fx(
                {
                    /* power spectrum: MDCT^2 + MDST^2 */
                    W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][0], inv_spectrum_fx[ch][n][0] ); /* 2*q_spec+1 */
                    tmp_s = sub( W_norm( W_tmp ), 1 );
                    tmp_s = W_norm( W_tmp );
                    W_tmp = W_shl( W_tmp, tmp_s );                                     /* 2*q_spec+1+tmp_s */
                    powerSpecMsInv_fx[ch][n][0] = W_extract_h( W_tmp );                /* 2*q_spec+1+tmp_s-32 */
                    tmp_q_psi[n][0] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
@@ -450,7 +452,7 @@ void stereo_mdct_core_enc_fx(
                        Word32 mdst_fx = L_sub( inv_spectrum_fx[ch][n][i + 1], inv_spectrum_fx[ch][n][i - 1] ); /* An MDST estimate q_spec*/

                        W_tmp = W_mac_32_32( W_mult_32_32( mdst_fx, mdst_fx ), inv_spectrum_fx[ch][n][i], inv_spectrum_fx[ch][n][i] ); /* 2*q_spec+1 */
                        tmp_s = sub( W_norm( W_tmp ), 1 );
                        tmp_s = W_norm( W_tmp );
                        W_tmp = W_shl( W_tmp, tmp_s );                                     /* 2*q_spec+1+tmp_s */
                        powerSpecMsInv_fx[ch][n][i] = W_extract_h( W_tmp );                /* 2*q_spec+1+tmp_s-32 */
                        tmp_q_psi[n][i] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
@@ -459,7 +461,7 @@ void stereo_mdct_core_enc_fx(
                    }

                    W_tmp = W_mult_32_32( inv_spectrum_fx[ch][n][L_subframeTCX - 1], inv_spectrum_fx[ch][n][L_subframeTCX - 1] ); /* 2*q_spec+1 */
                    tmp_s = sub( W_norm( W_tmp ), 1 );
                    tmp_s = W_norm( W_tmp );
                    W_tmp = W_shl( W_tmp, tmp_s );                                                     /* 2*q_spec+1+tmp_s */
                    powerSpecMsInv_fx[ch][n][L_subframeTCX - 1] = W_extract_h( W_tmp );                /* 2*q_spec+1+tmp_s-32 */
                    tmp_q_psi[n][L_subframeTCX - 1] = sub( add( imult1616( q_spec, 2 ), tmp_s ), 31 ); // Q = 2 * q_spec + 1 + tmp_s - 32
@@ -469,7 +471,7 @@ 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 = sub( W_norm( W_tmp ), 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
@@ -481,7 +483,7 @@ void stereo_mdct_core_enc_fx(
                    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 = sub( W_norm( W_tmp ), 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
@@ -490,7 +492,7 @@ void stereo_mdct_core_enc_fx(
                }

                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 = sub( W_norm( W_tmp ), 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
@@ -501,30 +503,36 @@ void stereo_mdct_core_enc_fx(

        /* 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 )
                IF( powerSpec_fx[ch][i] != 0 )
                {
                    tmp_q_powSpec[i] = 63;
                    q_powSpec[ch] = s_min( q_powSpec[ch], tmp_q_powSpec[i] );
                    move16();
                }
                if ( powerSpecMsInv_fx[ch][0][i] == 0 )
            }
            FOR( n = 0; n < nSubframes; n++ )
            {
                FOR( i = 0; i < L_subframeTCX; i++ )
                {
                    IF( powerSpecMsInv_fx[ch][n][i] != 0 )
                    {
                    tmp_q_powSpecInv[i] = 63;
                        q_powSpecMsInv[ch] = s_min( q_powSpecMsInv[ch], tmp_q_psi[n][i] );
                        move16();
                    }
                }
            minimum_s( tmp_q_powSpec, N_MAX, &q_powSpec[ch] );
            minimum_s( tmp_q_powSpecInv, N_MAX, &tmp_s );
            q_powSpec[ch] = s_min( q_powSpec[ch], tmp_s );
            move16();
            }

            FOR( n = 0; n < nSubframes; n++ )
            {
                FOR( i = 0; i < L_subframeTCX; i++ )
                {
                    powerSpecMsInv_fx[ch][n][i] = L_shr( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpec[ch] ) );                                          /* q_powSpec */
                    powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )] = L_shr( powerSpec_fx[ch][( i + ( n * L_subframeTCX ) )], sub( tmp_q_powSpec[i], q_powSpec[ch] ) ); /* q_powSpec */
                    powerSpecMsInv_fx[ch][n][i] = L_shr_sat( powerSpecMsInv_fx[ch][n][i], sub( tmp_q_psi[n][i], q_powSpecMsInv[ch] ) );
                    powerSpec_fx[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();
                }
@@ -603,6 +611,7 @@ void stereo_mdct_core_enc_fx(
                    FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
                    {
                        q_spec = sub( Q31, sts[ch]->hTcxEnc->spectrum_e[n] );
                        Word16 q_comm = s_min( sub( Q31, sts[ch]->hTcxEnc->spectrum_e[n] ), s_min( q_powSpec[ch], q_powSpecMsInv[ch] ) );
                        Word16 n_sb = NB_DIV;
                        move16();
                        if ( EQ_16( sts[ch]->hTcxEnc->tcxMode, TCX_20 ) )
@@ -611,17 +620,24 @@ void stereo_mdct_core_enc_fx(
                            move16();
                        }
                        length = idiv1616( sts[ch]->hTcxEnc->L_frameTCX, n_sb ); /* Q0 */
                        IF( GT_16( q_spec, q_powSpec[ch] ) )
                        IF( NE_16( q_spec, q_comm ) )
                        {
                            Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[n], length, sub( q_powSpec[ch], q_spec ) ); /* q_powSpec */
                            Scale_sig32( inv_spectrum_fx[ch][n], length, sub( q_powSpec[ch], q_spec ) );           /* q_powSpec */
                            sts[ch]->hTcxEnc->spectrum_e[n] = sub( Q31, q_powSpec[ch] );
                            Scale_sig32( sts[ch]->hTcxEnc->spectrum_fx[n], length, sub( q_comm, q_spec ) ); /* q_powSpec */
                            Scale_sig32( inv_spectrum_fx[ch][n], length, sub( q_comm, q_spec ) );           /* q_powSpec */
                            sts[ch]->hTcxEnc->spectrum_e[n] = sub( Q31, q_comm );
                            move16();
                        }
                        ELSE
                        IF( NE_16( q_powSpec[ch], q_comm ) )
                        {
                            Scale_sig32( &p_powerSpec_fx[ch][0], L_subframeTCX, sub( q_spec, q_powSpec[ch] ) );   /* q_spec */
                            Scale_sig32( powerSpecMsInv_fx[ch][0], L_subframeTCX, sub( q_spec, q_powSpec[ch] ) ); /* q_spec */
                            Scale_sig32( &p_powerSpec_fx[ch][0], L_subframeTCX, sub( q_comm, q_powSpec[ch] ) ); /* q_spec */
                            q_powSpec[ch] = q_comm;
                            move16();
                        }
                        IF( NE_16( q_powSpecMsInv[ch], q_comm ) )
                        {
                            Scale_sig32( powerSpecMsInv_fx[ch][0], L_subframeTCX, sub( q_comm, q_powSpecMsInv[ch] ) ); /* q_spec */
                            q_powSpecMsInv[ch] = q_comm;
                            move16();
                        }
                    }
                    hIGFEnc[0]->spec_be_igf_e = p_orig_spectrum_e[0];