Commit 3f52fcd4 authored by Fabian Bauer's avatar Fabian Bauer
Browse files

add macro HARMONIZE_2508_GetAttackForTCXDecision and its code

parent 496d928d
Loading
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -103,6 +103,7 @@
#define HARMONIZE_DCT                                   /* VA: removal of duplicated DCT functions */
#define FIX_2489_HARMONIZE_FdCng_encodeSID              /* FhG: harmonize FdCng_encodeSID_fx() and FdCng_encodeSID_ivas_fx()  */
#define FIX_1527_CMR_BITRATE_IDX                        /* Fix for incorrect bitrate idx packed in rtp CMR E-byte */
#define HARMONIZE_2508_GetAttackForTCXDecision          /* FhG: harmonize GetAttackForTCXDecision derivates for evs/ivas  */

/* #################### End BE switches ################################## */

+4 −0
Original line number Diff line number Diff line
@@ -160,7 +160,11 @@ typedef struct


/* Attack detection function. */
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
typedef void ( *TCheckSubblocksForAttack_fx )( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex, Word16 element_mode );
#else
typedef void ( *TCheckSubblocksForAttack_fx )( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex );
#endif

/* Transient detector. */
typedef struct TransientDetector
+125 −20
Original line number Diff line number Diff line
@@ -50,7 +50,11 @@ static void UpdateDelayBuffer( Word16 const *input, const Word16 nSamplesAvailab
static void HighPassFilter_fx( Word16 const *input, const Word16 length, Word16 *pFirState1, Word16 *pFirState2, Word16 *output );
static void UpdateSubblockEnergies( Word16 const *input, const Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies );
static void CalculateSubblockEnergies( Word16 const *input, const Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies );
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
static void RunTransientDetector_fx( TransientDetector *pTransientDetector, Word16 element_mode );
#else
static void RunTransientDetector_fx( TransientDetector *pTransientDetector );
#endif
static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, const Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies );
static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, const Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies );

@@ -60,12 +64,12 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, const Word16 nS
/*  Functions that define transient detectors   */
/*                                              */
/************************************************/

/** TCX decision.
 * Check IF there is an attack in a subblock. Version FOR TCX Long/Short decision.
 * See TCheckSubblocksForAttack_fx FOR definition of parameters.
 * It is assumed that the delay of MDCT overlap was not taken into account, so that the last subblock corresponds to the newest input subblock.
 */
#ifndef HARMONIZE_2508_GetAttackForTCXDecision
static void GetAttackForTCXDecision(
    Word32 const *pSubblockNrg,
    Word32 const *pAccSubblockNrg,
@@ -146,9 +150,11 @@ static void GetAttackForTCXDecision(

    return;
}
#endif


/* GetAttackForTCXDecision() version using 32-bit for energy change values */
#ifndef HARMONIZE_2508_GetAttackForTCXDecision
static void GetAttackForTCXDecision_ivas_fx(
    Word32 const *pSubblockNrg,
    Word32 const *pAccSubblockNrg,
@@ -157,11 +163,25 @@ static void GetAttackForTCXDecision_ivas_fx(
    Word16 attackRatioThreshold,
    Word16 *pbIsAttackPresent,
    Word16 *pAttackIndex )
#else
static void GetAttackForTCXDecision_fx(
    Word32 const *pSubblockNrg,
    Word32 const *pAccSubblockNrg,
    Word16 nSubblocks,
    Word16 nPastSubblocks,
    Word16 attackRatioThreshold,
    Word16 *pbIsAttackPresent,
    Word16 *pAttackIndex,
    Word16 element_mode )
#endif
{
    Word16 i;
    Word16 bIsAttackPresent, attackIndex;
    Word16 attackRatioThreshold_1_5;
    Word64 W_tmp1, W_tmp2, W_tmp3;
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
    Word32 L_tmp1, L_tmp2, L_tmp3;
#endif

    assert( nSubblocks >= NSUBBLOCKS );
    assert( nPastSubblocks >= 2 );
@@ -172,23 +192,53 @@ static void GetAttackForTCXDecision_ivas_fx(
    move16();
    move16();
    bIsAttackPresent = FALSE;
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
    attackIndex = EQ_16( element_mode, EVS_MONO ) ? 0 : -1;
#else
    attackIndex = -1;
#endif
    /* Search for the last attack in the subblocks */
    IF( s_or( (Word16) GT_32( L_shr( pSubblockNrg[-1], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-1], attackRatioThreshold ) ),
              L_sub( L_shr( pSubblockNrg[-2], ATTACKTHRESHOLD_E ), Mpy_32_16_1( pAccSubblockNrg[-2], attackRatioThreshold ) ) > 0 ) )
    {
        move16();
        bIsAttackPresent = TRUE;
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
        if ( GT_32( element_mode, EVS_MONO ) )
        {
            attackIndex = 0;
            move16();
        }
#else
        attackIndex = 0;
        move16();

#endif
    }

    FOR( i = 0; i < NSUBBLOCKS; i++ )
    {
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
        int condition;
        IF( EQ_16( element_mode, EVS_MONO ) )
        {
            L_tmp2 = L_shr( pSubblockNrg[i], ATTACKTHRESHOLD_E );
            L_tmp1 = Mpy_32_16_1( pAccSubblockNrg[i], attackRatioThreshold );
            condition = GT_32( L_tmp2, L_tmp1 );
        }
        ELSE
        {
            W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 );
            W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) );
            condition = GT_64( W_tmp1, W_tmp2 );
        }
        IF( condition )
#else
        W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 );
        W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) );

        IF( GT_64( W_tmp1, W_tmp2 ) )
