diff --git a/lib_com/options.h b/lib_com/options.h index e628cf13df47edce08dc03fdac03c2c31a968cf5..eead3c8ca079bf6a5b6cfc35eefc9b60ece6149d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -103,6 +103,7 @@ #define HARMONIZE_DCT /* VA: removal of duplicated DCT functions */ #define FIX_2489_HARMONIZE_FdCng_encodeSID /* FhG: harmonize FdCng_encodeSID_fx() and FdCng_encodeSID_ivas_fx() */ #define FIX_1527_CMR_BITRATE_IDX /* Fix for incorrect bitrate idx packed in rtp CMR E-byte */ +#define HARMONIZE_2494_FdCng_decodeSID_fx /* FhG: harmonize FdCng_decodeSID_fx with _ivas_ version */ /* #################### End BE switches ################################## */ diff --git a/lib_com/prot_fx.h b/lib_com/prot_fx.h index 1df94661325ecfc10e10246218d3b7f577e5184d..21035960d97191217a2cc5cd19087a779e3a4b78 100644 --- a/lib_com/prot_fx.h +++ b/lib_com/prot_fx.h @@ -6651,9 +6651,14 @@ void perform_noise_estimation_dec_ivas_fx( ); /* Decode the CLDFB-CNG bitstream */ +#ifdef HARMONIZE_2494_FdCng_decodeSID_fx +void FdCng_decodeSID_fx( + Decoder_State *st ); /* i/o: decoder state structure */ +#else void FdCng_decodeSID_fx( HANDLE_FD_CNG_COM st, /* i/o: FD_CNG structure containing all buffers and variables */ Decoder_State *corest ); /* i/o: decoder state structure */ +#endif void noisy_speech_detection_fx( HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ @@ -9595,9 +9600,11 @@ void SynthesisSTFT_fx( const Word16 nchan_out /* i : number of output channels */ ); +#ifndef HARMONIZE_2494_FdCng_decodeSID_fx void FdCng_decodeSID_ivas_fx( Decoder_State *st /* i/o: decoder state structure */ ); +#endif void cldfb_restore_memory_ivas_fx( HANDLE_CLDFB_FILTER_BANK hs /* i/o: filter bank handle */ diff --git a/lib_dec/acelp_core_dec_fx.c b/lib_dec/acelp_core_dec_fx.c index 0152fa0989378f6ae1ef6b8aff7de62bcbd82643..48101e1aa546fe1fca17d91a86a0686e205455ac 100644 --- a/lib_dec/acelp_core_dec_fx.c +++ b/lib_dec/acelp_core_dec_fx.c @@ -166,7 +166,11 @@ ivas_error acelp_core_dec_fx( /* Only run parameter decoding in SID frames */ IF( EQ_32( st->core_brate, SID_2k40 ) ) { +#ifndef HARMONIZE_2494_FdCng_decodeSID_fx FdCng_decodeSID_ivas_fx( st ); +#else + FdCng_decodeSID_fx( st ); +#endif Word16 n1, n2; n1 = L_norm_arr( st->hFdCngDec->hFdCngCom->sidNoiseEst, NPART ); @@ -663,14 +667,21 @@ ivas_error acelp_core_dec_fx( { IF( EQ_16( st->element_mode, EVS_MONO ) ) { +#ifndef HARMONIZE_2494_FdCng_decodeSID_fx FdCng_decodeSID_fx( st->hFdCngDec->hFdCngCom, st ); +#else + FdCng_decodeSID_fx( st ); +#endif } ELSE { Word16 old_NoiseEstExp = st->hFdCngDec->hFdCngCom->sidNoiseEstExp; move16(); - +#ifndef HARMONIZE_2494_FdCng_decodeSID_fx FdCng_decodeSID_ivas_fx( st ); +#else + FdCng_decodeSID_fx( st ); +#endif Scale_sig32( st->hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART, sub( old_NoiseEstExp, st->hFdCngDec->hFdCngCom->sidNoiseEstExp ) ); Scale_sig( st->hFdCngDec->hFdCngCom->A_cng, M + 1, sub( norm_s( st->hFdCngDec->hFdCngCom->A_cng[0] ), Q2 ) ); // Qx diff --git a/lib_dec/dec_acelp_tcx_main_fx.c b/lib_dec/dec_acelp_tcx_main_fx.c index 1eccbfeab0344714846a2e1d48fb2330596446d6..aed46c1efc95b3f3818508015872f31f7606c44f 100644 --- a/lib_dec/dec_acelp_tcx_main_fx.c +++ b/lib_dec/dec_acelp_tcx_main_fx.c @@ -521,7 +521,11 @@ Word16 dec_acelp_tcx_frame_fx( IF( EQ_16( st->m_frame_type, SID_FRAME ) ) { +#ifndef HARMONIZE_2494_FdCng_decodeSID_fx FdCng_decodeSID_fx( st->hFdCngDec->hFdCngCom, st ); +#else + FdCng_decodeSID_fx( st ); +#endif } /* updates */ diff --git a/lib_dec/fd_cng_dec_fx.c b/lib_dec/fd_cng_dec_fx.c index 93bedf43a00c89350d011790ead71a93914d2b5e..27772455be49f8af54eeb76b89b638c147718781 100644 --- a/lib_dec/fd_cng_dec_fx.c +++ b/lib_dec/fd_cng_dec_fx.c @@ -2142,6 +2142,7 @@ void perform_noise_estimation_dec_ivas_fx( } +#ifndef HARMONIZE_2494_FdCng_decodeSID_fx /* FdCng_decodeSID_fx @@ -2279,6 +2280,185 @@ void FdCng_decodeSID_fx( HANDLE_FD_CNG_COM st, Decoder_State *corest ) lpc_from_spectrum( st, st->startBand, st->stopFFTbin, preemph_fac ); } +#else +/* + FdCng_decodeSID_fx + + Parameters: + + st i/o: FD_CNG structure containing all buffers and variables + bs_word16 i : Bitstream + amrwb_io i : amr wideband mode + preemph_fac i : preemphase factor + + Function: + decode the FD-CNG bitstream + + Returns: + void +*/ +void FdCng_decodeSID_fx( Decoder_State *st ) +{ + Word16 N; + Word32 *sidNoiseEst; + Word16 sidNoiseEst_Exp = 0; + Word16 i, index; + HANDLE_FD_CNG_COM hFdCngCom = ( st->hFdCngDec )->hFdCngCom; + Word16 indices[32]; + Word32 v[32], gain; + Word32 *invTrfMatrix_fx; + Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; + Word32 gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0; + move16(); + move32(); + + if ( EQ_16( st->element_mode, EVS_MONO ) ) + { + gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0; /*60 Q0*/ + move32(); + } + + invTrfMatrix_fx = (Word32 *) tmpRAM_fx; + + + sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q31 - hFdCngCom->sidNoiseEstExp*/ + move16(); + + N = hFdCngCom->npart; /*Q0*/ + move16(); + hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); + move16(); + + /* Read bitstream */ + FOR( i = 0; i < stages_37bits; i++ ) + { + indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/ + move16(); + } + + index = get_next_indice_fx( st, 7 ); /*Q0*/ + + /* MSVQ decoder */ + + IF( NE_16( st->element_mode, EVS_MONO ) ) + { + create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); + msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages_37bits, N, maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 ); + } + ELSE + { + Word16 v16[32]; + msvq_decoder( cdk_37bits, stages_37bits, N, maxN_37bits, indices, v16 ); + + FOR( i = 0; i < N; i++ ) + { + v[i] = L_deposit_h( v16[i] ); /*Q23*/ + move32(); + } + } + + + /* Decode gain */ + // gain = ((float)index - gain_q_offset) / 1.5f; + /* format gain: Q9.23 */ + gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 ); + gain = L_sub( gain, L_shl( gain_q_offset, 23 ) /*60.0 Q23*/ ); /*Q23*/ + gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); /*Q23*/ + + /* Apply gain and undo log */ + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + /* format gain: Q9.23 */ + /* calculate worst case for scaling */ + Word32 maxVal = L_add( 0x80000000 /*-1.0 Q31*/, 0 ); + FOR( i = 0; i < N; i++ ) + { + maxVal = L_max( maxVal, v[i] ); /*Q23*/ + } + + maxVal = L_add( maxVal, gain ); /*Q23*/ + maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/ + + FOR( ; maxVal >= 0; maxVal -= 33554432l /*0.015625 Q31*/ ) + { + sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 ); + } + + /* format v: Q9.23, format sidNoiseEst: Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */ + Word32 E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE ); + FOR( i = 0; i < N; i++ ) + { + Word32 tmp = L_add( v[i], gain ); /*Q23*/ + tmp = L_shl( Mpy_32_16_1( tmp, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/ + tmp = L_sub( tmp, E_ExpLd64 ); + assert( tmp < 0 ); + sidNoiseEst[i] = BASOP_Util_InvLog2( tmp ); /*Q31 - hFdCngCom->sidNoiseEstExp*/ + move32(); + } + } + ELSE + { + gain = L_shr( gain, 8 ); /*Q23->Q15*/ + Word16 res_exp[NPART]; + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/ + move32(); + if ( LT_16( sidNoiseEst_Exp, res_exp[i] ) ) + { + sidNoiseEst_Exp = res_exp[i]; + move16(); + } + } + + FOR( i = 0; i < N; i++ ) + { + sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( sidNoiseEst_Exp, res_exp[i] ) ); /*Q31 - sidNoiseEst_Exp*/ + move32(); + } + } + + hFdCngCom->sidNoiseEstExp = sidNoiseEst_Exp; + move16(); + + /* NB last band energy compensation */ + + IF( EQ_16( hFdCngCom->CngBandwidth, NB ) ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); + move32(); + } + + test(); + IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) + { + sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); + move32(); + } + + scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 ); + IF( EQ_16( st->element_mode, EVS_MONO ) ) + { + hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; + move16(); + } + ELSE + { + Word16 shift1 = L_norm_arr( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ); + Word16 shift2 = L_norm_arr( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ) ); + Word16 shift = s_max( sub( hFdCngCom->sidNoiseEstExp, shift1 ), sub( hFdCngCom->cngNoiseLevelExp, shift2 ) ); + + scale_sig32( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( hFdCngCom->sidNoiseEstExp, shift ) ); + scale_sig32( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ), sub( hFdCngCom->cngNoiseLevelExp, shift ) ); + + hFdCngCom->cngNoiseLevelExp = shift; + move16(); + } + move16(); + + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac ); +} +#endif /* noisy_speech_detection_fx @@ -4343,6 +4523,7 @@ void configureFdCngDec_ivas_fx( return; } +#ifndef HARMONIZE_2494_FdCng_decodeSID_fx /*------------------------------------------------------------------- * FdCng_decodeSID_ivas_fx() * @@ -4471,6 +4652,7 @@ void FdCng_decodeSID_ivas_fx( return; } +#endif /*HARMONIZE_2494_FdCng_decodeSID_fx*/ /*------------------------------------------------------------------- * generate_masking_noise_ivas_fx()