Loading lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ #define FIX_2455_HARMONIZE_generate_comfort_noise_enc /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */ #define FIX_2455_HARMONIZE_configureFdCngEnc /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */ #define FIX_2463_EVS_BWE_LSF /* VA: basop issue 2463: harmonize calling of Quant_BWE_LSF_fx() */ #define FIX_2489_HARMONIZE_FdCng_encodeSID /* FhG: harmonize FdCng_encodeSID_fx() and FdCng_encodeSID_ivas_fx() */ /* #################### End BE switches ################################## */ Loading lib_enc/acelp_core_enc_fx.c +8 −0 Original line number Diff line number Diff line Loading @@ -358,7 +358,11 @@ ivas_error acelp_core_enc_fx( test(); IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID FdCng_encodeSID_fx( st ); #else FdCng_encodeSID_fx( st->hFdCngEnc, st, st->preemph_fac ); #endif st->hDtxEnc->last_CNG_L_frame = st->L_frame; move16(); } Loading Loading @@ -397,7 +401,11 @@ ivas_error acelp_core_enc_fx( test(); IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID FdCng_encodeSID_fx( st ); #else FdCng_encodeSID_ivas_fx( st ); #endif st->hDtxEnc->last_CNG_L_frame = st->L_frame; move16(); } Loading lib_enc/enc_acelp_tcx_main_fx.c +4 −0 Original line number Diff line number Diff line Loading @@ -88,7 +88,11 @@ void enc_acelp_tcx_main_fx( /* Run SID Coder */ IF( st->core_brate == SID_2k40 ) { #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID FdCng_encodeSID_fx( st ); #else FdCng_encodeSID_fx( st->hFdCngEnc, st, st->preemph_fac ); #endif } /* Generate Comfort Noise */ Loading lib_enc/fd_cng_enc_fx.c +369 −1 Original line number Diff line number Diff line Loading @@ -1071,7 +1071,7 @@ static void msvq_encoder( return; } #ifndef FIX_2489_HARMONIZE_FdCng_encodeSID /* FdCng_encodeSID_fx Loading @@ -1091,6 +1091,7 @@ static void msvq_encoder( Returns: void */ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG structure containing all buffers and variables */ Encoder_State *corest, Loading Loading @@ -1293,6 +1294,7 @@ void FdCng_encodeSID_fx( return; } #endif /*FIX_2489_HARMONIZE_FdCng_encodeSID*/ #ifndef FIX_2455_HARMONIZE_generate_comfort_noise_enc void generate_comfort_noise_enc_fx( Loading Loading @@ -2483,6 +2485,371 @@ void perform_noise_estimation_enc_ivas_fx( * * Generate a bitstream out of the partition levels *-------------------------------------------------------------------*/ #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID void FdCng_encodeSID_fx( Encoder_State *corest /* i/o: encoder state structure */ ) { Word16 i, index, N; Word32 temp, gain_fx, e_fx; HANDLE_FD_CNG_ENC hFdCngEnc = corest->hFdCngEnc; HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; Word16 preemph_fac = corest->preemph_fac; // Q15 move16(); BSTR_ENC_HANDLE hBstr = corest->hBstr; Word16 indices[32]; Word32 v_fx[32]; Word32 *E_fx; Word16 v_e, E_Exp; Word16 normFacN, normShiftN; Word16 normFacGain, normShiftGain; Word32 E_ExpLd64; IF( corest->element_mode > 0 ) { (void) normFacN; (void) normShiftN; (void) normFacGain; (void) normShiftGain; (void) E_ExpLd64; } ELSE { (void) v_e; } /* Init */ E_fx = hFdCngEnc->msNoiseEst_fx; N = hFdCngEnc->npartDec; move16(); E_Exp = hFdCngEnc->msNoiseEst_fx_exp; move16(); IF( corest->element_mode == 0 ) { E_ExpLd64 = L_shl( E_Exp, WORD32_BITS - 1 - LD_DATA_SCALE ); normFacN = getNormReciprocalWord16( N ); normShiftN = BASOP_util_norm_s_bands2shift( N ); normFacGain = getNormReciprocalWord16( N_GAIN_MAX - N_GAIN_MIN ); normShiftGain = BASOP_util_norm_s_bands2shift( N_GAIN_MAX - N_GAIN_MIN ); } ELSE { set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN ); } /* Convert to LOG */ e_fx = L_deposit_l( 0 ); IF( corest->element_mode == 0 ) { /* e: Q14.23 format, v_fx: Q9.23 format */ temp = Mpy_32_32_r( L_shl( 1, sub( 31, E_Exp ) ), 214748 ); /* 1e-4f, Q31-E_Exp */ FOR( i = 0; i < N; i++ ) { /* assert( E_fx[i] != 0 ); */ /* constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0) * 0.25 */ v_fx[i] = Mpy_32_16_1( L_add( BASOP_Util_Log2( L_add( E_fx[i], L_max( 1, temp ) ) ), E_ExpLd64 ), 24660 /*0.75257498916 Q15*/ ); move32(); e_fx = L_add( e_fx, L_shr( v_fx[i], normShiftN ) ); } e_fx = L_shl( Mpy_32_16_1( e_fx, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 ); } ELSE { FOR( i = 0; i < N; i++ ) { IF( E_fx[i] == 0 ) { /* 10 * log(1e-4) = 10 * (-4) = -40 */ v_fx[i] = -41943040; // -40.0 in Q20 move32(); } ELSE { v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], E_Exp ) ); // Q20 = 26+25-31 move32(); } e_fx = L_add( e_fx, L_shr( v_fx[i], 1 ) ); // Q19, add one bit headroom } } /* Normalize MSVQ input */ gain_fx = 0; move32(); IF( corest->element_mode == 0 ) { /* gain: Q9.23 format */ FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) { gain_fx = L_add( gain_fx, L_shr( v_fx[i], normShiftGain ) ); } gain_fx = L_shl( Mpy_32_16_1( gain_fx, shl( normFacGain, sub( normShiftGain, 1 ) ) ), 1 ); } ELSE { FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) { gain_fx = L_add( gain_fx, v_fx[i] ); // Q20 } /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/ gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20 FOR( i = 0; i < N; i++ ) { v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20 move32(); } v_e = 11; // Q20 move16(); } /*MSVQ*/ IF( corest->element_mode == 0 ) { Word16 v16[32]; FOR( i = 0; i < N; i++ ) { v16[i] = extract_h( L_sub( v_fx[i], gain_fx ) ); } /* MSVQ encoder */ msvq_encoder( cdk_37bits, v16, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices ); /* MSVQ decoder */ msvq_decoder( cdk_37bits, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, v16 ); FOR( i = 0; i < N; i++ ) { v_fx[i] = L_deposit_h( v16[i] ); } } ELSE { /* MSVQ encoder */ Word16 w_fx[32]; set_val_Word16( w_fx, ONE_IN_Q8, N ); Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; /* DCT domain compressed/truncated indices used for first stage */ /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched in FDCNG band domain */ Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; Word32 *invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) { /* truncated DCT21 analysis */ create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20 /* truncated IDCT21 extension to 24 bands */ extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20 Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q20 } create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 ); v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); } /* Compute gain */ IF( corest->element_mode == 0 ) { /*Q9.23 format */ gain_fx = 0; FOR( i = 0; i < N; i++ ) { gain_fx = L_add( gain_fx, L_shr( v_fx[i], normShiftN ) ); } gain_fx = L_sub( e_fx, L_shl( Mpy_32_16_1( gain_fx, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 ) ); /* Apply bitrate-dependant scale */ { apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); } } ELSE { gain_fx = 0; move32(); FOR( i = 0; i < N; i++ ) { gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e } e_fx = L_shl( e_fx, sub( 12, v_e ) ); // Q = 31 - v_e gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23 /* Apply bitrate-dependant scale */ apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); } /* Quantize gain */ IF( corest->element_mode == 0 ) { /*Q14.23 format */ gain_fx = L_add( gain_fx, L_shr( gain_fx, 1 ) ); gain_fx = L_add( gain_fx, 507510784l /*60.5 Q23*/ ); index = extract_l( L_shr( gain_fx, WORD32_BITS - 1 - 8 ) ); } ELSE { temp = Madd_32_32( L_shl( GAIN_Q_OFFSET_IVAS_FX_Q0, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22 index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0 } if ( index < 0 ) { index = 0; move16(); } if ( GT_16( index, 127 ) ) { index = 127; move16(); } /* Apply gain and undo log */ IF( corest->element_mode == 0 ) { /* gain Q14.23 format */ gain_fx = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 ); gain_fx = L_sub( gain_fx, 503316480l /*60.0 Q23*/ ); gain_fx = Mpy_32_16_1( gain_fx, 21845 /*2.0f/3.0f Q15*/ ); Word16 sidNoiseEst_Exp = 0; /* sidNoiseEst: format Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */ /* calculate worst case for scaling */ { Word32 maxVal = 0x80000000 /*-1.0 Q31*/; move32(); FOR( i = 0; i < N; i++ ) { maxVal = L_max( maxVal, v_fx[i] ); } maxVal = L_add( maxVal, gain_fx ); maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 ); move16(); WHILE( maxVal >= 0 ) { maxVal = L_sub( maxVal, 33554432l /*0.015625 Q31*/ ); sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 ); } hFdCngCom->sidNoiseEstExp = sidNoiseEst_Exp; move16(); E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE ); } FOR( i = 0; i < N; i++ ) { temp = L_add( v_fx[i], gain_fx ); temp = L_shl( Mpy_32_16_1( temp, 21771 /*0.66438561897 Q15*/ ), 1 ); temp = L_sub( temp, E_ExpLd64 ); assert( temp < 0 ); hFdCngCom->sidNoiseEst[i] = BASOP_Util_InvLog2( temp ); move32(); } } ELSE { gain_fx = L_shl( L_mult0( sub( index, GAIN_Q_OFFSET_IVAS_FX_Q0 ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e Word16 exp[32]; FOR( i = 0; i < N; i++ ) { temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] ); move32(); } maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp ); FOR( i = 0; i < N; i++ ) { hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp move32(); } } /* NB last band energy compensation */ IF( EQ_16( hFdCngCom->CngBandwidth, NB ) ) { hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) move32(); } test(); IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) { hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) move32(); } /* Write bitstream */ IF( EQ_16( corest->codec_mode, MODE2 ) ) { FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) { push_next_indice( hBstr, indices[i], bits_37bits[i] ); } push_next_indice( hBstr, index, 7 ); } ELSE { Word16 is_frame_len_16k = 0; move16(); Word16 IDX = IND_ACELP_16KHZ; move16(); push_indice( hBstr, IND_SID_TYPE, 1, 1 ); if ( corest->element_mode > 0 ) { IDX = IND_BWIDTH; move16(); } push_indice( hBstr, IDX, corest->bwidth, 2 ); if ( EQ_16( corest->L_frame, L_FRAME16k ) ) { is_frame_len_16k = 1; move16(); } push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 ); FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) { push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); } push_indice( hBstr, IND_ENERGY, index, 7 ); } /* Interpolate the bin/band-wise levels from the partition levels */ scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; move16(); lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); return; } #else /*FIX_2489_HARMONIZE_FdCng_encodeSID*/ void FdCng_encodeSID_ivas_fx( Encoder_State *st /* i/o: encoder state structure */ ) Loading Loading @@ -2710,6 +3077,7 @@ void FdCng_encodeSID_ivas_fx( return; } #endif /*FIX_2489_HARMONIZE_FdCng_encodeSID*/ /*-------------------------------------------------------------------* Loading lib_enc/prot_fx_enc.h +8 −0 Original line number Diff line number Diff line Loading @@ -1473,11 +1473,17 @@ void CNG_enc_fx( Word16 *sid_bw ); /* Generate a bitstream out of the partition levels */ #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC st /* i/o: FD_CNG structure containing all buffers and variables */ ); #else void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC st, /* i/o: FD_CNG structure containing all buffers and variables */ Encoder_State *corest, Word16 preemph_fac /* i : preemphase factor */ ); #endif #ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc /* Generate the comfort noise based on the target noise level */ Loading Loading @@ -1647,9 +1653,11 @@ Word16 AdjustFirstSID_fx( Encoder_State *stcod /* i : pointer to Coder_State_Plus structure */ ); #ifndef FIX_2489_HARMONIZE_FdCng_encodeSID void FdCng_encodeSID_ivas_fx( Encoder_State *st /* i/o: encoder state structure */ ); #endif void resetFdCngEnc_fx( Encoder_State *st ); Loading Loading
lib_com/options.h +1 −0 Original line number Diff line number Diff line Loading @@ -89,6 +89,7 @@ #define FIX_2455_HARMONIZE_generate_comfort_noise_enc /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */ #define FIX_2455_HARMONIZE_configureFdCngEnc /* FhG: harmonize generate_comfort_noise_enc and generate_comfort_noise_enc_ivas */ #define FIX_2463_EVS_BWE_LSF /* VA: basop issue 2463: harmonize calling of Quant_BWE_LSF_fx() */ #define FIX_2489_HARMONIZE_FdCng_encodeSID /* FhG: harmonize FdCng_encodeSID_fx() and FdCng_encodeSID_ivas_fx() */ /* #################### End BE switches ################################## */ Loading
lib_enc/acelp_core_enc_fx.c +8 −0 Original line number Diff line number Diff line Loading @@ -358,7 +358,11 @@ ivas_error acelp_core_enc_fx( test(); IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID FdCng_encodeSID_fx( st ); #else FdCng_encodeSID_fx( st->hFdCngEnc, st, st->preemph_fac ); #endif st->hDtxEnc->last_CNG_L_frame = st->L_frame; move16(); } Loading Loading @@ -397,7 +401,11 @@ ivas_error acelp_core_enc_fx( test(); IF( EQ_32( st->core_brate, SID_2k40 ) && NE_16( st->element_mode, IVAS_CPE_MDCT ) ) { #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID FdCng_encodeSID_fx( st ); #else FdCng_encodeSID_ivas_fx( st ); #endif st->hDtxEnc->last_CNG_L_frame = st->L_frame; move16(); } Loading
lib_enc/enc_acelp_tcx_main_fx.c +4 −0 Original line number Diff line number Diff line Loading @@ -88,7 +88,11 @@ void enc_acelp_tcx_main_fx( /* Run SID Coder */ IF( st->core_brate == SID_2k40 ) { #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID FdCng_encodeSID_fx( st ); #else FdCng_encodeSID_fx( st->hFdCngEnc, st, st->preemph_fac ); #endif } /* Generate Comfort Noise */ Loading
lib_enc/fd_cng_enc_fx.c +369 −1 Original line number Diff line number Diff line Loading @@ -1071,7 +1071,7 @@ static void msvq_encoder( return; } #ifndef FIX_2489_HARMONIZE_FdCng_encodeSID /* FdCng_encodeSID_fx Loading @@ -1091,6 +1091,7 @@ static void msvq_encoder( Returns: void */ void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG structure containing all buffers and variables */ Encoder_State *corest, Loading Loading @@ -1293,6 +1294,7 @@ void FdCng_encodeSID_fx( return; } #endif /*FIX_2489_HARMONIZE_FdCng_encodeSID*/ #ifndef FIX_2455_HARMONIZE_generate_comfort_noise_enc void generate_comfort_noise_enc_fx( Loading Loading @@ -2483,6 +2485,371 @@ void perform_noise_estimation_enc_ivas_fx( * * Generate a bitstream out of the partition levels *-------------------------------------------------------------------*/ #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID void FdCng_encodeSID_fx( Encoder_State *corest /* i/o: encoder state structure */ ) { Word16 i, index, N; Word32 temp, gain_fx, e_fx; HANDLE_FD_CNG_ENC hFdCngEnc = corest->hFdCngEnc; HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom; Word16 preemph_fac = corest->preemph_fac; // Q15 move16(); BSTR_ENC_HANDLE hBstr = corest->hBstr; Word16 indices[32]; Word32 v_fx[32]; Word32 *E_fx; Word16 v_e, E_Exp; Word16 normFacN, normShiftN; Word16 normFacGain, normShiftGain; Word32 E_ExpLd64; IF( corest->element_mode > 0 ) { (void) normFacN; (void) normShiftN; (void) normFacGain; (void) normShiftGain; (void) E_ExpLd64; } ELSE { (void) v_e; } /* Init */ E_fx = hFdCngEnc->msNoiseEst_fx; N = hFdCngEnc->npartDec; move16(); E_Exp = hFdCngEnc->msNoiseEst_fx_exp; move16(); IF( corest->element_mode == 0 ) { E_ExpLd64 = L_shl( E_Exp, WORD32_BITS - 1 - LD_DATA_SCALE ); normFacN = getNormReciprocalWord16( N ); normShiftN = BASOP_util_norm_s_bands2shift( N ); normFacGain = getNormReciprocalWord16( N_GAIN_MAX - N_GAIN_MIN ); normShiftGain = BASOP_util_norm_s_bands2shift( N_GAIN_MAX - N_GAIN_MIN ); } ELSE { set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN ); } /* Convert to LOG */ e_fx = L_deposit_l( 0 ); IF( corest->element_mode == 0 ) { /* e: Q14.23 format, v_fx: Q9.23 format */ temp = Mpy_32_32_r( L_shl( 1, sub( 31, E_Exp ) ), 214748 ); /* 1e-4f, Q31-E_Exp */ FOR( i = 0; i < N; i++ ) { /* assert( E_fx[i] != 0 ); */ /* constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0) * 0.25 */ v_fx[i] = Mpy_32_16_1( L_add( BASOP_Util_Log2( L_add( E_fx[i], L_max( 1, temp ) ) ), E_ExpLd64 ), 24660 /*0.75257498916 Q15*/ ); move32(); e_fx = L_add( e_fx, L_shr( v_fx[i], normShiftN ) ); } e_fx = L_shl( Mpy_32_16_1( e_fx, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 ); } ELSE { FOR( i = 0; i < N; i++ ) { IF( E_fx[i] == 0 ) { /* 10 * log(1e-4) = 10 * (-4) = -40 */ v_fx[i] = -41943040; // -40.0 in Q20 move32(); } ELSE { v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], E_Exp ) ); // Q20 = 26+25-31 move32(); } e_fx = L_add( e_fx, L_shr( v_fx[i], 1 ) ); // Q19, add one bit headroom } } /* Normalize MSVQ input */ gain_fx = 0; move32(); IF( corest->element_mode == 0 ) { /* gain: Q9.23 format */ FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) { gain_fx = L_add( gain_fx, L_shr( v_fx[i], normShiftGain ) ); } gain_fx = L_shl( Mpy_32_16_1( gain_fx, shl( normFacGain, sub( normShiftGain, 1 ) ) ), 1 ); } ELSE { FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ ) { gain_fx = L_add( gain_fx, v_fx[i] ); // Q20 } /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/ gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20 FOR( i = 0; i < N; i++ ) { v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20 move32(); } v_e = 11; // Q20 move16(); } /*MSVQ*/ IF( corest->element_mode == 0 ) { Word16 v16[32]; FOR( i = 0; i < N; i++ ) { v16[i] = extract_h( L_sub( v_fx[i], gain_fx ) ); } /* MSVQ encoder */ msvq_encoder( cdk_37bits, v16, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices ); /* MSVQ decoder */ msvq_decoder( cdk_37bits, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, v16 ); FOR( i = 0; i < N; i++ ) { v_fx[i] = L_deposit_h( v16[i] ); } } ELSE { /* MSVQ encoder */ Word16 w_fx[32]; set_val_Word16( w_fx, ONE_IN_Q8, N ); Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC]; Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN]; /* DCT domain compressed/truncated indices used for first stage */ /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched in FDCNG band domain */ Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; Word32 *invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */ IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) ) { /* truncated DCT21 analysis */ create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20 /* truncated IDCT21 extension to 24 bands */ extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20 Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q20 } create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31 msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices ); msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 ); v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) ); } /* Compute gain */ IF( corest->element_mode == 0 ) { /*Q9.23 format */ gain_fx = 0; FOR( i = 0; i < N; i++ ) { gain_fx = L_add( gain_fx, L_shr( v_fx[i], normShiftN ) ); } gain_fx = L_sub( e_fx, L_shl( Mpy_32_16_1( gain_fx, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 ) ); /* Apply bitrate-dependant scale */ { apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO ); } } ELSE { gain_fx = 0; move32(); FOR( i = 0; i < N; i++ ) { gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e } e_fx = L_shl( e_fx, sub( 12, v_e ) ); // Q = 31 - v_e gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23 /* Apply bitrate-dependant scale */ apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); } /* Quantize gain */ IF( corest->element_mode == 0 ) { /*Q14.23 format */ gain_fx = L_add( gain_fx, L_shr( gain_fx, 1 ) ); gain_fx = L_add( gain_fx, 507510784l /*60.5 Q23*/ ); index = extract_l( L_shr( gain_fx, WORD32_BITS - 1 - 8 ) ); } ELSE { temp = Madd_32_32( L_shl( GAIN_Q_OFFSET_IVAS_FX_Q0, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22 index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0 } if ( index < 0 ) { index = 0; move16(); } if ( GT_16( index, 127 ) ) { index = 127; move16(); } /* Apply gain and undo log */ IF( corest->element_mode == 0 ) { /* gain Q14.23 format */ gain_fx = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 ); gain_fx = L_sub( gain_fx, 503316480l /*60.0 Q23*/ ); gain_fx = Mpy_32_16_1( gain_fx, 21845 /*2.0f/3.0f Q15*/ ); Word16 sidNoiseEst_Exp = 0; /* sidNoiseEst: format Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */ /* calculate worst case for scaling */ { Word32 maxVal = 0x80000000 /*-1.0 Q31*/; move32(); FOR( i = 0; i < N; i++ ) { maxVal = L_max( maxVal, v_fx[i] ); } maxVal = L_add( maxVal, gain_fx ); maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 ); move16(); WHILE( maxVal >= 0 ) { maxVal = L_sub( maxVal, 33554432l /*0.015625 Q31*/ ); sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 ); } hFdCngCom->sidNoiseEstExp = sidNoiseEst_Exp; move16(); E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE ); } FOR( i = 0; i < N; i++ ) { temp = L_add( v_fx[i], gain_fx ); temp = L_shl( Mpy_32_16_1( temp, 21771 /*0.66438561897 Q15*/ ), 1 ); temp = L_sub( temp, E_ExpLd64 ); assert( temp < 0 ); hFdCngCom->sidNoiseEst[i] = BASOP_Util_InvLog2( temp ); move32(); } } ELSE { gain_fx = L_shl( L_mult0( sub( index, GAIN_Q_OFFSET_IVAS_FX_Q0 ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e Word16 exp[32]; FOR( i = 0; i < N; i++ ) { temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] ); move32(); } maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp ); FOR( i = 0; i < N; i++ ) { hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp move32(); } } /* NB last band energy compensation */ IF( EQ_16( hFdCngCom->CngBandwidth, NB ) ) { hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) move32(); } test(); IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) ) { hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp) move32(); } /* Write bitstream */ IF( EQ_16( corest->codec_mode, MODE2 ) ) { FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) { push_next_indice( hBstr, indices[i], bits_37bits[i] ); } push_next_indice( hBstr, index, 7 ); } ELSE { Word16 is_frame_len_16k = 0; move16(); Word16 IDX = IND_ACELP_16KHZ; move16(); push_indice( hBstr, IND_SID_TYPE, 1, 1 ); if ( corest->element_mode > 0 ) { IDX = IND_BWIDTH; move16(); } push_indice( hBstr, IDX, corest->bwidth, 2 ); if ( EQ_16( corest->L_frame, L_FRAME16k ) ) { is_frame_len_16k = 1; move16(); } push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 ); FOR( i = 0; i < FD_CNG_stages_37bits; i++ ) { push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] ); } push_indice( hBstr, IND_ENERGY, index, 7 ); } /* Interpolate the bin/band-wise levels from the partition levels */ scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 ); hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp; move16(); lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac ); return; } #else /*FIX_2489_HARMONIZE_FdCng_encodeSID*/ void FdCng_encodeSID_ivas_fx( Encoder_State *st /* i/o: encoder state structure */ ) Loading Loading @@ -2710,6 +3077,7 @@ void FdCng_encodeSID_ivas_fx( return; } #endif /*FIX_2489_HARMONIZE_FdCng_encodeSID*/ /*-------------------------------------------------------------------* Loading
lib_enc/prot_fx_enc.h +8 −0 Original line number Diff line number Diff line Loading @@ -1473,11 +1473,17 @@ void CNG_enc_fx( Word16 *sid_bw ); /* Generate a bitstream out of the partition levels */ #ifdef FIX_2489_HARMONIZE_FdCng_encodeSID void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC st /* i/o: FD_CNG structure containing all buffers and variables */ ); #else void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC st, /* i/o: FD_CNG structure containing all buffers and variables */ Encoder_State *corest, Word16 preemph_fac /* i : preemphase factor */ ); #endif #ifdef FIX_2455_HARMONIZE_generate_comfort_noise_enc /* Generate the comfort noise based on the target noise level */ Loading Loading @@ -1647,9 +1653,11 @@ Word16 AdjustFirstSID_fx( Encoder_State *stcod /* i : pointer to Coder_State_Plus structure */ ); #ifndef FIX_2489_HARMONIZE_FdCng_encodeSID void FdCng_encodeSID_ivas_fx( Encoder_State *st /* i/o: encoder state structure */ ); #endif void resetFdCngEnc_fx( Encoder_State *st ); Loading