From 819251dbb7b524df75ac3c10e8d35ecdb9453288 Mon Sep 17 00:00:00 2001 From: vaclav Date: Tue, 9 Sep 2025 09:10:33 +0200 Subject: [PATCH 1/5] remove duplicates of Transient detector handles + editorial improvements to match closer the FLP framework --- lib_com/ivas_prot_fx.h | 4 +- lib_enc/core_enc_ol_fx.c | 4 +- lib_enc/ext_sig_ana_fx.c | 4 +- lib_enc/igf_enc_fx.c | 2 +- lib_enc/init_enc_fx.c | 14 +- lib_enc/ivas_cpe_enc_fx.c | 2 +- lib_enc/ivas_ism_enc_fx.c | 2 +- lib_enc/ivas_sce_enc_fx.c | 2 +- lib_enc/mdct_selector_fx.c | 4 +- lib_enc/pre_proc_fx.c | 8 +- lib_enc/prot_fx_enc.h | 62 ++++-- lib_enc/stat_enc.h | 11 - lib_enc/tcx_ltp_enc_fx.c | 79 +++---- lib_enc/transient_detection_fx.c | 361 ++++++++++++++++++++++--------- 14 files changed, 365 insertions(+), 194 deletions(-) diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 12ad07e5c..6e7c88d12 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3152,9 +3152,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 bd9d5375f..c1e150e6e 100644 --- a/lib_enc/core_enc_ol_fx.c +++ b/lib_enc/core_enc_ol_fx.c @@ -693,7 +693,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; @@ -884,7 +884,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 87fa6a451..42f6dc487 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 c57f5ffb0..e3de5f9a6 100644 --- a/lib_enc/igf_enc_fx.c +++ b/lib_enc/igf_enc_fx.c @@ -1752,7 +1752,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 0ee479a7c..f08c41dc6 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -882,10 +882,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*/ ); + + 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" ) ); + } // PMT("Transient detector init needs review, handle hTranDet is missing") InitTransientDetection_fx( extract_l( Mult_32_16( st_fx->input_Fs, 0x0290 ) ), NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ), - &st_fx->transientDetection ); + st_fx->hTranDet, 0 ); st_fx->Q_syn2 = 0; move16(); @@ -2144,9 +2149,8 @@ ivas_error init_encoder_ivas_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); } - Word16 temp; - Word16 frame_length = BASOP_Util_Divide3232_Scale( st->input_Fs, FRAMES_PER_SEC, &temp ); - frame_length = shr( frame_length, sub( 15, temp ) ); + + Word16 frame_length = extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ); IF( GT_16( st->element_mode, EVS_MONO ) ) { @@ -2156,7 +2160,7 @@ ivas_error init_encoder_ivas_fx( { InitTransientDetection_fx( extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ), NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), - &st->transientDetection ); + st->hTranDet, 0 ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/ivas_cpe_enc_fx.c b/lib_enc/ivas_cpe_enc_fx.c index c9c54c2c6..b73702d21 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 dc41c784d..6b75a6be7 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_sce_enc_fx.c b/lib_enc/ivas_sce_enc_fx.c index 180e175ec..cb41ad51e 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 c4cc7d0db..8799806e4 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 55e7437ee..ea94e6236 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -209,7 +209,7 @@ void pre_proc_fx( /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ) ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ) ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* @@ -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 28389e9e0..0d7fa5968 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1044,14 +1044,17 @@ 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. */ -void InitTransientDetection_fx( Word16 nFrameLength, - Word16 nTCXDelay, - struct TransientDetection *pTransientDetection ); - -void InitTransientDetection_ivas_fx( Word16 nFrameLength, - Word16 nTCXDelay, - TRAN_DET_HANDLE pTransientDetection, - const Word16 ext_mem_flag ); +void InitTransientDetection_fx( + const Word16 nFrameLength, + const Word16 nTCXDelay, + TRAN_DET_HANDLE hTranDet, + const Word16 ext_mem_flag ); + +void InitTransientDetection_ivas_fx( + const Word16 nFrameLength, + const Word16 nTCXDelay, + TRAN_DET_HANDLE pTransientDetection, + const Word16 ext_mem_flag ); /** Runs transient detection. * Runs all transient detectors defined in pTransientDetection @@ -1060,7 +1063,10 @@ void InitTransientDetection_ivas_fx( Word16 nFrameLength, * @param nSamplesAvailable Number of new i samples available. * @param pTransientDetection Structure that contains transient detectors to be run. */ -void RunTransientDetection_fx( Word16 const *i, Word16 nSamplesAvailable, struct TransientDetection *pTransientDetection ); +void RunTransientDetection_fx( + Word16 const *i, + const Word16 nSamplesAvailable, + TRAN_DET_HANDLE hTranDet ); void RunTransientDetection_ivas_fx( @@ -1077,8 +1083,15 @@ void RunTransientDetection_ivas_fx( * @param nPrevSubblocks Number of subblocks from the previous frames to use for the calculation. * @return average temporal flatness measure with exponent AVG_FLAT_E */ -Word16 GetTCXAvgTemporalFlatnessMeasure_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ); -Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const *pTransientDetection, Word16 nCurrentSubblocks, Word16 nPrevSubblocks ); +Word16 GetTCXAvgTemporalFlatnessMeasure_fx( + TRAN_DET_HANDLE hTranDetn, + const Word16 nCurrentSubblocks, + const Word16 nPrevSubblocks ); + +Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( + 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. @@ -1087,16 +1100,18 @@ Word32 GetTCXAvgTemporalFlatnessMeasure_ivas_fx( struct TransientDetection const * @param nPrevSubblocks Number of subblocks from the previous frames to use for the calculation. * @param maximum energy change with exponent NRG_CHANGE_E */ -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 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 ); /** Set TCX window length and overlap configuration * @param prevEnergyHF previous HF energy. Exponent must be the same as for currEnergyHF. @@ -1112,9 +1127,10 @@ void SetTCXModeInfo_ivas_fx( * @param prevEnergyHF previous HF energy. Exponent must be the same as for currEnergyHF. * @param currEnergyHF current HF energy. Exponent must be the same as for prevEnergyHF. */ -void SetTCXModeInfo_fx( Encoder_State *st, - struct TransientDetection const *pTransientDetection, - Word16 *tcxModeOverlap ); +void SetTCXModeInfo_fx( + Encoder_State *st, + TRAN_DET_HANDLE hTranDet, + Word16 *tcxModeOverlap ); void GSC_enc_init_fx( GSC_ENC_HANDLE hGSCEnc /* i/o: GSC data handle */ @@ -2669,7 +2685,7 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, Word16 pitfr2, Word16 pitmax, Word16 pitres, - struct TransientDetection const *pTransientDetection, + TRAN_DET_HANDLE pTransientDetection, Word8 SideInfoOnly, Word16 *A, Word16 lpcorder ); diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index fdcff722c..d9afb7f99 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 3cb55ba25..94a655d6e 100644 --- a/lib_enc/tcx_ltp_enc_fx.c +++ b/lib_enc/tcx_ltp_enc_fx.c @@ -588,36 +588,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; @@ -632,7 +635,6 @@ void tcx_ltp_encode_fx( Word16 tcxltp_on, move32(); #endif - norm_corr = 0; move16(); @@ -669,11 +671,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(); @@ -877,8 +877,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, @@ -1023,15 +1026,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 1ad69a330..89b5464dd 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 ); + IF( ext_mem_flag ) + { + 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(); + } + + 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 +422,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 +445,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 +474,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 +491,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 +520,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 +540,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 +561,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 +603,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 +619,6 @@ Word16 GetTCXMaxenergyChange_ivas_fx( TRAN_DET_HANDLE hTranDet, Word16 maxEnergyChange; Word16 nTotBlocks; - pTransientDetector = &hTranDet->transientDetector; pSubblockEnergies = pTransientDetector->pSubblockEnergies; move16(); @@ -620,13 +680,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 +701,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 +791,13 @@ void RunTransientDetection_ivas_fx( return; } + /*-------------------------------------------------------------------* * isLongTermTransient_fx() * * *-------------------------------------------------------------------*/ + static Word16 isLongTermTransient_fx( const Word32 frameTFM, Word32 *lastTFM ) @@ -754,6 +821,7 @@ static Word16 isLongTermTransient_fx( { return 1; } + return 0; } @@ -814,7 +882,6 @@ void SetTCXModeInfo_ivas_fx( move16(); } } - #ifdef SUPPORT_FORCE_TCX10_TCX20 #ifdef DEBUGGING if ( st->force == FORCE_TCX10 ) @@ -865,7 +932,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 +962,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 +1000,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 +1025,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 +1074,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 +1084,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 +1094,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 +1125,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 +1151,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 +1184,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 +1229,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 +1244,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 +1276,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 +1322,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 +1364,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 +1390,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 +1418,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 +1448,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 +1481,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 +1504,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 +1624,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 +1729,11 @@ static void CalculateSubblockEnergies_ivas_fx( Word16 const *input, Word16 nSamp move16(); } } + + return; } + /*-------------------------------------------------------------------* * transient_analysis() * @@ -1583,9 +1744,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 +1837,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 +1879,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 */ -- GitLab From 2a12927459a32b8109bc6adcb88146dbaa24fb4a Mon Sep 17 00:00:00 2001 From: vaclav Date: Sun, 21 Sep 2025 19:58:06 +0200 Subject: [PATCH 2/5] clang-format --- lib_enc/pre_proc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/pre_proc_fx.c b/lib_enc/pre_proc_fx.c index 08d225f98..29a0aa229 100644 --- a/lib_enc/pre_proc_fx.c +++ b/lib_enc/pre_proc_fx.c @@ -209,7 +209,7 @@ void pre_proc_fx( /*----------------------------------------------------------------* * Change the sampling frequency to 12.8 kHz *----------------------------------------------------------------*/ - modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, (const Word16) ( EQ_16( st->max_bwidth, NB ) ) ); + modify_Fs_fx( signal_in, input_frame, st->input_Fs, new_inp_12k8, INT_FS_12k8, st->mem_decim_fx, ( const Word16 )( EQ_16( st->max_bwidth, NB ) ) ); Copy( new_inp_12k8, st->buf_speech_enc + L_FRAME32k, L_FRAME ); Scale_sig( st->buf_speech_enc + L_FRAME32k, L_FRAME, 1 ); /*------------------------------------------------------------------* -- GitLab From 6a8654c6a0fc874beecc1b09b8cad90b5aaec5ec Mon Sep 17 00:00:00 2001 From: vaclav Date: Sun, 21 Sep 2025 21:48:31 +0200 Subject: [PATCH 3/5] revert change in InitTransientDetection_fx() --- lib_enc/init_enc_fx.c | 8 +++----- lib_enc/prot_fx_enc.h | 3 +-- lib_enc/transient_detection_fx.c | 18 ++++-------------- 3 files changed, 8 insertions(+), 21 deletions(-) diff --git a/lib_enc/init_enc_fx.c b/lib_enc/init_enc_fx.c index 6de7d7955..4a8f3ea08 100644 --- a/lib_enc/init_enc_fx.c +++ b/lib_enc/init_enc_fx.c @@ -883,10 +883,10 @@ ivas_error init_encoder_fx( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Transient Detection\n" ) ); } - // PMT("Transient detector init needs review, handle hTranDet is missing") + InitTransientDetection_fx( extract_l( Mult_32_16( st_fx->input_Fs, 0x0290 ) ), NS2SA_FX2( st_fx->input_Fs, DELAY_FIR_RESAMPL_NS ), - st_fx->hTranDet, 0 ); + st_fx->hTranDet ); st_fx->Q_syn2 = 0; move16(); @@ -2154,9 +2154,7 @@ ivas_error init_encoder_ivas_fx( } ELSE { - InitTransientDetection_fx( extract_l( Mult_32_16( st->input_Fs, 0x0290 ) ), - NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), - st->hTranDet, 0 ); + InitTransientDetection_fx( frame_length, NS2SA_FX2( st->input_Fs, DELAY_FIR_RESAMPL_NS ), st->hTranDet ); } /*-----------------------------------------------------------------* diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 0ca11fdf8..e64c18468 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1073,8 +1073,7 @@ void calculate_hangover_attenuation_gain_fx( void InitTransientDetection_fx( const Word16 nFrameLength, const Word16 nTCXDelay, - TRAN_DET_HANDLE hTranDet, - const Word16 ext_mem_flag ); + TRAN_DET_HANDLE hTranDet ); void InitTransientDetection_ivas_fx( const Word16 nFrameLength, diff --git a/lib_enc/transient_detection_fx.c b/lib_enc/transient_detection_fx.c index 89b5464dd..bb8239f90 100644 --- a/lib_enc/transient_detection_fx.c +++ b/lib_enc/transient_detection_fx.c @@ -364,8 +364,7 @@ static void InitTCXTransientDetector( void InitTransientDetection_fx( const Word16 nFrameLength, const Word16 nTCXDelay, - TRAN_DET_HANDLE hTranDet, - const Word16 ext_mem_flag ) + TRAN_DET_HANDLE hTranDet ) { /* Init the delay buffer. */ InitDelayBuffer( nFrameLength, nTCXDelay, &hTranDet->delayBuffer ); @@ -377,18 +376,9 @@ void InitTransientDetection_fx( 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. */ - IF( ext_mem_flag ) - { - 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(); - } + hTranDet->transientDetector.pSubblockEnergies->nDelay = + add( hTranDet->transientDetector.pSubblockEnergies->nDelay, NSUBBLOCKS + 1 ); + move16(); return; } -- GitLab From 3c0f26cacd574114ebdf704902481b24fe69f6b4 Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 26 Sep 2025 11:59:15 +0200 Subject: [PATCH 4/5] simplify initialization with input_FS / FRAMES_PER_SEC --- lib_enc/ivas_mct_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 735e7e191..131ec9f8d 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( 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 ) -- GitLab From 4a81c7f67062bcc4da89cd65cc3e69c4b27792fa Mon Sep 17 00:00:00 2001 From: Markus Multrus Date: Fri, 26 Sep 2025 12:22:24 +0200 Subject: [PATCH 5/5] add missing extract_l() --- lib_enc/ivas_mct_enc_fx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_enc/ivas_mct_enc_fx.c b/lib_enc/ivas_mct_enc_fx.c index 131ec9f8d..39735ad03 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( Mult_32_16( st->input_Fs, INV_FRAME_PER_SEC_Q15 ), 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 ) -- GitLab