diff --git a/lib_com/options.h b/lib_com/options.h index 499a45afcaccdbf438b8eba5bbfc75c275211997..b3fcfadada0586b45cf97805c59c9a4396fda464 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -98,7 +98,7 @@ #define FIX_BASOP_2509_EVS_CONCEAL_UNINIT_MEM /* FhG: BASOP 2509: st->hTcxCfg->psychParamsCurrent is not initialized */ #define HARMONIZE_2499_CONFIGUREFDCNGDEC /* FhG: basop issue 2499: harmonoize configureFdCngDec */ #define FIX_BASOP_2530_IVAS_DECISION_MAT /* VA: Fix ambiguous usage of extract_l() */ - +#define HARMONIZE_2508_InitTransientDetection /* FhG: harmonize GetAttackForTCXDecision derivates for evs/ivas */ /* #################### End BE switches ################################## */ diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index a8315f55558aa9ebfa78fd07964e1f8314d41922..e47b7621f600edcb7e015104284d1027875515ef 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -1202,11 +1202,19 @@ ivas_error init_encoder_fx( IF( GT_16( st->element_mode, EVS_MONO ) ) { +#ifdef HARMONIZE_2508_InitTransientDetection + InitTransientDetection_fx( input_frame, 0, st->hTranDet, 1, 1 /* > EVS_MONO */ ); +#else InitTransientDetection_ivas_fx( input_frame, 0, st->hTranDet, 1 ); +#endif } ELSE { +#ifdef HARMONIZE_2508_InitTransientDetection + InitTransientDetection_fx( input_frame, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0, EVS_MONO ); +#else InitTransientDetection_fx( input_frame, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet ); +#endif } /*-----------------------------------------------------------------* diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 3f70a806c404163bdd887aa9a227ea571b9fea15..6abae475fdb0a99c9f0ff3c2f6fca0e60f331cfe 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -1195,8 +1195,11 @@ static ivas_error ivas_mc_enc_reconfig_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); } - +#ifdef HARMONIZE_2508_InitTransientDetection + InitTransientDetection_fx( extract_l( Mult_32_16( st->input_Fs, INV_FRAME_PER_SEC_Q15 ) ), NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0, st->element_mode ); +#else InitTransientDetection_ivas_fx( extract_l( Mult_32_16( st->input_Fs, INV_FRAME_PER_SEC_Q15 ) ), NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); +#endif } IF( st->hIGFEnc == NULL ) diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index d5987061021a9e1c325279704c598954de0e8c1b..7e4353573af2cb6108f591dbf2cd517bcd0b1312 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -878,6 +878,14 @@ void calculate_hangover_attenuation_gain_fx( * Don't include the delay of the MDCT overlap. * @param pTransientDetection Structure to be initialized. It contains all transient detectors to be used. */ +#ifdef HARMONIZE_2508_InitTransientDetection +void InitTransientDetection_fx( + const Word16 nFrameLength, + const Word16 nTCXDelay, + TRAN_DET_HANDLE hTranDet, + const Word16 ext_mem_flag, + Word16 element_mode ); +#else void InitTransientDetection_fx( const Word16 nFrameLength, const Word16 nTCXDelay, @@ -888,6 +896,7 @@ void InitTransientDetection_ivas_fx( const Word16 nTCXDelay, TRAN_DET_HANDLE hTranDet, const Word16 ext_mem_flag ); +#endif /** Runs transient detection. * Runs all transient detectors defined in pTransientDetection diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 2ee4a05f2d81af410b846214b414a897731adbbb..62e49a5a3c7ba873f8236560ea704ed0ba760af1 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -160,7 +160,11 @@ typedef struct /* Attack detection function. */ +#ifdef HARMONIZE_2508_InitTransientDetection +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 diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index f671b8d9eef275a7c27505c68bbdf9f21f422b5a..a413e8ac1ad691f8ae2bda7869cdf6916bff0faa 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -42,15 +42,21 @@ /************************************************/ static void InitDelayBuffer( const Word16 nFrameLength, const Word16 nDelay, DelayBuffer *pDelayBuffer ); +#ifdef HARMONIZE_2508_InitTransientDetection +static void InitSubblockEnergies_fx( const Word16 nFrameLength, const Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies, Word16 element_mode ); +static void InitTransientDetector_fx( SubblockEnergies *pSubblockEnergies, const Word16 nDelay, const Word16 nSubblocksToCheck, const TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, const Word16 attackRatioThreshold, TransientDetector *pTransientDetector, Word16 element_mode ); +static void RunTransientDetector_fx( TransientDetector *pTransientDetector, Word16 element_mode ); +#else static void InitSubblockEnergies( const Word16 nFrameLength, const Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ); static void InitSubblockEnergies_ivas_fx( const Word16 nFrameLength, const Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ); static void InitTransientDetector_fx( SubblockEnergies *pSubblockEnergies, const Word16 nDelay, const Word16 nSubblocksToCheck, const TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, const Word16 attackRatioThreshold, TransientDetector *pTransientDetector ); static void InitTransientDetector_ivas_fx( SubblockEnergies *pSubblockEnergies, const Word16 nDelay, const Word16 nSubblocksToCheck, const TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, const Word16 attackRatioThreshold, TransientDetector *pTransientDetector ); +static void RunTransientDetector_fx( TransientDetector *pTransientDetector ); +#endif static void UpdateDelayBuffer( Word16 const *input, const Word16 nSamplesAvailable, DelayBuffer *pDelayBuffer ); 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 ); -static void RunTransientDetector_fx( TransientDetector *pTransientDetector ); 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 ); @@ -66,6 +72,7 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, const Word16 nS * 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_InitTransientDetection static void GetAttackForTCXDecision( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, @@ -146,9 +153,11 @@ static void GetAttackForTCXDecision( return; } +#endif /* GetAttackForTCXDecision() version using 32-bit for energy change values */ +#ifndef HARMONIZE_2508_InitTransientDetection static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, @@ -157,11 +166,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_InitTransientDetection + Word32 L_tmp1, L_tmp2, L_tmp3; +#endif assert( nSubblocks >= NSUBBLOCKS ); assert( nPastSubblocks >= 2 ); @@ -172,23 +195,53 @@ static void GetAttackForTCXDecision_ivas_fx( move16(); move16(); bIsAttackPresent = FALSE; +#ifdef HARMONIZE_2508_InitTransientDetection + 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_InitTransientDetection + if ( GT_16( element_mode, EVS_MONO ) ) + { + attackIndex = 0; + move16(); + } +#else attackIndex = 0; move16(); + +#endif } FOR( i = 0; i < NSUBBLOCKS; i++ ) { +#ifdef HARMONIZE_2508_InitTransientDetection + Word16 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 = (Word16) 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 = (Word16) 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,23 +253,44 @@ static void GetAttackForTCXDecision_ivas_fx( { move16(); attackIndex = i; - 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 ) ); - if ( s_and( (Word16) LT_64( W_tmp1, W_tmp2 ), s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) +#ifdef HARMONIZE_2508_InitTransientDetection + IF( GT_16( element_mode, EVS_MONO ) ) { - attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ +#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 ) ); + if ( s_and( (Word16) LT_64( W_tmp1, W_tmp2 ), 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_InitTransientDetection } +#endif } } ELSE /* no attack, but set index anyway in case of strong energy increase */ { - 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_InitTransientDetection + 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_InitTransientDetection + 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 +298,22 @@ static void GetAttackForTCXDecision_ivas_fx( move16(); attackIndex = i; - 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 ) ), - s_or( (Word16) EQ_16( i, 2 ), (Word16) EQ_16( i, 6 ) ) ) ) +#ifdef HARMONIZE_2508_InitTransientDetection + IF( GT_32( element_mode, EVS_MONO ) ) { - attackIndex = add( attackIndex, 1 ); /* avoid minimum overlap to prevent clicks */ +#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 ) ), + 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_InitTransientDetection } +#endif } } } @@ -259,6 +339,7 @@ static void GetAttackForTCXDecision_ivas_fx( } +#ifndef HARMONIZE_2508_InitTransientDetection /** Initialize TCX transient detector. * See InitTransientDetector_fx for definition of parameters. */ @@ -271,6 +352,7 @@ static void InitTCXTransientDetector( return; } +#endif /************************************************/ @@ -278,7 +360,7 @@ static void InitTCXTransientDetector( /* Interface functions */ /* */ /************************************************/ - +#ifndef HARMONIZE_2508_InitTransientDetection void InitTransientDetection_fx( const Word16 nFrameLength, const Word16 nTCXDelay, @@ -299,27 +381,57 @@ void InitTransientDetection_fx( return; } +#endif - +#ifdef HARMONIZE_2508_InitTransientDetection +void InitTransientDetection_fx( + const Word16 nFrameLength, + const Word16 nTCXDelay, + TRAN_DET_HANDLE hTranDet, + const Word16 ext_mem_flag, + Word16 element_mode ) +#else void InitTransientDetection_ivas_fx( const Word16 nFrameLength, const Word16 nTCXDelay, TRAN_DET_HANDLE hTranDet, const Word16 ext_mem_flag ) +#endif { /* Init the delay buffer. */ InitDelayBuffer( nFrameLength, nTCXDelay, &hTranDet->delayBuffer ); /* Init a subblock energies buffer used for the TCX Short/Long decision. */ +#ifdef HARMONIZE_2508_InitTransientDetection + InitSubblockEnergies_fx( nFrameLength, nTCXDelay, &hTranDet->delayBuffer, &hTranDet->subblockEnergies, element_mode ); +#else InitSubblockEnergies_ivas_fx( nFrameLength, nTCXDelay, &hTranDet->delayBuffer, &hTranDet->subblockEnergies ); - +#endif /* Init the TCX Short/Long transient detector. */ +#ifdef HARMONIZE_2508_InitTransientDetection + InitTransientDetector_fx( &hTranDet->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision_fx, 17408 /*8.5f/(1<transientDetector, element_mode ); +#else InitTransientDetector_ivas_fx( &hTranDet->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision_ivas_fx, 17408 /*8.5f/(1<transientDetector ); +#endif /*HARMONIZE_2508_InitTransientDetection*/ /* We need two past subblocks for the TCX TD and NSUBBLOCKS+1 for the temporal flatness measure FOR the TCX LTP. */ +#ifdef HARMONIZE_2508_InitTransientDetection + IF( ext_mem_flag && GT_16( element_mode, EVS_MONO ) ) + { + hTranDet->transientDetector.pSubblockEnergies->nDelay = + add( hTranDet->transientDetector.pSubblockEnergies->nDelay, add( ( NSUBBLOCKS + 1 ), ( NSUBBLOCKS_SHIFT + 1 ) ) ); + move16(); + } + ELSE + { + hTranDet->transientDetector.pSubblockEnergies->nDelay = + add( hTranDet->transientDetector.pSubblockEnergies->nDelay, NSUBBLOCKS + 1 ); + move16(); + } +#else IF( ext_mem_flag ) { hTranDet->transientDetector.pSubblockEnergies->nDelay = @@ -332,6 +444,7 @@ void InitTransientDetection_ivas_fx( add( hTranDet->transientDetector.pSubblockEnergies->nDelay, NSUBBLOCKS + 1 ); move16(); } +#endif return; } @@ -607,7 +720,11 @@ void RunTransientDetection_fx( UpdateSubblockEnergies( filteredInput, nSamplesAvailable, pSubblockEnergies ); /* Run transient detectors. */ +#ifdef HARMONIZE_2508_InitTransientDetection + RunTransientDetector_fx( pTransientDetector, EVS_MONO ); +#else RunTransientDetector_fx( pTransientDetector ); +#endif /* Update the delay buffer. */ UpdateDelayBuffer( filteredInput, nSamplesAvailable, &hTranDet->delayBuffer ); @@ -678,7 +795,11 @@ void RunTransientDetection_ivas_fx( UpdateSubblockEnergies_ivas_fx( filteredInput_fx, length, pSubblockEnergies ); /* Run transient detectors. */ +#ifdef HARMONIZE_2508_InitTransientDetection + RunTransientDetector_fx( pTransientDetector, 1 /*signal non-EVS*/ ); +#else RunTransientDetector_fx( pTransientDetector ); +#endif /* Update the delay buffer. */ UpdateDelayBuffer( filteredInput_fx, length, &hTranDet->delayBuffer ); @@ -1064,7 +1185,7 @@ static void InitDelayBuffer( return; } - +#ifndef HARMONIZE_2508_InitTransientDetection static void InitSubblockEnergies( const Word16 nFrameLength, const Word16 nDelay, @@ -1096,33 +1217,55 @@ static void InitSubblockEnergies( return; } +#endif +#ifdef HARMONIZE_2508_InitTransientDetection +static void InitSubblockEnergies_fx( + const Word16 nFrameLength, + const Word16 nDelay, + DelayBuffer *pDelayBuffer, + SubblockEnergies *pSubblockEnergies, + Word16 element_mode ) +#else static void InitSubblockEnergies_ivas_fx( const Word16 nFrameLength, const Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ) +#endif { - Word16 const nMaxBuffSize = NSUBBLOCKS + MAX_TD_DELAY; - move16(); - assert( ( pDelayBuffer != NULL ) && ( pSubblockEnergies != NULL ) && ( pDelayBuffer->nSubblockSize * NSUBBLOCKS == nFrameLength ) && ( pDelayBuffer->nSubblockSize > 0 ) ); - set32_fx( pSubblockEnergies->subblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize ); - set32_fx( pSubblockEnergies->accSubblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize + 1 ); - set32_fx( pSubblockEnergies->subblockNrgChange_32fx, ONE_IN_Q15, nMaxBuffSize ); - set16_fx( pSubblockEnergies->subblockNrgChange_exp, 16, nMaxBuffSize ); - IF( nDelay != 0 ) + Word16 nMaxBuffSize; + +#ifdef HARMONIZE_2508_InitTransientDetection + IF( EQ_16( element_mode, EVS_MONO ) ) { - pSubblockEnergies->nDelay = idiv1616( nDelay, pDelayBuffer->nSubblockSize ); + nMaxBuffSize = sizeof( pSubblockEnergies->subblockNrg ) / sizeof( pSubblockEnergies->subblockNrg[0] ); move16(); + + set32_fx( pSubblockEnergies->subblockNrg, MIN_BLOCK_ENERGY, nMaxBuffSize ); + set32_fx( pSubblockEnergies->accSubblockNrg, MIN_BLOCK_ENERGY, nMaxBuffSize + 1 ); + set16_fx( pSubblockEnergies->subblockNrgChange, 0x7fff, nMaxBuffSize ); } ELSE { - pSubblockEnergies->nDelay = 0; +#endif + nMaxBuffSize = NSUBBLOCKS + MAX_TD_DELAY; + move16(); + + + set32_fx( pSubblockEnergies->subblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize ); + set32_fx( pSubblockEnergies->accSubblockNrg, 54 /* 107.37 in Q(-1) */, nMaxBuffSize + 1 ); + set32_fx( pSubblockEnergies->subblockNrgChange_32fx, ONE_IN_Q15, nMaxBuffSize ); + set16_fx( pSubblockEnergies->subblockNrgChange_exp, 16, nMaxBuffSize ); + pSubblockEnergies->q_firState = 15; move16(); +#ifdef HARMONIZE_2508_InitTransientDetection } +#endif + pSubblockEnergies->nDelay = idiv1616_1( nDelay, pDelayBuffer->nSubblockSize ); assert( pSubblockEnergies->nDelay < nMaxBuffSize ); pSubblockEnergies->nPartialDelay = nDelay % pDelayBuffer->nSubblockSize; move16(); @@ -1132,8 +1275,6 @@ static void InitSubblockEnergies_ivas_fx( move16(); pSubblockEnergies->firState2 = 0; move16(); - pSubblockEnergies->q_firState = 15; - move16(); pSubblockEnergies->pDelayBuffer = pDelayBuffer; pDelayBuffer->nDelay = s_max( pDelayBuffer->nDelay, pSubblockEnergies->nPartialDelay ); @@ -1142,7 +1283,6 @@ static void InitSubblockEnergies_ivas_fx( return; } - /** Init transient detector. * Fills TransientDetector structure with sensible content and enable it. * @param pSubblockEnergies Subblock energies used in this transient detector. @@ -1153,6 +1293,7 @@ static void InitSubblockEnergies_ivas_fx( * @param attackRatioThreshold Attack ratio threshold with exponent ATTACKTHRESHOLD_E. * @param pTransientDetector Structure to be initialized. */ +#ifndef HARMONIZE_2508_InitTransientDetection static void InitTransientDetector_fx( SubblockEnergies *pSubblockEnergies, const Word16 nDelay, @@ -1188,8 +1329,18 @@ static void InitTransientDetector_fx( return; } +#endif - +#ifdef HARMONIZE_2508_InitTransientDetection +static void InitTransientDetector_fx( + SubblockEnergies *pSubblockEnergies, + const Word16 nDelay, + const Word16 nSubblocksToCheck, + const TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, + const Word16 attackRatioThreshold, + TransientDetector *pTransientDetector, + Word16 element_mode ) +#else static void InitTransientDetector_ivas_fx( SubblockEnergies *pSubblockEnergies, const Word16 nDelay, @@ -1197,7 +1348,37 @@ static void InitTransientDetector_ivas_fx( const TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, const Word16 attackRatioThreshold, TransientDetector *pTransientDetector ) +#endif { +#ifdef HARMONIZE_2508_InitTransientDetection + Word16 nMaxBuffSize; + IF( EQ_16( element_mode, EVS_MONO ) ) + { + nMaxBuffSize = sizeof( pSubblockEnergies->subblockNrg ) / sizeof( pSubblockEnergies->subblockNrg[0] ); + move16(); + assert( ( pSubblockEnergies != NULL ) && ( pSubblockEnergies->pDelayBuffer != NULL ) && ( pTransientDetector != NULL ) && ( pSubblockEnergies->pDelayBuffer->nSubblockSize != 0 ) ); + pTransientDetector->pSubblockEnergies = pSubblockEnergies; + pTransientDetector->nDelay = ( nDelay - pSubblockEnergies->nPartialDelay ) / pSubblockEnergies->pDelayBuffer->nSubblockSize; + } + ELSE + { + nMaxBuffSize = NSUBBLOCKS + MAX_TD_DELAY; + move16(); + assert( ( pSubblockEnergies != NULL ) && ( pSubblockEnergies->pDelayBuffer != NULL ) && ( pTransientDetector != NULL ) && ( pSubblockEnergies->pDelayBuffer->nSubblockSize != 0 ) ); + pTransientDetector->pSubblockEnergies = pSubblockEnergies; + IF( sub( nDelay, pSubblockEnergies->nPartialDelay ) != 0 ) + { + pTransientDetector->nDelay = idiv1616( sub( nDelay, pSubblockEnergies->nPartialDelay ), pSubblockEnergies->pDelayBuffer->nSubblockSize ); + move16(); + } + ELSE + { + pTransientDetector->nDelay = 0; + move16(); + } + } + +#else const Word16 nMaxBuffSize = NSUBBLOCKS + MAX_TD_DELAY; move16(); @@ -1213,6 +1394,7 @@ static void InitTransientDetector_ivas_fx( pTransientDetector->nDelay = 0; move16(); } +#endif assert( nDelay == pTransientDetector->nDelay * pSubblockEnergies->pDelayBuffer->nSubblockSize + pSubblockEnergies->nPartialDelay ); assert( pTransientDetector->nDelay < nMaxBuffSize ); pSubblockEnergies->nDelay = s_max( pSubblockEnergies->nDelay, pTransientDetector->nDelay ); @@ -1229,9 +1411,17 @@ static void InitTransientDetector_ivas_fx( move16(); pTransientDetector->attackIndex = -1; move16(); +#ifdef HARMONIZE_2508_InitTransientDetection + IF( GT_16( element_mode, EVS_MONO ) ) + { + pTransientDetector->pSubblockEnergies->ramp_up_flag = 0x0; + move16(); + } +#else pTransientDetector->pSubblockEnergies->ramp_up_flag = 0x0; move16(); +#endif return; } @@ -1277,9 +1467,14 @@ static void HighPassFilter_fx( return; } - +#ifdef HARMONIZE_2508_InitTransientDetection +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 +1489,17 @@ static void RunTransientDetector_fx( assert( ( pTransientDetector->CheckSubblocksForAttack_fx != NULL ) ); #define WMC_TOOL_SKIP +#ifdef HARMONIZE_2508_InitTransientDetection + 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;