diff --git a/lib_com/cldfb_evs.c b/lib_com/cldfb_evs.c index c22e583be72911deda754f7d5297659237654203..923d2b8873b3f15ed2a49e3371ce98da27b4d4f2 100644 --- a/lib_com/cldfb_evs.c +++ b/lib_com/cldfb_evs.c @@ -1405,7 +1405,11 @@ void GetEnergyCldfb( Word32 *energyLookahead, /*!< o: Q(*sf_energyLookahead) { FOR( j = 20; j < numberBandsM; j++ ) { +#ifdef BASOP_NOGLOB + nrg = L_add_o( nrg, L_shr_o( energyValues[k][j], s, &Overflow ), &Overflow ); +#else nrg = L_add( nrg, L_shr( energyValues[k][j], s ) ); +#endif } } diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 2409d91bd764c8d79a6c9985bf0275f7cec0a281..119824b03fca1b39ca343a5ad8ca77f83dc41131 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -612,6 +612,7 @@ void stereo_tcx_core_dec( ); #endif // !IVAS_FLOAT_FIXED +#ifndef IVAS_FLOAT_FIXED void stereo_tcx_core_enc( Encoder_State *st, /* i/o: encoder state structure */ const float new_samples_12k8[], /* i : buffer of input signal @12.8 kHz */ @@ -623,6 +624,7 @@ void stereo_tcx_core_enc( const Word16 last_element_mode, /* i : last element mode, Q0 */ const Word16 vad_hover_flag /* i : VAD hangover flag, Q0 */ ); +#endif void stereo_tcx_init_dec( diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index d549056b50fef8628dbfda221f6d0d119996f7fb..e383aeea06a2558c21e7ed78aa1be0251c47f9ff 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -3080,6 +3080,19 @@ void InternalTCXDecoder_fx( Word16 *gain_tcx_q /* o : quantized global gain (at low bitrates) */ ); +void stereo_tcx_core_enc( + Encoder_State *st, /* i/o: encoder state structure */ + const Word16 new_samples_12k8[], /* i : buffer of input signal @12.8 kHz */ + const Word16 new_samples_16k[], /* i : buffer of input signal @16 kHz */ + const Word16 Aw_fx[], /* i : weighted A(z) unquant. for subframes, Q12 */ + Word16 lsp_new_fx[], /* i : LSPs at the end of the frame, Q15 */ + Word16 lsp_mid_fx[], /* i : LSPs in the middle of the frame, Q15 */ + Word16 pitch_buf_fx[NB_SUBFR16k], /* o : pitch for each subframe, Q6 */ + const Word16 last_element_mode, /* i : last element mode, Q0 */ + const Word16 vad_hover_flag /* i : VAD hangover flag, Q0 */ +); + + 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 */ diff --git a/lib_com/ivas_sns_com_fx.c b/lib_com/ivas_sns_com_fx.c index 9a7a092b3c78726cfa8def33b907da3d1909fc1e..5931c4ea1345e88bdad1ca30b998dfbcae89a882 100644 --- a/lib_com/ivas_sns_com_fx.c +++ b/lib_com/ivas_sns_com_fx.c @@ -123,10 +123,18 @@ void sns_compute_scf_fx( } /* Move accumulated values to 32-bit */ - q_shift = W_norm( x_64[0] ); + q_shift = 0; + move16(); + IF( x_64[0] != 0 ) + { + q_shift = W_norm( x_64[0] ); + } FOR( i = 1; i < nBands; ++i ) { - q_shift = s_min( q_shift, W_norm( x_64[i] ) ); + IF( x_64[i] != 0 ) + { + q_shift = s_min( q_shift, W_norm( x_64[i] ) ); + } } FOR( i = 0; i < nBands; ++i ) { diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 76d46c48cc168aeab9994bc80cd2b79c277028bf..f1cb75f78ea1fd3cdfd70794d58bcc04c59c078a 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -3512,17 +3512,6 @@ Word16 ITF_Detect_fx( Word32 const pSpectrum[], Word16 *curr_order, Word16 Q ); -Word16 ITF_Detect_ivas_fx( - const Word32 pSpectrum[], - const Word16 startLine, - const Word16 stopLine, - const Word16 maxOrder, - Word16 *A, - Word16 *Q_A, - Word16 *predictionGain, - Word16 *curr_order, - Word16 Q ); - void ITF_Apply_fx( Word32 spectrum[], Word16 startLine, Word16 stopLine, diff --git a/lib_com/tns_base.c b/lib_com/tns_base.c index 5e16ff6c27270431af98c80796275d5221c020f4..1e8e45df7ebeb49cb70d4a6709d3c2937690ee78 100644 --- a/lib_com/tns_base.c +++ b/lib_com/tns_base.c @@ -613,179 +613,6 @@ Word16 ITF_Detect_fx( return 1; } - -Word16 ITF_Detect_ivas_fx( - const Word32 pSpectrum[], /*Q*/ - const Word16 startLine, /*Q0*/ - const Word16 stopLine, /*Q0*/ - const Word16 maxOrder, /*Q0*/ - Word16 *A, /*Q_A*/ - Word16 *Q_A, - Word16 *predictionGain, /*Q7*/ - Word16 *curr_order, /*Q0*/ - Word16 Q ) -{ - - Word16 spectrumLength; - Word16 const nSubdivisions = MAX_SUBDIVISIONS; - move16(); - Word16 iSubdivisions; - Word16 iStartLine; - Word16 iEndLine; - Word16 facs[MAX_SUBDIVISIONS]; - Word16 facs_e[MAX_SUBDIVISIONS]; /* exponents of facs[][] */ - Word16 shifts[MAX_SUBDIVISIONS]; - Word16 tmp, headroom, shift; - Word32 rxx[ITF_MAX_FILTER_ORDER + 1]; - Word16 lag; - Word32 L_tmp, tmp32; - Word16 tmpbuf[325]; - Word16 n, i; - Word32 norms[MAX_SUBDIVISIONS]; - Word16 norms_e[MAX_SUBDIVISIONS]; -#ifdef BASOP_NOGLOB_DECLARE_LOCAL - Flag Overflow = 0; - move32(); -#endif - - set16_fx( norms_e, sub( 31, Q ), MAX_SUBDIVISIONS ); - if ( maxOrder <= 0 ) - { - return 0; - } - - /* Calculate norms for each spectrum part */ - FOR( iSubdivisions = 0; iSubdivisions < nSubdivisions; iSubdivisions++ ) - { - assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) ); - - tmp = sub( stopLine, startLine ); - iStartLine = imult1616( tmp, iSubdivisions ); /*Q0*/ - iEndLine = add( iStartLine, tmp ); - - IF( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/ - iStartLine = add( iStartLine, startLine ); - - IF( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/ - iEndLine = add( iEndLine, startLine ); - headroom = getScaleFactor32( pSpectrum + iStartLine - IGF_START_MN, sub( iEndLine, iStartLine ) ); - /* Calculate norm of spectrum band */ - L_tmp = Norm32Norm( pSpectrum + iStartLine - IGF_START_MN, headroom, sub( iEndLine, iStartLine ), &shift ); /*Q31 - shift*/ - - /* Check threshold HLM_MIN_NRG */ - BASOP_SATURATE_WARNING_OFF_EVS; -#ifdef BASOP_NOGLOB - tmp32 = L_sub( L_shl_o( L_tmp, sub( shift, 24 - Q ), &Overflow ), 4194304l /*HLM_MIN_NRG Q7*/ ); /*Q7*/ -#else /* BASOP_NOGLOB */ - tmp32 = L_sub( L_shl( L_tmp, sub( shift, 24 - Q ) ), 4194304l /*HLM_MIN_NRG Q7*/ ); -#endif - BASOP_SATURATE_WARNING_ON_EVS; - - /* get pre-shift for autocorrelation */ - tmp = sub( shift, norm_l( L_tmp ) ); /* exponent for normalized L_tmp */ - tmp = shr( sub( 1, tmp ), 1 ); /* pre-shift to apply before autocorrelation */ - shifts[iSubdivisions] = s_min( tmp, headroom ); - move16(); - - /* calc normalization factor */ - facs[iSubdivisions] = 0; - move16(); - facs_e[iSubdivisions] = 0; - move16(); - - if ( tmp32 > 0 ) - { - facs[iSubdivisions] = 0x7FFF; /*Q15*/ - move16(); /* normalization not needed for one subdivision */ - } - - IF( L_tmp > 0 ) - { - facs_e[iSubdivisions] = shl( sub( tmp, shifts[iSubdivisions] ), 1 ); - move16(); - - tmp = sub( 1, shl( tmp, 1 ) ); /* exponent of autocorrelation */ - L_tmp = L_shl( L_tmp, sub( shift, tmp ) ); /* shift L_tmp to that exponent */ - - /* calc factor (with 2 bits headroom for sum of 3 subdivisions) */ - facs[iSubdivisions] = div_s( 0x2000, round_fx_o( L_tmp, &Overflow ) ); /* L_tmp is >= 0x2000000 Q15*/ - move16(); - } - norms[iSubdivisions] = sum2_32_fx( pSpectrum + sub( iStartLine, IGF_START_MN ), sub( iEndLine, iStartLine ), &norms_e[iSubdivisions] ); /*Q31 - norms_e*/ - move16(); - } - - /* Calculate normalized autocorrelation for spectrum subdivision and get filter parameters based on it */ - set32_fx( rxx, 0, ITF_MAX_FILTER_ORDER + 1 ); - - spectrumLength = sub( stopLine, startLine ); - test(); - FOR( iSubdivisions = 0; ( iSubdivisions < nSubdivisions ) && GT_64( norms[iSubdivisions], W_shl( HLM_MIN_NRG_FX, sub( 31, norms_e[iSubdivisions] ) ) ); iSubdivisions++ ) - { - test(); - assert( ( nSubdivisions == 1 ) || ( nSubdivisions == 3 ) ); - - iStartLine = imult1616( spectrumLength, iSubdivisions ); /*Q0*/ - iEndLine = add( iStartLine, spectrumLength ); - - IF( EQ_16( nSubdivisions, 3 ) ) - iStartLine = mult( iStartLine, 0x2AAB ); /*Q0*/ - iStartLine = add( iStartLine, startLine ); - - IF( EQ_16( nSubdivisions, 3 ) ) - iEndLine = mult( iEndLine, 0x2AAB ); /*Q0*/ - iEndLine = add( iEndLine, startLine ); - - - move16(); - shift = shifts[iSubdivisions]; - - n = sub( iEndLine, iStartLine ); - assert( n < (Word16) ( sizeof( tmpbuf ) / sizeof( Word16 ) ) ); - FOR( i = 0; i < n; i++ ) - { - tmpbuf[i] = round_fx_o( L_shl( pSpectrum[iStartLine + i - IGF_START_MN], shift ), &Overflow ); /*Q+shift-16*/ - move16(); - } - - FOR( lag = 1; lag <= maxOrder; lag++ ) - { - n = sub( sub( iEndLine, lag ), iStartLine ); - - { - Word64 tmp64 = 0; - FOR( i = 0; i < n; i++ ) - { - tmp64 = W_mac0_16_16( tmp64, tmpbuf[i], tmpbuf[i + lag] ); /*2*( Q+shift-16)*/ - } - L_tmp = W_sat_l( tmp64 ); /*2*( Q+shift-16)*/ - } - - L_tmp = Mpy_32_16_1( L_tmp, facs[iSubdivisions] ); /*2*( Q+shift-16)*/ - L_tmp = L_shl( L_tmp, facs_e[iSubdivisions] ); - - rxx[lag] = L_add( rxx[lag], L_tmp ); /*2*( Q+shift-16)*/ - move32(); - } - } - - *predictionGain = 0; - move16(); - IF( EQ_16( iSubdivisions, nSubdivisions ) ) /* meaning there is no subdivision with low energy */ - { - rxx[0] = 3 * ONE_IN_Q29; - move32(); - /* Limit the maximum order to spectrum length/4 */ - ITF_GetFilterParameters_fx( rxx, s_min( maxOrder, shr( spectrumLength, 2 ) ), A, Q_A, predictionGain ); - - *curr_order = maxOrder; /*Q0*/ - move16(); - } - - return 1; -} /* Helper functions for Hufmann table coding */ diff --git a/lib_enc/ext_sig_ana_fx.c b/lib_enc/ext_sig_ana_fx.c index f81c1a665ac8c04ddb93cd34cf049312b9899b55..4092c58f2a3eabd47319ebfe4ee924ad911e0543 100644 --- a/lib_enc/ext_sig_ana_fx.c +++ b/lib_enc/ext_sig_ana_fx.c @@ -660,11 +660,12 @@ void core_signal_analysis_high_bitrate_ivas_fx( Word16 i, frameno; Word16 L_subframe; Word16 left_overlap = -1, right_overlap = -1, folding_offset; - Word32 buf[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ - Word16 mdstWin[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for MDST windowing */ + Word32 buf[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ + Word32 buf_powerSPec[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for TCX20/TCX10 windowing */ + Word16 mdstWin[N_MAX + L_MDCT_OVLP_MAX]; /* Buffer for MDST windowing */ Word16 *pMdstWin; Word16 lpc_left_overlap_mode, lpc_right_overlap_mode; - Word32 *powerSpec = buf; + Word32 *powerSpec = buf_powerSPec; Word16 powerSpec_e; Word16 *tcx20Win = (Word16 *) buf; Word32 *tcx20Win_32 = buf; @@ -1146,9 +1147,9 @@ void core_signal_analysis_high_bitrate_ivas_fx( } /* Compute noise-measure flags for spectrum filling and quantization */ - AnalyzePowerSpectrum_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ), - L_subframe, left_overlap, right_overlap, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_e[frameno], - pMdstWin, powerSpec, &powerSpec_e ); + AnalyzePowerSpectrum_ivas_fx( st, div_l( L_mult( L_subframe, st->L_frame ), hTcxEnc->L_frameTCX ), + L_subframe, left_overlap, right_overlap, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_e[frameno], + pMdstWin, powerSpec, &powerSpec_e ); } } } @@ -1387,6 +1388,8 @@ void core_signal_analysis_high_bitrate_ivas_fx( { Word16 q_spectrum = sub( Q31, hTcxEnc->spectrum_e[frameno] ); Word16 q_powerSpec = sub( Q31, powerSpec_e ); + st->hIGFEnc->spec_be_igf_e = hTcxEnc->spectrum_e[frameno]; + move16(); ProcessIGF_ivas_fx( st, hTcxEnc->spectrum_fx[frameno], hTcxEnc->spectrum_fx[frameno], &q_spectrum, powerSpec, &q_powerSpec, transform_type[frameno] == TCX_20, frameno, 0, vad_hover_flag ); } } diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 52ca1a022b5d36afb6b7c5a51217f6aed58ef105..0cd4a48b91a96ef1808c346006a213722c6106e4 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1049,7 +1049,12 @@ static void IGF_CalculateEnvelope_ivas_fx( FOR( sb = swb_offset[sfb]; sb < swb_offset[sfb + 1]; sb++ ) { sfbEnergyC = BASOP_Util_Add_Mant32Exp( sfbEnergyC, sfbEnergyC_e, pPowerSpectrum_fx[sb], e_ps, &sfbEnergyC_e ); - sfbEnergyTileR = BASOP_Util_Add_Mant32Exp( sfbEnergyTileR, sfbEnergyTileR_e, Mult_32_32( pMDCTSpectrum_fx[strt_cpy], pMDCTSpectrum_fx[strt_cpy] ), shl( e_mdct, 1 ), &sfbEnergyTileR_e ); + // sfbEnergyTileR = BASOP_Util_Add_Mant32Exp( sfbEnergyTileR, sfbEnergyTileR_e, Mult_32_32( pMDCTSpectrum_fx[strt_cpy], pMDCTSpectrum_fx[strt_cpy] ), shl( e_mdct, 1 ), &sfbEnergyTileR_e ); + Word64 tmp64 = W_mult_32_32( pMDCTSpectrum_fx[strt_cpy], pMDCTSpectrum_fx[strt_cpy] ); + Word16 tmp64_e = W_norm( tmp64 ); + tmp64 = W_shl( tmp64, tmp64_e ); + + sfbEnergyTileR = BASOP_Util_Add_Mant32Exp( sfbEnergyTileR, sfbEnergyTileR_e, W_extract_h( tmp64 ), shl( e_mdct, 1 ) - tmp64_e, &sfbEnergyTileR_e ); sfbEnergyTileC = BASOP_Util_Add_Mant32Exp( sfbEnergyTileC, sfbEnergyTileC_e, pPowerSpectrum_fx[strt_cpy], e_ps, &sfbEnergyTileC_e ); strt_cpy = add( strt_cpy, 1 ); diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index 5b1bf1f14b210bb89368990f8babe6aad7039d80..6dd5c909b747990ac833f7ccd8dd912646360653 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -135,6 +135,10 @@ ivas_error ivas_core_enc( Word16 i; #endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + Word16 lsp_new_fx[CPE_CHANNELS][M], lsp_mid_fx[CPE_CHANNELS][M]; +#endif + set32_fx( new_swb_speech_buffer_fx, 0, L_FRAME48k + STEREO_DFT_OVL_MAX ); set16_fx( new_swb_speech_buffer_fx_16, 0, L_FRAME48k + STEREO_DFT_OVL_MAX ); @@ -421,12 +425,8 @@ ivas_error ivas_core_enc( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS Word16 Aw_fx[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )]; float Aw_flt[CPE_CHANNELS][NB_SUBFR16k * ( M + 1 )]; - // Word16 lsp_new_fx[M], lsp_mid_fx[M]; - // Word16 n_subframes = EQ_16( st->hTcxEnc->tcxMode, TCX_10 ) ? 2 : 1; mvr2r( Aw[n], Aw_flt[n], st->nb_subfr * ( M + 1 ) ); floatToFixed_arr( Aw_flt[n], Aw_fx[n], Q12, st->nb_subfr * ( M + 1 ) ); - // floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); - // floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); st->hTcxCfg->preemph_fac = float_to_fix16( st->hTcxCfg->preemph_fac_flt, Q15 ); st->hTcxEnc->measuredBwRatio = float_to_fix16( st->hTcxEnc->measuredBwRatio_flt, Q14 ); @@ -434,13 +434,69 @@ ivas_error ivas_core_enc( st->hTcxEnc->Q_old_out = Q_factor_arr( st->hTcxEnc->old_out, L_FRAME32k ) - 1; floatToFixed_arr( st->hTcxEnc->old_out, st->hTcxEnc->old_out_fx, st->hTcxEnc->Q_old_out, L_FRAME32k ); -#endif // IVAS_FLOAT_FIXED_CONVERSIONS + Word16 nSubframes; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + IF( EQ_16( hTcxEnc->tcxMode, TCX_20 ) ) + { + nSubframes = 1; + } + ELSE + { + nSubframes = 2; + } + hTcxEnc->tcxltp_norm_corr_past = float_to_fix16( hTcxEnc->tcxltp_norm_corr_past_flt, Q15 ); + floatToFixed_arr16( st->lspold_enc, st->lspold_enc_fx, Q15, M ); + + Word16 q_spectrum = L_get_q_buf1( hTcxEnc->spectrum[0], st->hTcxEnc->L_frameTCX / nSubframes ); + hTcxEnc->spectrum_e[0] = 31 - q_spectrum; + floatToFixed_arrL32( hTcxEnc->spectrum[0], hTcxEnc->spectrum_fx[0], sub( Q31, hTcxEnc->spectrum_e[0] ), st->hTcxEnc->L_frameTCX / nSubframes ); + IF( hTcxEnc->tcxMode != TCX_20 ) + { + q_spectrum = L_get_q_buf1( hTcxEnc->spectrum[1], st->hTcxEnc->L_frameTCX / nSubframes ); + hTcxEnc->spectrum_e[1] = 31 - q_spectrum; + floatToFixed_arrL32( hTcxEnc->spectrum[1], hTcxEnc->spectrum_fx[1], sub( Q31, hTcxEnc->spectrum_e[1] ), st->hTcxEnc->L_frameTCX / nSubframes ); + } + + floatToFixed_arr( lsp_new[n], lsp_new_fx[n], Q15, M ); + floatToFixed_arr( lsp_mid[n], lsp_mid_fx[n], Q15, M ); +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + q_old_inp_12k8_fx = Q_factor_arr( old_inp_12k8[n], L_INP_12k8 ); + q_old_inp_16k_fx = Q_factor_arr( old_inp_16k[n], L_INP ); + floatToFixed_arr16( old_inp_12k8[n], old_inp_12k8_fx, q_old_inp_12k8_fx, L_INP_12k8 ); + floatToFixed_arr16( old_inp_16k[n], old_inp_16k_fx, q_old_inp_16k_fx, L_INP ); +#endif /* TCX core encoder */ - stereo_tcx_core_enc( st, old_inp_12k8[n] + L_INP_MEM, old_inp_16k[n] + L_INP_MEM, Aw_fx[n], lsp_new[n], lsp_mid[n], pitch_buf_fx[n], last_element_mode, vad_hover_flag[0] ); + stereo_tcx_core_enc( st, old_inp_12k8_fx + L_INP_MEM, old_inp_16k_fx + L_INP_MEM, Aw_fx[n], lsp_new_fx[n], lsp_mid_fx[n], pitch_buf_fx[n], last_element_mode, vad_hover_flag[0] ); + +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( lsp_new_fx[n], lsp_new[n], Q15, M ); + fixedToFloat_arr( lsp_mid_fx[n], lsp_mid[n], Q15, M ); + fixedToFloat_arr( st->lspold_enc_fx, st->lspold_enc, Q15, M ); +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS_ + if ( st->element_mode == IVAS_CPE_DFT ) + { + fixedToFloat_arr( st->buf_wspeech_enc, st->buf_wspeech_enc_flt, q_fac, L_FRAME16k + L_SUBFR + L_FRAME16k + L_NEXT_MAX_16k + 320 ); + } + else if ( st->element_mode != IVAS_CPE_MDCT ) + { + hTcxEnc->tcxltp_gain_past_flt = fix16_to_float( hTcxEnc->tcxltp_gain_past, Q15 ); + hTcxEnc->tcxltp_gain_flt = fix16_to_float( hTcxEnc->tcxltp_gain, Q15 ); + fixedToFloat_arr( st->hTcxEnc->buf_speech_ltp, st->hTcxEnc->buf_speech_ltp_flt, q_fac, L_PAST_MAX_32k + L_FRAME32k + L_NEXT_MAX_32k ); + } + + fixedToFloat_arrL32( hTcxEnc->spectrum_fx[0], hTcxEnc->spectrum[0], sub( Q31, hTcxEnc->spectrum_e[0] ), st->hTcxEnc->L_frameTCX / nSubframes ); + IF( hTcxEnc->tcxMode != TCX_20 ) + { + fixedToFloat_arrL32( hTcxEnc->spectrum_fx[1], hTcxEnc->spectrum[1], sub( Q31, hTcxEnc->spectrum_e[1] ), st->hTcxEnc->L_frameTCX / nSubframes ); + } +#endif #ifdef IVAS_FLOAT_FIXED_CONVERSIONS + hTcxEnc->tcxltp_norm_corr_past_flt = fix16_to_float( hTcxEnc->tcxltp_norm_corr_past, Q15 ); fixedToFloat_arr( pitch_buf_fx[n], pitch_buf[n], Q6, NB_SUBFR16k ); fixedToFloat_arr( st->hTcxEnc->old_out_fx, st->hTcxEnc->old_out, st->hTcxEnc->Q_old_out, L_FRAME32k ); diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 8d7aa9855eac22e954c73a010a4d606d7016dff2..c719ac54e841a6b5147f306938e50722a628d8f6 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -1850,7 +1850,8 @@ void ivas_mdct_core_whitening_enc( overlap_mode[2] = st->hTcxCfg->tcx_curr_overlap_mode; /* Overlap between the current and the next frame */ move16(); } - +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS_ Word16 offset; IF( ( EQ_16( transform_type[0], TCX_20 ) ) && ( NE_16( st->hTcxCfg->tcx_last_overlap_mode, TRANSITION_OVERLAP ) ) ) { @@ -1913,7 +1914,8 @@ void ivas_mdct_core_whitening_enc( floatToFixed_arrL32( windowedSignal[ch] + L_FRAME48k + 2, windowedSignal_fx[ch] + L_FRAME48k + 2, 0, len_windowSignal ); } } - +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS if ( st->element_mode == IVAS_CPE_DFT ) { hTcxEnc->tcxltp_norm_corr_past = float_to_fix16( hTcxEnc->tcxltp_norm_corr_past_flt, Q15 ); @@ -1941,10 +1943,13 @@ void ivas_mdct_core_whitening_enc( floatToFixed_arrL32( hTcxEnc->spectrum[1], hTcxEnc->spectrum_fx[1], sub( Q31, hTcxEnc->spectrum_e[1] ), st->hTcxEnc->L_frameTCX / nSubframes ); } + floatToFixed_arr( st->input_buff, st->input_buff_fx, 0, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ); + Q_new = 0; #endif core_signal_analysis_high_bitrate_ivas_fx( new_samples_fx[ch] + L_INP_MEM, T_op[ch], NULL, NULL, st, tnsSize[ch], tnsBits[ch], param_core[ch], <pBits[ch], windowedSignal_fx[ch], st->L_frame, st->hTcxEnc->L_frameTCX, hCPE->last_element_mode, 0, mdst_spectrum_fx[ch], mdst_spectrum_e[ch], &Q_new ); #ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( st->input_buff_fx, st->input_buff, 0, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ); IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 26a1d1ffb84dc6f2035afc029681ac3ed42a0097..2b6e1907dee1f68cb4fe067c91e887d642500301 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -229,11 +229,11 @@ void stereo_tcx_init_enc( #ifdef IVAS_FLOAT_FIXED void stereo_tcx_core_enc( Encoder_State *st, /* i/o: encoder state structure */ - const float new_samples_12k8[], /* i : buffer of input signal @12.8 kHz */ - const float new_samples_16k[], /* i : buffer of input signal @16 kHz */ + const Word16 new_samples_12k8[], /* i : buffer of input signal @12.8 kHz */ + const Word16 new_samples_16k[], /* i : buffer of input signal @16 kHz */ const Word16 Aw_fx[], /* i : weighted A(z) unquant. for subframes, Q12 */ - float lsp_new[], /* i : LSPs at the end of the frame, Q15 */ - float lsp_mid[], /* i : LSPs in the middle of the frame, Q15 */ + Word16 lsp_new_fx[], /* i : LSPs at the end of the frame, Q15 */ + Word16 lsp_mid_fx[], /* i : LSPs in the middle of the frame, Q15 */ Word16 pitch_buf_fx[NB_SUBFR16k], /* o : pitch for each subframe, Q6 */ const Word16 last_element_mode, /* i : last element mode, Q0 */ const Word16 vad_hover_flag /* i : VAD hangover flag, Q0 */ @@ -244,7 +244,7 @@ void stereo_tcx_core_enc( Word16 tmp1, tmp2; /*size and windowing*/ - const float *p_new_samples; + const Word16 *p_new_samples; Word16 q_ind_val; Word16 n_subframes; Word16 last_core_orig; @@ -306,7 +306,6 @@ void stereo_tcx_core_enc( #ifdef IVAS_FLOAT_FIXED_CONVERSIONS Word16 Q_new, Q_exc, q_comm_Bin; - Word16 lsp_new_fx[M], lsp_mid_fx[M]; #endif /*--------------------------------------------------------------* @@ -380,13 +379,11 @@ void stereo_tcx_core_enc( IF( EQ_16( st->L_frame, L_FRAME ) ) { - move16(); p_new_samples = new_samples_12k8; } ELSE { p_new_samples = new_samples_16k; - move16(); } /*--------------------------------------------------------------* @@ -452,7 +449,21 @@ void stereo_tcx_core_enc( *---------------------------------------------------------------*/ /* TODO: integrate this. */ +#ifdef IVAS_FLOAT_FIXED +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + floatToFixed_arr( st->input_buff, st->input_buff_fx, 0, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ); + st->prev_Q_new = 0; + st->Q_old = 0; +#endif + Q_new = 0; + move16(); + core_signal_analysis_high_bitrate_ivas_fx( p_new_samples, T_op, lsp_new_fx, lsp_mid_fx, st, tnsSize, tnsBits, param_core, <pBits, NULL, st->L_frame, hTcxEnc->L_frameTCX, last_element_mode, vad_hover_flag, NULL, NULL, &Q_new ); +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS + fixedToFloat_arr( st->input_buff_fx, st->input_buff, 0, L_FRAME48k + L_FRAME48k + NS2SA( 48000, DELAY_FIR_RESAMPL_NS ) ); +#endif +#else core_signal_analysis_high_bitrate( p_new_samples, T_op, lsp_new, lsp_mid, st, NULL, tnsSize, tnsBits, param_core, <pBits, NULL, st->L_frame, hTcxEnc->L_frameTCX, last_element_mode, vad_hover_flag ); +#endif bitsAvailable = sub( st->bits_frame_core, nbits_header ); IF( st->igf ) @@ -461,13 +472,13 @@ void stereo_tcx_core_enc( } #ifdef IVAS_FLOAT_FIXED_CONVERSIONS - floatToFixed_arr( lsp_new, lsp_new_fx, Q15, M ); - floatToFixed_arr( lsp_mid, lsp_mid_fx, Q15, M ); - q_comm_Bin = s_min( Q_factor_arrL( st->Bin_E_old, 128 ), Q_factor_arrL( st->Bin_E, 256 ) ); Q_new = q_comm_Bin - ( QSCALE - 2 ); const Word16 Q_ener = Q_new + Q_SCALE - 2; // Q_new + Q_SCALE -2 +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS_ + st->stab_fac_fx = float_to_fix16( st->stab_fac, Q15 ); floatToFixed_arrL( st->Bin_E_old, st->Bin_E_old_fx, q_comm_Bin, 128 ); floatToFixed_arrL( st->Bin_E, st->Bin_E_fx, q_comm_Bin, 256 ); @@ -500,7 +511,9 @@ void stereo_tcx_core_enc( L_frameTCX = sub( L_frameTCX, st->hTcxCfg->lfacNextFB ); } } +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS Q_new = 0; st->hTcxCfg->bandwidth = float_to_fix16( st->hTcxCfg->bandwidth_flt, Q15 ); @@ -512,7 +525,8 @@ void stereo_tcx_core_enc( { floatToFixed_arr( st->hTdCngEnc->cng_exc2_buf_flt, st->hTdCngEnc->cng_exc2_buf, Q_exc, HO_HIST_SIZE * L_FFT ); } - +#endif +#ifdef IVAS_FLOAT_FIXED_CONVERSIONS floatToFixed_arr( st->synth_flt, st->synth, Q_new, st->L_frame ); floatToFixed_arr( st->hLPDmem->syn_flt, st->hLPDmem->syn, Q_new, M + 1 ); if ( st->tcxonly == 0 ) @@ -822,9 +836,6 @@ void stereo_tcx_core_enc( fixedToFloat_arrL( st->Bin_E_old_fx, st->Bin_E_old, q_comm_Bin, 128 ); fixedToFloat_arrL( st->Bin_E_fx, st->Bin_E, q_comm_Bin, 256 ); - - fixedToFloat_arr( lsp_new_fx, lsp_new, Q15, M ); - fixedToFloat_arr( lsp_mid_fx, lsp_mid, Q15, M ); #endif pop_wmops(); diff --git a/lib_enc/prot_fx_enc.h b/lib_enc/prot_fx_enc.h index cfb2ba9d262cb2c401c26a06c188f1c4e94cd08f..0a9bc483ea33b3380ca9284c6d10fb05e6011a11 100644 --- a/lib_enc/prot_fx_enc.h +++ b/lib_enc/prot_fx_enc.h @@ -1246,6 +1246,18 @@ void AnalyzePowerSpectrum_fx( Word16 const signal[], /* i : windowed signal corresponding to mdctSpectrum */ Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ Word16 *powerSpec_e ); + +void AnalyzePowerSpectrum_ivas_fx( + Encoder_State *st, /* i/o: encoder states */ + Word16 L_frame, /* i : frame length */ + Word16 L_frameTCX, /* i : full band frame length */ + Word16 left_overlap, /* i : left overlap length */ + Word16 right_overlap, /* i : right overlap length */ + Word32 const mdctSpectrum[], /* i : MDCT spectrum */ + Word16 mdctSpectrum_e, + Word16 const signal[], /* i : windowed signal corresponding to mdctSpectrum */ + Word32 powerSpec[], /* o : Power spectrum. Can point to signal */ + Word16 *powerSpec_e ); void AdaptLowFreqEmph_fx( Word32 x[], Word16 x_e, Word16 xq[], diff --git a/lib_enc/swb_tbe_enc_fx.c b/lib_enc/swb_tbe_enc_fx.c index 3974a326dec150a4ac3291a9f47337465bd44fba..9b193ef8d4d186aa2266feccaf530cc52793b1d7 100644 --- a/lib_enc/swb_tbe_enc_fx.c +++ b/lib_enc/swb_tbe_enc_fx.c @@ -3714,32 +3714,49 @@ void swb_tbe_enc_ivas_fx( } Copy( shaped_shb_excitationTemp_fx, &shaped_shb_excitation_fx[L_SHB_LAHEAD], L_FRAME16k ); - - tmp = sub( shl( Q_bwe_exc, 1 ), 31 ); - prev_pow_fx = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 2*(Q_bwe_exc) */ - curr_pow_fx = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 2*(Q_bwe_exc) */ - FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + Word16 max_val; + maximum_abs_16_fx( shaped_shb_excitation_fx, L_FRAME16k + L_SHB_LAHEAD, &max_val ); + IF( max_val == 0 ) { + Lscale = ONE_IN_Q31; /* 1.0f in Q31 */ + move32(); + IF( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) + { + Lscale = ONE_IN_Q30; /* sqrtf(0.25) = 0.5 in Q31 */ + move32(); + } + exp = 0; + move16(); + } + ELSE + { + tmp = sub( shl( Q_bwe_exc, 1 ), 31 ); + prev_pow_fx = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 2*(Q_bwe_exc) */ + curr_pow_fx = L_shl( 21475l /*0.00001f Q31*/, tmp ); /* 2*(Q_bwe_exc) */ + FOR( i = 0; i < L_SHB_LAHEAD + 10; i++ ) + { #ifdef BASOP_NOGLOB - prev_pow_fx = L_mac0_o( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i], &Overflow ); /* 2*Q_bwe_exc */ - curr_pow_fx = L_mac0_o( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], &Overflow ); /* 2*Q_bwe_exc */ + prev_pow_fx = L_mac0_o( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i], &Overflow ); /* 2*Q_bwe_exc */ + curr_pow_fx = L_mac0_o( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], &Overflow ); /* 2*Q_bwe_exc */ #else - prev_pow_fx = L_mac0( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* 2*Q_bwe_exc */ - curr_pow_fx = L_mac0( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ + prev_pow_fx = L_mac0( prev_pow_fx, shaped_shb_excitation_fx[i], shaped_shb_excitation_fx[i] ); /* 2*Q_bwe_exc */ + curr_pow_fx = L_mac0( curr_pow_fx, shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10], shaped_shb_excitation_fx[i + L_SHB_LAHEAD + 10] ); /* 2*Q_bwe_exc */ #endif - } + } - if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) - { - /*curr_pow_fx = Mult_32_16( curr_pow_fx, 8192);*/ /* Q(2*Q_bwe_exc) */ - curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* scale by 0.25 */ + if ( GT_16( voice_factors_fx[0], 24576 /*0.75f Q15*/ ) ) + { + /*curr_pow_fx = Mult_32_16( curr_pow_fx, 8192);*/ /* Q(2*Q_bwe_exc) */ + curr_pow_fx = L_shr( curr_pow_fx, 2 ); /* scale by 0.25 */ + } + + Lscale = root_a_over_b_fx( curr_pow_fx, + shl( Q_bwe_exc, 1 ), + prev_pow_fx, + shl( Q_bwe_exc, 1 ), + &exp ); } - Lscale = root_a_over_b_fx( curr_pow_fx, - shl( Q_bwe_exc, 1 ), - prev_pow_fx, - shl( Q_bwe_exc, 1 ), - &exp ); FOR( i = 0; i < L_SHB_LAHEAD; i++ ) { L_tmp = Mult_32_16( Lscale, shaped_shb_excitation_fx[i] ); /* Q(16-exp+Q_bwe_exc) */ @@ -3758,8 +3775,8 @@ void swb_tbe_enc_ivas_fx( tmp = i_mult_o( sub( i, 19 ), 3277 /*0.1f Q15*/, &Overflow ); /* Q15 */ L_tmp1 = Mult_32_16( L_shl_o( 1, sub( 31, exp ), &Overflow ), tmp ); /* Q31-exp */ #else - tmp = i_mult( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ - L_tmp1 = Mult_32_16( L_shl( 1, sub( 31, exp ) ), tmp ); /* Q31-exp */ + tmp = i_mult( sub( i, 19 ), 3277 /*0.1f Q15*/ ); /* Q15 */ + L_tmp1 = Mult_32_16( L_shl( 1, sub( 31, exp ) ), tmp ); /* Q31-exp */ #endif tmp = sub( 32767 /*1.0f Q15*/, tmp ); Lscale = L_add( Mult_32_16( Lscale, tmp ), L_tmp1 ); @@ -3767,7 +3784,7 @@ void swb_tbe_enc_ivas_fx( #ifdef BASOP_NOGLOB shaped_shb_excitation_fx[i] = round_fx_o( L_shl_o( L_tmp, exp, &Overflow ), &Overflow ); /* Q_bwe_exc */ #else - shaped_shb_excitation_fx[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ + shaped_shb_excitation_fx[i] = round_fx( L_shl( L_tmp, exp ) ); /* Q_bwe_exc */ #endif move16(); } @@ -4276,7 +4293,7 @@ void swb_tbe_enc_ivas_fx( #ifdef BASOP_NOGLOB tmp = round_fx_o( L_shl_o( L_tmp, 31 - ( 7 - exp ), &Overflow ), &Overflow ); /* Q15 */ #else - tmp = round_fx( L_shl( L_tmp, 31 - ( 7 - exp ) ) ); /* Q15 */ + tmp = round_fx( L_shl( L_tmp, 31 - ( 7 - exp ) ) ); /* Q15 */ #endif } tmp = s_min( tmp, 32767 /*1.0f Q15*/ ); @@ -4550,10 +4567,10 @@ static void EstimateSHBFrameGain_fx( sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[i] ), &Overflow ); /*Q_synSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_synSHB */ #else - sig = mult_r( oriSHB[i], win_shb[i] ); /* Q_oriSHB */ - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_orisHB*/ - sig = round_fx( Mult_32_16( mod_syn[i], win_shb[i] ) ); /*Q_synSHB */ - synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_synSHB */ + sig = mult_r( oriSHB[i], win_shb[i] ); /* Q_oriSHB */ + oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_orisHB*/ + sig = round_fx( Mult_32_16( mod_syn[i], win_shb[i] ) ); /*Q_synSHB */ + synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_synSHB */ #endif } @@ -4564,9 +4581,9 @@ static void EstimateSHBFrameGain_fx( sig = round_fx_o( mod_syn[i], &Overflow ); /* Q_oriSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ #else - oriNrg = L_mac0( oriNrg, oriSHB[i], oriSHB[i] ); /* 2*Q_oriSHB */ - sig = round_fx( mod_syn[i] ); /* Q_oriSHB */ - synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_oriSHB */ + oriNrg = L_mac0( oriNrg, oriSHB[i], oriSHB[i] ); /* 2*Q_oriSHB */ + sig = round_fx( mod_syn[i] ); /* Q_oriSHB */ + synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_oriSHB */ #endif } @@ -4580,8 +4597,8 @@ static void EstimateSHBFrameGain_fx( sig = round_fx_o( Mult_32_16( mod_syn[i], win_shb[l_frame + l_shb_lahead - 1 - i] ), &Overflow ); /* Q_oriSHB */ synNrg = L_mac0_o( synNrg, sig, sig, &Overflow ); /* 2*Q_oriSHB */ #else - sig = mult_r( oriSHB[i], win_shb[l_frame + l_shb_lahead - 1 - i] ); /* Q_oriSHB */ - oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB */ + sig = mult_r( oriSHB[i], win_shb[l_frame + l_shb_lahead - 1 - i] ); /* Q_oriSHB */ + oriNrg = L_mac0( oriNrg, sig, sig ); /* 2*Q_oriSHB */ sig = round_fx( Mult_32_16( mod_syn[i], win_shb[l_frame + l_shb_lahead - 1 - i] ) ); /* Q_oriSHB */ synNrg = L_mac0( synNrg, sig, sig ); /* 2*Q_oriSHB */ diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c index a4225f2ce8d001d8eeaf787e50bffb55f7b8a096..f10b01afbc95be3437b9539806f7e5040c7a1b26 100644 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -1571,7 +1571,7 @@ void ProcessIGF_ivas_fx( q_A = 0; move16(); - ITF_Detect_ivas_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) ); + ITF_Detect_fx( hIGFEnc->spec_be_igf, hIGFEnc->infoStartLine, hIGFEnc->infoStopLine, 8 /*maxOrder*/, A, &q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc->spec_be_igf_e ) ); test(); IF( LT_32( L_deposit_l( hIGFEnc->tns_predictionGain ), 9646899 /* 1.15 in Q23 */ ) && LT_32( L_deposit_l( predictionGain ), 9646899 /* 1.15 in Q23 */ ) ) @@ -1748,7 +1748,10 @@ void ProcessStereoIGF_fx( Q_A = 0; move16(); - ITF_Detect_ivas_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); + predictionGain = 0; + move16(); + + ITF_Detect_fx( hIGFEnc[ch]->spec_be_igf, hIGFEnc[ch]->infoStartLine, hIGFEnc[ch]->infoStopLine, 8 /*maxOrder*/, A, &Q_A, &predictionGain, &curr_order, sub( 31, hIGFEnc[ch]->spec_be_igf_e ) ); test(); hIGFEnc[ch]->flatteningTrigger = LT_32( hIGFEnc[ch]->tns_predictionGain, ONE_POINT_ONE_FIVE_Q23 ) && LT_32( predictionGain, ONE_POINT_ONE_FIVE_Q7 ); diff --git a/lib_enc/tcx_utils_enc_fx.c b/lib_enc/tcx_utils_enc_fx.c index cef9e3066157fa14291decf36385bddde4f3525d..950856d739fcd502840e58411cbc9cb35bc99944 100644 --- a/lib_enc/tcx_utils_enc_fx.c +++ b/lib_enc/tcx_utils_enc_fx.c @@ -315,6 +315,122 @@ void AnalyzePowerSpectrum_fx( } } +void AnalyzePowerSpectrum_ivas_fx( + Encoder_State *st, /* i/o: encoder states */ + Word16 L_frame, /* input: frame length */ + Word16 L_frameTCX, /* input: full band frame length */ + Word16 left_overlap, /* input: left overlap length */ + Word16 right_overlap, /* input: right overlap length */ + Word32 const mdctSpectrum[], /* input: MDCT spectrum */ + Word16 mdctSpectrum_e, + Word16 const signal[], /* input: windowed signal corresponding to mdctSpectrum */ + Word32 powerSpec[], /* output: Power spectrum. Can point to signal */ + Word16 *powerSpec_e ) +{ + Word16 i, iStart, iEnd, lowpassLine; + Word16 tmp, s1, s2; + Word32 tmp32; + Word8 tmp8; + TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc; + + lowpassLine = L_frameTCX; + move16(); + + *powerSpec_e = 16; + move16(); + TCX_MDST( signal, powerSpec, powerSpec_e, left_overlap, sub( L_frameTCX, shr( add( left_overlap, right_overlap ), 1 ) ), right_overlap, st->element_mode ); + + iStart = 0; + move16(); + iEnd = L_frameTCX; + move16(); + + IF( st->narrowBand != 0 ) + { + attenuateNbSpectrum_fx( L_frameTCX, powerSpec ); + } + + /* get shift to common exponent */ + s1 = 0; + move16(); + s2 = 0; + move16(); + tmp = sub( mdctSpectrum_e, *powerSpec_e ); + if ( tmp > 0 ) + { + s2 = negate( tmp ); + } + if ( tmp < 0 ) + { + s1 = tmp; + move16(); + } + + /* get headroom */ + tmp = sub( getScaleFactor32( mdctSpectrum, L_frameTCX ), s1 ); + tmp = s_min( tmp, sub( getScaleFactor32( powerSpec, L_frameTCX ), s2 ) ); + s1 = add( s1, tmp ); + s2 = add( s2, tmp ); + + /* power spectrum: MDCT^2 + MDST^2 */ + FOR( i = iStart; i < iEnd; i++ ) + { + // To be checked +#ifdef BASOP_NOGLOB + tmp = round_fx_sat( L_shl_sat( mdctSpectrum[i], s1 ) ); +#else + tmp = round_fx( L_shl( mdctSpectrum[i], s1 ) ); +#endif + tmp32 = L_mult0( tmp, tmp ); + +#ifdef BASOP_NOGLOB + tmp = round_fx_sat( L_shl_sat( powerSpec[i], s2 ) ); +#else + tmp = round_fx( L_shl( powerSpec[i], s2 ) ); +#endif + tmp32 = L_mac0( tmp32, tmp, tmp ); + + powerSpec[i] = tmp32; + move32(); + } + + *powerSpec_e = add( shl( sub( mdctSpectrum_e, s1 ), 1 ), 1 ); + move16(); + + tmp8 = 0; + move16(); + test(); + if ( L_msu0( L_mult0( st->L_frame, extract_l( st->last_sr_core ) ), st->L_frame_past, extract_l( st->sr_core ) ) != 0 || NE_16( st->last_core, TCX_20_CORE ) ) + { + tmp8 = 1; + move16(); + } + + ComputeSpectrumNoiseMeasure_fx( powerSpec, + L_frameTCX, + divide3216( L_mult( hTcxEnc->nmStartLine, L_frame ), st->L_frame ), + tmp8, + hTcxEnc->memQuantZeros, + lowpassLine ); + + IF( LE_32( st->total_brate, ACELP_24k40 ) ) + { + lowpassLine = shl( mult( st->hTcxCfg->bandwidth, L_frame ), 1 ); + + test(); + detectLowpassFac( powerSpec, *powerSpec_e, + L_frame, + sub( st->last_core, ACELP_CORE ) == 0, + &hTcxEnc->measuredBwRatio, + lowpassLine ); + } + ELSE + { + hTcxEnc->measuredBwRatio = 0x4000; + move16(); + } +} + void AdaptLowFreqEmph_fx( Word32 x[], Word16 x_e, Word16 xq[],