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

Merge branch '3gpp_issue_1313_fix_1' into 'main'

Fix for 3GPP issue 1313: Multi-frame attenuation for MDCT-stereo 48kbps with input +10dB [allow regression]

See merge request !1209
parents cf120d13 f3a52497
Loading
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -1639,8 +1639,8 @@ static void ivas_param_mc_transient_detection_fx(
    push_wmops( "param_mc_trn_det" );

    attackRatioThreshold_fx = hTranDet->transientDetector.attackRatioThreshold;
    pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay];       // Q0
    pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q0
    pSubblockNrg_fx = &hTranDet->subblockEnergies.subblockNrg[hParamMC->transient_detector_delay];       // Q(-1)
    pAccSubblockNrg_fx = &hTranDet->subblockEnergies.accSubblockNrg[hParamMC->transient_detector_delay]; // Q(-1)

    bIsAttackPresent = FALSE;
    move16();
@@ -1651,8 +1651,8 @@ static void ivas_param_mc_transient_detection_fx(
     * if we had an attack very late in the last frame,
     * make the current frame also a transient one... */
    test();
    IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 31, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) ||
        EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 31, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) )
    IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-1], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-1], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ||
        EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[-2], 32, Mpy_32_16_1( pAccSubblockNrg_fx[-2], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) )
    {
        bIsAttackPresent = TRUE;
        move16();
@@ -1661,7 +1661,7 @@ static void ivas_param_mc_transient_detection_fx(
    }

    FOR( i = 0; i < NSUBBLOCKS; i++ ){
        IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 31, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 31 + ATTACKTHRESHOLD_E ) ), 1 ) ){
        IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg_fx[i], 32, Mpy_32_16_1( pAccSubblockNrg_fx[i], attackRatioThreshold_fx ), ( 32 + ATTACKTHRESHOLD_E ) ), 1 ) ){
            bIsAttackPresent = TRUE;
    move16();
    attackIndex = i;
+4 −4
Original line number Diff line number Diff line
@@ -53,13 +53,13 @@ static void sync_tcx_mode_fx(
    Encoder_State **st /* i/o: Encoder state */
)
{
    const Word32 prevAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[st[0]->hTranDet->subblockEnergies.nDelay]; /* Q0 */
    const Word32 prevAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[st[0]->hTranDet->subblockEnergies.nDelay]; /* Q(-1) */
    move32();
    const Word32 prevAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[st[1]->hTranDet->subblockEnergies.nDelay]; /* Q0 */
    const Word32 prevAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[st[1]->hTranDet->subblockEnergies.nDelay]; /* Q(-1) */
    move32();
    const Word32 lastAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[( st[0]->hTranDet->subblockEnergies.nDelay + st[0]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q0 */
    const Word32 lastAccNrg0 = st[0]->hTranDet->subblockEnergies.accSubblockNrg[( st[0]->hTranDet->subblockEnergies.nDelay + st[0]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q(-1) */
    move32();
    const Word32 lastAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[( st[1]->hTranDet->subblockEnergies.nDelay + st[1]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q0 */
    const Word32 lastAccNrg1 = st[1]->hTranDet->subblockEnergies.accSubblockNrg[( st[1]->hTranDet->subblockEnergies.nDelay + st[1]->hTranDet->transientDetector.nSubblocksToCheck )]; /* Q(-1) */
    move32();

    test();
+2 −2
Original line number Diff line number Diff line
@@ -138,8 +138,8 @@ typedef struct
typedef struct
{
    DelayBuffer *pDelayBuffer;                                                                     /* Delay buffer. */
    Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY];                                                 // IVAS Q0
    Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1];                                          // IVAS Q0
    Word32 subblockNrg[NSUBBLOCKS + MAX_TD_DELAY];                                                 // IVAS Q(-1)
    Word32 accSubblockNrg[NSUBBLOCKS + MAX_TD_DELAY + 1];                                          // IVAS Q(-1)
    Word16 subblockNrgChange[NSUBBLOCKS + MAX_TD_DELAY]; /* EVS: Q7(15 - SUBBLOCK_NRG_CHANGE_E) */ /* IVAS: Q3 */
    int16_t nDelay;                                                                                /* Size of the delay buffer in use, as number of subblocks. Maximum delay from all users of this buffer. */
    int16_t nPartialDelay;                                                                         /* Delay of the input (modulo pDelayBuffer->nSubblockSize), nPartialDelay <= pDelayBuffer->nDelay. */
+19 −29
Original line number Diff line number Diff line
@@ -726,7 +726,7 @@ void RunTransientDetection_ivas_fx(
    e0_fx = dotp_fx( filteredInput_fx + /* length / 2 */ shr( length, 1 ), filteredInput_fx + /* length / 2 */ shr( length, 1 ), shr( pSubblockEnergies->pDelayBuffer->nSubblockSize, 1 ) /* pSubblockEnergies->pDelayBuffer->nSubblockSize / 2 */, &exp );
    exp = sub( exp, 2 * 0 - 1 ); // Q = 2*0 + (30-exp), E = 31 - (2*0 + 30 - exp) = 1 + exp - 2*0 = exp - (2*0-1)
    e0_fx = BASOP_Util_Add_Mant32Exp( MIN_BLOCK_ENERGY_IVAS_FX_Q7 / 2, 31 - Q7, e0_fx, exp, &exp );
    e1_fx = BASOP_Util_Add_Mant32Exp( pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4], 31 - 0, L_negate( e0_fx ), exp, &exp1 );
    e1_fx = BASOP_Util_Add_Mant32Exp( pSubblockEnergies->subblockNrg[pSubblockEnergies->nDelay + 4], 32, L_negate( e0_fx ), exp, &exp1 );
    IF( BASOP_Util_Cmp_Mant32Exp( e1_fx, exp1, e0_fx, exp ) > 0 )
    {
        pSubblockEnergies->ramp_up_flag = (UWord16) L_or( pSubblockEnergies->ramp_up_flag, 0x0001 );
@@ -1122,8 +1122,8 @@ static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, De

    assert( ( pDelayBuffer != NULL ) && ( pSubblockEnergies != NULL ) && ( pDelayBuffer->nSubblockSize * NSUBBLOCKS == nFrameLength ) && ( pDelayBuffer->nSubblockSize > 0 ) );

    set32_fx( pSubblockEnergies->subblockNrg, 107 /* 107.37 in Q0 */, nMaxBuffSize );
    set32_fx( pSubblockEnergies->accSubblockNrg, 107 /* 107.37 in Q0 */, nMaxBuffSize + 1 );
    set32_fx( pSubblockEnergies->subblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize );
    set32_fx( pSubblockEnergies->accSubblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize + 1 );
    set16_fx( pSubblockEnergies->subblockNrgChange, ONE_IN_Q3, nMaxBuffSize );
    IF( nDelay != 0 )
    {
@@ -1495,9 +1495,9 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp
    Word16 *pSubblockNrgChange;
    Word32 *pAccSubblockTmp;
    Word16 nWindows;
    Word16 w, k, k2, tmp;
    Word16 w, k, k2;
    Word32 w0, w1;
    Word32 accu;
    Word64 accu;

    move16();
    pDelayBuffer = pSubblockEnergies->pDelayBuffer;
@@ -1522,45 +1522,35 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp
    IF( nWindows > 0 )
    {
        /* Process left over samples from the previous frame. */
        accu = 107; // 107.37f in Q0
        move32();
        assert( ( SUBBLOCK_NRG_E & 1 ) == 0 );
        accu = 215; // 107.37f in Q1
        move64();
        FOR( k = 0; k < nPartialDelay; k++ )
        {
            tmp = delayBuffer[k]; // Q0
            move16();
            accu = L_mac0( accu, tmp, tmp ); // Q0
            accu = W_mac_16_16( accu, delayBuffer[k], delayBuffer[k] ); // Q1
        }

        /* Process new samples in the 0. subblock. */
        w = sub( nSubblockSize, nPartialDelay );
        assert( ( SUBBLOCK_NRG_E & 1 ) == 0 );
        FOR( k = 0; k < w; k++ )
        FOR( k = 0; k < ( nSubblockSize - nPartialDelay ); k++ )
        {
            tmp = input[k]; // Q0
            move16();
            accu = L_mac0_sat( accu, tmp, tmp ); // Q0
            accu = W_mac_16_16( accu, input[k], input[k] ); // Q1
        }

        pSubblockNrg[0] = accu; // Q0
        pSubblockNrg[0] = W_shl_sat_l( accu, -2 ); // Q(-1)
        move32();
        /* Set accumulated subblock energy at this point. */
        UpdatedAndStoreAccWindowNrg( pSubblockNrg[0], pAccSubblockTmp, facAccSubblockNrg, &pAccSubblockNrg[0] );

        FOR( w = 1; w < nWindows; w++ )
        {
            accu = 107; // 107.37f in Q0
            move32();
            accu = 215; // 107.37f in Q1
            move64();
            /* Process new samples in the w. subblock. */
            k2 = add( k, nSubblockSize );
            assert( ( SUBBLOCK_NRG_E & 1 ) == 0 );
            FOR( ; k < k2; k++ )
            {
                tmp = input[k]; // Q0
                move16();
                accu = L_mac0_sat( accu, tmp, tmp ); // Q0
                accu = W_mac_16_16( accu, input[k], input[k] ); // Q1
            }
            pSubblockNrg[w] = accu; // Q0
            pSubblockNrg[w] = W_shl_sat_l( accu, -2 ); // Q(-1)
            move32();
            /* Set accumulated subblock energy at this point. */
            UpdatedAndStoreAccWindowNrg( pSubblockNrg[w], pAccSubblockTmp, facAccSubblockNrg, &pAccSubblockNrg[w] );
@@ -1743,7 +1733,7 @@ Word16 transient_analysis_ivas_fx(
    /*  Forward attack analysis */
    FOR( i = -2; i < 7; i++ )
    {
        IF( BASOP_Util_Cmp_Mant32Exp( hTranDet->subblockEnergies.subblockNrg[nRelativeDelay + i], 31, Mpy_32_16_1( hTranDet->subblockEnergies.accSubblockNrg[nRelativeDelay + i], thr_fwd_fx ), ( 31 + 4 ) ) > 0 )
        IF( BASOP_Util_Cmp_Mant32Exp( hTranDet->subblockEnergies.subblockNrg[nRelativeDelay + i], 32, Mpy_32_16_1( hTranDet->subblockEnergies.accSubblockNrg[nRelativeDelay + i], thr_fwd_fx ), ( 32 + 4 ) ) > 0 )
        {
            prel_force_td = s_or( prel_force_td, 0x0001 );
        }
@@ -1780,7 +1770,7 @@ Word16 transient_analysis_ivas_fx(

        /* -3 check */
        test();
        IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[1 + offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[1], thr_rev_fx ), ( 31 + 4 ) ) > 0 )
        IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[1 + offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[1], thr_rev_fx ), ( 32 + 4 ) ) > 0 )
        {
            prel_force_td = s_or( prel_force_td, 0x0002 );
            move16();
@@ -1788,10 +1778,10 @@ Word16 transient_analysis_ivas_fx(

        /* -4 check */
        test();
        IF( prel_force_td == 0 && BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[0], thr_rev_fx ), ( 31 + 4 ) ) > 0 )
        IF( prel_force_td == 0 && BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[0], thr_rev_fx ), ( 32 + 4 ) ) > 0 )
        {

            IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 31, Mpy_32_16_1( accSubblockNrgRev_fx[0], add( thr_rev_fx, THR_LOW_STEP_FX ) ), ( 31 + 4 ) ) > 0 )
            IF( BASOP_Util_Cmp_Mant32Exp( pSubblockNrg[offset], 32, Mpy_32_16_1( accSubblockNrgRev_fx[0], add( thr_rev_fx, THR_LOW_STEP_FX ) ), ( 32 + 4 ) ) > 0 )
            {
                prel_force_td = s_or( prel_force_td, 0x0004 );
            }