From 50852fa60db649b94a3e7da799c17a82af7579fe Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 27 Feb 2025 18:30:52 +0530 Subject: [PATCH 1/2] Fix for 3GPP issue 1308: Large differences between BASOP and float for critical item in MDCT-stereo @96kbps Link #1308 --- lib_com/lpc_tools_fx.c | 85 +++++++++++++++++++++++++++++++++++++++ lib_com/prot_fx.h | 1 + lib_com/stat_com.h | 1 + lib_com/tns_base.c | 2 + lib_enc/cod_tcx.c | 41 ++++++++++--------- lib_enc/prot_fx_enc.h | 3 +- lib_enc/tns_base_enc_fx.c | 74 +++++++++++++++++++++++++++++----- 7 files changed, 175 insertions(+), 32 deletions(-) diff --git a/lib_com/lpc_tools_fx.c b/lib_com/lpc_tools_fx.c index ef6c0b0ff..bde05b4f4 100644 --- a/lib_com/lpc_tools_fx.c +++ b/lib_com/lpc_tools_fx.c @@ -1210,6 +1210,91 @@ Word16 E_LPC_lsp_unweight( return 0; } +/* + * E_LPC_schur_ivas + * + * Parameters: + * R I: Rh[M+1] Vector of autocorrelations (msb) + * reflCoeff O: rc[M] Reflection coefficients. Q15 + * epsP O: error vector + * + * Function: + * Schur algorithm to compute + * the LPC parameters from the autocorrelations of speech. + * + * Returns: + * void + */ +Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m ) +{ + Word16 i, j, temp16, mMi, s; + Word32 g0[M], *g1, tmp32; + const Word32 min_epsP = 1; /* > 0.01f*2^27/2^30 */ + Word32 tmp_epsP; + + s = getScaleFactor32( r, add( m, 1 ) ); + IF( s != 0 ) + { + scale_sig32( r, add( m, 1 ), s ); /* scale in-place */ + } + + g1 = r; + Copy32( r + 1, g0, m ); + + /* compute g0[0]/g1[0], where g0[0] < g1[0] */ + temp16 = negate( divide3232( g0[0], g1[0] ) ); + reflCoeff[0] = temp16; + move16(); + // epsP[0] = r[0]; + move32(); + + + FOR( i = 0; i < m; i++ ) + { + /* g1[0] = g0[0]*temp16 + g1[0]; */ + tmp32 = Mpy_32_16_1( g0[0], temp16 ); + g1[0] = L_add( g1[0], tmp32 ); + move32(); + + mMi = sub( m, i ); + FOR( j = 1; j < mMi; j++ ) + { + /* g0[j-1] = g0[j] + g1[j]*temp16; + g1[j] = g0[j]*temp16 + g1[j]; */ + g0[j - 1] = L_add( g0[j], Mpy_32_16_1( g1[j], temp16 ) ); + move32(); + g1[j] = L_add( g1[j], Mpy_32_16_1( g0[j], temp16 ) ); + move32(); + } + temp16 = negate( divide3232( g0[0], g1[0] ) ); + reflCoeff[i + 1] = temp16; + move16(); + + /* Prediction errors */ + tmp_epsP = L_shr( g1[0], s ); + if ( tmp_epsP <= 0 ) + { + tmp_epsP = min_epsP; + move32(); + } + // epsP[i + 1] = tmp_epsP; + move32(); + } + + /* epsP[i+1] = g0[0]*temp16 + g1[0]; */ + tmp_epsP = L_add( g1[0], Mpy_32_16_1( g0[0], temp16 ) ); + tmp_epsP = L_shr( tmp_epsP, s ); + if ( tmp_epsP <= 0 ) + { + tmp_epsP = min_epsP; + move32(); + } + + /* prediction gain = divide3232(L_shr(epsP[0], PRED_GAIN_E), g1[0]); */ + + + return g1[0]; +} /* * E_LPC_schur diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index c67e2da28..5a6e24046 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -1198,6 +1198,7 @@ Word16 E_LPC_lsp_unweight( ); Word32 E_LPC_schur( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, Word32 epsP[] /*Qr*/, const Word16 m ); +Word32 E_LPC_schur_ivas( Word32 r[] /*Qr*/, Word16 reflCoeff[] /*Q15*/, const Word16 m ); void E_LPC_a_lsf_isf_conversion( Word16 *lpcCoeffs /*Qx*/, Word16 *lsf /*15Q16*/, const Word16 *old_lsf /*15Q16*/, Word16 lpcOrder, Word8 lpcRep /*Q0*/ ); diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index 2340c7a75..b1b1d1f61 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -197,6 +197,7 @@ typedef struct TNS_filter_structure Word16 order; /* Filter order. */ Word16 coefIndex[TNS_MAX_FILTER_ORDER]; /* Quantized filter coefficients. */ Word16 predictionGain; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q7 */ + Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q23 */ Word16 avgSqrCoef; /* Average squared filter coefficient. E(0), Q15 */ } STnsFilter; diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index af4a87d34..b5fd1f41f 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -1202,6 +1202,8 @@ void ResetTnsData( STnsData *pTnsData ) move16(); pTnsFilter->predictionGain = ONE_IN_Q7; /*Q7*/ move16(); + pTnsFilter->predictionGain32 = ONE_IN_Q23; /*Q23*/ + move32(); pTnsFilter->avgSqrCoef = 0; move16(); pTnsFilter->filterType = TNS_FILTER_OFF; /*Q0*/ diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 25f615e6a..d0d36b502 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -55,8 +55,9 @@ * *-------------------------------------------------------------------*/ -#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) -#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) +#define SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ( 1311 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ( 384 ) +#define TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ( 25165824 ) void TNSAnalysisStereo_fx( Encoder_State **sts, /* i : encoder state handle */ Word32 *mdst_spectrum_fx[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum Qx*/ @@ -72,7 +73,7 @@ void TNSAnalysisStereo_fx( Encoder_State *st = NULL; TCX_ENC_HANDLE hTcxEnc = NULL; Word16 individual_decision[NB_DIV]; - Word16 maxPredictionGain_fx = 0, meanPredictionGain_fx; + Word32 maxPredictionGain_fx = 0, meanPredictionGain_fx; move16(); individual_decision[0] = 0; @@ -144,7 +145,7 @@ void TNSAnalysisStereo_fx( BREAK; } - CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k], NULL ); + CalculateTnsFilt_fx( st->hTcxCfg->pCurrentTnsConfig, spectrum_fx, hTcxEnc->spectrum_e[k], &hTcxEnc->tnsData[k] ); } } } @@ -209,7 +210,7 @@ void TNSAnalysisStereo_fx( test(); IF( sts[0]->hTcxCfg->fIsTNSAllowed && NE_16( individual_decision[k], 1 ) && ( !bWhitenedDomain || sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word16 maxPredGain_fx = -ONE_IN_Q7; + Word32 maxPredGain_fx = -ONE_IN_Q23; move16(); sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; @@ -227,30 +228,30 @@ void TNSAnalysisStereo_fx( * both filters for the decision */ - meanPredictionGain_fx = mac_r( L_mult( pFilter[0]->predictionGain, 16384 /*0.5f Q15*/ ), pFilter[1]->predictionGain, 16384 /*0.5f Q15*/ ); // Q7 - maxPredictionGain_fx = s_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q7 + meanPredictionGain_fx = L_add( Mpy_32_16_1( pFilter[0]->predictionGain32, 16384 /*0.5f Q15*/ ), Mpy_32_16_1( pFilter[1]->predictionGain32, 16384 /*0.5f Q15*/ ) ); // Q23 + maxPredictionGain_fx = L_max( maxPredictionGain_fx, meanPredictionGain_fx ); // Q23 test(); test(); test(); - IF( GT_16( pFilter[0]->predictionGain, pTnsParameters[0]->minPredictionGain ) && LT_32( sts[0]->element_brate, IVAS_80k ) && - GT_16( pFilter[1]->predictionGain, pTnsParameters[1]->minPredictionGain ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) + IF( GT_32( pFilter[0]->predictionGain32, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) && LT_32( sts[0]->element_brate, IVAS_80k ) && + GT_32( pFilter[1]->predictionGain32, L_shl( pTnsParameters[1]->minPredictionGain, 16 ) ) && EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) { - pFilter[0]->predictionGain = pFilter[1]->predictionGain = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ + pFilter[0]->predictionGain32 = pFilter[1]->predictionGain32 = meanPredictionGain_fx; /* more TNS filter sync at 48kbps */ move16(); move16(); } test(); - IF( LT_16( abs_s( sub( pFilter[0]->predictionGain, pFilter[1]->predictionGain ) ), mult( SIMILAR_TNS_THRESHOLD_FX_IN_Q15, meanPredictionGain_fx ) ) && + IF( LT_32( L_abs( L_sub( pFilter[0]->predictionGain32, pFilter[1]->predictionGain32 ) ), Mpy_32_16_1( meanPredictionGain_fx, SIMILAR_TNS_THRESHOLD_FX_IN_Q15 ) ) && ( EQ_16( sts[0]->hTcxEnc->tnsData[k].nFilters, sts[1]->hTcxEnc->tnsData[k].nFilters ) ) ) { Word16 maxAvgSqrCoef_fx = s_max( pFilter[0]->avgSqrCoef, pFilter[1]->avgSqrCoef ); // Q15 Word16 meanLtpGain_fx = add( shr( sts[0]->hTcxEnc->tcxltp_gain, 1 ), shr( sts[1]->hTcxEnc->tcxltp_gain, 1 ) ); - maxPredGain_fx = s_max( maxPredGain_fx, meanPredictionGain_fx ); + maxPredGain_fx = L_max( maxPredGain_fx, meanPredictionGain_fx ); test(); test(); - IF( GT_16( meanPredictionGain_fx, pTnsParameters[0]->minPredictionGain ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) + IF( GT_32( meanPredictionGain_fx, L_shl( pTnsParameters[0]->minPredictionGain, 16 ) ) || GT_16( maxAvgSqrCoef_fx, pTnsParameters[0]->minAvgSqrCoef ) ) { test(); test(); @@ -456,7 +457,7 @@ void TNSAnalysisStereo_fx( test(); test(); test(); - IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_16( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && individual_decision[k] == 0 && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[0]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[0]->hTcxEnc->bTnsOnWhithenedSpectra[k] = 1; move16(); @@ -476,7 +477,7 @@ void TNSAnalysisStereo_fx( ClearTnsFilterCoefficients( sts[1]->hTcxEnc->tnsData[k].filter + iFilter ); } } - maxPredictionGain_fx = s_max( maxPredictionGain_fx, maxPredGain_fx ); + maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); } } } @@ -514,7 +515,7 @@ void TNSAnalysisStereo_fx( IF( sts[ch]->hTcxCfg->fIsTNSAllowed && ( individual_decision[k] || mct_on ) && ( !bWhitenedDomain || sts[ch]->hTcxEnc->bTnsOnWhithenedSpectra[k] ) ) { - Word16 maxPredGain_fx = -ONE_IN_Q7; // Q7 + Word32 maxPredGain_fx = -ONE_IN_Q23; // Q23 move16(); sts[ch]->hTcxCfg->pCurrentTnsConfig = &sts[ch]->hTcxCfg->tnsConfig[sts[ch]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[ch]->last_core == ACELP_CORE )]; @@ -525,9 +526,9 @@ void TNSAnalysisStereo_fx( pFilter = sts[ch]->hTcxEnc->tnsData[k].filter + iFilter; pTnsParameters = sts[ch]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; - maxPredGain_fx = s_max( maxPredGain_fx, pFilter->predictionGain ); + maxPredGain_fx = L_max( maxPredGain_fx, pFilter->predictionGain32 ); test(); - IF( GT_16( pFilter->predictionGain, pTnsParameters->minPredictionGain ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) + IF( GT_32( pFilter->predictionGain32, L_shl( pTnsParameters->minPredictionGain, 16 ) ) || GT_16( pFilter->avgSqrCoef, pTnsParameters->minAvgSqrCoef ) ) { test(); test(); @@ -601,7 +602,7 @@ void TNSAnalysisStereo_fx( move16(); test(); test(); - IF( !bWhitenedDomain && LT_16( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q7 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) + IF( !bWhitenedDomain && LT_32( maxPredGain_fx, TNS_GAIN_THRESHOLD_FOR_WHITE_FX_IN_Q23 ) && NE_16( sts[ch]->hTcxEnc->transform_type[k], TCX_5 ) ) { sts[ch]->hTcxEnc->fUseTns[k] = 0; move16(); @@ -616,7 +617,7 @@ void TNSAnalysisStereo_fx( move16(); } } - maxPredictionGain_fx = s_max( maxPredictionGain_fx, maxPredGain_fx ); + maxPredictionGain_fx = L_max( maxPredictionGain_fx, maxPredGain_fx ); } } } diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index 38552ba0d..a8e7f1047 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1629,8 +1629,7 @@ void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ const Word16 pSpectrum_e, - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain Q7*/ + STnsData *pTnsData /* o : TNS data struct */ ); /** Detect TNS parameters. diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index d1763e039..cc9596ba0 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -26,6 +26,8 @@ */ static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ); +static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ); + /** Quantization for reflection coefficients. * * @param parCoeff input reflection coefficients. @@ -313,8 +315,7 @@ void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum */ const Word16 pSpectrum_e, - STnsData *pTnsData, /* o : TNS data struct */ - Word16 *predictionGain /* o : TNS prediction gain */ + STnsData *pTnsData /* o : TNS data struct */ ) { Word32 norms[TNS_MAX_NUM_OF_FILTERS][MAX_SUBDIVISIONS]; @@ -410,17 +411,10 @@ void CalculateTnsFilt_fx( pFilter->spectrumLength = spectrumLength; move16(); /* Limit the maximum order to spectrum length/4 */ - GetFilterParameters( rxx, s_min( pTnsConfig->maxOrder, shr( pFilter->spectrumLength, 2 ) ), pFilter ); + GetFilterParameters_ivas( rxx, s_min( pTnsConfig->maxOrder, shr( pFilter->spectrumLength, 2 ) ), pFilter ); } } - IF( predictionGain ) - { - assert( pTnsConfig->nMaxFilters == 1 ); - *predictionGain = pTnsData->filter->predictionGain; - move16(); - } - return; } @@ -845,7 +839,67 @@ Word16 WriteTnsData_ivas_fx( STnsConfig const *pTnsConfig, Word16 const *stream, /********************************/ /* Private functions */ /********************************/ +static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ) +{ + Word16 i; + Word16 parCoeff[TNS_MAX_FILTER_ORDER + 1]; + Word32 rxx_0; + Word32 L_tmp; +#if TNS_COEF_RES == 5 + Word16 const *values = tnsCoeff5; +#elif TNS_COEF_RES == 4 + Word16 const *values = tnsCoeff4; +#elif TNS_COEF_RES == 3 + Word16 const *values = tnsCoeff3; +#endif + Word16 *indexes = pTnsFilter->coefIndex; + + rxx_0 = rxx[0]; + move32(); + /* compute TNS filter in lattice (ParCor) form with LeRoux-Gueguen algorithm */ + L_tmp = E_LPC_schur_ivas( rxx, parCoeff, maxOrder ); + BASOP_SATURATE_WARNING_OFF_EVS /* Allow saturation, this value is compared against a threshold. */ + Word16 temp_e = 0; + move16(); + Word16 temp = BASOP_Util_Divide3232_Scale( rxx_0, L_tmp, &temp_e ); + pTnsFilter->predictionGain32 = L_shl( temp, ( sub( add( 16, temp_e ), PRED_GAIN_E ) ) ); // Q23 + move32(); + pTnsFilter->predictionGain = extract_h( pTnsFilter->predictionGain32 ); // Q7 + move16(); + BASOP_SATURATE_WARNING_ON_EVS + /* non-linear quantization of TNS lattice coefficients with given resolution */ + Parcor2Index( parCoeff, indexes, maxOrder ); + /* reduce filter order by truncating trailing zeros */ + i = sub( maxOrder, 1 ); + + test(); + WHILE( ( i >= 0 ) && ( indexes[i] == 0 ) ) + { + i = sub( i, 1 ); + } + + + pTnsFilter->order = add( i, 1 ); + move16(); + + /* compute avg(coef*coef) */ + L_tmp = L_deposit_l( 0 ); + + FOR( i = pTnsFilter->order - 1; i >= 0; i-- ) + { + Word16 value; + + value = shr( values[indexes[i] + INDEX_SHIFT], 1 ); + + L_tmp = L_mac0( L_tmp, value, value ); + } + + pTnsFilter->avgSqrCoef = round_fx( L_tmp ); + move16(); + /* assert(maxOrder == 8); + pTnsFilter->avgSqrCoef = shr(pTnsFilter->avgSqrCoef, 3); */ +} static void GetFilterParameters( Word32 rxx[], Word16 maxOrder, STnsFilter *pTnsFilter ) { Word16 i; -- GitLab From 643d82a6a705e2fa53484c8941c439b18e8023d1 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Thu, 27 Feb 2025 18:34:48 +0530 Subject: [PATCH 2/2] Clang formatting changes --- lib_com/stat_com.h | 2 +- lib_enc/prot_fx_enc.h | 2 +- lib_enc/tns_base_enc_fx.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index b1b1d1f61..af097da84 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -197,7 +197,7 @@ typedef struct TNS_filter_structure Word16 order; /* Filter order. */ Word16 coefIndex[TNS_MAX_FILTER_ORDER]; /* Quantized filter coefficients. */ Word16 predictionGain; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q7 */ - Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q23 */ + Word32 predictionGain32; /* Prediction gain. The ratio of a signal and TNS residual energy. E(PRED_GAIN_E), Q23 */ Word16 avgSqrCoef; /* Average squared filter coefficient. E(0), Q15 */ } STnsFilter; diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index a8e7f1047..58da977a7 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1629,7 +1629,7 @@ void CalculateTnsFilt_fx( STnsConfig const *pTnsConfig, /* i : TNS Configuration struct */ const Word32 pSpectrum[], /* i : MDCT spectrum Qx*/ const Word16 pSpectrum_e, - STnsData *pTnsData /* o : TNS data struct */ + STnsData *pTnsData /* o : TNS data struct */ ); /** Detect TNS parameters. diff --git a/lib_enc/tns_base_enc_fx.c b/lib_enc/tns_base_enc_fx.c index cc9596ba0..452842e30 100644 --- a/lib_enc/tns_base_enc_fx.c +++ b/lib_enc/tns_base_enc_fx.c @@ -879,7 +879,7 @@ static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter i = sub( i, 1 ); } - + pTnsFilter->order = add( i, 1 ); move16(); @@ -894,7 +894,7 @@ static void GetFilterParameters_ivas( Word32 rxx[], Word16 maxOrder, STnsFilter L_tmp = L_mac0( L_tmp, value, value ); } - + pTnsFilter->avgSqrCoef = round_fx( L_tmp ); move16(); /* assert(maxOrder == 8); -- GitLab