#endif
        {
            if ( i < 6 )
            {
@@ -200,6 +250,10 @@ static void GetAttackForTCXDecision_ivas_fx(
            {
                move16();
                attackIndex = i;
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
                IF( GT_16( element_mode, EVS_MONO ) )
                {
#endif
                    W_tmp2 = W_shr( W_mult_32_16( pAccSubblockNrg[i], attackRatioThreshold ), 1 );
                    W_tmp2 = W_add( W_tmp2, W_shr( W_tmp2, 3 ) ); // pAccSubblockNrg[i] * 1.125f
                    W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) );
@@ -207,16 +261,33 @@ static void GetAttackForTCXDecision_ivas_fx(
                    {
                        attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */
                    }
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
                }
#endif
            }
        }
        ELSE /* no attack, but set index anyway in case of strong energy increase */
        {
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
            IF( EQ_16( element_mode, EVS_MONO ) )
            {
                L_tmp2 = Mpy_32_16_1( pSubblockNrg[i - 1], attackRatioThreshold_1_5 );
                L_tmp1 = L_shr( pSubblockNrg[i], 1 + ATTACKTHRESHOLD_E );
                L_tmp3 = Mpy_32_16_1( pSubblockNrg[i - 2], attackRatioThreshold_1_5 );
                condition = s_and( ( (Word16) GT_32( L_tmp1, L_tmp2 ) ), ( L_sub( L_tmp1, L_tmp3 ) > 0 ) );
            }
            ELSE
            {
#endif
                W_tmp2 = W_shr( W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold_1_5 ), 1 );
                W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ( ATTACKTHRESHOLD_E + 1 ) ) );
                W_tmp3 = W_shr( W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold_1_5 ), 1 );
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
                condition = s_and( ( (Word16) GT_64( W_tmp1, W_tmp2 ) ), ( W_sub( W_tmp1, W_tmp3 ) > 0 ) );
            }

            IF( s_and( ( (Word16) GT_64( W_tmp1, W_tmp2 ) ),
                       ( W_sub( W_tmp1, W_tmp3 ) > 0 ) ) )
            IF( condition )
