diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 0576e4760daa3a7cad29b9e5c03545858eeeadd9..7c3354dbadb992eb3b15044aac801ac5316882be 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3170,9 +3170,9 @@ void stereo_tcx_core_enc( Word16 transient_analysis_ivas_fx( TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */ const Word16 cor_map_LT[], /* i : LT correlation map Q_cor_map = Qx */ - Word16 Q_cor_map, + const Word16 Q_cor_map, const Word16 multi_harm_limit, /* i : multi harmonic threshold Q_multi_harm_limit = Qx */ - Word16 Q_multi_harm_limit ); + const Word16 Q_multi_harm_limit ); void set_transient_stereo_fx( CPE_ENC_HANDLE hCPE, /* i : CPE structure */ diff --git a/lib_enc/core_enc_ol_fx.c b/lib_enc/core_enc_ol_fx.c index 9f9476812bcbbb013f6b4bda4d0c9e41749bc0a2..2483fe95d7dfd61525827fcbe15d94cdb8d96aa9 100644 --- a/lib_enc/core_enc_ol_fx.c +++ b/lib_enc/core_enc_ol_fx.c @@ -698,7 +698,7 @@ void core_encode_openloop_fx( test(); test(); IF( rf_PLC_Mode == 0 && hRF->rf_gain_tcx[1] != 0 && - ( ( st->transientDetection.transientDetector.bIsAttackPresent != 0 && LT_16( hRF->rf_gain_tcx[0], mult_r( hRF->rf_gain_tcx[1], 31785 /*0.97f Q15*/ ) ) ) || + ( ( st->hTranDet->transientDetector.bIsAttackPresent != 0 && LT_16( hRF->rf_gain_tcx[0], mult_r( hRF->rf_gain_tcx[1], 31785 /*0.97f Q15*/ ) ) ) || LT_16( hRF->rf_gain_tcx[0], mult_r( hRF->rf_gain_tcx[1], 29491 /*0.90f Q15*/ ) ) ) ) { TD_mode = 0; @@ -898,7 +898,7 @@ void core_acelp_tcx20_switching_fx( st->pit_fr2, st->pit_max, st->pit_res_max, - &st->transientDetection, + st->hTranDet, 0, A_q_tcx, M ); diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index 87fa6a451061c07e284666c6bd70cb22ac42ac79..42f6dc487b52d5df5c56c46676513741ff3d6f8e 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -118,7 +118,7 @@ void core_signal_analysis_high_bitrate_fx( &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, &hTcxEnc->tcxltp_gain, &hTcxEnc->tcxltp_pitch_int_past, &hTcxEnc->tcxltp_pitch_fr_past, &hTcxEnc->tcxltp_gain_past, &hTcxEnc->tcxltp_norm_corr_past, st->last_core, st->pit_min, st->pit_fr1, - st->pit_fr2, st->pit_max, st->pit_res_max, &st->transientDetection, + st->pit_fr2, st->pit_max, st->pit_res_max, st->hTranDet, tmp8, NULL, M ); } ELSE @@ -130,7 +130,7 @@ void core_signal_analysis_high_bitrate_fx( &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, &hTcxEnc->tcxltp_gain, &hTcxEnc->tcxltp_pitch_int_past, &hTcxEnc->tcxltp_pitch_fr_past, &hTcxEnc->tcxltp_gain_past, &hTcxEnc->tcxltp_norm_corr_past, st->last_core, st->pit_min, st->pit_fr1, - st->pit_fr2, st->pit_max, st->pit_res_max, &st->transientDetection, + st->pit_fr2, st->pit_max, st->pit_res_max, st->hTranDet, tmp8, NULL, M ); } diff --git a/lib_enc/igf_enc_fx.c b/lib_enc/igf_enc_fx.c index 96c24db79ef8774801d47482f19a66bceb6baebc..4225570dd03e3b584e87b8b63a6f95a3c1123260 100755 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1811,7 +1811,7 @@ void IGFEncApplyMono_fx( const IGF_ENC_INSTANCE_HANDLE hInstance, /**< in pPowerSpectrumParameterWhitening, /* i: MDCT^2 + MDST^2 spectrum, or estimate */ PowerSpectrum_e, /* i: exponent of powerSpectrum */ igfGridIdx, /* i: IGF grid index */ - ( st->transientDetection.transientDetector.bIsAttackPresent == 1 ), + ( st->hTranDet->transientDetector.bIsAttackPresent == 1 ), last_core_acelp ); /* i: last frame was acelp indicator */ pPowerSpectrumParameter = NULL; diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 105bb7d10ededa263e597b329b9abc06106237d6..b3ddbf663f702cbd1db6b37f5bdc9dc3563b2b73 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -878,10 +878,15 @@ ivas_error init_encoder_fx( st_fx->totalNoise_increase_len = 0; move16(); init_coder_ace_plus_fx( st_fx, st_fx->last_total_brate, 0, -10 /*hack*/ ); - // PMT("Transient detector init needs review, handle hTranDet is missing") + + IF( ( st_fx->hTranDet = (TRAN_DET_HANDLE) malloc( sizeof( TRAN_DET_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); + } + InitTransientDetection_fx( extract_l( Mult_32_16( st_fx->input_Fs, INV_FRAME_PER_SEC_Q15 ) ), NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ), - &st_fx->transientDetection ); + st_fx->hTranDet ); st_fx->Q_syn2 = 0; move16(); @@ -2149,9 +2154,7 @@ ivas_error init_encoder_ivas_fx( } ELSE { - 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->transientDetection ); + InitTransientDetection_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index c9c54c2c6eb9a497bee38b29dd513848e8c8cbe3..b73702d21a52ede899b97ae516e3bc94266c6c72 100644 --- a/lib_enc/ivas_cpe_enc_fx.c +++ b/lib_enc/ivas_cpe_enc_fx.c @@ -493,7 +493,7 @@ ivas_error ivas_cpe_enc_fx( RunTransientDetection_ivas_fx( sts[n]->input_fx, input_frame, sts[n]->hTranDet, sts[n]->q_inp ); // Note q of sts[n]->input_fx changes inside function } - currFlatness_fx[n] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) sts[n]->hTranDet, NSUBBLOCKS, 0 ); // Q21 + currFlatness_fx[n] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( sts[n]->hTranDet, NSUBBLOCKS, 0 ); // Q21 move32(); } diff --git a/lib_enc/ivas_ism_enc_fx.c b/lib_enc/ivas_ism_enc_fx.c index dc41c784dd77f9a7d402e949bf786b3a9967559e..6b75a6be7494dc6490eeb62381b0840438e4a4f5 100644 --- a/lib_enc/ivas_ism_enc_fx.c +++ b/lib_enc/ivas_ism_enc_fx.c @@ -217,7 +217,7 @@ ivas_error ivas_ism_enc_fx( RunTransientDetection_ivas_fx( st->input_fx, input_frame, st->hTranDet, st->q_inp ); - currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, 0 ); // Q21 + currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS, 0 ); // Q21 move16(); /*----------------------------------------------------------------* diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 735e7e191fbaad5242907fac0268daddd6fccb38..39735ad030624045c49913f5a43e4c28e5f070b0 100644 --- a/lib_enc/ivas_mct_enc_fx.c +++ b/lib_enc/ivas_mct_enc_fx.c @@ -1188,7 +1188,7 @@ static ivas_error ivas_mc_enc_reconfig_fx( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); } - InitTransientDetection_ivas_fx( shl( div_l( st->input_Fs, FRAMES_PER_SEC ), 1 ), NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet, 0 ); + 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 ); } IF( st->hIGFEnc == NULL ) diff --git a/lib_enc/ivas_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 12a6fecf81023c805ce5f48646ccfed8cf71d3e8..8ad20a539678a179572b2d572f72e6da7ad6a578 100644 --- a/lib_enc/ivas_sce_enc_fx.c +++ b/lib_enc/ivas_sce_enc_fx.c @@ -184,7 +184,7 @@ ivas_error ivas_sce_enc_fx( RunTransientDetection_ivas_fx( st->input_fx, input_frame, st->hTranDet, q_input ); } - currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, 0 ); // Q21 + currFlatness_fx[0] = GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS, 0 ); // Q21 move32(); /*----------------------------------------------------------------* diff --git a/lib_enc/mdct_selector_fx.c b/lib_enc/mdct_selector_fx.c index c4cc7d0db8bcca97c26af11090363cbb12dfc166..8799806e4c021daccb656d6ca4935a28c934327a 100644 --- a/lib_enc/mdct_selector_fx.c +++ b/lib_enc/mdct_selector_fx.c @@ -315,11 +315,11 @@ void MDCT_selector_fx( test(); prefer_hq_core = ( LT_16( sub( Etot, sp_floor ), sig_lo_level_thr ) ) || /* noise floor is very high */ ( LT_16( cor_map_sum, cor_thr2 ) && LT_16( frame_voicing, voicing_thr2 ) && LT_16( sparseness, sparseness_thr2 ) ) || /* too weak tonal components */ - ( EQ_16( st->mdct_sw_enable, MODE1 ) && prefer_tcx == 0 && EQ_16( st->transientDetection.transientDetector.bIsAttackPresent, 1 ) ); + ( EQ_16( st->mdct_sw_enable, MODE1 ) && prefer_tcx == 0 && EQ_16( st->hTranDet->transientDetector.bIsAttackPresent, 1 ) ); /* Prefer HQ_CORE on transients */ test(); - IF( EQ_16( st->mdct_sw_enable, MODE2 ) && EQ_16( st->transientDetection.transientDetector.bIsAttackPresent, 1 ) ) + IF( EQ_16( st->mdct_sw_enable, MODE2 ) && EQ_16( st->hTranDet->transientDetector.bIsAttackPresent, 1 ) ) { prefer_tcx = 0; move16(); diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 6949618d1ee48417c52a8c7c018c9adea79f5098..29a0aa229357128eb352843d193f2dfc1e8d0c8e 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -393,8 +393,8 @@ void pre_proc_fx( test(); IF( st->tcx10Enabled || st->tcx20Enabled ) { - RunTransientDetection_fx( signal_in, input_frame, &st->transientDetection ); - currFlatness = GetTCXAvgTemporalFlatnessMeasure_fx( &st->transientDetection, NSUBBLOCKS, 0 ); + RunTransientDetection_fx( signal_in, input_frame, st->hTranDet ); + currFlatness = GetTCXAvgTemporalFlatnessMeasure_fx( st->hTranDet, NSUBBLOCKS, 0 ); } /*----------------------------------------------------------------* @@ -1261,7 +1261,7 @@ void pre_proc_fx( * TCX mode decision *---------------------------------------------------------------*/ - SetTCXModeInfo_fx( st, &st->transientDetection, &st->hTcxCfg->tcx_curr_overlap_mode ); + SetTCXModeInfo_fx( st, st->hTranDet, &st->hTcxCfg->tcx_curr_overlap_mode ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 9b4ac5917076bb6e99445df5a322c8185363e34a..e64c18468db76ef4f161075c927b97b44f1e13e2 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1071,13 +1071,13 @@ void calculate_hangover_attenuation_gain_fx( * @param pTransientDetection Structure to be initialized. It contains all transient detectors to be used. */ void InitTransientDetection_fx( - Word16 nFrameLength, - Word16 nTCXDelay, - struct TransientDetection *pTransientDetection ); + const Word16 nFrameLength, + const Word16 nTCXDelay, + TRAN_DET_HANDLE hTranDet ); void InitTransientDetection_ivas_fx( - Word16 nFrameLength, - Word16 nTCXDelay, + const Word16 nFrameLength, + const Word16 nTCXDelay, TRAN_DET_HANDLE pTransientDetection, const Word16 ext_mem_flag ); @@ -1090,8 +1090,8 @@ void InitTransientDetection_ivas_fx( */ void RunTransientDetection_fx( Word16 const *i, - Word16 nSamplesAvailable, - struct TransientDetection *pTransientDetection ); + const Word16 nSamplesAvailable, + TRAN_DET_HANDLE hTranDet ); void RunTransientDetection_ivas_fx( @@ -1109,14 +1109,14 @@ void RunTransientDetection_ivas_fx( * @return average temporal flatness measure with exponent AVG_FLAT_E */ Word16 GetTCXAvgTemporalFlatnessMeasure_fx( - struct TransientDetection const *pTransientDetection, - Word16 nCurrentSubblocks, - Word16 nPrevSubblocks ); + TRAN_DET_HANDLE hTranDetn, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks ); Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( - struct TransientDetection const *pTransientDetection, - Word16 nCurrentSubblocks, - Word16 nPrevSubblocks ); + TRAN_DET_HANDLE hTranDet, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks ); /** Get the maximum energy change using subblock energies aligned with the TCX. * @param pTransientDetection Structure that contains transient detectors to be run. @@ -1126,7 +1126,7 @@ Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( * @param maximum energy change with exponent NRG_CHANGE_E */ Word16 GetTCXMaxenergyChange_fx( - struct TransientDetection const *pTransientDetection, + TRAN_DET_HANDLE hTranDet, const Word8 isTCX10, const Word16 nCurrentSubblocks, const Word16 nPrevSubblocks ); @@ -1154,7 +1154,7 @@ void SetTCXModeInfo_ivas_fx( */ void SetTCXModeInfo_fx( Encoder_State *st, - struct TransientDetection const *pTransientDetection, + TRAN_DET_HANDLE hTranDet, Word16 *tcxModeOverlap ); void GSC_enc_init_fx( @@ -2766,7 +2766,7 @@ void tcx_ltp_encode_fx( Word16 pitfr2, Word16 pitmax, Word16 pitres, - struct TransientDetection const *pTransientDetection, + TRAN_DET_HANDLE hTranDet, Word8 SideInfoOnly, Word16 *A, Word16 lpcorder ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index fdcff722c69470c085b1554759425d926fa23ab7..d9afb7f996e8e889ddcf74a95f8a68dda943d4a8 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -1221,15 +1221,6 @@ typedef struct tcx_enc_structure Word16 spectrum_length; /* corresponds to L_frameTCX, used for scaling of MDCT/MDST buffers */ } TCX_ENC_DATA, *TCX_ENC_HANDLE; -typedef struct TransientDetection -{ - /** Transient detector. */ - TransientDetector transientDetector; - /** Delay buffer used by the transient detectors. */ - DelayBuffer delayBuffer; - /** Subblock energies used by the transient detector. */ - SubblockEnergies subblockEnergies; -} TransientDetection; /*----------------------------------------------------------------------------------* * @@ -1671,13 +1662,11 @@ typedef struct enc_core_structure Word16 inv_gamma; /* Q14 */ TRAN_DET_HANDLE hTranDet; - TransientDetection transientDetection; Word16 transient_info[3]; Word16 acelpFramesCount; Word16 prevTempFlatness_fx; /* exponent is AVG_FLAT_E Q7 in EVS */ /* Q4 in IVAS */ Word32 prevTempFlatness_32fx; /* Q21 in IVAS */ - // float currEnergyLookAhead; Word32 currEnergyLookAhead_fx; // Q31 Word32 prevEnergyHF_fx; Word32 currEnergyHF_fx; diff --git a/lib_enc/tcx_ltp_enc_fx.c b/lib_enc/tcx_ltp_enc_fx.c index c57e1d8d5cce6f6c772dc9773c77996a3de2ae10..c492fd100fb159608d1780c7d6ea85f170805093 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -608,36 +608,39 @@ static void tcx_ltp_find_gain_ivas_fx( Word16 *speech /*Qx*/, Word16 *pred_speec /* Dequantize gain */ *gain = imult1616( add( g, 1 ), 0x1400 ); /*Q15*/ move16(); + + return; } -void tcx_ltp_encode_fx( Word16 tcxltp_on, - Word8 tcxOnly, - Word16 tcxMode, - Word16 L_frame, - Word16 L_subfr, - Word16 *speech, - Word16 *speech_ltp, - Word16 *wsp, - Word16 Top, - Word16 *ltp_param, - Word16 *ltp_bits, - Word16 *pitch_int, - Word16 *pitch_fr, - Word16 *gain, - Word16 *pitch_int_past, - Word16 *pitch_fr_past, - Word16 *gain_past, - Word16 *norm_corr_past, - Word16 last_core, - Word16 pitmin, - Word16 pitfr1, - Word16 pitfr2, - Word16 pitmax, - Word16 pitres, - struct TransientDetection const *pTransientDetection, - Word8 SideInfoOnly, - Word16 *A, - Word16 lpcorder ) +void tcx_ltp_encode_fx( + Word16 tcxltp_on, + Word8 tcxOnly, + Word16 tcxMode, + Word16 L_frame, + Word16 L_subfr, + Word16 *speech, + Word16 *speech_ltp, + Word16 *wsp, + Word16 Top, + Word16 *ltp_param, + Word16 *ltp_bits, + Word16 *pitch_int, + Word16 *pitch_fr, + Word16 *gain, + Word16 *pitch_int_past, + Word16 *pitch_fr_past, + Word16 *gain_past, + Word16 *norm_corr_past, + Word16 last_core, + Word16 pitmin, + Word16 pitfr1, + Word16 pitfr2, + Word16 pitmax, + Word16 pitres, + TRAN_DET_HANDLE hTranDet, + Word8 SideInfoOnly, + Word16 *A, + Word16 lpcorder ) { Word16 n; Word16 norm_corr; @@ -654,7 +657,6 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, #endif #endif - norm_corr = 0; move16(); @@ -691,11 +693,9 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, nPrevSubblocks = extract_h( L_mac( 0x17fff, NSUBBLOCKS, div_s( *pitch_int, L_frame ) ) ); nPrevSubblocks = add( s_min( nPrevSubblocks, NSUBBLOCKS ), 1 ); - tempFlatness = GetTCXAvgTemporalFlatnessMeasure_fx( pTransientDetection, NSUBBLOCKS, nPrevSubblocks ); + tempFlatness = GetTCXAvgTemporalFlatnessMeasure_fx( hTranDet, NSUBBLOCKS, nPrevSubblocks ); - maxEnergyChange = GetTCXMaxenergyChange_fx( pTransientDetection, - (const Word8) isTCX10, - NSUBBLOCKS, nPrevSubblocks ); + maxEnergyChange = GetTCXMaxenergyChange_fx( hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks ); /* Switch LTP on */ test(); @@ -915,8 +915,11 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, move16(); *norm_corr_past = norm_corr; move16(); + + return; } + void tcx_ltp_encode_ivas_fx( Encoder_State *st, const Word16 tcxMode, @@ -1063,15 +1066,13 @@ void tcx_ltp_encode_ivas_fx( IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) ) { - tempFlatness_fx = extract_l( L_shr( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ), 14 ) ); // Q7 - maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, - NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ); // Q3 + tempFlatness_fx = extract_l( L_shr( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ), 14 ) ); // Q7 + maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ); // Q3 } ELSE { - tempFlatness_fx = extract_l( L_shr( ( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) st->hTranDet, NSUBBLOCKS, nPrevSubblocks ) ), 14 ) ); // Q7 - maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, - NSUBBLOCKS, nPrevSubblocks ); // Q3 + tempFlatness_fx = extract_l( L_shr( ( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS, nPrevSubblocks ) ), 14 ) ); // Q7 + maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks ); // Q3 } /* Switch LTP on */ diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 1ad69a3302b2c79e2879d313f98413b1a7eba2fc..bb8239f90a4ab6ae55edc1b245017274bec24154 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -2,11 +2,9 @@ EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0 ====================================================================================*/ - #include "options.h" #include "stl.h" #include "basop_util.h" -// #include "prot_fx.h" #include "rom_com.h" #include #include @@ -36,26 +34,26 @@ #define THR_LOW_STEP_FX ONE_IN_Q11 /* 1 in Q11 */ #define MIN_BLOCK_ENERGY_IVAS_FX_Q7 13743 /* 107.37f in Q7 */ + /************************************************/ /* */ /* Internal functions prototypes */ /* */ /************************************************/ -static void InitDelayBuffer( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pDelayBuffer ); -static void InitSubblockEnergies( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ); -static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ); -static void InitTransientDetector_fx( SubblockEnergies *pSubblockEnergies, Word16 nDelay, Word16 nSubblocksToCheck, TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, Word16 attackRatioThreshold, TransientDetector *pTransientDetector ); -static void InitTransientDetector_ivas_fx( SubblockEnergies *pSubblockEnergies, Word16 nDelay, Word16 nSubblocksToCheck, TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, Word16 attackRatioThreshold, TransientDetector *pTransientDetector ); -static void UpdateDelayBuffer( Word16 const *input, Word16 nSamplesAvailable, DelayBuffer *pDelayBuffer ); -static void HighPassFilter_fx( Word16 const *input, Word16 length, Word16 *pFirState1, Word16 *pFirState2, Word16 *output ); -static void UpdateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ); -static void CalculateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ); +static void InitDelayBuffer( const Word16 nFrameLength, const Word16 nDelay, DelayBuffer *pDelayBuffer ); +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 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 ); -static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ); - -static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ); /************************************************/ /* */ @@ -68,14 +66,19 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamples * 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. */ -static void GetAttackForTCXDecision( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) +static void GetAttackForTCXDecision( + Word32 const *pSubblockNrg, + Word32 const *pAccSubblockNrg, + Word16 nSubblocks, + Word16 nPastSubblocks, + Word16 attackRatioThreshold, + Word16 *pbIsAttackPresent, + Word16 *pAttackIndex ) { Word16 i; Word16 bIsAttackPresent, attackIndex; Word16 attackRatioThreshold_1_5; - (void) nPastSubblocks; - (void) nSubblocks; assert( nSubblocks >= NSUBBLOCKS ); assert( nPastSubblocks >= 2 ); @@ -140,17 +143,26 @@ static void GetAttackForTCXDecision( Word32 const *pSubblockNrg, Word32 const *p move16(); *pAttackIndex = attackIndex; *pbIsAttackPresent = bIsAttackPresent; + + return; } -static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) + +/* GetAttackForTCXDecision() version using 32-bit for energy change values */ +static void GetAttackForTCXDecision_ivas_fx( + Word32 const *pSubblockNrg, + Word32 const *pAccSubblockNrg, + Word16 nSubblocks, + Word16 nPastSubblocks, + Word16 attackRatioThreshold, + Word16 *pbIsAttackPresent, + Word16 *pAttackIndex ) { Word16 i; Word16 bIsAttackPresent, attackIndex; Word16 attackRatioThreshold_1_5; Word64 W_tmp1, W_tmp2, W_tmp3; - (void) nPastSubblocks; - (void) nSubblocks; assert( nSubblocks >= NSUBBLOCKS ); assert( nPastSubblocks >= 2 ); @@ -242,16 +254,24 @@ static void GetAttackForTCXDecision_ivas_fx( Word32 const *pSubblockNrg, Word32 move16(); *pAttackIndex = attackIndex; *pbIsAttackPresent = bIsAttackPresent; + + return; } -void GetAttackForTCXDecision_fx( Word32 const *pSubblockNrg, Word32 const *pAccSubblockNrg, Word16 nSubblocks, Word16 nPastSubblocks, Word16 attackRatioThreshold, Word16 *pbIsAttackPresent, Word16 *pAttackIndex ) + +void GetAttackForTCXDecision_fx( + Word32 const *pSubblockNrg, + Word32 const *pAccSubblockNrg, + Word16 nSubblocks, + Word16 nPastSubblocks, + Word16 attackRatioThreshold, + Word16 *pbIsAttackPresent, + Word16 *pAttackIndex ) { Word16 i; Word16 bIsAttackPresent, attackIndex; Word16 attackRatioThreshold_1_5; - (void) nPastSubblocks; - (void) nSubblocks; assert( nSubblocks >= NSUBBLOCKS ); assert( nPastSubblocks >= 2 ); @@ -316,14 +336,22 @@ void GetAttackForTCXDecision_fx( Word32 const *pSubblockNrg, Word32 const *pAccS move16(); *pAttackIndex = attackIndex; *pbIsAttackPresent = bIsAttackPresent; + + return; } + /** Initialize TCX transient detector. * See InitTransientDetector_fx for definition of parameters. */ -static void InitTCXTransientDetector( Word16 nDelay, SubblockEnergies *pSubblockEnergies, TransientDetector *pTransientDetector ) +static void InitTCXTransientDetector( + Word16 nDelay, + SubblockEnergies *pSubblockEnergies, + TransientDetector *pTransientDetector ) { InitTransientDetector_fx( pSubblockEnergies, nDelay, NSUBBLOCKS, GetAttackForTCXDecision, 17408 /*8.5f/(1<delayBuffer ); + InitDelayBuffer( nFrameLength, nTCXDelay, &hTranDet->delayBuffer ); + /* Init a subblock energies buffer used for the TCX Short/Long decision. */ - InitSubblockEnergies( nFrameLength, nTCXDelay, &pTransientDetection->delayBuffer, &pTransientDetection->subblockEnergies ); + InitSubblockEnergies( nFrameLength, nTCXDelay, &hTranDet->delayBuffer, &hTranDet->subblockEnergies ); + /* Init the TCX Short/Long transient detector. */ - InitTCXTransientDetector( nTCXDelay, &pTransientDetection->subblockEnergies, &pTransientDetection->transientDetector ); + InitTCXTransientDetector( nTCXDelay, &hTranDet->subblockEnergies, &hTranDet->transientDetector ); + /* We need two past subblocks for the TCX TD and NSUBBLOCKS+1 for the temporal flatness measure FOR the TCX LTP. */ - pTransientDetection->transientDetector.pSubblockEnergies->nDelay = - add( pTransientDetection->transientDetector.pSubblockEnergies->nDelay, NSUBBLOCKS + 1 ); + hTranDet->transientDetector.pSubblockEnergies->nDelay = + add( hTranDet->transientDetector.pSubblockEnergies->nDelay, NSUBBLOCKS + 1 ); + move16(); + + return; } -void InitTransientDetection_ivas_fx( Word16 nFrameLength, - Word16 nTCXDelay, - TRAN_DET_HANDLE pTransientDetection, - const Word16 ext_mem_flag ) + +void InitTransientDetection_ivas_fx( + const Word16 nFrameLength, + const Word16 nTCXDelay, + TRAN_DET_HANDLE pTransientDetection, + const Word16 ext_mem_flag ) { /* Init the delay buffer. */ InitDelayBuffer( nFrameLength, nTCXDelay, &pTransientDetection->delayBuffer ); + /* Init a subblock energies buffer used for the TCX Short/Long decision. */ InitSubblockEnergies_ivas_fx( nFrameLength, nTCXDelay, &pTransientDetection->delayBuffer, &pTransientDetection->subblockEnergies ); + /* Init the TCX Short/Long transient detector. */ InitTransientDetector_ivas_fx( &pTransientDetection->subblockEnergies, nTCXDelay, NSUBBLOCKS, GetAttackForTCXDecision_ivas_fx, 17408 /*8.5f/(1<transientDetector ); + /* We need two past subblocks for the TCX TD and NSUBBLOCKS+1 for the temporal flatness measure FOR the TCX LTP. */ IF( ext_mem_flag ) { @@ -372,13 +412,19 @@ void InitTransientDetection_ivas_fx( Word16 nFrameLength, add( pTransientDetection->transientDetector.pSubblockEnergies->nDelay, NSUBBLOCKS + 1 ); move16(); } + + return; } + /** * \brief Calculate average of temporal energy change. * \return average temporal energy change with exponent = 8 */ -Word16 GetTCXAvgTemporalFlatnessMeasure_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ) +Word16 GetTCXAvgTemporalFlatnessMeasure_fx( + TRAN_DET_HANDLE hTranDet, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks ) { Word16 i; TransientDetector const *pTransientDetector; @@ -389,9 +435,8 @@ Word16 GetTCXAvgTemporalFlatnessMeasure_fx( struct TransientDetection const *pTr Word32 sumTempFlatness; Word16 nTotBlocks; - /* Initialization */ - pTransientDetector = &pTransientDetection->transientDetector; + pTransientDetector = &hTranDet->transientDetector; pSubblockEnergies = pTransientDetector->pSubblockEnergies; move16(); nDelay = pTransientDetector->nDelay; @@ -419,7 +464,11 @@ Word16 GetTCXAvgTemporalFlatnessMeasure_fx( struct TransientDetection const *pTr return i; } -Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ) + +Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( + TRAN_DET_HANDLE hTranDet, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks ) { Word32 i; TransientDetector const *pTransientDetector; @@ -432,7 +481,7 @@ Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const Word16 nTotBlocks, sumTempFlatness_exp, exp; /* Initialization */ - pTransientDetector = &pTransientDetection->transientDetector; + pTransientDetector = &hTranDet->transientDetector; pSubblockEnergies = pTransientDetector->pSubblockEnergies; nDelay = pTransientDetector->nDelay; move16(); @@ -461,13 +510,16 @@ Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const i = BASOP_Util_Divide3232_Scale_newton( sumTempFlatness, nTotBlocks, &exp ); exp = add( exp, sub( sumTempFlatness_exp, 31 ) ); i = L_shl_sat( i, sub( exp, 10 ) ); // Can be saturated, since it is used for comparision againt 3.25/20.0f, Q21 + return i; } -Word16 GetTCXMaxenergyChange_fx( struct TransientDetection const *pTransientDetection, - const Word8 isTCX10, - const Word16 nCurrentSubblocks, - const Word16 nPrevSubblocks ) + +Word16 GetTCXMaxenergyChange_fx( + TRAN_DET_HANDLE hTranDet, + const Word8 isTCX10, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks ) { Word16 i; TransientDetector const *pTransientDetector; @@ -478,8 +530,7 @@ Word16 GetTCXMaxenergyChange_fx( struct TransientDetection const *pTransientDete Word16 maxEnergyChange; Word16 nTotBlocks; - - pTransientDetector = &pTransientDetection->transientDetector; + pTransientDetector = &hTranDet->transientDetector; pSubblockEnergies = pTransientDetector->pSubblockEnergies; move16(); nDelay = pTransientDetector->nDelay; @@ -500,7 +551,6 @@ Word16 GetTCXMaxenergyChange_fx( struct TransientDetection const *pTransientDete Word32 const *pSubblockNrg = &pSubblockEnergies->subblockNrg[sub( nRelativeDelay, nPrevSubblocks )]; Word32 nrgMin, nrgMax; Word16 idxMax = 0; - move16(); nrgMax = L_add( pSubblockNrg[0], 0 ); @@ -543,10 +593,11 @@ Word16 GetTCXMaxenergyChange_fx( struct TransientDetection const *pTransientDete } -Word16 GetTCXMaxenergyChange_ivas_fx( TRAN_DET_HANDLE hTranDet, - const Word8 isTCX10, - const Word16 nCurrentSubblocks, - const Word16 nPrevSubblocks ) +Word16 GetTCXMaxenergyChange_ivas_fx( + TRAN_DET_HANDLE hTranDet, + const Word8 isTCX10, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks ) { Word16 i; TransientDetector const *pTransientDetector; @@ -558,7 +609,6 @@ Word16 GetTCXMaxenergyChange_ivas_fx( TRAN_DET_HANDLE hTranDet, Word16 maxEnergyChange; Word16 nTotBlocks; - pTransientDetector = &hTranDet->transientDetector; pSubblockEnergies = pTransientDetector->pSubblockEnergies; move16(); @@ -620,13 +670,17 @@ Word16 GetTCXMaxenergyChange_ivas_fx( TRAN_DET_HANDLE hTranDet, return i; } -void RunTransientDetection_fx( Word16 const *input, Word16 nSamplesAvailable, TransientDetection *pTransientDetection ) + +void RunTransientDetection_fx( + Word16 const *input, + const Word16 nSamplesAvailable, + TRAN_DET_HANDLE hTranDet ) { Word16 filteredInput[L_FRAME48k]; - SubblockEnergies *pSubblockEnergies = &pTransientDetection->subblockEnergies; - TransientDetector *pTransientDetector = &pTransientDetection->transientDetector; + SubblockEnergies *pSubblockEnergies = &hTranDet->subblockEnergies; + TransientDetector *pTransientDetector = &hTranDet->transientDetector; - assert( ( input != NULL ) && ( pTransientDetection != NULL ) && ( pSubblockEnergies != NULL ) && ( pTransientDetector != NULL ) ); + assert( ( input != NULL ) && ( hTranDet != NULL ) && ( pSubblockEnergies != NULL ) && ( pTransientDetector != NULL ) ); HighPassFilter_fx( input, nSamplesAvailable, &pSubblockEnergies->firState1, &pSubblockEnergies->firState2, filteredInput ); @@ -637,18 +691,19 @@ void RunTransientDetection_fx( Word16 const *input, Word16 nSamplesAvailable, Tr RunTransientDetector_fx( pTransientDetector ); /* Update the delay buffer. */ - UpdateDelayBuffer( filteredInput, nSamplesAvailable, &pTransientDetection->delayBuffer ); + UpdateDelayBuffer( filteredInput, nSamplesAvailable, &hTranDet->delayBuffer ); + + return; } void RunTransientDetection_ivas_fx( - Word16 *input_fx, /* i : input signal Q: q_input */ + Word16 *input_fx, /* i : input signal Q: q_input */ const Word16 length, /* i : frame length */ TRAN_DET_HANDLE hTranDet, /* i/o: transient detection handle */ - Word16 q_input /*i: stores q for input_fx*/ + Word16 q_input /* i : stores q for input_fx */ ) { - Word16 filteredInput_fx[L_FRAME_MAX]; SubblockEnergies *pSubblockEnergies = &hTranDet->subblockEnergies; TransientDetector *pTransientDetector = &hTranDet->transientDetector; @@ -726,11 +781,13 @@ void RunTransientDetection_ivas_fx( return; } + /*-------------------------------------------------------------------* * isLongTermTransient_fx() * * *-------------------------------------------------------------------*/ + static Word16 isLongTermTransient_fx( const Word32 frameTFM, Word32 *lastTFM ) @@ -754,6 +811,7 @@ static Word16 isLongTermTransient_fx( { return 1; } + return 0; } @@ -814,7 +872,6 @@ void SetTCXModeInfo_ivas_fx( move16(); } } - #ifdef SUPPORT_FORCE_TCX10_TCX20 #ifdef DEBUGGING if ( st->force == FORCE_TCX10 ) @@ -865,7 +922,7 @@ void SetTCXModeInfo_ivas_fx( move16(); } } - tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q21, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); + tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q21, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); tmp = shl_sat( tmp, exp_diff ); // Q15 test(); IF( isLongTermTransient_fx( L_deposit_h( tmp ), &hTcxEnc->tfm_mem_fx ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) @@ -895,7 +952,7 @@ void SetTCXModeInfo_ivas_fx( *tcxModeOverlap = ALDO_WINDOW; move16(); } - tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q21, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( (const TransientDetection *) hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); + tmp = BASOP_Util_Divide3232_Scale( ONE_IN_Q21, GetTCXAvgTemporalFlatnessMeasure_ivas_fx( hTranDet, NSUBBLOCKS, 0 ), &exp_diff ); tmp = shl_sat( tmp, exp_diff ); // Q15 test(); IF( isLongTermTransient_fx( L_deposit_h( tmp ), &hTcxEnc->tfm_mem_fx ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) ) @@ -933,19 +990,24 @@ void SetTCXModeInfo_ivas_fx( } -void SetTCXModeInfo_fx( Encoder_State *st, - TransientDetection const *pTransientDetection, - Word16 *tcxModeOverlap ) +/*-------------------------------------------------------------------* + * SetTCXModeInfo() + * + * + *-------------------------------------------------------------------*/ + +void SetTCXModeInfo_fx( + Encoder_State *st, + TRAN_DET_HANDLE hTranDet, + Word16 *tcxModeOverlap ) { TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; - assert( pTransientDetection != NULL ); + assert( hTranDet != NULL ); IF( EQ_16( st->codec_mode, MODE2 ) ) { - /* determine window sequence (1 long or 2 short windows) */ - test(); IF( st->tcx10Enabled != 0 && st->tcx20Enabled != 0 ) { @@ -953,7 +1015,7 @@ void SetTCXModeInfo_fx( Encoder_State *st, test(); test(); test(); - IF( ( ( pTransientDetection->transientDetector.bIsAttackPresent != 0 ) || ( GT_32( Mpy_32_16_1( st->currEnergyHF_fx, 840 /*1.0f/39.0f Q15*/ ), st->prevEnergyHF_fx ) ) ) && ( ( NE_16( st->last_core, ACELP_CORE ) ) && ( NE_16( st->last_core, AMR_WB_CORE ) ) ) ) + IF( ( ( hTranDet->transientDetector.bIsAttackPresent != 0 ) || ( GT_32( Mpy_32_16_1( st->currEnergyHF_fx, 840 /*1.0f/39.0f Q15*/ ), st->prevEnergyHF_fx ) ) ) && ( ( NE_16( st->last_core, ACELP_CORE ) ) && ( NE_16( st->last_core, AMR_WB_CORE ) ) ) ) { move16(); hTcxEnc->tcxMode = TCX_10; @@ -1002,10 +1064,9 @@ void SetTCXModeInfo_fx( Encoder_State *st, } /* determine window overlaps (0 full, 2 none, or 3 half) */ - IF( EQ_16( hTcxEnc->tcxMode, TCX_10 ) ) { - IF( pTransientDetection->transientDetector.attackIndex < 0 ) + IF( hTranDet->transientDetector.attackIndex < 0 ) { move16(); *tcxModeOverlap = HALF_OVERLAP; @@ -1013,7 +1074,7 @@ void SetTCXModeInfo_fx( Encoder_State *st, ELSE { move16(); - *tcxModeOverlap = s_and( pTransientDetection->transientDetector.attackIndex, 3 ); + *tcxModeOverlap = s_and( hTranDet->transientDetector.attackIndex, 3 ); if ( EQ_16( *tcxModeOverlap, 1 ) ) { move16(); @@ -1023,12 +1084,12 @@ void SetTCXModeInfo_fx( Encoder_State *st, } ELSE IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) { - IF( EQ_16( pTransientDetection->transientDetector.attackIndex, 7 ) ) + IF( EQ_16( hTranDet->transientDetector.attackIndex, 7 ) ) { move16(); *tcxModeOverlap = HALF_OVERLAP; } - ELSE IF( EQ_16( pTransientDetection->transientDetector.attackIndex, 6 ) ) + ELSE IF( EQ_16( hTranDet->transientDetector.attackIndex, 6 ) ) { move16(); *tcxModeOverlap = MIN_OVERLAP; @@ -1054,19 +1115,24 @@ void SetTCXModeInfo_fx( Encoder_State *st, /* Sanity check */ assert( *tcxModeOverlap != 1 ); } + + return; } + /************************************************/ /* */ /* Internal functions */ /* */ /************************************************/ -static void InitDelayBuffer( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pDelayBuffer ) +static void InitDelayBuffer( + const Word16 nFrameLength, + const Word16 nDelay, + DelayBuffer *pDelayBuffer ) { Word16 const nMaxBuffSize = sizeof( pDelayBuffer->buffer ) / sizeof( pDelayBuffer->buffer[0] ); - move16(); move16(); assert( ( nFrameLength > NSUBBLOCKS ) && ( nFrameLength % NSUBBLOCKS == 0 ) && ( nDelay >= 0 ) && ( pDelayBuffer != NULL ) ); @@ -1075,14 +1141,19 @@ static void InitDelayBuffer( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pD set16_fx( pDelayBuffer->buffer, 0, nMaxBuffSize ); pDelayBuffer->nDelay = nDelay % pDelayBuffer->nSubblockSize; assert( pDelayBuffer->nDelay <= nMaxBuffSize ); + + return; } -static void InitSubblockEnergies( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ) + +static void InitSubblockEnergies( + const Word16 nFrameLength, + const Word16 nDelay, + DelayBuffer *pDelayBuffer, + SubblockEnergies *pSubblockEnergies ) { Word16 const nMaxBuffSize = sizeof( pSubblockEnergies->subblockNrg ) / sizeof( pSubblockEnergies->subblockNrg[0] ); move16(); - (void) nFrameLength; - assert( ( pDelayBuffer != NULL ) && ( pSubblockEnergies != NULL ) && ( pDelayBuffer->nSubblockSize * NSUBBLOCKS == nFrameLength ) && ( pDelayBuffer->nSubblockSize > 0 ) ); @@ -1103,9 +1174,16 @@ static void InitSubblockEnergies( Word16 nFrameLength, Word16 nDelay, DelayBuffe pSubblockEnergies->pDelayBuffer = pDelayBuffer; pDelayBuffer->nDelay = s_max( pDelayBuffer->nDelay, pSubblockEnergies->nPartialDelay ); + + return; } -static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, DelayBuffer *pDelayBuffer, SubblockEnergies *pSubblockEnergies ) + +static void InitSubblockEnergies_ivas_fx( + const Word16 nFrameLength, + const Word16 nDelay, + DelayBuffer *pDelayBuffer, + SubblockEnergies *pSubblockEnergies ) { Word16 const nMaxBuffSize = NSUBBLOCKS + MAX_TD_DELAY; move16(); @@ -1141,8 +1219,11 @@ static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, De pSubblockEnergies->pDelayBuffer = pDelayBuffer; pDelayBuffer->nDelay = s_max( pDelayBuffer->nDelay, pSubblockEnergies->nPartialDelay ); move16(); + + return; } + /** Init transient detector. * Fills TransientDetector structure with sensible content and enable it. * @param pSubblockEnergies Subblock energies used in this transient detector. @@ -1153,7 +1234,13 @@ static void InitSubblockEnergies_ivas_fx( Word16 nFrameLength, Word16 nDelay, De * @param attackRatioThreshold Attack ratio threshold with exponent ATTACKTHRESHOLD_E. * @param pTransientDetector Structure to be initialized. */ -static void InitTransientDetector_fx( SubblockEnergies *pSubblockEnergies, Word16 nDelay, Word16 nSubblocksToCheck, TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, Word16 attackRatioThreshold, TransientDetector *pTransientDetector ) +static void InitTransientDetector_fx( + SubblockEnergies *pSubblockEnergies, + const Word16 nDelay, + const Word16 nSubblocksToCheck, + const TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, + const Word16 attackRatioThreshold, + TransientDetector *pTransientDetector ) { Word16 nMaxBuffSize; @@ -1179,9 +1266,18 @@ static void InitTransientDetector_fx( SubblockEnergies *pSubblockEnergies, Word1 move16(); pTransientDetector->attackIndex = -1; move16(); + + return; } -static void InitTransientDetector_ivas_fx( SubblockEnergies *pSubblockEnergies, Word16 nDelay, Word16 nSubblocksToCheck, TCheckSubblocksForAttack_fx pCheckSubblocksForAttack, 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 ) { const Word16 nMaxBuffSize = NSUBBLOCKS + MAX_TD_DELAY; move16(); @@ -1216,17 +1312,29 @@ static void InitTransientDetector_ivas_fx( SubblockEnergies *pSubblockEnergies, move16(); pTransientDetector->pSubblockEnergies->ramp_up_flag = 0x0; move16(); + + return; } + /* This function should be inlined and WMOPS instrumentation takes that into account, meaning that all references are considered as local variables */ -static Word32 InlineFilter( Word16 inValue, Word16 firState1, Word16 firState2 ) +static Word32 InlineFilter( + const Word16 inValue, + const Word16 firState1, + const Word16 firState2 ) { /* 0.375f * inValue - 0.5f * firState1 + 0.125f * firState2 */ return L_msu( L_mac( L_mult( firState2, 4096 /*0.125f Q15*/ ), inValue, 12288 /*0.375f Q15*/ ), firState1, 16384 /*0.5f Q15*/ ); } -static void HighPassFilter_fx( Word16 const *input, Word16 length, Word16 *pFirState1, Word16 *pFirState2, Word16 *output ) + +static void HighPassFilter_fx( + Word16 const *input, + const Word16 length, + Word16 *pFirState1, + Word16 *pFirState2, + Word16 *output ) { Word16 i; @@ -1246,9 +1354,13 @@ static void HighPassFilter_fx( Word16 const *input, Word16 length, Word16 *pFirS move16(); *pFirState2 = input[length - 2]; *pFirState1 = input[length - 1]; + + return; } -static void RunTransientDetector_fx( TransientDetector *pTransientDetector ) + +static void RunTransientDetector_fx( + TransientDetector *pTransientDetector ) { Word16 const attackRatioThreshold = pTransientDetector->attackRatioThreshold; move16(); @@ -1268,14 +1380,19 @@ static void RunTransientDetector_fx( TransientDetector *pTransientDetector ) attackRatioThreshold, &pTransientDetector->bIsAttackPresent, &pTransientDetector->attackIndex ); #undef WMC_TOOL_SKIP + + return; } -static void UpdateDelayBuffer( Word16 const *input, Word16 nSamplesAvailable, DelayBuffer *pDelayBuffer ) + +static void UpdateDelayBuffer( + Word16 const *input, + const Word16 nSamplesAvailable, + DelayBuffer *pDelayBuffer ) { Word16 i; Word16 nDelay; - move16(); nDelay = pDelayBuffer->nDelay; @@ -1291,13 +1408,18 @@ static void UpdateDelayBuffer( Word16 const *input, Word16 nSamplesAvailable, De pDelayBuffer->buffer[i] = input[i + nSamplesAvailable - nDelay]; } } + + return; } -static void UpdateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ) + +static void UpdateSubblockEnergies( + Word16 const *input, + const Word16 nSamplesAvailable, + SubblockEnergies *pSubblockEnergies ) { Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ @@ -1316,13 +1438,19 @@ static void UpdateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailabl /* Compute filtered subblock energies for the new samples */ CalculateSubblockEnergies( input, nSamplesAvailable, pSubblockEnergies ); + + return; } -static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ) + +/* UpdateSubblockEnergies() version using 32-bit for energy change values */ +static void UpdateSubblockEnergies_ivas_fx( + Word16 const *input, + const Word16 nSamplesAvailable, + SubblockEnergies *pSubblockEnergies ) { Word16 i; - assert( ( pSubblockEnergies->nDelay >= 0 ) && ( pSubblockEnergies->nDelay + NSUBBLOCKS <= (Word32) sizeof( pSubblockEnergies->subblockNrg ) / (Word32) sizeof( pSubblockEnergies->subblockNrg[0] ) ) ); assert( pSubblockEnergies->nPartialDelay <= pSubblockEnergies->pDelayBuffer->nDelay ); /* At least one block delay is required when subblock energy change is required */ @@ -1343,10 +1471,17 @@ static void UpdateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamples /* Compute filtered subblock energies for the new samples */ CalculateSubblockEnergies_ivas_fx( input, nSamplesAvailable, pSubblockEnergies ); + + return; } + /* This function should be inlined and WMOPS instrumentation takes that into account, meaning that all references are considered as local variables */ -static void UpdatedAndStoreAccWindowNrg( Word32 newWindowNrgF, Word32 *pAccSubblockNrg, Word16 facAccSubblockNrg, Word32 *pOutAccWindowNrgF ) +static void UpdatedAndStoreAccWindowNrg( + Word32 newWindowNrgF, + Word32 *pAccSubblockNrg, + const Word16 facAccSubblockNrg, + Word32 *pOutAccWindowNrgF ) { /* Store the accumulated energy */ move32(); @@ -1359,9 +1494,15 @@ static void UpdatedAndStoreAccWindowNrg( Word32 newWindowNrgF, Word32 *pAccSubbl move32(); *pAccSubblockNrg = newWindowNrgF; } + + return; } -static void CalculateSubblockEnergies( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ) + +static void CalculateSubblockEnergies( + Word16 const *input, + const Word16 nSamplesAvailable, + SubblockEnergies *pSubblockEnergies ) { DelayBuffer *pDelayBuffer; Word16 nSubblockSize; @@ -1473,9 +1614,16 @@ static void CalculateSubblockEnergies( Word16 const *input, Word16 nSamplesAvail move16(); pSubblockEnergies->firState1 = firState1; pSubblockEnergies->firState2 = firState2; + + return; } -static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamplesAvailable, SubblockEnergies *pSubblockEnergies ) + +/* CalculateSubblockEnergies() version using 32-bit energy change values */ +static void CalculateSubblockEnergies_ivas_fx( + Word16 const *input, + const Word16 nSamplesAvailable, + SubblockEnergies *pSubblockEnergies ) { DelayBuffer *pDelayBuffer; Word16 nSubblockSize; @@ -1571,8 +1719,11 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp move16(); } } + + return; } + /*-------------------------------------------------------------------* * transient_analysis() * @@ -1583,9 +1734,9 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp Word16 transient_analysis_ivas_fx( TRAN_DET_HANDLE hTranDet, /* i : handle transient detection */ const Word16 cor_map_LT[], /* i : LT correlation map Q_cor_map */ - Word16 Q_cor_map, + const Word16 Q_cor_map, const Word16 multi_harm_limit, /* i : multi harmonic threshold Q_multi_harm_limit */ - Word16 Q_multi_harm_limit ) + const Word16 Q_multi_harm_limit ) { const Word32 *pSubblockNrg; Word32 accSubblockNrgRev_fx[NSUBBLOCKS]; @@ -1676,7 +1827,6 @@ Word16 transient_analysis_ivas_fx( FOR( i = NSUBBLOCKS - 1; i > -1; i-- ) { - IF( EQ_16( i, NSUBBLOCKS - 1 ) ) { accSubblockNrgRev_fx[i] = pSubblockNrg[i + offset]; @@ -1719,15 +1869,16 @@ Word16 transient_analysis_ivas_fx( } } - return prel_force_td != 0; } + /*-------------------------------------------------------------------* * set_transient_stereo() * * *-------------------------------------------------------------------*/ + void set_transient_stereo_fx( CPE_ENC_HANDLE hCPE, /* i : CPE structure */ Word32 currFlatness[] /* i/o: current flatness */