#endif
            {

                IF( s_and( (Word16) NE_16( attackIndex, 2 ), (Word16) NE_16( attackIndex, 6 ) ) )
@@ -224,16 +295,22 @@ static void GetAttackForTCXDecision_ivas_fx(
                    move16();
                    attackIndex = i;

#ifdef HARMONIZE_2508_GetAttackForTCXDecision
                    IF( GT_32( element_mode, EVS_MONO ) )
                    {
#endif
                        W_tmp2 = W_mult_32_16( pSubblockNrg[i - 1], attackRatioThreshold );
                        W_tmp3 = W_mult_32_16( pSubblockNrg[i - 2], attackRatioThreshold );
                        W_tmp1 = W_shl( pSubblockNrg[i], ( 15 - ATTACKTHRESHOLD_E ) );

                    if ( s_and( (Word16) s_or( (Word16) LT_64( W_tmp1, W_tmp2 ), (Word16)
                                                                                     LT_64( W_tmp1, W_tmp3 ) ),
                        if ( s_and( (Word16) s_or( (Word16) LT_64( W_tmp1, W_tmp2 ), (Word16) LT_64( W_tmp1, W_tmp3 ) ),
                                    s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) )
                        {
                            attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */
                        }
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
                    }
#endif
                }
            }
        }
@@ -267,7 +344,11 @@ static void InitTCXTransientDetector(
    SubblockEnergies *pSubblockEnergies,
    TransientDetector *pTransientDetector )
{
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
    InitTransientDetector_fx( pSubblockEnergies, nDelay, NSUBBLOCKS, GetAttackForTCXDecision_fx, 17408 /*8.5f/(1<<ATTACKTHRESHOLD_E) Q15*/, pTransientDetector );
#else
    InitTransientDetector_fx( pSubblockEnergies, nDelay, NSUBBLOCKS, GetAttackForTCXDecision, 17408 /*8.5f/(1<<ATTACKTHRESHOLD_E) Q15*/, pTransientDetector );
#endif

    return;
}
@@ -316,7 +397,11 @@ void InitTransientDetection_ivas_fx(


    /* Init the TCX Short/Long transient detector. */
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
    InitTransientDetector_ivas_fx( &hTranDet->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision_fx, 17408 /*8.5f/(1<<ATTACKTHRESHOLD_E) Q15*/, &hTranDet->transientDetector );
#else
    InitTransientDetector_ivas_fx( &hTranDet->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision_ivas_fx, 17408 /*8.5f/(1<<ATTACKTHRESHOLD_E) Q15*/, &hTranDet->transientDetector );
#endif


    /* We need two past subblocks for the TCX TD and NSUBBLOCKS+1 for the temporal flatness measure FOR the TCX LTP. */
@@ -607,7 +692,11 @@ void RunTransientDetection_fx(
    UpdateSubblockEnergies( filteredInput, nSamplesAvailable, pSubblockEnergies );

    /* Run transient detectors. */
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
    RunTransientDetector_fx( pTransientDetector, EVS_MONO );
#else
    RunTransientDetector_fx( pTransientDetector );
#endif

    /* Update the delay buffer. */
    UpdateDelayBuffer( filteredInput, nSamplesAvailable, &hTranDet->delayBuffer );
@@ -678,7 +767,11 @@ void RunTransientDetection_ivas_fx(
    UpdateSubblockEnergies_ivas_fx( filteredInput_fx, length, pSubblockEnergies );

    /* Run transient detectors. */
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
    RunTransientDetector_fx( pTransientDetector, 1 );
#else
    RunTransientDetector_fx( pTransientDetector );
#endif

    /* Update the delay buffer. */
    UpdateDelayBuffer( filteredInput_fx, length, &hTranDet->delayBuffer );
@@ -1277,9 +1370,14 @@ static void HighPassFilter_fx(
    return;
}


#ifdef HARMONIZE_2508_GetAttackForTCXDecision
static void RunTransientDetector_fx(
    TransientDetector *pTransientDetector,
    Word16 element_mode)
#else
static void RunTransientDetector_fx(
    TransientDetector *pTransientDetector )
#endif
{
    Word16 const attackRatioThreshold = pTransientDetector->attackRatioThreshold;
    move16();
@@ -1294,10 +1392,17 @@ static void RunTransientDetector_fx(
    assert( ( pTransientDetector->CheckSubblocksForAttack_fx != NULL ) );

#define WMC_TOOL_SKIP
#ifdef HARMONIZE_2508_GetAttackForTCXDecision
    pTransientDetector->CheckSubblocksForAttack_fx( pSubblockNrg, pAccSubblockNrg,
                                                    NSUBBLOCKS + nDelay, nRelativeDelay,
                                                    attackRatioThreshold,
                                                    &pTransientDetector->bIsAttackPresent, &pTransientDetector->attackIndex, element_mode );
#else
    pTransientDetector->CheckSubblocksForAttack_fx( pSubblockNrg, pAccSubblockNrg,
                                                    NSUBBLOCKS + nDelay, nRelativeDelay,
                                                    attackRatioThreshold,
                                                    &pTransientDetector->bIsAttackPresent, &pTransientDetector->attackIndex );
#endif
#undef WMC_TOOL_SKIP

    return;